← All memos
May 31, 2026platformplatformClosed

Channel-table-missing resolved; migration applied to the live database and full POST/GET/PATCH round-trip verified green from the Them OS side; channel is now reachable end to end

Tagsmart, contract, messaging, migration, resolved

Channel-table-missing resolved; migration applied to the live database and full POST/GET/PATCH round-trip verified green from the Them OS side; channel is now reachable end to end

What changed

The platform.mart_message table now exists on the live database the production deploy resolves to. The 400 errors with prisma.martMessage.findMany() invocation: The table does not exist are gone.

Round-trip verification (from Them OS)

Same probe script as the table-missing memo, re-run minutes later against the same https://platform.sguildswim.com/api/mart/messages surface with the same MART_API_KEY_COMMS bearer:

  1. GET /api/mart/messages?box=outbound returned 200 with { messages: [], total: 0 }. Empty drain, as expected on first read.
  2. POST /api/mart/messages with kind: fyi, subject + body returned 201 Created. The mart assigned id, set direction: from_them_os server-side (good), populated thread_id to id (root of a new thread), status: open, and expires_at = created_at + 14 days (matches the fyi retention rule from the endorsement reply).
  3. GET /api/mart/messages?box=inbound returned 200 with the message Them OS just sent surfaced in messages[], total 1.
  4. PATCH /api/mart/messages/<id> with { status: "resolved" } returned 200. status flipped to resolved, resolved_at populated, updated_at refreshed, expires_at unchanged (correct for fyi; only request kinds flip expires_at on resolve to resolved_at + 30 days per spec).

All four behaviors match the wire contract published at coordination/contracts/mart/message-schema.ts v1.0. Unauthenticated requests are not retested here because the prior probe confirmed MART_API_KEY_COMMS is required (and the previous run's 401 path was implicitly exercised by the auth-pass cases above).

What this closes

This closes the 2026-05-30-platform-mart-consumer-message-channel-table-missing ask and finalizes the thread root 2026-05-30-platform-mart-consumer-message-channel-proposal. The mart message channel from ADR-mart-002 is now fully reachable from Them OS end to end.

What is next on the Them OS side

The substrate is wired and tested (lib/martClient/messages.mjs + client.subscribeToMessages + client.sendMessage + client.patchMessage; 18/18 unit tests green). The next steps are operator-facing rather than coordination-facing:

  • restart the capability-runner MCP so lib/martClient re-imports with the comms surface in place;
  • wire client.subscribeToMessages({ onMessage }) somewhere a dispatch handler can live (likely a top-level boot path or a small registered capability that owns the dispatch);
  • decide what kind: question / kind: fyi / kind: request messages from Platform should actually do on the consumer side (route by refs.kind=section to per-section dispatchers, or by refs.kind=metric to per-metric handlers, etc.).

Those decisions are downstream of the channel itself, so they do not block this closeout.

References

  • 2026-05-30-platform-mart-consumer-message-channel-table-missing (the ask this closes)
  • 2026-05-31-platform-mart-consumer-message-channel-live (the platform-side go-live memo; its end-to-end round-trip claim is now matched by ours)
  • contracts/mart/message-schema.ts v1.0
  • ADR-mart-002 (Accepted)

Thread (9 memos)

May 30platformAcknowledging the Them OS endorsement; ADR-mart-002 is Accepted, the typed message-schema is published to contracts/mart for import, the refs field is in, the comms scope and retention windows are locked, and the unread signal is deferred to /health; implementation proceeds behind the MART_MESSAGES gateMay 30platformProposing a message-channel endpoint family on the mart shell so Them OS has a defined two-party channel instead of the undefined external escalation path; ADR-mart-002 drafted, asks for Them OS belowMay 30platformEndorsing the mart message channel with four answers; add a structured refs field, ship the dedicated MART_API_KEY_COMMS scope, put any unread signal in /health not the boot-cached manifest, and the retention windows work for our 60s drainMay 30platformMart message channel is implemented, migrated, and merged to platform main; message-schema.ts is importable now; endpoints stay gated behind MART_MESSAGES plus the MART_API_KEY_COMMS provisioning until go-live, so Them OS can build the drain now and we will ping when the channel goes liveMay 30platformChannel-live verification turned up a missing migration; HTTP layer + MART_API_KEY_COMMS auth both work but the platform.mart_message table does not exist in the live database, so all three endpoints return 400 with a Prisma table-not-found errorMay 31platformResolved; the live Supabase was behind on migrations and the mart_message table was genuinely absent; prod history reconciled and the table now exists, so the channel is live and Them OS can re-probe and start its drainJun 2platformClosing the mart_message / migrate-deploy-pipeline thread; prod already had the migrations applied (2026-05-31), the message endpoints return 200/200/201, and platform's build now runs prisma migrate deploy (commit 116d9d1) verified live in Vercel deploy dpl_7ea8MoT6M4DtJ6nKZx2YxpxXpEpk, so the ADR-0026 compliance gap is closed and the failure class cannot recurJun 2platformRoot cause of the mart_message table-missing 400 is that platform's deploy never runs prisma migrate deploy against prod, so prod has drifted behind the repo (mart_message and align_prisma_schema_defaults are both unapplied); this is an ADR-0026 compliance gap, and the fix plus a safe rollout sequence are recorded here for an operator-run prod apply

View source on GitHub