RESEARCH — Adopt ordna as ledger substrate: task-view + ledger-cli retirement (ID-165.1)
RESEARCH — ID-165 Adopt ordna as ledger substrate
Section titled “RESEARCH — ID-165 Adopt ordna as ledger substrate”Task: ID-165 — Adopt ordna as ledger substrate: task-view + ledger-cli retirement.
Subtask: {165.1} RESEARCH.
Author date: 23/07/2026.
Status: research only — no spec, no migration, no retirement performed. The eight
ratified decisions (kickoff intent-kickoff-id-165.md, feasibility session 22/07/2026)
are treated as constraints throughout; anywhere the code contradicts one it is flagged,
not worked around. Evidence base: ordna v0.3.0 source (git tag release: v0.3.0,
commit 1ab8a912, 20/07/2026, cloned read-only), the live ledger JSONs, and the
canonical + docs-site working trees at time of writing.
Supersession context: ID-164 is done (closed S491); its WP5 (“task-view decoupling +
interim ledger simplification”) folds into this task. ID-163 is in_progress
(spec-tier TECH+PLAN lane) — see §6 cutover sequencing.
1. Ordna capability verification against the eight ratified decisions
Section titled “1. Ordna capability verification against the eight ratified decisions”Every feasibility claim from the seed was checked against the v0.3.0 source. Verdicts: all eight decisions are supported by the code as ratified — none contradicted. Two adjacent findings the decisions do not cover (priority-value coercion, status-set mapping) are in §5 and the open questions; they are migration-mapping gaps, not decision contradictions.
| # | Decision | Verdict | Evidence |
|---|---|---|---|
| 1 | No fork; consume @frehilm/ordna-core / -cli as dependencies | Verified | Both packages published at 0.3.0 on npm (npm view @frehilm/ordna-core version → 0.3.0; same for -cli). MIT (repo LICENSE). Core is a pure data layer with no UI imports (packages/core/src/); CLI re-exports the full core API (README §Packages). |
| 2 | Ordna root = private docs-site checkout | Verified | Ordna operates on process.cwd() — createContext(cwd = process.cwd()) (packages/core/src/store.ts:64); config resolved from <cwd>/.ordna/config.yaml (config.ts:58). Running from the docs-site root keeps all task content in the private repo. Caveat: every ordna invocation is cwd-bound — see §5 issue I-3. |
| 3 | tasks/ at docs-site repo root, not under src/content/ | Verified | tasksDir default tasks, resolved relative to project root (config.ts:8, config.ts:92-94). Docs-site root has no existing tasks/ dir (checked 23/07/2026) — no collision. Astro content collections only scan src/content/, so ordna frontmatter never hits collection validation. |
| 4 | storage: file; schema: ordna; statuses: [backlog, todo, doing, done]; idPrefix: id; zeroPaddedIds: 0 | Verified | Config schema accepts all values: statuses any string array min 1, idPrefix any string, zeroPaddedIds int 0–10, storage enum incl. file (default) (config.ts:7-18). formatId emits ${idPrefix}-${n} with no padding at 0 → id-165 exactly (ids.ts:4-8). Filename is <id>.md in ordna schema → tasks/id-165.md (storage/file-io.ts:68-81). First configured status is the default for new tasks (AGENTS.md §3 rules) → new items land in backlog unless -s passed. The backlog status name does not collide with schema: backlog (unrelated config axes). |
| 5 | Backlog = status column, single id-space | Verified | ID allocation scans tasksDir for the highest numeric id and increments (ids.ts:31-44) — one id-space across all statuses by construction. With 154 task records migrated (highest id-165), the next create allocates id-166; renumbered bl-* items simply continue the sequence. Promotion = status flip (ordna move <id> todo), no file move. |
| 6 | Subtasks inside the parent task file; no child files | Verified | Parser splits the body on any ## heading and preserves arbitrary sections verbatim (parser.ts:77-105); writer re-emits every section (writer.ts:53-64). ###-level content (e.g. per-subtask blocks inside a ## Subtasks section) is preserved as section content — not separately parsed, which is exactly the no-hierarchy-extension posture decision 6 wants. Caveat on AC parsing: only the ## Acceptance Criteria section’s checkboxes are structurally parsed for board AC progress (parser.ts:116-125, aliases schema.ts:136-142) — per-subtask checklists elsewhere are preserved but invisible to the board counter (see OQ-6). |
| 7 | Initiatives + retros exit the ledger system; initiative: extra-frontmatter key | Verified | Extra frontmatter keys round-trip: schema is .passthrough() (schema.ts:176), unknown keys are collected into extra_frontmatter (parser.ts:127-137) and written back untouched (writer.ts:47-49); AGENTS.md states “Extra frontmatter keys are preserved on write but ignored by the board” (template §2). An initiative: key needs no ordna support at all. |
| 8 | Direct agent writes; Coordinator owns done; CLI-only dependency gate | Verified | File mode = plain markdown files, editable by anything (README §storage-modes table). The depends_on gate lives in moveTask in core (store.ts:147-174) and fires only when the target status is the LAST configured status (store.ts:155 — done in our four-status config), only via CLI/TUI/web code paths. Raw file edits bypass it entirely, confirming “gate discipline is convention” as ratified. updateTask (non-move patch) does not run the gate (store.ts:131-140). |
Seed feasibility claims, individually
Section titled “Seed feasibility claims, individually”| Claim | Verdict | Evidence |
|---|---|---|
| Extra frontmatter keys round-trip untouched | Verified | schema.ts:146-176 (.passthrough()), parser.ts:127-137 (collectExtraFrontmatter), writer.ts:47-49 (re-emitted unless colliding with a canonical key). Nuance: keys whose names are known aliases (priority, status, labels, dependencies, created, updated, …, full list schema.ts:108-119) are NOT “extra” — they are normalised, and unknown values in them can be coerced (see §5 I-1). |
idPrefix: id + zeroPaddedIds: 0 reproduces id-N exactly | Verified | ids.ts:4-8; parseId accepts id-165 back (ids.ts:10-16); filename id-165.md (file-io.ts:80). |
Parser accepts arbitrary ## body sections | Verified | parser.ts:77-105 (splitSections — every ## heading becomes a Section; pre-heading content kept as a level-0 preamble). Round-trip normalises blank lines (sections re-joined with \n\n, content trimmed — writer.ts:53-64) but loses no content. |
archived status built in and hidden from the board | Verified | ARCHIVED_STATUS = "archived" reserved sentinel, accepted by update/move regardless of config.statuses (storage/backend.ts:11-17). Hidden from board/all views and given its own sidebar bucket in both UIs: TUI Sidebar.tsx:40,106-107, App.tsx:192-194,233; web App.tsx:277-295,359. No dependency gate on archiving (it is not the terminal status). |
storage: file default; hybrid a drop-in later upgrade | Verified | Default file (config.ts:18). Hybrid keeps the identical on-disk layout and only adds a git-ref CAS id-allocator (refs/ordna/state) — README §hybrid; requires a git repo (store.ts:68-76), which the docs-site is. Switching later = edit storage: in config; task files unchanged. ORDNA_STORAGE env var overrides per-process (config.ts:84-87) — useful for CI. |
| Per-file markdown kills JSON size / server / CLI chattiness | Verified by construction | cat tasks/id-165.md replaces show; board derived by reading the files (FileBackend.list, storage/backends/file.ts). At migrated scale (~350 files) a full-board list is a few hundred small file reads — no server, no cache, no budget shaping. |
Also verified, relevant to WP1/WP5: CLI verb surface is init, list/ls, show, create, move, assign, attach, commit, web, board, skill (packages/cli/src/commands/); there
is no body-edit verb and no delete verb — body edits and deletions are direct file
operations, which matches decision 8. ordna commit stages tasks/ + commits,
never auto-runs (AGENTS.md §4).
2. What exists today — retirement-surface inventory
Section titled “2. What exists today — retirement-surface inventory”Headline inbound-reference counts (canonical repo, excluding scripts/ledger-* themselves
and node_modules): ledger-cli appears on 150 lines across 46 files; task-view on
200 lines. Full file list held in the audit greps below; the per-surface breakdown:
2.1 Code to retire (canonical repo)
Section titled “2.1 Code to retire (canonical repo)”| Surface | Size | Notes |
|---|---|---|
scripts/ledger-cli.ts | 5,907 LOC | The mutation CLI. Journal verbs (journal, journal-search, append-journal) confirm journals live in subtask.details (header comments ledger-cli.ts:24-39,79). |
scripts/ledger-server-lifecycle.ts | 803 LOC | Spawns/pins the patch-server from .cache/task-view-<tag>/ (:208,254-255). |
scripts/ledger-server-client.ts | 392 LOC | HTTP client for the patch-server. |
scripts/ledger-compact-done.ts | 179 LOC | Journal compaction → ledgers/archive/ID-N-journals.md. |
scripts/regen-mirrors.sh | 156 LOC | Per-record mirror regeneration. |
lib/ledger/ (4 modules + README) | 2,086 LOC | The vendored task-view surface — CLI-side validation oracle, byte-faithful copies of task-view packages/server/* (lib/ledger/README.md). |
.claude/hooks/ledger-compact-session-end.sh | ~90 LOC | SessionEnd compaction hook (spawn-avoidant, lock in shared .cache/). Not named in the kickoff — additional surface found. |
.cache/task-view-v0.12.1-task-view/ | untracked | Present in the primary checkout only (gitignored); absent from worktrees. |
Already removed ahead of this task (commit 37042db1, 22/07/2026, owner-approved):
all __tests__/scripts/ledger-* + __tests__/docs/*ledger* suites, ledger fixtures,
scripts/ledger-differential-parity.ts, scripts/task-view-drift-age.ts,
scripts/kh-output-budget.ts. The kickoff’s retirement list includes two files that
no longer exist (ledger-differential-parity, task-view-drift-age) — nothing to do
there except the dangling references below.
2.2 CI surface
Section titled “2.2 CI surface”| Workflow | Ledger-facing? | Finding |
|---|---|---|
task-view-vendor-drift.yml | Entirely | Retire whole workflow. Already broken: it invokes scripts/task-view-drift-age.ts (task-view-vendor-drift.yml:37-38,374,390), deleted in 37042db1 — any PR touching the four watched schema files will hit a missing-script step. Non-blocking by design (OQ-T2), so it degrades quietly, but it is dead weight from day one of ID-165. |
ci.yml quality-test job | One step | Lines 275-290 clone + provision task-view v0.12.1-task-view because “the ledger WRITE suites default to the server transport”. Those suites were all deleted in 37042db1 → the clone step is already vestigial and can go in the retirement sweep independent of cutover. No other ci.yml job touches ledgers. |
schema-parity.yml | No | Kickoff assumption contradicted — flagged, not worked around. schema-parity.yml is a manual-dispatch Supabase prod↔staging schema-dump diff (pg_dump --schema-only both DBs, python diff, artefact upload). It has no ledger-facing parts at all; it must NOT be touched by ID-165. The ledger-schema CI concern the kickoff likely meant is task-view-vendor-drift.yml (which watches lib/validation/{task-list,initiatives,backlog}-schema.ts, doc-link.ts, work-status.ts). Those lib/validation ledger-schema modules are themselves retirement candidates — a follow-on sweep item the kickoff doesn’t list (verify no non-ledger imports before removal). |
2.3 Skills, agents, hooks, config referencing the old stack (canonical)
Section titled “2.3 Skills, agents, hooks, config referencing the old stack (canonical)”46 files reference ledger-cli; the live (non-historical) ones:
- Skills:
update-ledgers(SKILL.md 281 + references 311 lines — see §7),handoff(1 ref),start-session(6 refs),research,recall-grounding,triage-finding(+ its references),propagate-workflow-change(+references/surface-map.md— itself a map of this surface; will need re-authoring, not just patching),audit-skill/scripts/detect-drift.sh. - Legacy dev-workflow tree (
.dev-workflow/sdlc/.claude/agents + skills — task-planner/executor/checker, workflow-orchestration, implement-subtask, workflow-curator, shared-discipline/planner-reporting references): quarantined surface from ID-164; references here are stale-by-design, lowest priority. - Hooks/config:
.claude/hooks/mempal-recall.sh,.claude/hooks/ledger-compact-session-end.sh,.claude/settings.json(4 permission-allowlist lines, incl. the S492 ledger-cli read shapes — commit3013f2d6),.prettierignore:66-70(ledger fixtures — fixtures already deleted, entry vestigial),tsconfig.ci.json:6-12(comment-only). - Docs/other:
CLAUDE.mdLedgers section + Orchestration bullet (“Workers never write the ledger in-branch” — inverted by decision 8),AGENTS.md,lib/client-config.ts+ its test (comment-level),docs/reports/jscpd-report/.
2.4 Docs-site surfaces
Section titled “2.4 Docs-site surfaces”- Live:
runbooks/local-development.md(patch-server client-name guard §, worktree provisioning § —:161-198,704-706),runbooks/ci.md(quality-test row:69, §4.4 side-workflow list:196, header note:7),reference/platform-context.md(retro pointer vialedger-cli show retro:71),reference/decision-register.md(context table only), the docs-site’s own.claude/skills (grep hit), plusworkflow-evaluation/friction-register.md. - Historical (do not patch): point-in-time spec dirs (
id-34,id-90,id-92,id-113,id-115, …),_archive/runbooks, operator-command reports. - The task-view repo itself (
github.com/liam-jons/task-view) becomes orphaned once vendor-drift + the server spawn path go — archival of that repo is an owner decision outside canonical’s tree (OQ-10).
3. Migration-source inventory and shape analysis
Section titled “3. Migration-source inventory and shape analysis”Counts measured 23/07/2026 against the live ledgers
(${KH_PRIVATE_DOCS_DIR}/src/content/docs/ledgers/):
| Source | Records | Split | Mirrors |
|---|---|---|---|
task-list.json (2.9 MB) | 154 tasks | done 132, cancelled 4 → archived (136); open 18: in_progress 11, pending 4, blocked 1, deferred 1, spec_needed 1 | tasks/ 154 |
product-backlog.json (256 KB) | 197 items | ready 59, spec_needed 60, needs_research 20, parked 55, blocked 3 → all status: backlog | backlog/ 197 |
initiatives.json (64 KB) | 10 initiatives | exit ledger system (decision 7) | initiatives/ 10 |
product-retros.json (688 KB) | 105 retros | exit ledger system (decision 7) | retros/ 105 |
ledgers/archive/ | 105 ID-N-journals.md, 3.2 MB | already-compacted done-task journals — the pre-migration snapshot must include these | — |
Post-migration tasks/ dir ≈ 351 files (154 + 197), of which 136 archived and
~197 backlog — the board’s visible working set is ~18 open tasks. Subtask volume:
1,422 subtasks total (max 51 on one task). Journal volume for open tasks
(journals live in subtask.details — ledger-cli.ts:79): ~686 KB across the 18
open tasks, heavily skewed: id-132 ≈ 212 KB/48 subtasks, id-127 ≈ 145 KB, id-128 ≈
86 KB, id-71 ≈ 86 KB, id-147 ≈ 52 KB, id-163 ≈ 49 KB. A verbatim carry of the largest
would produce a ~200 KB+ task file — see OQ-4 on compaction depth.
3.1 Field-fidelity mapping (task record → ordna file)
Section titled “3.1 Field-fidelity mapping (task record → ordna file)”| Ledger field | Ordna home | Fidelity notes |
|---|---|---|
id (“165”) | id: id-165 frontmatter + filename | Crosswalk trivial for tasks; bl-* renumber needs the id-crosswalk file (decision 5). |
title, description | title: frontmatter; ## Goal (ordna’s description section, alias schema.ts:121-126) | Clean. |
status | status: | Mapping required — see OQ-1. Proposed: pending→todo, in_progress→doing, done/cancelled→archived, blocked/deferred/spec_needed→todo + qualifier. Unmapped statuses would render the task invisible on the board (columns are config.statuses only). |
priority (must/should/could) | priority: after mapping | Lossy if unmapped: priority is a known key; normalizePriority silently coerces anything outside high/medium/low to null (parser.ts:41-44; enum schema.ts:144). See §5 I-1 / OQ-2. |
dependencies ([“164”]) | depends_on: [id-164] | Convert to full ids; gate then works via CLI move. |
subtasks[] (id/title/description/details/status/testStrategy/dependencies) | ## Subtasks section, per-subtask ### {N.M} blocks with status markers + AC checkboxes | Preserved verbatim as section content (§1 decision 6). Board-parsed AC lives only in ## Acceptance Criteria — decide the aggregation convention (OQ-6). |
journal threads (in subtask.details) | ## Progress (compacted) | Full history goes to the canonical-archive snapshot, not the migrated file (kickoff WP2). Compaction depth = OQ-4. |
status_note, priority_note, owner, effort_estimate, capability_theme, session_refs, commit_refs, cross_doc_links | extra frontmatter (round-trips, §1) | Suggest a kh_ prefix is NOT needed — only alias-named keys are normalised; these names collide with nothing (schema.ts:108-119). owner and assignee are distinct keys — no collision. |
updatedAt (ISO datetime) | updated_at: (YYYY-MM-DD) | Day-granularity only; ordna bumps it on every write (storage/backends/file.ts:144). Preserve the original ISO value in extra frontmatter at migration if wanted (cheap). |
| — (no created date exists) | created_at: | Backfill policy = OQ-3. |
backlog track, type, notes | extra frontmatter / ## Notes | Clean. |
3.2 Initiatives + retros
Section titled “3.2 Initiatives + retros”Per-record mirrors (initiatives/ 10, retros/ 105) are the ratified starting
material for the plain-markdown conversion — already one file per record with
frontmatter. The conversion is mostly a relocation + frontmatter trim, not a rewrite.
Target locations = OQ-7.
4. Draft .ordna/config.yaml (per decision 4)
Section titled “4. Draft .ordna/config.yaml (per decision 4)”To live at ${KH_PRIVATE_DOCS_DIR}/.ordna/config.yaml:
# ID-165 — ordna ledger substrate (decision 4 of the 22/07/2026 ratification).storage: file # direct agent file access is the point; hybrid is the # drop-in upgrade if parallel-create id collisions bite # (same on-disk layout — config.ts:14-18, README §hybrid)schema: ordnastatuses: [backlog, todo, doing, done] # first = default for new items; # last = dependency-gated terminal (store.ts:155)idPrefix: id # id-165 — ids.ts:4-8zeroPaddedIds: 0# webPort: 7420 # default; uncomment to pin a different portDefaults deliberately not restated (tasksDir: tasks, attachment cap 25 MB). The
archived status needs no config entry — it is a reserved sentinel
(storage/backend.ts:11). ORDNA_STORAGE=file can pin the mode in any CI that runs
ordna commands (config.ts:84-87).
5. Issues found (resolve-first vs build-on calls)
Section titled “5. Issues found (resolve-first vs build-on calls)”- I-1 — Priority coercion is silently lossy. Canonical uses MoSCoW
(must/should/could); ordna’s known
prioritykey admits only high/medium/low and nulls anything else on parse (parser.ts:41-44). An unmapped migration would erase every priority. Resolve at migration (it is a mapping bug waiting to happen, not a foundation to build on): either map must→high / should→medium / could→low, or move MoSCoW to an extra-frontmatter key — owner call, OQ-2. - I-2 — Status sets do not overlap. Seven task statuses + five backlog statuses
collapse into four columns +
archived. Tasks whose status is not inconfig.statuses(and notarchived) appear in no board column (columns derive 1:1 from config — AGENTS.md §3; webApp.tsx:295). Resolve at migration with an explicit mapping table (OQ-1); qualifiers survive astagsor extra frontmatter. - I-3 — Every ordna CLI invocation is cwd-bound to the docs-site root
(
store.ts:64; no--cwd/-Cflag exists in the CLI). Agents working in canonical worktrees mustcd "$KH_PRIVATE_DOCS_DIR" && ordna …(or a one-line alias/wrapper — within decision 1’s “trivial wrapper” allowance; anything beyond that escalates). Build-on — a documented convention in the adapted AGENTS.md suffices; no code needed. Reads need no CLI at all (cat $KH_PRIVATE_DOCS_DIR/tasks/id-165.md). - I-4 —
task-view-vendor-drift.ymlis already broken (references the deletedscripts/task-view-drift-age.ts— §2.2). Resolve-first candidate: it can be retired in WP3 immediately, before cutover, since the thing it guards (vendored schema parity) is itself condemned. Same for the vestigialci.ymltask-view clone step (tests it served were deleted in37042db1). - I-5 — The kickoff’s schema-parity assumption is wrong (§2.2).
schema-parity.ymlis Supabase-only and out of scope. Flagged so WP3 doesn’t touch it; the ledger-schema modules underlib/validation/are the actual follow-on sweep item (import-check before removal —work-status.tsin particular may have non-ledger consumers). - I-6 — File-mode id collisions on parallel creates are real but accepted by
decision 4 (README §file “watch out for”). The docs-site is a git repo, so
hybridis available the day it bites. Build-on (ratified). - I-7 — Board AC counter only reads
## Acceptance Criteria(§1 decision 6 row). Build-on, but the subtask template convention must decide where checkboxes live (OQ-6) or board AC progress will read 0/0 forever.
6. Cutover sequencing options
Section titled “6. Cutover sequencing options”Constraints: id-163 is the only in-flight spec lane (id-164 closed); ledger writes otherwise occur at session boundaries (open-task/status flips, journal appends via sessions) and via the SessionEnd compaction hook. A “write-freeze” therefore only has to cover active sessions, not wall-clock days.
- Option A — single-window big-bang (recommended). Between sessions: (1) disable
the SessionEnd compaction hook + declare freeze; (2) snapshot all four JSONs +
ledgers/archive/+ mirrors tocanonical-archive(complete journal history lives there — kickoff WP2); (3) run the migration script; (4) fidelity checks — record counts (154/197/10/105), id-crosswalk completeness, owner-approved spot-diff sample; (5) land.ordna/config.yaml+tasks/in one docs-site commit; (6) flip the reference surfaces (CLAUDE.md, skills) in the same wave. Freeze window ≈ one working session. id-163 interplay: its record migrates like any open task; its next session simply starts ontasks/id-163.md. Risk: biggest single wave — mitigated by the snapshot being restorable and the old stack remaining in git history. - Option B — two-stage (archive first). Stage 1 (no freeze needed): migrate the
136 done/cancelled + 105 retros + 10 initiatives — content that receives no writes —
and verify fidelity mechanics on the safe 80 %. Stage 2 (short freeze): the 18 open
tasks + 197 backlog items + reference flips. Lower per-wave risk, but the ledgers
and
tasks/coexist for the interim with a split read surface — every agent needs “which system holds this record?” logic for the gap. Only worth it if Option A’s spot-diff fails on first attempt. - Option C — parallel-run / dual-write. Rejected. Recreates exactly the parity-maintenance burden (mirror regen, differential parity) this task retires.
Sequencing note either way: retire the two already-dead CI surfaces (I-4) and the
.prettierignore fixture entry now; retire ledger-cli + server + lib/ledger/ only
after cutover verification (WP5 smoke: create via CLI, worker file-edit in-branch,
merge, board reflects, move gate fires, cat from a worktree), since the freeze
window depends on the old CLI staying functional until the snapshot is taken.
7. WP4 recommendation — update-ledgers: retire, don’t rewrite
Section titled “7. WP4 recommendation — update-ledgers: retire, don’t rewrite”Recommendation: retire the skill; fold the canonical conventions into the adapted ordna AGENTS.md (WP1) in the docs-site. Rationale:
- The skill + references (592 lines total) are ~90 % CLI mechanics that cease to
exist: budget gates, record-set delta gates, exit envelopes, size-shaped reads,
promote atomicity, mirror regen (
SKILL.md:38-42,references/cli-mechanics.md). - Every remaining verb maps to a one-liner ordna already documents: create →
ordna create(backlog default per config), promote →ordna move <id> todo, status flip →ordna move, delete → file removal, read →cat/ordna show. The bundled AGENTS.md (packages/cli/templates/AGENTS.md) covers all of them. - What is genuinely canonical is thin and belongs in the layered agent guidance
decision-4/WP1 already commissions: Coordinator-gated
done, Progress-append discipline,initiative:key, extra-frontmatter field glossary, the cwd convention (I-3), and the triage-finding hand-off (create-with-provenance becomesordna create …+ frontmatter keys).triage-findingkeeps routing to that guidance; a separate CRUD skill would just restate it (the drift patternaudit-skillexists to kill). - One open dependency:
triage-finding’s Create-mode currently invokes update-ledgers by name — WP4 must repoint it, andpropagate-workflow-change’ssurface-map.mdneeds re-authoring rather than patching (§2.3).
8. Prior decisions & context
Section titled “8. Prior decisions & context”- DR-089 (S490): plan/decomposition surface is the Intent workspace spec-note —
{N.4}PLAN.md retired. Ordna task files must not grow a competing plan surface;## Subtasksmirrors Intent decomposition (decision 6 aligns). - DR-086b/DR-087: canonical is PUBLIC; docs-site PRIVATE + citable — the root constraint behind decisions 2/3.
- DR-070 (closed-task guard): status-check cited ids; reopens explicit — under
ordna this becomes “check frontmatter
statusbefore citing”, worth carrying into the adapted AGENTS.md. - DR-009/DR-003 (mempalace single-writer / lock-free recall) — unaffected, but
mempal-recall.shgreps ledger surfaces and is on the reference-update list. - ID-164 (
done, closed S491) delivered the Intent substrate this rides on; its WP5 folds here (taskstatus_note, kickoff preamble). ID-163 in flight (§6). - Memory recall: session digests S490–S492 confirm the Intent adoption arc; palace search for the 22/07 ordna feasibility session itself is low-signal (session likely not yet mined) — the kickoff seed is treated as the authoritative record of that ratification, which is what it declares itself to be.
9. What are we not thinking about?
Section titled “9. What are we not thinking about?”- The docs-site’s own CI/build —
tasks/at repo root is outside Astro’s collections, but the docs-site also runs vitest/playwright/knip-style tooling from root config; the WP1 task should confirm none glob the new dir (and add it to ignores where needed). lib/validationledger schemas +work-status.ts— the un-listed second half of the vendor surface (§5 I-5); import-graph check before deletion.- Session tooling still writing at teardown — the SessionEnd compaction hook will
fire during the freeze window unless disabled first (§6 step 1);
handoff/start-sessionskills embed ledger-cli read shapes and will error post-cutover if flipped late in the wave order. settings.jsonpermission allowlist — stale ledger-cli entries are harmless but the absence of ordna/cat tasks/shapes will cause permission-prompt friction in the first post-cutover session; pre-add them.- updated_at day-granularity silently degrades the “which record moved last”
signal
updatedAtISO timestamps provided; if any tooling sorts by it, preserve the original in extra frontmatter (§3.1). - The board’s default
ordnainvocation opens the TUI — fine for humans; agents should be steered tolist/show/cat(non-interactive) in the adapted AGENTS.md, since a TUI launch in a background shell hangs exactly likesupabase db push(CLAUDE.md environment note). canonical-archivesnapshot completeness — must includeledgers/archive/(3.2 MB compacted journals) and the per-record mirrors, not just the four JSONs, or “the complete journal history lives there” is untrue.
10. If this breaks in three months, why?
Section titled “10. If this breaks in three months, why?”Ranked most-likely first:
- Convention-only gate discipline erodes — decision 8 moves
done-gating and Progress-append discipline from enforced server gates to convention. A worker flippingstatus: doneby file edit bypasses the dependency gate silently (store.tsgate is CLI-path-only). Mitigation: the adapted AGENTS.md states the Coordinator-owns-donerule bluntly; the WP5 smoke verifies the CLI path; periodicgrep -l "status: done"review in PRs is cheap if it ever bites. - Reference-surface stragglers — 46 canonical files + live runbooks reference the
old stack; any missed live surface (a skill invoking
bun scripts/ledger-cli.tspost-retirement) fails hard mid-session. Mitigation: WP3’s dangling-reference grep after each removal (propagate-workflow-changediscipline) + re-authoringsurface-map.mdfrom this inventory. - Status/priority mapping regret — if OQ-1/OQ-2 are decided hastily, the collapse
of parked/needs_research/deferred into
backlog/todo+ tags loses triage signal the backlog curation flow relies on; re-wideningstatuseslater is config-only but re-tagging 197 files is a chore. Decide the mapping with the curation workflow in view, not just board aesthetics. - Parallel-create id collision (I-6) — two same-instant
ordna createcalls in different worktrees both allocate id-366. Detectable at merge; fix is the documentedhybridflip. Low likelihood at current create rates.
11. Open questions for the owner
Section titled “11. Open questions for the owner”| # | Question | Research’s suggested default |
|---|---|---|
| OQ-1 | Status mapping: task pending→todo; blocked/deferred/spec_needed→todo + tags: [blocked]/[deferred]/[spec-needed]? Backlog qualifiers (ready/spec_needed/needs_research/parked/blocked) → tags on status: backlog items? | Yes to both — tags keep the board at four columns and survive round-trips. |
| OQ-2 | Priority: map must→high/should→medium/could→low, or keep MoSCoW in extra frontmatter? | Map, and additionally preserve the original as kh_priority: at migration only (belt-and-braces, zero ongoing cost). |
| OQ-3 | created_at backfill: git-derived first-mirror date, updatedAt, or migration date? | Migration date for archived; earliest session_refs/git date for open tasks if cheap, else migration date. Low stakes. |
| OQ-4 | ## Progress compaction depth for open tasks (686 KB total; id-132 alone 212 KB) | Per-subtask one-to-three-line outcome summaries + pointer to the canonical-archive snapshot; verbatim carry only for the active lane (id-163). |
| OQ-5 | Where does the id-crosswalk file live? | ${KH_PRIVATE_DOCS_DIR}/tasks/ID-CROSSWALK.md is self-describing and greppable next to the ids it maps; .ordna/ also acceptable. |
| OQ-6 | AC convention: single board-parsed ## Acceptance Criteria aggregating subtask-level criteria, with per-subtask checklists under ## Subtasks? | Yes — board AC = task-level definition of done; subtask checklists stay narrative content. |
| OQ-7 | Target homes for initiatives (10) + retros (105) as plain docs | src/content/docs/initiatives/ exists as mirror source already — promote in place and drop ledger frontmatter; retros likewise under retros/. |
| OQ-8 | Confirm WP4 recommendation (§7): retire update-ledgers; conventions live in the adapted AGENTS.md | Retire. |
| OQ-9 | Cutover Option A vs B (§6) | A, with B as the fallback if the spot-diff sample fails. |
| OQ-10 | Archive the external task-view repo (github.com/liam-jons/task-view) once orphaned? | Owner call — outside canonical’s tree; a repo-archive (read-only) preserves the tags CI history references. |