Skip to content

ID-148 PLAN — Initiatives-ledger CLI support (Option C: repurpose roadmap server arm)

ID-148 PLAN — {148.4} decomposition (Option C)

Section titled “ID-148 PLAN — {148.4} decomposition (Option C)”

Authority. Decomposes the revised TECH.md (Option C — server-side, pending re-ratification). Behaviour contract INV-1…INV-13 is the acceptance authority. No PRODUCT.md. Machine-readable Subtask records in the Appendix (TM-shape JSON).

Revision note — Option B → C (S-current)

Section titled “Revision note — Option B → C (S-current)”

What changed and why. Liam ratified the Option-B OQs and overrode OQ1: the initiatives WRITE path must be server-side. Both prior revisions mishandled the load-bearing fact that ledger writes are owned by the task-view patch-server (in-process writer deleted at ID-90.22 R1b — ledger-cli.ts:~1767; every write is a ServerIntent → transport). Option A/B’s in-process writer re-introduced exactly what R1b removed. Option C repurposes the roadmap SERVER ARM into an initiatives server arm (the roadmap ledger IS the pre-repurpose initiatives ledger) rather than retiring it and rebuilding KH-native.

Ratified OQs: OQ1 → server-side; OQ2 → add an initiatives UI view + editing upstream; OQ3 → Executor cuts v0.10.0-task-view; OQ4 → umbrellas.json file-delete DEFERRED.

Already-landed .5/.6/.9 disposition (canonical main, this session):

  • {148.6} read verbs — KEEP (local reads; verify the schema import resolves after .5 re-homes).
  • {148.5} initiatives-schema.ts — RE-HOME + VENDOR + REGISTER. Authored upstream ({148.10}), vendored into canonical (the existing file becomes the vendored twin), and REGISTERED in the re-vendored detect-schema.ts (kind:'initiatives'). Its “stay KH-native / not in detect-schema” constraint REVERSES. Strict-write enum enforcement moves server-side.
  • {148.9} KH-native generators — SUPERSEDED / REVERT. Server-side generation replaces them ({148.12} deletes the two scripts + rewires regen-mirrors.sh). The committed mirror OUTPUT is valid data and stays; only the mechanism re-bases.

Subtask deltas vs Option B:

  • {148.7} rewritten — write verbs build ServerIntents (no in-process writer).
  • {148.10} rewritten — task-view repurpose roadmap→initiatives server arm (nested) + add UI view + editing (OQ2), not a retirement.
  • {148.12} rewritten — re-vendor registers kind:'initiatives' + reconciles the vendored schema + reverts .9; still deletes the roadmap-schema shell + ledger-budgets theme.
  • {148.8} narrowed — umbrella retirement + roadmap verb-name retirement + DocLinkSchema relocation only (the roadmap server arm is repurposed, not retired).
  • New INV-13 (nested project addressing); INV-8/INV-9 inverted to server-side.

Application caveat for the Orchestrator. {148.7}, {148.8}, {148.10}, {148.11} exist as ledger records — apply the Appendix as updates (set-subtask-field / re-add); {148.12} is a genuine add-subtasks insert. Budgets verified within gate (max desc 247 / test 280).

Architecture decisions (see TECH.md §4 + DR-intents)

Section titled “Architecture decisions (see TECH.md §4 + DR-intents)”
  • D1 — write path = SERVER-SIDE (Option C; supersedes A/B). Repurpose the roadmap server arm → initiatives; writes route through the patch-server via ServerIntents; no in-process writer.
  • D2 — mirror-as-SoT, now server-generated (INV-9).
  • D3 — originating_session = z.array(z.string()).
  • D4a — retire umbrella CODE now (both repos), DEFER umbrellas.json file-delete (OQ4).
  • D4b — task-view repurpose + re-vendor + TASK_VIEW_TAG bump IN scope; Executor cuts the release (OQ3). {68.30} dissolved into ID-148.
  • D5 (NEW) — nested addressing (INV-13): project by globally-unique slug (server tree-walk); initiative/sub-initiative by path; create-project carries the parent path; move-* is a dedicated atomic op. (OQ1/OQ2 below.)

