Fast deterministic KB integrity check (kb:check) — make SSOT cheap to uphold
0060-fast-kb-integrity-check
- Reversibility
- two-way door
DEC-0060 — Fast deterministic KB integrity check (kb:check)
Reversibility: two-way door — a read-only script plus one package.json line; delete it and nothing else changes. The durable commitment is the principle (KB integrity must be checkable deterministically and fast, not re-derived by hand), not this exact implementation.
Context
A DX audit found the inner loop on a "small change" had become slow and painful. Measured ground truth: knowledge/log.md is 233 KB; recent ADRs run 8–27 KB with 20–44 [[wiki-links]] each; the KB holds 2,302 wiki-link occurrences across 152 targets; and a single in-flight schema-conformance change (moving free-text out of the reversibility: enum) was sitting in the working tree as 41 modified decision files. The only KB validator was scripts/_kb-load-scan.mjs, explicitly labelled // TEMP diagnostic, parse-only (no edge/link integrity), and unwired from package.json — so cross-reference integrity (the costliest part of SSOT) was verified by hand or by a full log-auditor agent pass every time. The keystone already shipped parse, buildGraph, and validateGraph (dangling-edge detection); they were just never wired into a command.
Options considered
- Keep the TEMP scan / manual verification. Rejected: parse-only misses dangling edges and link rot — the exact integrity the discipline is built on — and pushes that work onto a slow agent pass.
- A fast deterministic
kb:checkover the real keystone (chosen). parse → schema →validateGraph(frontmatter edges) → body[[wiki-link]]scan, with a small curated allow-list for prose-words and gitignored client/tenant silos, and fenced-code-block stripping so schema examples are never false-flagged. Read-only; exits non-zero on error;--jsonfor hooks/CI. - A heavier graph/lint framework. Rejected (for now): over-built; the keystone already has the primitives.
kb:checkis the thin wiring (Claude-primitives/keystone-first, DEC-0008).
Decision
Add scripts/kb-check.mjs + pnpm kb:check. It is the deterministic integrity gate; the log-auditor stays the judgment layer (rationale, contradiction, framing) but no longer has to be the mechanical link-checker.
Consequences
- SSOT integrity is now a ~600 ms command (warm; ~2.3 s cold incl. the 52 ms okf build) instead of a multi-minute agent pass — a fast inner-loop signal available before commit and wireable into a hook.
- On its first real run it isolated, with zero false positives, a genuine drift: DEC-0058 claims a task (
task-docs-home-synthesize-overview-when-no-root-index) "is filed" four times, but the task atom does not exist — routed to the log-auditor/starlight-engineer, not buried. - The allow-list is a deliberate, auditable "this id is external/prose" assertion — additions are explicit, never a silent relaxation of provenance.
- Supersedes the TEMP
_kb-load-scan.mjsfunctionally (left in place; removal is separate cleanup).
Review
confidence: verified — built and reproduced this session: pnpm kb:check scans 135 atoms / 143 node ids in ~600 ms, exits 1 on the DEC-0058 drift, --json emits the same. Gate already met. Open follow-on (separate sign-off): wiring kb:check into a pre-commit/PostToolUse hook, and the larger question of the log-auditor cascade cost (the 41-file change) — recommended but not decided here.