Splits copilot chat messages out of the copilot_chats.messages JSONB
column into a dedicated copilot_messages table. JSONB stays canonical
during R+0 — every write path dual-writes to the new table best-effort
(try/catch + log warn, never throws).
Migration 0217 creates the table + indexes and inline-backfills history
from JSONB so OSS self-hosters don't need to run a separate script.
Write paths covered:
- post.ts (user message append)
- terminal-state.ts (assistant turn finalize)
- update-messages/route.ts (snapshot replace)
- inbox/executor.ts (background turn)
- fork/route.ts (chat clone)
- superuser/import-workflow/route.ts (chat import)
Each call threads chatModel + streamId where relevant; ON CONFLICT DO
UPDATE preserves existing stream_id / model via COALESCE.
For pre-R+1 reconciliation, run:
bun apps/sim/scripts/copilot-messages-reconcile.ts [--since='7 days']
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>