Sibling-only digit-string dependencies.

Phase 1 — Foundation (DONE this session — dispositions above)

Section titled “Phase 1 — Foundation (DONE this session — dispositions above)”
  • {148.5} Schema — DONE → re-home upstream + vendor + register ({148.10}/{148.12}).
  • {148.6} Read verbs — DONE → KEEP.
  • {148.9} Mirror generators — DONE → SUPERSEDED (server-side; reverted in {148.12}).

Phase 2 — Canonical retire + upstream repurpose (parallel)

Section titled “Phase 2 — Canonical retire + upstream repurpose (parallel)”
  • {148.8} Retire umbrella + roadmap verb-names + relocate DocLinkSchema (M · dep .6) — umbrella verbs/schema + roadmap verb names behind RETIRED_VERBS; delete umbrellas-schema +3 tests +helpers +detect-roadmap-shipped-framings; strip parity roadmap legs; relocate DocLinkSchemalib/validation/doc-link.ts; leave roadmap-schema shell for {148.12}. INV-7, INV-12(b/c/d).
  • {148.10} task-view repurpose + UI + release (XL, task-view repo · dep none) — roadmap→initiatives SERVER arm (nested: detect-schema kind, patch-apply tree-walk + atomic move, record-mutate nested insert/delete/id-mint, record-set gate tree-walk), mirror-generator initiatives + retros arms, initiatives UI view + editing (OQ2), author initiatives-schema upstream, relocate DocLinkSchema, retire umbrella, cut v0.10.0-task-view. Critical-path head. INV-12(a), INV-13.

Phase 3 — Re-vendor, write verbs, propagation

