ID-148 TECH — Initiatives-ledger CLI support (Option C: repurpose roadmap server arm)
ID-148 TECH — Initiatives-ledger CLI support + repurpose roadmap→initiatives (server-side)
Section titled “ID-148 TECH — Initiatives-ledger CLI support + repurpose roadmap→initiatives (server-side)”Spec-tier note. TECH+PLAN by design — no PRODUCT.md. The S472 structural audit is the research substrate; this TECH.md carries its own numbered Behaviour contract (§2).
Revision note — Option B → C (S-current)
Section titled “Revision note — Option B → C (S-current)”Why this third revision exists. Liam ratified the Option-B open questions and overrode OQ1: the initiatives WRITE path must be server-side, not a KH-native in-process writer.
The architecture fact both prior revisions mishandled (now verified — §1.1). Since the
ID-90.22 R1b cutover, ledger WRITES are owned by the task-view patch-server; the
in-process direct-write path was deleted (scripts/ledger-cli.ts line ~1767; every mutating
call site supplies a ServerIntent → buildTransportRequest → serverCommitMutation →
transportCommit). Option A/B’s Decision 1 (a scoped atomic+advisory-locked in-process writer
for initiatives.json) re-introduces exactly what R1b removed — it is wrong. Liam:
“writes were moved server-side previously; not doing this properly undoes the original work.”
Option C — repurpose, don’t retire-and-rebuild. product-roadmap.json was manually
repurposed into initiatives.json; the roadmap ledger is the pre-repurpose initiatives
ledger. So repurpose the roadmap SERVER ARM into an initiatives server arm rather than
retiring it KH-side and rebuilding a KH-native writer:
- Upstream (task-view): adapt
packages/schemas/src/roadmap-schema.ts→initiatives-schema.ts; repurpose the server write/mutate arm (detect-schemakind:'initiatives',patch-apply,record-mutate, id-minting, record-set gate) for the nested initiatives shape; repurpose the roadmap mirror generator → server-side initiatives mirror (and add the retros mirror arm, currently excluded); repurpose the roadmap UI view → an initiatives view plus editing (OQ2). RelocateDocLinkSchema. Retire the umbrella surface. Cutv0.10.0-task-view(Executor, OQ3). - Canonical: re-vendor
lib/ledger/{detect-schema,patch-apply,record-mutate}.tsso the oracle registerskind:'initiatives'(importsInitiativesSchema); the CLI WRITE verbs (create/update/delete-project, link/unlink task+backlog, move-task/move-backlog) build ServerIntents routed through the transport — NO in-process writer. Read verbs stay local file reads ({148.6}, DONE). - Retire fully (no initiatives analog): the umbrella surface (both repos incl. tests) and
roadmap-only concepts with no initiatives mapping —
themes[], thecapability_themewrite back-link,product-roadmap.jsonconsumption,detect-roadmap-shipped-framings.ts, and theupdate-roadmap/create-themeverb names (replaced by the initiatives verbs).
Ratified OQ outcomes (from the Option-B report): OQ1 → server-side (this revision);
OQ2 → add an initiatives view + editing upstream; OQ3 → Executor cuts + tags + uploads
v0.10.0-task-view; OQ4 → umbrellas.json physical deletion stays DEFERRED to the
data-quality task.
Disposition of the already-landed {148.5} / {148.6} / {148.9} (on canonical main,
pushed this session) — see §8 for the load-bearing detail; in brief: {148.6} read verbs
KEEP; {148.5} schema re-homes upstream + is vendored + REGISTERED in detect-schema.ts
(its KH-native “not referenced from detect-schema” constraint reverses); {148.9} KH-native
mirror generators are SUPERSEDED by server-side generation (revert the scripts + rewire
regen-mirrors.sh; the committed mirror OUTPUT stays as valid data — only the mechanism changes).
Nothing is lost — it re-bases onto the server architecture.
Delta at a glance — INV-8 inverts (server-side write, no in-process writer); INV-9 inverts
(server-side mirror regen); INV-12 changes (roadmap arm REPURPOSED not retired, + upstream
initiatives UI view/editing); INV-3 strict-write enforcement moves server-side; new INV-13 (nested
project addressing). Subtasks: {148.7} rewritten (ServerIntents), {148.10} rewritten (upstream
repurpose + UI), {148.12} rewritten (re-vendor+register+supersede-.9); {148.8} narrows
(umbrella + roadmap-verb-name retirement + DocLinkSchema relocation only).
1. Context
Section titled “1. Context”1.1 Code-intelligence orientation (verbatim tool output)
Section titled “1.1 Code-intelligence orientation (verbatim tool output)”Run against repo: /Users/liamj/Documents/development/canonical.
gitnexus_query({query: 'roadmap umbrella schema retire'}) → no processes; definitions incl.
Function:scripts/ledger-cli.ts:run (2595–4158), …:updateUmbrella (4405–4596),
Function:lib/ledger/patch-apply.ts:applyRoadmapPatch (188–236),
Function:lib/validation/umbrellas-helpers.ts:formatRetrospectiveJournalBlock (102–162, dead export).
gitnexus_context({name: 'DocLinkSchema'}) → Const:lib/validation/roadmap-schema.ts:DocLinkSchema
(88–103), empty edges (Zod const). gitnexus_impact({target:'roadmap-schema.ts',direction:'upstream', summaryOnly:true}) → impactedCount:9, risk:"MEDIUM", direct:7, byDepthCounts:{"1":7,"2":2}.
Server-side write-path grounding (verifies the Option-C correction — direct read):
scripts/ledger-cli.ts:155—type LedgerSlug = 'task-list' | 'roadmap' | 'backlog' | 'umbrellas' | 'retro';:157LEDGER_NAME_TO_SLUG;:212type LedgerName = 'task' | 'roadmap' | 'backlog' | 'retro';:214LEDGER_FILES. (Roadmap→initiatives swap targets.)scripts/ledger-cli.ts:174–208—type ServerIntentunion:field-patch/record-create/subtask-create/subtask-delete/record-delete(all{slug: LedgerSlug, …}) /umbrella-patch/transaction.:1790commitMutation→:1791“delegates unconditionally to serverCommitMutation”;:1803buildTransportRequestbuilds${base}/${intent.slug}/record/…URLs;:1889serverCommitMutation→transportCommit→ensureServer(spawns the pinned task-view clone). Confirms: every write is an HTTP call to the patch-server; there is no in-process writer.lib/ledger/detect-schema.ts:68–98—detectSchemaroutes bydocument_nameliteral →kind→schema.parse. Known kinds:task-list | roadmap | backlog | retro(canonical oracle; note it does not import umbrellas — umbrella handling is ledger-cli-only). Addingkind:'initiatives'= one arm routing"Canonical Platform - Initiatives"→InitiativesSchema.- Nested-topology mismatch finding (load-bearing). The roadmap server arm assumes a flat
themes[]collection — verified in task-viewpackages/server/:record-mutate.ts:90–93collectionKeyFor('roadmap')→'themes',:102–103idsForDetected('roadmap')→themes.map(t=>t.id),insertRecord/removeRecordoperate on the flatrawClone[collectionKey]array;patch-apply.tsapplyRoadmapPatchaddresses['themes', themeId, field](single level, no nesting);mirror-generator.ts:381planRoadmapMirrorsmapsroadmap.themesone-per-theme;patch-server.ts:263kind:'roadmap' → recordKind:'roadmap-theme'. The initiatives ledger is nested + recursive (initiatives[]→projects[]+ recursivesub-initiatives[]; projects are globally-unique kebab slugs — audit A9). So the repurpose reuses the roadmap arm’s id-minting / record-set-gate / budget-gate / patch-validation scaffolding but replaces the flat-array addressing with a tree walk (INV-13).mirror-generator.ts:89–94currently EXCLUDESretrofrom mirrors — the retros arm is added here ({148.9}superseded, §8).
1.2 How the ledger CLI writes today (the load-bearing constraint — Option C’s foundation)
Section titled “1.2 How the ledger CLI writes today (the load-bearing constraint — Option C’s foundation)”Since ID-90.22 R1b there is exactly one write path and it is server-side: every mutation routes
through the task-view patch-server via serverCommitMutation → transportCommit → ensureServer,
which spawns the pinned clone .cache/task-view-<TASK_VIEW_TAG>/apps/server/index.ts. The server
owns serialisation, the record-set + budget gates, the discipline sweep and mirror regen. The CLI
keeps a client-side validation oracle (lib/ledger/{detect-schema,patch-apply,record-mutate}.ts,
vendored from task-view packages/server/*) that fails a malformed mutation fast client-side before
the server re-validates authoritatively. Option C makes initiatives a first-class server kind
in exactly this model — identical to how task-list/backlog/retro already work.
1.3 Why every roadmap/umbrella verb is currently broken
Section titled “1.3 Why every roadmap/umbrella verb is currently broken”(Unchanged from prior revisions.) product-roadmap.json renamed → initiatives.json; LEDGER_FILES. roadmap ENOENTs; detectSchema returns unknown for the new document_name; RoadmapSchema
requires themes[]; umbrellas.json is malformed/truncated.
1.4 The real initiatives.json shape (verified — schema MUST match this)
Section titled “1.4 The real initiatives.json shape (verified — schema MUST match this)”ledgers/initiatives.json (43.5 KB; 10 initiatives). Top-level document_name `“Canonical Platform
- Initiatives”
.initiatives[]:id(bare-digit string),title,description,substrate_doc,status,projects[],originating_session[](array),sub-initiatives[](recursive; second-level nesting under initiative4;substrate_docoptional on sub-initiatives).projects[]:id(kebab slug — **globally unique**, audit A9),title,summary,description,substrate_doc,status,blocked_by[],blocking[],linked_tasks[],linked_backlog[],originating_session[]. **Transitional (audit A3):** initiative4carrieslinked_tasks/linked_backlogat the **initiative** level — the schema MUST read this (INV-2); the data-quality task redistributes it via{148.7}'s CLI verbs (INV-5 preamble). Statuses: project ∈{idea,proposal,backlog,discovery, accepted,ready,paused,in-progress,maintenance,completed,cancelled}; initiative/sub-initiative ∈{proposed,planned,active,completed,cancelled}`.
1.5 Mirror + CI state (verified)
Section titled “1.5 Mirror + CI state (verified)”ledgers/initiatives/{1..16}.md = stale theme mirror (the DONE {148.9} regenerated the current
topology — that OUTPUT is valid data and stays; the generation MECHANISM re-bases server-side under
Option C, §8). TASK_VIEW_TAG is v0.9.0-task-view (ci.yml:282/290). task-view-vendor-drift.yml
is non-blocking; watch/download name roadmap-schema.ts.
2. Behaviour contract (numbered invariants — Checker verifies against these)
Section titled “2. Behaviour contract (numbered invariants — Checker verifies against these)”Project-model requirement (load-bearing, new-dev-workflow-concepts.md). Only projects hold
linked_tasks/linked_backlog; a project contains multiple tasks; the data-quality task must
(a) redistribute initiative-4’s links to projects and (b) consolidate the current 1:1 project→task
records into fewer multi-task projects (Liam ratified: sub-init 2’s 3 projects→one, sub-init 4’s
2→one, next session) — as CLI operations, never hand-edited JSON. INV-5 supplies the full verb
set.
- INV-1 — Read the file as-is.
show/list/getparse the current dirtyinitiatives.jsonwith no clean-data precondition. (DONE —{148.5}/{148.6}.) - INV-2 — Schema matches the real shape (§1.4). Optional
substrate_docon sub-initiatives; recursivesub-initiatives[]; initiative-4 off-project links tolerated; gitignored-dirsubstrate_doc→ non-fatal warning (D2). (DONE — now re-homed upstream, §8.) - INV-3 — Lenient read / strict write on
status. Read accepts any string. A mutation that SETSstatusrejects an out-of-enum value for that node kind with an actionableinvalid-statusenvelope. Under Option C the strict-write enum check is enforced server-side (the patch-server initiatives arm), with the client-side oracle able to surface it early; existing dirty values elsewhere are preserved. - INV-4 — Read verbs.
show/list initiatives|projects+--status/--initiative/--recent/--limit/ --fields/--ids-only. (DONE — local reads.) - INV-5 — Project CRUD (via ServerIntents).
create-project <initiativePath> …;update-project <slug> <field> <value>(inclstatus);delete-project <slug>(rejectsproject-not-emptyif it still holdslinked_tasks/linked_backlog);link-tasks/unlink-tasks/link-backlog/unlink-backlog <slug> <ids…>;move-task <taskId> --from <slug> --to <slug>andmove-backlog <backlogId> --from <slug> --to <slug>(atomic re-parent). Each verb builds a ServerIntent routed through the transport (no in-process write). Bare-digit id validation on task/backlog ids; slug validation on projects. - INV-6 — Links are project-only. Link/unlink/move operate ONLY at project level; targeting an
initiative/sub-initiative rejects
links-project-only. - INV-7 — Retired verbs fail cleanly. The roadmap/umbrella verb names —
show/list/update- roadmap,create-theme,show/list umbrellas,update-umbrella,promote --capability-theme— returnretired-verb/retired-flag(never ENOENT/parse/stack). Note: the roadmap server arm is repurposed, not retired; only the CLI verb names retire (initiatives verbs replace them). Theroadmap/umbrellas<ledger>argument is rejected by ledger-name validation. - INV-8 — Safe write is SERVER-SIDE (INVERTED from Option A/B). Initiatives writes route through
the task-view patch-server via a
ServerIntent(field-patch/record-create/record-deleteonslug:'initiatives', plus an atomic move op — INV-13). The server owns atomicity, the record-set gate (post-write id-set delta ∅/+1/−1; move ops are ∅), the budget gate, serialisation and mirror regen — identical totask-list/backlog/retro. There is NO in-process writer; the R1b single-write-path invariant is preserved.--dry-runis honoured server-side;--forcedowngrades the budget gate to a warning (server flag). - INV-9 — Mirror regen is SERVER-SIDE (INVERTED from Option A/B). The task-view mirror generator
gains an initiatives arm (one mirror per top-level initiative, rendering the nested
sub-initiative→project→links tree) and a retros arm (currently excluded). Mirrors regenerate on
every server write and via
regen-mirrors.sh(rewired to request initiatives + retros from task-view). The DONE KH-native generators are reverted (§8). - INV-10 — Envelope + argv parity. Standard envelope (
{ok:true}exit 0 /{ok:false,error, detail}exit 1;--pretty,--dry-run). - INV-11 — stdout purity. Initiatives verbs keep stdout pure JSON.
- INV-12 — Repurpose + relocation + retire (Option C). After ID-148: (a) the roadmap server
arm (schema,
detect-schemakind,patch-apply/record-mutatearm, mirror generator, UI view) is REPURPOSED to initiatives upstream — including an initiatives UI view + editing (OQ2) — and re-vendored so the canonical oracle registerskind:'initiatives'; (b) the umbrella surface is fully retired in both repos incl. tests (umbrellas.jsonfile-delete DEFERRED — OQ4); (c)DocLinkSchemais relocated to a neutraldoc-link.ts(both repos) and its live consumers (backlog/task-list/retro + curator-smoke test) repointed; (d) roadmap-only concepts with no initiatives analog (themes[],capability_themewrite,product-roadmap.json,detect-roadmap-shipped-framings.ts) are removed; (e)TASK_VIEW_TAGbumped consistently. - INV-13 — Nested project addressing (NEW). The server initiatives arm addresses records across
the nesting: a project by its globally-unique slug (server tree-walks
initiatives[]+ recursivesub-initiatives[]to locate it); an initiative/sub-initiative by its path (e.g.4,4.2).create-project’srecord-createintent carries the parentinitiativePathso the server inserts under the addressed parent.move-task/move-backlogare a single atomic server op touching source + target project records (record-set delta ∅). The record-set gate and id-minting walk the whole tree (not a flat array).
3. Proposed changes
Section titled “3. Proposed changes”3.1 Upstream (task-view repo) — the repurpose + retire ({148.10})
Section titled “3.1 Upstream (task-view repo) — the repurpose + retire ({148.10})”Work in /Users/liamj/Documents/development/task-view (branch main; separate repo we own).
(a) Schema. Adapt packages/schemas/src/roadmap-schema.ts → initiatives-schema.ts — port the
lenient-read/strict-write initiatives shape (matching the DONE {148.5} canonical schema: 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 schemas. Retire umbrellas-schema.ts (+ test) and the
ledger-budgets.ts theme entry.
(b) Server write/mutate arm. packages/server/: detect-schema.ts — replace the roadmap
document_name/kind arm with kind:'initiatives' ("Canonical Platform - Initiatives" →
InitiativesSchema); remove the umbrellas kind. record-mutate.ts — replace the flat
collectionKeyFor('roadmap')→'themes' + flat insertRecord/removeRecord/idsForDetected with the
nested initiatives model (INV-13): tree-walk to locate a project by slug / a parent by path;
create-project inserts under the addressed parent; id-minting for new projects (slug uniqueness
guard across the whole tree); record-set gate walks initiatives+sub-initiatives+projects.
patch-apply.ts — replace applyRoadmapPatch’s ['themes', themeId, field] addressing with
initiatives addressing (project fields by slug; initiative/sub-initiative fields by path); add an
atomic move op (source+target project linked_* edit in one gate cycle). patch-server.ts — swap
the roadmap/roadmap-theme recordKind for initiatives record kinds; remove the umbrellas arm.
Repurpose mirror-generator.ts roadmap arm → initiatives (nested render) and add the retros arm
(remove retro from the mirror-exclusion set).
(c) UI view + editing (OQ2). Repurpose packages/ui/record-view roadmap/theme views
(roadmap-index-view, roadmap-theme-view, roadmap-sort, theme-*, inverse-theme-index) →
an initiatives view with editing (render the nested tree; edit project fields, link/unlink, create/
delete/move via the server write arm). Update ledger-switcher/index-search/types initiatives
arms. Delete umbrella UI. Update all corresponding .test.*.
(d) Retire umbrella + release. Remove the umbrella surface across packages/{schemas,server,ui}
- tests. Run the task-view suite green. Cut release
v0.10.0-task-viewwith the schema assets the drift workflow downloads (OQ3 — Executor cuts + tags + uploads).
3.2 Canonical re-vendor + register + supersede-.9 ({148.12})
Section titled “3.2 Canonical re-vendor + register + supersede-.9 ({148.12})”Dep {148.10} (release) + {148.8} (DocLinkSchema relocated). Bump TASK_VIEW_TAG → v0.10.0- task-view in ci.yml + task-view-vendor-drift.yml + lib/ledger/README.md. Re-vendor
lib/ledger/{detect-schema,patch-apply,record-mutate}.ts from the new tag: detect-schema.ts now
imports InitiativesSchema and registers kind:'initiatives' (drops roadmap); the mutate/patch
arms carry the nested initiatives logic. 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. Update the drift-yml
watch/download lists (drop roadmap-schema.ts/umbrellas-schema.ts; add initiatives-schema.ts +
doc-link.ts). Delete the now-unreferenced lib/validation/roadmap-schema.ts shell (DocLinkSchema
relocated in {148.8}, oracle no longer imports RoadmapSchema) + the ledger-budgets.ts theme
entry. Supersede {148.9}: delete scripts/generate-initiatives-mirror.ts +
generate-retros-mirror.ts; rewire regen-mirrors.sh to request initiatives + retros mirrors from
task-view (whose generator now emits them). The already-committed mirror OUTPUT stays valid.
3.3 Canonical write verbs as ServerIntents ({148.7})
Section titled “3.3 Canonical write verbs as ServerIntents ({148.7})”Dep {148.12} (the re-vendored oracle must register kind:'initiatives', and the bumped tag must
spawn the initiatives-capable server). Add initiatives to LedgerSlug + LedgerName +
LEDGER_NAME_TO_SLUG + LEDGER_FILES (initiatives.json). Each write verb builds a ServerIntent:
create-project → record-create (slug:'initiatives', record carries the project + parent
initiativePath); update-project/link/unlink → field-patch (slug:'initiatives', recordId: <projectSlug>, patches); delete-project → record-delete (recordId:<projectSlug>,
non-empty guard client-side + server); move-task/move-backlog → the atomic move op (INV-13). 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 + gates authoritatively. --dry-run/--force threaded as transport flags (INV-8/10).
links-project-only (INV-6) enforced at the CLI before building the intent.
3.4 Canonical retire ({148.8}) — umbrella + roadmap-verb-names + DocLinkSchema relocation
Section titled “3.4 Canonical retire ({148.8}) — umbrella + roadmap-verb-names + DocLinkSchema relocation”Dep {148.6}. Runs before {148.12}/{148.7} in ledger-cli.ts. Remove the umbrella verbs
(show umbrellas read 2783; update-umbrella write 4405–4596 + umbrella-patch ServerIntent leg +
buildTransportRequest case + registry/USAGE/op-flag) and the roadmap verb names
(show/list/update-roadmap, create-theme, promote --capability-theme); intercept all via
RETIRED_VERBS → retired-verb/retired-flag (INV-7). Delete lib/validation/umbrellas-schema.ts
- its 3 test dependents +
umbrellas-helpers.ts(+ test, after confirming the dead export). Deletescripts/detect-roadmap-shipped-framings.ts. Stripscripts/ledger-differential-parity.tsroadmap legs. RelocateDocLinkSchema→lib/validation/doc-link.ts; repointbacklog-schema.ts:22,task-list-schema.ts:26,retro-schema.ts:31,__tests__/skills/curator-rewrites-smoke.test.ts:54. Leaveroadmap-schema.tsaRoadmapSchemashell (still imported by the not-yet-revendored oracle;{148.12}deletes it).
3.5 Empirical-verification gate
Section titled “3.5 Empirical-verification gate”N/A — no new external-library symbols. zod already pinned; server transport already exercised.
The repurpose is internal symbol/arm movement, verified by both repos’ bun run test + the
drift-workflow byte compare, not import-and-call.
4. Ratification gate — Liam signs off (each PROPOSED with a recommendation)
Section titled “4. Ratification gate — Liam signs off (each PROPOSED with a recommendation)”Decision 1 — Initiatives WRITE path = SERVER-SIDE (Option C; supersedes A/B Option A). Repurpose the roadmap server arm into an initiatives arm; writes route through the patch-server via ServerIntents; no in-process writer. Grounded in §1.1/§1.2 (R1b single-write-path).
Decision 2 — mirror-as-SoT (unchanged): generated initiatives/{id}.md is the readable SoT;
substrate_doc demoted. Now server-generated (INV-9).
Decision 3 — originating_session = z.array(z.string()) (unchanged).
Decision 4a — retire umbrella CODE now (both repos), DEFER umbrellas.json file deletion
(ratified OQ4): deletion gated on the data-quality task reconciling 49+ orphaned task_ids.
Decision 4b — task-view repo repurpose + re-vendor + TASK_VIEW_TAG bump = IN scope (ratified):
{148.10} + {148.12}. Executor cuts the release (OQ3).
Decision 5 (NEW) — nested addressing (INV-13). PROPOSED: address a project by its
globally-unique slug (server tree-walk), reusing the generic field-patch/record-delete
ServerIntents; create-project carries the parent initiativePath; move-* is a dedicated atomic
op. See Open Question 1 (slug vs path addressing) + Open Question 2 (atomic-move mechanism).
Design ruling — repurpose over rebuild. The ledger file, the server kind slot, the mirror
generator and the UI view are repurposed (honouring “repurpose/rename, don’t retire-and-rebuild”);
the flat themes[] addressing is replaced by a nested tree walk (INV-13). DocLinkSchema is
relocated, not deleted.
5. Testing and validation
Section titled “5. Testing and validation”- Upstream (task-view,
{148.10}) — the task-view suite green after the repurpose:detect-schemaroutesinitiatives; the mutate arm inserts/deletes/patches nested projects + mints slugs + gates the record set; the atomic move op moves a task with delta ∅; the mirror generator emits initiatives- retros mirrors; the initiatives UI view renders + edits. Umbrella removed.
- Canonical re-vendor (
{148.12}) — fullbun run testgreen; the re-vendoredlib/ledger/*diff vs prior pin shows only the roadmap→initiatives arm swap + import-specifier; no unresolvedroadmap-schemaimports; drift-yml parses withoutroadmap-schema.ts. - Canonical write verbs (
{148.7}, server-backed) —ledger-cli-initiatives.test.ts: create/update/delete-project (non-empty guard); link/unlink; move-task/move-backlog re-parent (delta ∅);invalid-status(server-enforced, surfaced client-side);links-project-only;--dry-runwrites nothing;--forcebudget downgrade. Behaviour-first perreference/test-philosophy.md; the permitted mock is the process/spawn seam (server transport) — tests run against a tmp-dir fixture with a real (or stubbed-transport) server, matching the existingledger-server-*.test.tspattern. - Retire (
{148.8}) — retired-verb coverage (roadmap/umbrella verb names →retired-verb/retired-flag, no ENOENT/parse/stack);DocLinkSchemaimports resolve fromdoc-link.ts; backlog/task-list/retro + curator-smoke tests pass. - Regression —
ledger-server-*.test.tsextended for the initiatives slug; task-list/backlog/retro write contracts unaffected.
6. Risks and mitigations
Section titled “6. Risks and mitigations”- “Repurpose” understates the nested-arm work. The roadmap arm is flat; initiatives is nested +
recursive (INV-13). Mitigation:
{148.10}reuses the scaffolding (gates, id-mint, patch validation) but treats the tree-walk addressing as new; sized L/XL with an internal slice order indetails. - Long server-first critical path.
{148.10}→{148.12}→{148.7}serialises (upstream release → re-vendor → CLI verbs) — longer than the (rejected) in-process shortcut, but architecturally correct. Mitigation:{148.8}(retire/relocate) and the read path (DONE) run off the critical path. - Re-vendor drift.
{148.12}diffs the re-vendored primitives vs the prior pin; asserts only the arm-swap + import-specifier; gates on fullbun run test. .5/.9re-base churn. Already-landed KH-native work re-homes/reverts. Mitigation: §8 states each disposition explicitly; the committed mirror OUTPUT is preserved (only the mechanism changes).- Atomic move (INV-13). Two-record edit needs a dedicated server op. Mitigation: Decision 5 / Open Question 2 — dedicated atomic op recommended.
umbrellas.jsonvalue loss / docs drift — Decision 4a defers the file delete;{148.11}propagates the vocabulary.
7. Ordered migration plan (seeds {148.4} PLAN.md)
Section titled “7. Ordered migration plan (seeds {148.4} PLAN.md)”D = DONE this session; U = unstarted.
- [D]
{148.5}Schema — re-homes upstream + vendored + registered (§8). - [D]
{148.6}Read verbs — KEEP (local reads). - [D]
{148.9}KH-native mirrors — SUPERSEDED; reverted in{148.12}(§8). - [U]
{148.8}Canonical retire + DocLinkSchema relocation — umbrella verbs/schema, roadmap verb names (RETIRED_VERBS), relocateDocLinkSchema, strip parity/detect-roadmap. Dep 2. - [U]
{148.10}task-view repurpose + UI + release — roadmap→initiatives server arm (nested), schema, mirror (+retros arm), UI view+editing (OQ2), retire umbrella, relocate DocLinkSchema upstream, cutv0.10.0-task-view. Dep: none (separate repo). Critical-path head. - [U]
{148.12}Canonical re-vendor + register + supersede-.9— bump tag; re-vendor oracle (kind:‘initiatives’); vendor+register schema; drift-yml; delete roadmap-schema shell + ledger-budgets theme; revert.9generators + rewireregen-mirrors.sh. Dep 4 + 5. - [U]
{148.7}Write verbs as ServerIntents — create/update/delete-project, link/unlink, move-task/move-backlog; addinitiativesslug/name/file. Dep 6. - [U]
{148.11}propagate-workflow-change sweep — canonical.claude/{skills,agents}+ rootCLAUDE.md+ docs-site references. Dep 4,5,6,7 (last).
Critical path: {148.10} → {148.12} → {148.7} → {148.11}. {148.8} parallelises (dep the DONE
read path). Compound invariants + two-repo + release-gated server-first chain → PLAN warranted.
8. Follow-ups / deferred + explicit .5/.6/.9 disposition
Section titled “8. Follow-ups / deferred + explicit .5/.6/.9 disposition”Already-landed work (canonical main, this session) — Option C disposition:
{148.6}read verbs — KEEP. Local file reads, unaffected by the server write path. Verify thelib/validation/initiatives-schema.tsimport still resolves after.5re-homes (same path, now vendored).{148.5}lib/validation/initiatives-schema.ts— RE-HOME + VENDOR + REGISTER. The schema LOGIC is reused, but under Option C it is authored upstream ({148.10}, adapted fromroadmap-schema.ts) and vendored into canonical (the existing file becomes the vendored twin, same symbols + import-specifier convention) and REGISTERED in the re-vendoredlib/ledger/detect-schema.ts(kind:'initiatives'). Its DONE checker constraint “must NOT be referenced fromdetect-schema.ts/ stay KH-native” REVERSES. Strict-write enum enforcement moves to the server-side write gate.{148.9}KH-native generators (scripts/generate-initiatives-mirror.ts,generate-retros-mirror.ts,regen-mirrors.shKH wiring) — SUPERSEDED / REVERT. Server-side generation (task-viewmirror-generator.tsinitiatives + retros arms,{148.10}) replaces them;{148.12}deletes the two scripts and rewiresregen-mirrors.shto request initiatives + retros mirrors from task-view. The committed mirror OUTPUT (initiatives/{id}.md,retros/{session}.md) is valid DATA and stays — only the mechanism changes; the next server regen reproduces it.
Deferred (NOT in ID-148):
initiatives-ledger-data-qualitytask (ID-148 gates it): initiative-4 redistribution + 1:1→multi-task project consolidation (via{148.7}verbs), status normalisation, deadlinked_backlogrefs, population gaps,substrate_doccleanup,umbrellas.jsonphysical deletion after task_id reconciliation (Decision 4a / OQ4).{68.30}dissolved into ID-148 — the repurpose + re-vendor land here.ledger-workflow-quality-of-lifetask:[branding]stdout fix (INV-11), journal date-range search/export, task-levelblocked_by/blocking.- Task
capability_themefield dormant-cleanup (vendored task-list-schema + live data).