Mailbox's code is complete; when it "doesn't work" it's almost always an activation gap (a worker not deployed, a secret unset, a migration or backfill not run, or a stale session), not a bug. This is the checklist to bring it live and to pinpoint a failure. Steps marked ⚙ run by you touch production (deploys / prod DB) and can't be run from the assistant sandbox.
How the pieces connect
Dashboard → /api/mailbox/* (Next proxy, attaches JWT) → gateway /mailbox/*
(nav shows on the `mailbox` service) (authorizes on `mailbox` OR `comms`)
→ logicspike-mailbox worker (Neon) ← sends replies through → logicspike-communication- Nav appears when the tenant has the
mailboxservice enabled (+ a fresh login). - API now authorizes on
mailboxORcomms(hardened — wascomms-only). - Create/verify relies on comms (
/internal/sending-domains+ verified domains). - Inbox visibility = org-admin (
system:owner/mailbox:accounts.manage) sees all; everyone else sees only mailboxes they hold a grant on.
Activation checklist
- ⚙ Deploy the worker —
pnpm --filter logicspike-mailbox deploy. - ⚙ Set its secrets (Windows-safe, use
secret bulknot pipedsecret put):MAILBOX_DATABASE_URL(the mailbox Neon URL — note theMAILBOX_prefix, notDATABASE_URL),GATEWAY_SECRET,INTERNAL_KEY. Verify withwrangler secret list. - ⚙ Apply the schema to the mailbox Neon (
mailbox_accounts,mailbox_account_access,mailbox_threads,mailbox_messages) viadrizzle-kit push. - ⚙ Redeploy the edge:
gateway(picks up the mailbox route/binding + the new 403-mapping andmailbox-or-commsauthorization +/healthreporting),comms(/internal/sending-domains),manager(new-signup provisioning already listscomms+mailbox). - ⚙ Provision the tenant — ensure
tenant_serviceshas bothcommsandmailboxenabled for the workspace. - ⚙ Backfill grants — run
apps/mailbox/backfill-owner-access.mjsso the owner/members holdmailbox_account_accessrows (otherwise non-admins see an empty inbox). - Re-login in the dashboard — mints a fresh JWT carrying the updated
servicesandmailbox:*/system:ownerpermissions. Without this, even a fully-deployed stack shows an empty inbox + "admin access required." - Open Mailbox → Domains, verify a domain → Mailboxes → New mailbox on it, assign a teammate, send a reply, and confirm an inbound reply lands.
Diagnostics — which step is missing?
curl https://api.vlozi.app/health→ look for"MAILBOX_SERVICE": true. Missing/false → step 1/4 (worker not deployed or gateway not redeployed).wrangler tail logicspike-mailboxwhile loading the inbox →MAILBOX_DATABASE_URLerrors ⇒ step 2/3; no requests arriving ⇒ gateway routing (step 4).- Signed-in, hit
/api/mailbox/v1/accountsand read the status:- 403
{code:"SERVICE_DISABLED"}→ entitlement (step 5) or stale session (step 7). - 5xx → worker/DB down (steps 1–3).
- 200 with
[]→ deployed & entitled, but no mailboxes/grants (steps 6/8).
- 403
- Check the DB:
tenant_serviceshas comms+mailbox enabled;mailbox_accounts/mailbox_account_accesshave rows for the tenant.
What the UI now tells you (post-hardening)
The dashboard no longer shows a bare "couldn't load." It distinguishes: 403 → "Mailbox isn't enabled here — an admin must enable it, or sign out/in"; 5xx → "Mailbox is unavailable"; empty + admin → "No mailboxes yet → Set up Mailbox"; empty + member → "No inboxes assigned to you — ask an admin." The Domains page says "couldn't reach the sending service" instead of a false "no domains yet."