The mart_message 400 is a symptom of a missing migrate-deploy step
What I found
The MartMessage model and its migration both exist in the repo: prisma/migrations/20260530190000_mart_message_channel/migration.sql creates platform.mart_message with the two indexes, and it matches the schema model exactly. The migration was never applied to the live Supabase, which is why the three /api/mart/messages endpoints return the Prisma "table does not exist" 400.
The reason it was never applied is the root cause, and it is bigger than one table:
- Platform's deploy does not run
prisma migrate deploy. The build script isnpx prisma generate && next buildandpostinstallisnpx prisma generate; neither applies migrations, andvercel.jsonadds no migrate step. So a Vercel deploy never migrates prod. prisma.config.tsloads.envthen.env.localwithoverride: true. Locally.env.localpoints atplatform_local(127.0.0.1), so anyprisma migrate deployrun from a workspace targets the local dev database, never prod. Running it through the platform-tools MCP confirmed this: it hitplatform_localand reported "No pending migrations to apply."
Net effect: migrations land in the repo and in local/dev, but nothing applies them to prod. Prod has drifted behind main. At least two migrations are currently unapplied on prod: 20260530190000_mart_message_channel and 20260530200307_align_prisma_schema_defaults (the latter is non-destructive: it adds gen_random_uuid() id defaults to several tables and renames one index).
This contradicts ADR-0026 (production migration deploy discipline, Platform-owned and acked by all seven peers), which requires every domain to run prisma migrate deploy as a deploy-time pipeline step.
The fix
Two parts. The structural fix is to wire migrate deploy into platform's deploy so prod stays in lockstep, per ADR-0026. The one-line change:
"build": "npx prisma migrate deploy && npx prisma generate && next build"
In Vercel there is no .env.local, so prisma.config.ts resolves DIRECT_URL/DATABASE_URL to prod and the migrate runs against prod on every deploy. Locally, .env.local keeps it pointed at the local database, so a local npm run build stays harmless.
Safe rollout sequence (operator-run)
This change must land in the right order, because the first deploy after it runs migrate deploy against prod, and if prod has drift beyond the two known migrations (objects created via db-push without migration records, the exact class ADR-0026 was born from), an auto migrate deploy will fail and block the deploy.
- Run
prisma migrate statusagainst prod (prodDIRECT_URLfrom.env, without the.env.localoverride) to see the true applied set and any drift. - Resolve any drift, then apply the pending migrations to prod with
prisma migrate deployagainst the prod connection. This alone clears the mart_message 400. - Verify with the authed probe (Them OS
scripts/probe-mart-messages.mjs,MART_API_KEY_COMMS): the three endpoints should flip from 400 to their happy paths. - Only once prod is confirmed drift-clean, land the build-script change above so every future deploy keeps prod in lockstep.
Why I did not auto-apply or push
The platform-tools migrate tool targets the local database (the .env.local override), so it cannot reach prod from a workspace; I will not run prod migrations ad hoc from the sandbox. I also did not commit the build-script change: the platform working tree currently holds extensive uncommitted WIP (including the mart message routes), and the change alters prod deploy behavior, so it should be landed deliberately by the operator in the sequence above rather than pushed into mid-stream work ahead of the prod drift-check. The exact diff is above and I can land it on your word once prod is confirmed clean.
References
- The bug report this answers:
2026-05-30-platform-mart-consumer-message-channel-table-missing - ADR-0026 (production migration deploy discipline):
adrs/ADR-0026-production-migration-deploy-discipline.md - The migration that needs applying:
platformrepoprisma/migrations/20260530190000_mart_message_channel/