Skip to contentWolf-Rayet

Decision records

ADR-0049 A narrative may not be checked wholesale, and one section of it must be

Accepted2026-09-05Phase 4

#Context

Two passes shipped with their docs/STATUS.md narratives missing, and the file's own snapshot table left describing a system two units out of date. It said 20 enforcement checks where there were 22, and 43/137 baselines where there were 45/140.

Nothing measured was wrong. The baselines, the receipts, the engine checks and the two new scenes in those commits were all correct, and CI verified every one of them. What was wrong was the account.

The cause is worth stating plainly because it is not carelessness in a way a person can simply be more careful about. The edit scripts that write this file build the whole document in memory and write once at the end. A failed assertion part-way through therefore discards every earlier substitution — including the ones that had already succeeded — and the script exits. The commit that follows carries the unedited file, and looks exactly like a commit that had nothing to say.

ADR-0047 closed the same shape of defect one level down: a component's own files asserting something false about the component. This is the same defect at the level of the record, and it was already named — standing item 18 opened three passes ago, after two figures in this very table were found stale by 116 and 13.

What made item 18 hard is real, and it is the reason no check existed. STATUS.md is a narrative of passes, and most of its numbers are *deliberately* historical. The line

| baseline.json darwin-arm64 | 40 | 101 | unchanged — carried forward |

in the pass for bc1bc37 was true when it was written, is false now, and must stay exactly as it is. A pass narrative that updated itself would stop being a record of what happened. So the file cannot be checked wholesale, and a check that tried would fail on every historical line in it.

#Decision

A narrative's historical claims are not checkable and must not be checked. Its snapshot claims are checkable and must be.

The distinction is not a judgement call to be made line by line — it is already drawn in the document's own structure, and this record does no more than say so and act on it.

"The system as disk holds it" is a snapshot. Its own preamble says *read from committed receipts and source this pass*. Every figure in it is a claim about the repository at HEAD, and every one is therefore checkable. So is the record count that opens "The decision register".

Everything above those two sections is history. The pass narratives are dated accounts of what was measured when, and they are read by nothing.

tools/check-status-figures.js reads those two sections and no other part of the file.

#Each claim is derived from the artifact that owns it

The roster count from docs/adr/0021-carbon-roster.md, the ADR count from the directory listing, the scene roster from the engine's own SCENES, the baselines from the baseline files, the enforcement count from playbook §10's own rows, the component count from COMPONENT_LAYERS.

Never from a second copy of the claim. A table checked against another table saying the same thing agrees with itself and is wrong twice — which is the failure mode ADR-0043 found in the token verifier and the reason Rule A now builds its pair set from declared roles rather than referenced ones.

#A claim that cannot be found is a failure, not a skip

Each row is located by a pattern that must match exactly once. A row that was renamed, reworded past recognition or deleted reports as a failure rather than passing silently, because a row that vanished and a row that agrees are otherwise the same silence. That is ADR-0041's requirement applied to this file's own check.

#Rejected options

Generate the snapshot table. It would be checkable by construction and it would be worth less. Half of what those rows carry is the sentence after the number — *why* the figure moved, what it was before, which platform measured it. That prose is the reason the table is read at all, and generating it would leave a table of correct numbers nobody learns anything from.

Check the whole file. Fails on every historical line, which is most of them. A check that must be suppressed on the majority of its subject teaches people to suppress it.

Make the edit scripts safer instead. Necessary and insufficient. Writing verify-then-write scripts is the right habit and the right fix for the proximate cause — but a check cannot stop a script from failing, and the thing that actually went wrong was not the failure. It was that the failure left no trace. This record addresses the trace.

Wait for a general answer. Standing item 18 framed this as needing a decision about which of the file's numbers are claims about now. That decision turned out to be already made, in the document's own headings, three passes before anyone went looking for it.

#Consequences

The snapshot table becomes maintained data rather than decaying prose, and a pass that moves a figure without updating it fails at the commit that moved it rather than being found later by accident.

The check is small on purpose and will need extending. Ten claims today, against a table of twenty-three rows. The rest are either measured by a suite that would have to be run to derive them — the APCA total, the docs route count — or are prose about a decision rather than a number about an artifact. Extending it is a per-row question, and the coverage count is printed on every run so the gap is visible rather than assumed.

It does not check that a pass narrative was written at all. That would need the file to know what a pass is, and a commit that legitimately writes no narrative — a record-only commit, a correction like this one — would fail it. What it does instead is guarantee that a narrative which *is* missing cannot leave the snapshot lying, which is the half that caused harm.

#Measured

Run against the repository at the commit that introduces it:

  • 10 claims about now, each derived from the artifact that owns it: 48 ADR records against three registers, 24 components of a 53-component roster, 16 semantic roles, 22 enforcement checks, 8 registry lists × 24, 45 unthemed and 140 themed scenes, 25 must-fail fixtures, 145 committed build outputs, and both baselines level at 45/140 with 119 and 378 Scope values.

It found a stale row on its first run. Scene roster said 43 unthemed, 137 themed — the figures from before ADR-0048's pair landed — while the Baselines row four lines below it correctly said 45 and 140. One table, two answers, and the same shape as the $stackingNote that said *"First consumer"* eleven lines under a $surfaceNote saying *"The second consumer"* in ADR-0047's context.

Seen failing before being trusted (ADR-0041). Broken two ways and observed to fire on both: a stale figure reported *"STATUS says 15, the system says 16"*, and a renamed row reported *"the row this reads was found 0 time(s) — a claim that cannot be located is not a claim that agrees."* Restored, the check returns green.

Standing item 18 closes on this record.