Section titled “Phase 3 — Re-vendor, write verbs, propagation”
  • {148.12} Canonical re-vendor + register + supersede-.9 (M · dep .8,.10) — bump TASK_VIEW_TAG; re-vendor lib/ledger/* registering kind:'initiatives'; reconcile+register the vendored schema; drift-yml watch/download; delete roadmap-schema shell + ledger-budgets theme; revert .9 generators
    • rewire regen-mirrors.sh. INV-9, INV-12(e).
  • {148.7} Write verbs as ServerIntents (L · dep .12) — add initiatives slug/name/file; create/update/delete-project, link/unlink, move-task/move-backlog each build a ServerIntent routed through the transport (no in-process writer). INV-3/5/6/8/10/13.
  • {148.11} propagate-workflow-change sweep (L, two-repo · dep .7,.8,.10,.12) — canonical .claude/{skills,agents} + root CLAUDE.md + docs-site refs; record the server-managed-initiatives reality. Last.
  • INV-1…INV-13 satisfied; initiatives is a first-class SERVER kind (writes via ServerIntent, mirrors server-generated); umbrella gone; DocLinkSchema in doc-link.ts; .9 reverted; both test suites green; workflow surface documents the new vocabulary + server-side reality.
{148.6}[D] ── {148.8} ──┐
├── {148.12} ── {148.7} ── {148.11}
{148.10} (task-view) ───┘
{148.5}[D] re-homes via {148.10}/{148.12}; {148.9}[D] reverted in {148.12}
  • Critical path (server-first): {148.10}{148.12}{148.7}{148.11} — upstream release → canonical re-vendor → CLI write verbs → propagate. This is longer than the rejected in-process shortcut but is the correct consequence of a server-managed ledger.
  • Parallel: {148.8} (canonical retire/relocate) runs off the critical path (dep the DONE read path); {148.10} (task-view repo) runs alongside {148.8}.
  • All deps sibling-only within Task 148 (the data-quality dependency is Task-level).
  • {148.10} is XL (task-view repo). The roadmap arm is FLAT (themes[]); initiatives is NESTED + recursive (INV-13), so the server-arm repurpose reuses scaffolding (gates, id-mint, patch validation) but rebuilds the addressing as a tree-walk — plus a UI view + editing (OQ2), the retros mirror arm, umbrella retirement, and a release cut. Fallback split (if an Executor stalls): server-arm vs UI — but the release must include both, so it is one Subtask by default. Needs a frontend-capable Executor for the UI slice.
  • {148.7} is server-backed, not in-process. The verbs build ServerIntents; correctness depends on the re-vendored oracle ({148.12}) registering kind:'initiatives' and the bumped tag spawning the initiatives-capable server — hence dep {148.12}, not a shortcut.
  • {148.12} separate from {148.8}. The roadmap-schema shell deletion + .9 revert are gated on the re-vendor (which is gated on the {148.10} release) — a different repo/phase from {148.8}’s verb retirement.
ItemNote
Nested addressing (OQ1, D5) — RESOLVED S473RATIFIED: address a project by its globally-unique slug (server tree-walk), reusing generic field-patch/record-delete intents; create-project carries the parent path. Path-addressing alternative rejected.
Atomic move mechanism (OQ2, D5) — RESOLVED S473RATIFIED: a dedicated atomic server op (record-set delta ∅) for move-task/move-backlog. Two-sequential-patches alternative rejected (partial-move risk).
{148.10} is XL / two-concernServer arm + UI + release in one Subtask (release atomicity). Fallback split documented; frontend-capable Executor needed for the UI slice.
.5/.9 re-baseAlready-landed KH-native work re-homes/reverts; committed mirror OUTPUT preserved. The .5 checker constraint reversal must be briefed to the {148.12} Executor + Checker.
Two-repo Subtasks ({148.10}, {148.11})task-view + docs-site edits route through their own commit lanes, not a canonical worktree.
umbrellas-helpers.ts dead-export{148.8} Executor confirms via gitnexus impact before deleting.

Appendix — TM-shape Subtask records (JSON for add-subtasks 148)

Section titled “Appendix — TM-shape Subtask records (JSON for add-subtasks 148)”

{148.7}/{148.8}/{148.10}/{148.11} are updates to existing records (rewritten/narrowed); {148.12} is a genuine add-subtasks insert. Budgets verified within gate (max desc 247 / test 280).

[
{
"id": 7,
"title": "Initiatives write verbs as ServerIntents (project CRUD)",
"description": "Add initiatives to LedgerSlug/LedgerName/LEDGER_FILES; project CRUD verbs (create/update/delete-project, link/unlink task+backlog, move-task/move-backlog) each build a ServerIntent routed via the transport - NO in-process writer.",
"details": "REWRITTEN under Option C (server-side; supersedes the Option-A/B in-process writer). Dep {148.12} (the re-vendored oracle must register kind:'initiatives' and the bumped TASK_VIEW_TAG must spawn the initiatives-capable server). Edit scripts/ledger-cli.ts: add 'initiatives' to LedgerSlug (:155), LedgerName (:212), LEDGER_NAME_TO_SLUG (:157), LEDGER_FILES (:214 -> 'initiatives.json'). Each write verb builds a ServerIntent (:174-208) routed via commitMutation -> serverCommitMutation -> buildTransportRequest (:1803) -> transport: create-project <initiativePath> -> record-create {slug:'initiatives', record: project + parent initiativePath}; update-project <slug> <field> <value> incl status + link-tasks/unlink-tasks/link-backlog/unlink-backlog -> field-patch {slug:'initiatives', recordId:<projectSlug>, patches}; delete-project <slug> -> record-delete {recordId:<projectSlug>} with a client-side + server non-empty guard (reject project-not-empty if linked_tasks/linked_backlog present); move-task <taskId> --from <slug> --to <slug> and move-backlog <backlogId> --from <slug> --to <slug> -> the atomic move op (INV-13; server touches source+target project linked_* in one gate cycle, record-set delta 0). The CLI-side oracle (loadLedger->detectSchema->initiatives, fieldPatchMutation->applyPatches, insertRecord/removeRecord) runs at the call site for the fast local envelope; the server re-validates + runs the record-set/budget gates authoritatively. strict-write status enum enforced server-side, surfaced client-side (INV-3). links-project-only (INV-6) enforced before building the intent. --dry-run/--force threaded as transport flags (INV-8/10). NO atomic-write/advisory-lock/in-process writer (that was the rejected Option-A/B design). Spec: TECH.md §2 INV-3/5/6/8/10/13, §3.3. gitnexus impact on run()/buildTransportRequest before editing; detect_changes before commit.",
"status": "pending",
"dependencies": [12],
"testStrategy": "ledger-cli-initiatives.test.ts (server-backed): create/update/delete-project (non-empty guard); link/unlink; move-task/move-backlog re-parent (delta 0); invalid-status (server-enforced); links-project-only; --dry-run no-write; --force budget downgrade. bun run test green."
},
{
"id": 8,
"title": "Retire umbrella + roadmap verb-names + relocate DocLinkSchema",
"description": "Canonical: remove umbrella verbs + roadmap verb-names behind RETIRED_VERBS; delete umbrellas-schema +3 tests +helpers +detect-roadmap-shipped-framings; strip parity roadmap legs; relocate DocLinkSchema to lib/validation/doc-link.ts.",
"details": "NARROWED under Option C (the roadmap SERVER arm is REPURPOSED upstream, not retired; only the CLI VERB NAMES + the umbrella surface retire here). Dep {148.6}; runs before {148.12}/{148.7} in scripts/ledger-cli.ts to avoid same-file contention. Edit scripts/ledger-cli.ts: remove the umbrella verbs (show umbrellas read :2783; update-umbrella write 4405-4596 + the umbrella-patch ServerIntent leg :190 + buildTransportRequest umbrella-patch case :1846 + registry/USAGE/op-flag) and the roadmap VERB NAMES (show/list/update-roadmap, create-theme, promote --capability-theme) + the UmbrellasSchema import :120 + RoadmapThemeSchema import :117 uses; add RETIRED_VERBS: Record<string,string> checked at the top of run() dispatch returning {ok:false,error:'retired-verb',detail:'<verb> removed under ID-148 - use <initiatives replacement>'}; promote --capability-theme -> retired-flag (INV-7). DELETE lib/validation/umbrellas-schema.ts + its 3 test dependents (__tests__/validation/umbrellas-schema.test.ts, umbrellas-roundtrip.test.ts, __tests__/docs/umbrellas-task-list-roundtrip.test.ts - last DROPPED not re-homed) + lib/validation/umbrellas-helpers.ts (+ test) after CONFIRMING formatRetrospectiveJournalBlock is a dead export via gitnexus impact. DELETE scripts/detect-roadmap-shipped-framings.ts. Strip scripts/ledger-differential-parity.ts roadmap MatrixEntry + product-roadmap.json targets. RELOCATE DocLinkSchema: create lib/validation/doc-link.ts (verbatim from roadmap-schema.ts:88-103); repoint backlog-schema.ts:22, task-list-schema.ts:26, retro-schema.ts:31, __tests__/skills/curator-rewrites-smoke.test.ts:54. DO NOT delete roadmap-schema.ts yet (the not-yet-revendored lib/ledger/{detect-schema,patch-apply,record-mutate}.ts still import RoadmapSchema; {148.12} deletes the shell post re-vendor). Spec: TECH.md §3.4, INV-7, INV-12(b/c/d). gitnexus impact before each deletion; detect_changes before commit.",
"status": "pending",
"dependencies": [6],
"testStrategy": "Retired-verb coverage: roadmap+umbrella verb names return retired-verb/retired-flag (no ENOENT/parse/stack). DocLinkSchema imports resolve from doc-link.ts; backlog/task-list/retro + curator-smoke tests pass. bun run test green (roadmap-schema shell remains for 148.12)."
},
{
"id": 10,
"title": "Repurpose roadmap->initiatives in task-view + UI + release",
"description": "In task-view: repurpose the roadmap SERVER arm (detect-schema/patch-apply/record-mutate/mirror-generator, +retros arm) for nested initiatives shape; add initiatives UI view + editing; relocate DocLinkSchema; retire umbrella; cut v0.10.0-task-view.",
"details": "NEW/REWRITTEN under Option C. SEPARATE repo /Users/liamj/Documents/development/task-view (branch main) - git ops route through its own lane, not a canonical worktree; follow its CLAUDE.md/AGENTS.md. CRITICAL-PATH HEAD (canonical re-vendor + write verbs depend on the release). (a) SCHEMA: adapt packages/schemas/src/roadmap-schema.ts -> initiatives-schema.ts porting the DONE {148.5} lenient-read/strict-write shape (status z.string() read, recursive z.lazy sub-initiatives, optional substrate_doc, originating_session array, initiative-4 tolerance) + INITIATIVE_STATUSES/PROJECT_STATUSES for the server strict-write gate; relocate DocLinkSchema -> packages/schemas/src/doc-link.ts, repoint task-list/backlog/retro; retire umbrellas-schema.ts (+test) + ledger-budgets.ts theme entry. (b) SERVER ARM packages/server/: detect-schema.ts swap roadmap arm -> kind:'initiatives' (document_name 'Canonical Platform - Initiatives' -> InitiativesSchema), drop umbrellas kind; record-mutate.ts replace flat collectionKeyFor('roadmap')->'themes' + flat insert/remove/idsForDetected with the NESTED model (INV-13: tree-walk to locate a project by globally-unique slug / a parent by initiativePath; create-project inserts under the addressed parent; slug-uniqueness id-mint across the whole tree; record-set gate walks initiatives+sub-initiatives+projects); patch-apply.ts replace applyRoadmapPatch ['themes',id,field] with initiatives addressing (project fields by slug, initiative/sub-init by path) + ADD an atomic move op (source+target project linked_* edit in one gate cycle); patch-server.ts swap roadmap-theme recordKind -> initiatives kinds, drop umbrellas; mirror-generator.ts repurpose the roadmap arm -> nested initiatives render AND add the retros arm (remove 'retro' from the mirror-exclusion set :89-94). (c) UI packages/ui/record-view: repurpose roadmap/theme views (roadmap-index-view, roadmap-theme-view, roadmap-sort, theme-*, inverse-theme-index) -> an initiatives view WITH EDITING (render nested tree; edit fields, link/unlink, create/delete/move via the server write arm) - OQ2; update ledger-switcher/index-search/types; delete umbrella UI. (d) tests: update all .test.*; task-view suite green. (e) RELEASE: Executor cuts + tags + uploads v0.10.0-task-view with the schema assets the canonical task-view-vendor-drift.yml download list names (OQ3). Spec: TECH.md §3.1, INV-12(a), INV-13. Sizing: L/XL - drive server-arm slice then UI slice then release; if an Executor stalls, server-arm vs UI is the fallback split (but the release must include both).",
"status": "pending",
"dependencies": [],
"testStrategy": "task-view suite green: detect-schema routes initiatives; mutate arm inserts/deletes/patches nested projects + mints slugs + atomic move (delta 0); mirror-generator emits initiatives+retros; initiatives UI renders+edits; umbrella gone. Release v0.10.0-task-view with schema assets."
},
{
"id": 11,
"title": "propagate-workflow-change sweep (initiatives vocab)",
"description": "Run propagate-workflow-change over canonical .claude skills/agents + root CLAUDE.md and docs-site references (~19 files) so initiatives/project vocab lands and retired roadmap/umbrella verb-names leave. Documents landed state; two-repo.",
"details": "Run the propagate-workflow-change skill LAST (documents the landed Option-C state). Canonical surface (audit §C): .claude/skills/{update-roadmap-backlog,propagate-workflow-change,workflow-orchestration,triage-finding,start-session,session-driver-cmux,handoff,spec-driven-implementation,write-product-spec,write-tech-spec,implement-subtask}, .claude/agents/{workflow-curator,task-checker,task-planner}.md + references/shared-discipline.md, root CLAUDE.md. Docs-site (~19 files, separate repo, own commit lane): src/content/docs/reference/{skill-routing-map,state-of-the-product,task-list-discipline,documentation-inventory,skill-interaction-matrix,data-entry-points,decision-register,field-consumer-dependency-map,platform-direction,ai-integration-layers,sector-intelligence-pathway,prompt-improvement-methodology,two-pass-validation-results,gh-security-unused-code-triage,test-philosophy,corpus-writer-fence}.md, runbooks/ci.md, .claude/skills/{sync-ledger-context,evaluate-workflow}. Replace roadmap/theme/umbrella/session_refs/product-roadmap.json vocabulary with initiatives/sub-initiatives/projects + originating_session; record that initiatives is now a SERVER-managed ledger (writes via ServerIntent, mirrors server-generated), DocLinkSchema lives in doc-link.ts, TASK_VIEW_TAG bumped. Patch minimally in each file's voice; flag ambiguous cases to the owner. Spec: TECH.md §3, §6.",
"status": "pending",
"dependencies": [7, 8, 10, 12],
"testStrategy": "Grep the workflow surface for roadmap/theme/umbrella/session_refs/product-roadmap.json - no stale references outside intentional history; the server-managed-initiatives reality is documented; each patched file reads coherently; ambiguous cases flagged to the owner."
},
{
"id": 12,
"title": "Re-vendor + register initiatives kind + supersede .9",
"description": "Bump TASK_VIEW_TAG; re-vendor lib/ledger oracle registering kind:initiatives (InitiativesSchema); vendor+register schema; update drift-yml; delete roadmap-schema shell + ledger-budgets theme; revert .9 KH generators + rewire regen-mirrors.sh.",
"details": "NEW/REWRITTEN under Option C. Canonical repo. GATED on {148.10} (v0.10.0-task-view release must exist) AND {148.8} (DocLinkSchema relocated, roadmap/umbrella verbs gone). Step 1 - bump TASK_VIEW_TAG v0.9.0-task-view -> v0.10.0-task-view in .github/workflows/ci.yml (:282/290), task-view-vendor-drift.yml (:95), lib/ledger/README.md. Step 2 - re-vendor lib/ledger/{detect-schema,patch-apply,record-mutate}.ts from the new tag (byte-faithful except the schema import specifier): detect-schema.ts now imports InitiativesSchema and registers kind:'initiatives' (document_name 'Canonical Platform - Initiatives'), drops the roadmap arm + RoadmapSchema import (:37,79); record-mutate.ts (:42,116) + patch-apply.ts (:36,37,63,382) carry the nested initiatives mutate/patch logic (no RoadmapSchema import). Diff re-vendored files vs prior pin; ASSERT only the roadmap->initiatives arm swap + import-specifier differ. Step 3 - reconcile lib/validation/initiatives-schema.ts (the DONE {148.5} artifact) as the VENDORED TWIN of the upstream schema (same symbols; import-specifier convention); the read verbs {148.6} keep importing it from this path; its 'stay KH-native / not in detect-schema' constraint REVERSES (now referenced by the vendored detect-schema). Step 4 - update task-view-vendor-drift.yml watch (:41) + download (:104): drop roadmap-schema.ts + umbrellas-schema.ts, add initiatives-schema.ts + doc-link.ts. Step 5 - DELETE lib/validation/roadmap-schema.ts (RoadmapSchema shell now unreferenced: oracle re-vendored, verbs gone in {148.8}, DocLinkSchema relocated in {148.8}) + the theme entry in lib/validation/ledger-budgets.ts. Step 6 - SUPERSEDE {148.9}: delete scripts/generate-initiatives-mirror.ts + scripts/generate-retros-mirror.ts; rewire scripts/regen-mirrors.sh to request initiatives + retros mirrors from task-view (its mirror-generator now emits them). Committed mirror OUTPUT stays valid. Spec: TECH.md §3.2, §8, INV-9, INV-12(e). gitnexus impact on roadmap-schema.ts (MEDIUM, 7 direct) - confirm severed before delete; detect_changes before commit.",
"status": "pending",
"dependencies": [8, 10],
"testStrategy": "Full bun run test green after re-vendor + register + revert; detect-schema routes kind:initiatives; no unresolved roadmap-schema imports; re-vendored lib/ledger diff vs prior pin shows only arm-swap + import-specifier; drift-yml parses without roadmap-schema.ts."
}
]