skip to main content

Decision records and document ingest — Implementation Plan

Source design

decision-records-design.md (decisions 1–5 confirmed 2026-08-24, decision 6 — cross-tier references — added 2026-08-25) and ~/WorkLab/DECISION_RECORD_FORMAT.md (the file format, amended three times during the conversion pilot — see “What the pilot changed” below — and again on 2026-08-25 with the “Cross-tier references” section and a revised index line format).

TDD throughout: write the *_test.go file before the implementation it covers, red confirmed first, matching this module’s existing practice.

Status (2026-08-26)

All eight phases are implemented and green, pending review. records.go, recordfile.go, cmd/kb/ingest.go, cmd/kb/record.go, cmd/kb/recordnew.go and cmd/kb/index.go; 322 tests, none skipped; released as v0.0.4.

Decisions taken along the way are DR-0004 through DR-0011 in decisions/. DR-0004..0007 are accepted; DR-0008..0011 are still proposed.

Five corpora, 205 records, all in canonical form and all round-tripping byte-identically:

Corpus Records Origin Notes
~/Laboratory/knowledge/decisions/ 11 3 converted, 8 authored during this effort this module’s own log; DR-0004..0011 record the build
~/WorkLab/clasm/decisions/ 169 decisions_split.ts kind on all, trigger on 70, 2 supersessions, 3 relates_to, 2 phase
~/WorkLab/CMTools/decisions/ 13 hand-authored the richest corpus per record — see below
~/WorkLab/cold/decisions/ 7 hand-authored first corpus with decisions[] (3 records), trigger: design, phase on 5
~/WorkLab/agents/decisions/ 6 hand-authored the workspace tier (project: ""); DR-0001 and DR-0002 carry the only cross-tier relates_to in existence

The hand-authored corpora matter disproportionately for testing: the two converted corpora leave decisions[], session, initiative, tags and trigger: design unpopulated, because conversion cannot invent what a monolithic log never recorded.

CMTools is the strongest single test corpus (added 2026-08-25) and is worth reaching for first in any table test:

Index generation is already implemented outside kb, by ~/WorkLab/decisions_index.ts (2026-08-25), which currently maintains all five indexes. W6 supersedes it — see that phase.

Every phase below can be verified against real data rather than fixtures alone. That is deliberate — the pilot found three format defects that only appeared on real files, and building the index generator found two more.

What the pilot changed, that this plan must honour

Four findings from converting 172 real records. Each is a place where the obvious implementation is wrong:

  1. superseded_by does not imply status: superseded. Because the unit is an episode, a later record can invalidate one decision inside a multi-decision episode while the rest stand. clasm DR-0160 is accepted and carries superseded_by: ["0159"]. Ingest stores what the file says and derives neither field from the other.
  2. trigger: "" is valid. Converted records legitimately carry an empty trigger. Validation must not reject it.
  3. Ids are identity, not chronology. Within a single date, real logs are inconsistently ordered, so a correction can carry a lower id than the record it supersedes (clasm DR-0159 supersedes DR-0160). Every ordered query sorts by date then record_id, never record_id alone.
  4. id, date and phase are quoted scalars. Bare 0142 parses as the integer 142; bare 2026-08-19 resolves to a timestamp. The Go structs use string for all three.

W1 — Schema and types

Files to create

Work items

Acceptance criteria


W2 — Frontmatter parsing and rendering

Files to create

Work items

Acceptance criteria


W3 — kb ingest

Files to create

Work items

Acceptance criteria


W4 — kb record read and status verbs

Files to create

Work items

Acceptance criteria


W5 — kb record new, kb record fmt, and the identity-collision guard

Work items

Acceptance criteria


W6 — kb index and search surfacing

kb index supersedes ~/WorkLab/decisions_index.ts. That Deno tool was written 2026-08-25 because no index generator existed and cold needed one; it currently maintains all five indexes (WorkLab/agents/decisions, WorkLab/CMTools/decisions, WorkLab/cold/decisions, WorkLab/clasm/decisions, and this module’s own). One implementation serving both workspaces was this design’s original argument for putting index in kb, so the Deno tool is a stopgap and retires when this phase ships. Until then it is the live generator and its output is the reference behaviour.

Work items

Acceptance criteria

On retiring the Deno tool

Delete decisions_index.ts, decisions_index_test.ts, its deno.json test and build entries, and the bin/decisions_index build artifact — but only after the byte-identical criterion above passes, since that comparison is what proves kb index is a faithful replacement. decisions_split.ts is unaffected and stays: it converts monolithic DECISIONS.md files, which is explicitly out of scope for kb (design, “What this design does not cover”).


W7 — Documentation and downstream

Work items

Acceptance criteria

Out of this repo, but blocked on it

Both tracked in ~/WorkLab/TODO.md and ~/Laboratory/TODO.md:


Out of scope here