# Tasks — @boocode/contracts SSOT Nine phases, each independently verifiable. Phases 1–7 are the migration units (one contract group each after a proven tracer); Phase 8 is the audit gate; Phase 9 is the human smoke test. All shipped 2026-06-02. ## Phase 1 — Tracer: scaffold package + build-order inversion + web proof ✅ SHIPPED - [x] Create `packages/contracts` (`@boocode/contracts`): `declaration:true`, per-subpath exports map, zod `^3.23.8`. Placeholder `src/index.ts`. - [x] Add `packages/*` to `pnpm-workspace.yaml`. - [x] Invert build order everywhere: root `package.json` build script, `Dockerfile` (`COPY packages/*` + contracts build before web/server), coder deploy command. - [x] Regenerate `pnpm-lock.yaml` (Dockerfile uses `--frozen-lockfile`). - [x] Prove the web consumption path end-to-end: `tsc -b` (composite+Bundler), `vite dev` HMR, and `vite build` all resolve the built `.d.ts`+`.js` via the exports map. - [x] Verify all consumer builds + `docker compose build boocode` green. - [x] Remove Phase 1 probe artifacts before Phase 2. ## Phase 2a — Single-source the ws-frames runtime schema ✅ SHIPPED - [x] Move ws-frames schema to `packages/contracts/src/ws-frames.ts` (`./ws-frames` subpath). - [x] Repoint 8 server/coder importers + 2 web validators to `@boocode/contracts/ws-frames`. - [x] Delete `apps/server/src/types/ws-frames.ts`; drop server `./ws-frames` exports subpath. - [x] Delete `apps/web/src/api/ws-frames.ts`. - [x] Move KNOWN_FRAME_TYPES drift + accept/reject tests into the package (11/11); delete byte-parity test; keep broker fail-closed tests in server importing from the package. - [x] Container smoke: `docker compose up`, `/api/health` 200, broker imports from package. ## Phase 3 — Single-source provider snapshot types ✅ SHIPPED - [x] Move `ProviderSnapshotEntry`, `ProviderModel`, `ProviderMode`, `ThinkingOption`, `AgentCommand`, `ProviderSnapshotStatus` to `packages/contracts/src/provider-snapshot.ts` (`./provider-snapshot` subpath). - [x] `apps/coder/src/services/provider-types.ts` re-exports them (importers unchanged). - [x] Delete web mirror block; delete `provider-types-parity.test.ts` (coder −6 tests). - [x] All builds and typechecks green; server 543 / coder 293 unchanged. ## Phase 4 — Single-source the Zod provider-config schemas ✅ SHIPPED - [x] Move `ProviderOverrideSchema`, `CoderProvidersFileSchema`, `ProviderConfigPatchSchema` + `z.infer` types to `packages/contracts/src/provider-config.ts` (`./provider-config` subpath). - [x] `apps/coder/src/services/provider-config.ts` imports + re-exports (importers unchanged). - [x] Delete 17-line web hand-mirror. - [x] Coder provider-config tests 13/13; all builds green. ## Phase 5 — Single-source type-only contracts (MessageMetadata + AgentSessionConfig) ✅ SHIPPED - [x] Move `MessageMetadata`, `ErrorReason`, `AgentSessionConfig` to `packages/contracts/src/message-metadata.ts` (`./message-metadata` subpath). - [x] Unify `AgentSessionConfig` to the web required/nullable shape; delete the coder's dead all-optional copy (zero live importers confirmed). - [x] Delete all duplicate `MessageMetadata` + `ErrorReason` copies (confirmed byte-identical). - [x] Repoint server `api.ts`, web types, and `MessageBubble.tsx` to the package. - [x] Server 543 / coder 293 unchanged; all builds green. ## Phase 6 — Single-source WorktreeRiskReport ✅ SHIPPED - [x] Move `WorktreeRiskReport` to `packages/contracts/src/worktree-risk.ts` (`./worktree-risk` subpath); unify name (coder `RiskReport` → `WorktreeRiskReport`). - [x] Delete all three copies (shapes identical, names differed). - [x] Repoint `sessions.ts`, `ProjectSidebar.tsx`, `orphan-worktree-reaper.ts`, `worktree-safety.ts` via re-exports; `checkWorktreeWorkAtRisk` returns shared type. - [x] Server 543 / coder 293 unchanged; all builds green. ## Phase 7 — Migrate apps/coder/web (fallback SPA) ✅ SHIPPED - [x] Add `@boocode/contracts` `workspace:*` dep to `apps/coder/web/package.json`. - [x] Delete hand-copied 9-arm `WsFrame` union; import canonical `WsFrame` from the package. - [x] Reconcile field conflicts: `tool_result.error` boolean→string; `tokens_used` number→number|null; `snapshot.messages` cast `as Message[]`; `chat_id ?? ''`. - [x] Delete dead `pending_change_added`/`pending_change_updated` reducer arms + the entire dead `onPendingChange` WS plumbing (`DiffPane` prop, `Session.tsx` listener). - [x] Confirm HTTP pending-change apply/reject path untouched. - [x] `apps/coder/web` Vite build green; root build + server 543 / coder 293 green. ## Phase 8 — Audit every requirement bullet ✅ PASSED (12/12) - [x] Verify one definition per contract (file + line evidence for each). - [x] Verify `z.infer` for both Zod contracts (ws-frames, provider-config). - [x] Verify all four consumers wired via exports map (no project refs, no src imports). - [x] Verify all hand-copies + parity tests deleted; drift/broker tests preserved. - [x] Verify single zod version; build-order inverted in root + Dockerfile + deploy docs. - [x] Verify `packages/*` in workspace; dead `pending_change_*` arms gone. - [x] Verify web strict union preserved + coherent post-migration. - [x] Close gap G: update coder deploy command in all 7 doc sites (CLAUDE.md, apps/coder/CLAUDE.md, BOOCODER.md, docs/ARCHITECTURE.md, docs/project-discovery.md, README.md, docs/coder-backends.md). - [x] Correct now-false byte-parity/duplication claims in CLAUDE.md conventions, apps/server/CLAUDE.md broker note, docs/coder-backends.md, and docs/coding-standards/cross-app-contract-parity.md (rewritten to describe the SSOT). - [x] Mark DEFERRED-WORK §3 + STALE-DEPRECATED item as shipped. - [x] Clean `docker compose build --no-cache boocode` green; server 543 / coder 293 / contracts 11 at exact baselines; nothing staged (HEAD e5ce01a). ## Phase 9 — Human smoke test ✅ PASSED (Sam, 2026-06-02) - [x] Web dev HMR, web prod build at :9500, live WS stream rendering. - [x] Coder restart + a turn; fallback SPA; pending-change apply. ## Verify (all runs green) - `pnpm -C packages/contracts build` - `pnpm -C apps/server test` (543) - `pnpm -C apps/coder test` (293) - `pnpm -C apps/server build && pnpm -C apps/coder build` - `npx tsc -p apps/web/tsconfig.app.json --noEmit` - `docker compose build --no-cache boocode`