ID-90 — Server-ledger cutover: PLAN
ID-90 — Server-ledger cutover: PLAN
Section titled “ID-90 — Server-ledger cutover: PLAN”{90.4} PLAN artefact — authored against the ratified {90.2} PRODUCT (S322, 62
invariants incl. the amended invariant-14 wording) + {90.3} TECH (S322, incl. OQ-7
Semantics B RATIFIED and the T-1…T-5 decisions). Decomposes the ratified Option A
two-phase cutover into implementation Subtasks for the parallel-cmux sub-track.
- Task: ID-90 “Server-ledger cutover — task-view patch-server replaces ledger-cli (gates + guard port)”
- Authored: 07/06/2026 (fresh Planner per Q-PLANNER-2 — no carryover from the RESEARCH/PRODUCT/TECH Planners).
- Predecessors:
docs/specs/ID-90-server-ledger-cutover/{RESEARCH,PRODUCT,TECH}.md— all ratified S322. - Grounded at:
canonical-pipeline-setupHEAD876c68ac(07/06/2026). Pin facts re-verified at that SHA:TASK_VIEW_TAG: v0.3.1-task-viewatci.yml:1139;lib/ledger/carries the five modules R2 deletes;lib/validation/ledger-budgets.tspresent. Executors re-verify at dispatch. - Identity hygiene: public-track artefact. The denylist is referred to generically throughout; zero denylist tokens herein; guard fixtures are synthetic only (AC-I).
0. Ledger reconciliation + decomposition decisions
Section titled “0. Ledger reconciliation + decomposition decisions”- Records
{90.1}–{90.4}are the spec chain (1–3 done; 4 closes with this artefact). New implementation records number 5–23 — 19 records; Task total 23 of the 25-record soft cap. Approaching the cap: any further ID-90 record needs Orchestrator review; spillover is a Task-split signal. - Grouping by file-ownership + TECH change-item seams, not micro-slices: U2+U3 share the gate-hook surface (record 7); U5+U6 share the mutation primitives (record 9); U7+U8 are small per-file extensions (record 10); P3 splits into R1–R3 (ordered code chain, record 22) and R4–R6 (tests/docs/evidence, record 23).
- U11 kept as one record (13): test-only, no production-code risk. A per-suite split was considered and rejected to preserve cap headroom; the Orchestrator may sub-batch within the record if the executor session runs long.
- Sibling-only dependency discipline verified: every
dependencies[]entry below references ids 4–22 within ID-90. Every cross-Task gate ({68.30} Gate-2, {68.27} holdback, OQ-3 private home, OQ-8 referent re-point) is details prose, never deps[]. No cross-Task Subtask dependency was needed; if execution surfaces one, the Executor stops and escalates per the forcing function (§4).
1. Phase map (TECH §Migration plan ↔ subtask ids)
Section titled “1. Phase map (TECH §Migration plan ↔ subtask ids)”| Phase | Where | TECH change items (internal order) | Subtask records | Exit gate |
|---|---|---|---|---|
| P0 | task-view repo — parallel-cmux sub-track, zero KH impact | U0 → U1 → {U2, U3, U4} → {U5, U6, U7, U8} → U9 → U10 → U11 → U12 | 5 → 6 → {7 ∥ 8} → {9 ∥ 10} → 11 → 12 → 13 → 14 | AC-P0 (named in record 14) |
| P1 | KH, flag OFF | K1 ∥ K6 ∥ {K2 → K3 → K4} → K5 | 15 ∥ 16 ∥ {17 → 18 → 19} → 20 | AC-P1 (named in record 20) |
| P2 | KH, flag ON default | F1 + soak | 21 | AC-P2 (named in record 21) |
| P3 | KH retirement + S2-i | R1 → R2 → R3, then R4 → R5 → R6 | 22 → 23 | AC-P3 + AC-H1(i–iii) + AC-H2 (named in record 23) |
Phase-boundary gates AC-P0…AC-P3 are Orchestrator-owned between waves — each
boundary record (14, 20, 21, 23) carries the PRODUCT gate text reference in its
details; no executor self-certifies a phase exit.
2. Per-subtask table
Section titled “2. Per-subtask table”| id | Title | Phase | Surface | Deps |
|---|---|---|---|---|
| 5 | P0-U0 — task-view schema re-vendor + budgets/umbrellas vendor | P0 | task-view repo | 4 |
| 6 | P0-U1 — conforming serialisation port into patch-server write paths | P0 | task-view repo | 5 |
| 7 | P0-U2/U3 — budget + record-set gates ported server-side | P0 | task-view repo | 6 |
| 8 | P0-U4 — client-name guard (de-ID gate) with JSON denylist parser | P0 | task-view repo | 6 |
| 9 | P0-U5/U6 — subtask CRUD + auto-id + create defaults; append op | P0 | task-view repo | 7, 8 |
| 10 | P0-U7/U8 — promote third leg; umbrellas document kind | P0 | task-view repo | 7, 8 |
| 11 | P0-U9 — multi-document daemon: slug routing, mutex, lifecycle flags | P0 | task-view repo | 9, 10 |
| 12 | P0-U10 — mutation body overrides + response warnings + dryRun | P0 | task-view repo | 11 |
| 13 | P0-U11 — upstream test ports + relocated guard suite + concurrency | P0 | task-view repo | 12 |
| 14 | P0-U12 — cut tag v0.4.0-task-view + AC-P0 exit record | P0 | task-view repo (orchestrator-direct) | 13 |
| 15 | P1-K1 — pin bumps: TASK_VIEW_TAG v0.4.0 across ci.yml, vendor-drift, README | P1 | KH | 14 |
| 16 | P1-K6 — umbrellas.json normalisation + serialiseUmbrellas flip (one commit) | P1 | KH | 14 |
| 17 | P1-K2 — transport client: scripts/ledger-server-client.ts | P1 | KH | 14 |
| 18 | P1-K3 — lifecycle manager: scripts/ledger-server-lifecycle.ts | P1 | KH | 17 |
| 19 | P1-K4 — façade flag branch: KH_LEDGER_SERVER + ServerIntent at 12 call sites | P1 | KH | 18 |
| 20 | P1-K5 — differential parity harness + CI step (AC-P1 boundary) | P1 | KH | 15, 16, 19 |
| 21 | P2-F1 — default flip + live-session soak + rollback drill (AC-P2) | P2 | KH (orchestrator-direct, session-spanning) | 20 |
| 22 | P3-R1/R2/R3 — retirement chain: direct-path removal, deletions, drift shrink | P3 | KH | 21 |
| 23 | P3-R4/R5/R6 — test migration, docs pass, cutover journal (AC-P3/H1/H2) | P3 | KH | 22 |
3. Wave/dispatch guidance (cmux sub-track)
Section titled “3. Wave/dispatch guidance (cmux sub-track)”P0 — every record 5–14 executes in the task-view repo. Each P0 details carries the
EXECUTION SURFACE contract verbatim: work at the operator’s task-view checkout
(github.com/liam-jons/task-view), NOT the KH repo; KH is read-only reference for porting
sources; out-of-tree git via --git-dir/--work-tree or cd-subshell; commits stay
local — the Orchestrator reviews, pushes and tags. A P0 executor that finds itself
editing KH files must STOP and escalate (brief-composition defect per Inv 10).
- Wave A: record 5 (solo — foundation; everything imports its vendored modules).
- Wave B: record 6 (solo — the largest single slice; all gates assert on its bytes).
- Wave C: records 7 ∥ 8 — parallelisable as separate terminals, but both wire into the four mutating handler bodies: record 7 owns the shared gate-chain hook seam; record 8 registers into it. Merge order 7 → 8 (or run sequentially in one terminal).
- Wave D: records 9 ∥ 10 — small overlap on
patch-apply.ts(9 widensFieldPatch; 10 adds the umbrellas walk). Merge order 9 → 10. - Waves E–G: 11 → 12 → 13, strictly sequential (routing/mutex pervades patch-server; envelope fields wire the gates; the test ports close the phase).
- Record 14: orchestrator-direct — review the local commit chain, push, cut
v0.4.0-task-view, write the AC-P0 exit record (any P1-deferred gap named explicitly).
P1 — KH records; normal worktree discipline (isolation worktree; first action
git fetch origin canonical-pipeline-setup && git reset --hard origin/<branch>;
Orchestrator cherry-picks, never merges). All five carry code-intel executor blocks.
- Wave H: 15 ∥ 16 ∥ 17 (three independent lanes; record 15 is orchestrator-direct-eligible — a 3-file pin bump).
- Then 18 → 19 (chain on the same transport seam), then Wave I: record 20 (the AC-P1 boundary record).
P2 — record 21 is orchestrator-direct and session-spanning: the F1 flip is one line; the soak evidence accrues across ≥1 full live SDLC session and is journalled into the record as it lands. Cannot be pre-scheduled (§4).
P3 — records 22 → 23 strictly sequential, dispatched only after the AC-P2 evidence
set is complete. Single executor each (or one executor running both in order); record 22
is an ordered three-commit chain with full bun run test green after each commit.
4. Risks and holds
Section titled “4. Risks and holds”| # | Risk / hold | Class | Handling |
|---|---|---|---|
| 1 | AC-H1(iv) HOLDS on OQ-3 (post-cutover private home for ledgers + mirrors + parity-gate re-home — Liam + Orchestrator decision). AC-H1 cannot complete before that decision is recorded. | HOLD | Record 23’s R6 journal states the hold explicitly; {68.30} stays blocked on AC-H1 meanwhile. Releasing OQ-3 is outside ID-90. |
| 2 | AC-P2 soak is session-boundary-bound — it rides a live SDLC session and cannot be pre-scheduled. | Scheduling | Record 21 stays in_progress across the boundary; evidence journalled incrementally; Orchestrator gates P3 on the complete set. |
| 3 | Upstream tag v0.4.0 cut (record 14 / U12) gates every P1 record. | Sequencing | Encoded as deps on 14 for all of 15–17; AC-P0 is the Orchestrator’s phase gate. |
| 4 | Shared-file contention upstream (patch-server.ts handler bodies; patch-apply.ts). | Merge | §3 merge-order discipline: 7 → 8 and 9 → 10; record 7 owns the gate-chain seam. |
| 5 | mtime millisecond-granularity residual while flag-OFF and flag-ON writers mix (P1–P2 window). | Accepted | Equal to today’s CLI-vs-CLI hazard, never worse (TECH §Risks); the phased flip minimises the window; the U9 mutex closes it intra-daemon. |
| 6 | Vendored-schema drift (found live: upstream parse helper lacks budget soft-warns). | Covered | Repaired by record 5; record 15’s vendor-drift diff verifies at the new tag. |
| 7 | Identity hygiene across a public-track repo. | Gate | AC-I grep over every ID-90 artefact; synthetic guard fixtures only (records 8, 13, 20); rejection surfaces redacted by design (invariant 32). |
| 8 | 25-record soft cap: 23/25 after this PLAN. | Capacity | No further ID-90 records without Orchestrator review; spillover signals a Task split. |
| 9 | Cross-Task referents: {68.30}/{68.27} consume record 23’s R6 evidence; ID-68 records still say “ID-20” (OQ-8). | Boundary | Prose-only references — never deps[]. OQ-8 re-point is the Orchestrator’s action before {68.30} dispatch. Record 22 must NOT git-rm any ledger JSON/mirror (that is {68.30}‘s move). |
| 10 | Sibling-only escalation path. | Forcing function | None needed at decomposition. If execution surfaces a cross-Task Subtask dep, the Executor/Orchestrator escalates for a Task split/merge — the constraint is never bent. |
5. Estimate
Section titled “5. Estimate”| Phase | Records | Executor effort | Elapsed shape |
|---|---|---|---|
| P0 | 9 executor + 1 orchestrator action | ~18–26 h (U1, U9, U11 are M–L; others S–M) | ~2–3 sub-track sessions with Waves C/D parallel |
| P1 | 5 records (1 orchestrator-eligible) | ~8–12 h | ~1–2 sessions |
| P2 | 1 record | ~1 h active | ≥1 full SDLC session elapsed (soak-bound) |
| P3 | 2 records | ~5–7 h | ~1 session |
| Total | 19 records | ~30–45 h agent effort | ~4–6 elapsed sessions (P2 soak dominates elapsed time) |