<!-- source: openspec/changes/migrate-canvas-realtime-to-broadcast/tasks.md -->

# Tasks — migrate-canvas-realtime-to-broadcast

> Companion to proposal.md + design.md.

## Wave 1 — Scaffold

- [x] Author `proposal.md`.
- [x] Author `design.md` with D-BR-1..7.
- [x] Author `tasks.md` (this file).
- [x] Author `verification.md`.

## Wave 2 — P7a migration: canvas_messages prototype

- [ ] `supabase/migrations/<ts>_canvas_messages_broadcast.sql` — trigger function + AFTER INSERT/UPDATE/DELETE trigger per D-BR-6.
- [ ] Apply via MCP `apply_migration`; reconcile `schema_migrations.version` per memory `supabase_mcp_timestamp_reconcile`.
- [ ] Regenerate types (no schema change but trigger should appear in `pg_trigger`): `pnpm db:types`.

## Wave 3 — Bridge conditional path

- [ ] `packages/state/src/actors/supabase-realtime-bridge.ts` — `canvasChannelName(canvasId, table)` helper per D-BR-2; `HOT_TABLES` array seeded with `canvas_messages` only.
- [ ] Conditional path per D-BR-3: subscribe to broadcast for `HOT_TABLES`; legacy postgres_changes path remains for other tables.
- [ ] `visibilitychange → 'visible'` refetch wired per D-BR-4.

## Wave 4 — P7a conformance test

- [ ] `apps/studio/src/__tests__/realtime-conformance.test.ts` — single-table assertion for `canvas_messages` per D-BR-7.
- [ ] Round-trip topic-name conformance: INSERT-then-receive on the bridge's subscribed topic; topic mismatch fails fast.

## Wave 5 — P7a soak monitoring

- [ ] Synthetic monitor (from RAP-1096) emits `bridge_latency_p95_ms` metric in addition to the existing TTFT/throughput/settle metrics.
- [ ] One-week soak: dashboard tracks daily p95 against the 2000ms ceiling.
- [ ] Soak runbook: `openspec/_methodology/research/p7a-soak-runbook.md` documents the gate, when to abort, when to advance to P7b.

## Wave 6 — P7a PR + ratification

- [ ] Open PR titled `RAP-1098: P7a — broadcast prototype on canvas_messages + visibility refetch`.
- [ ] PR body summarizes D-BR-1..7 and links the soak runbook.

## Wave 7 — Soak gate (one week)

- [ ] `bridge_latency_p95_ms ≤ 2000` for 7 consecutive days against the prototype channel.
- [ ] No alerts fired by the synthetic monitor (RAP-1096 alert routing).

## Wave 8 — P7b migration: remaining 5 HOT tables

- [ ] `supabase/migrations/<ts>_canvas_remaining_broadcast.sql` — five trigger pairs (canvas_files, canvas_project_instructions, canvas_invitees, canvas_sessions, research_runs).
- [ ] Apply via MCP `apply_migration`; reconcile `schema_migrations.version`.

## Wave 9 — Bridge consolidation

- [ ] `HOT_TABLES` array extends to all six tables.
- [ ] Bridge's postgres_changes path now applies only to non-HOT tables; HOT tables route exclusively through broadcast.

## Wave 10 — P7b conformance test extension

- [ ] `realtime-conformance.test.ts` extends to all six tables via `test.each(HOT_TABLES)`.
- [ ] Asserts p95 ≤ 2s and p99 ≤ 5s per D-BR-7.

## Wave 11 — Gates

- [ ] `pnpm --filter studio lint` exits 0.
- [ ] `pnpm --filter studio test realtime-conformance` exits 0 across all six tables.
- [ ] `pnpm typecheck` exits 0.
- [ ] Migration drift guard passes (`schema_migrations.version` reconciled).

## Wave 12 — P7b PR + ratification

- [ ] Open PR titled `RAP-1098: P7b — broadcast rollout for remaining 5 HOT tables`.

## Wave 13 — Archive amendments

- [ ] Amend `openspec/current/canvas.md` § Realtime transport: HOT tier now rides `broadcast_changes`.
- [ ] Amend `openspec/current/frontend-runtime.md` L335/L561: visibility-refetch path is now 6/6 conforming.
- [ ] Move `openspec/changes/migrate-canvas-realtime-to-broadcast/` to `openspec/archive/<YYYY-MM-DD>-migrate-canvas-realtime-to-broadcast/`.
