D314 - the decision gate checks the log this repository actually has

decided - 2026-09-03

obscene-tool decisions built the index at the top of a single-file DECISIONS.md by reading its ## D001 - … headings. The log was later split into one file per entry with a generated table of links, and the subcommand was never repointed. It has been reporting

no entries found in ./docs/DECISIONS.md

and exiting 1 ever since, so verify.sh has carried a failing gate that checks nothing.

What it does now

The index is generated by tools/split-decisions.sh --index obscene, shared with the sibling repositories. Two generators for one file is how a file ends up with two values, so this does not write. It checks the half a generator cannot check for itself - that the directory and the index still describe the same set:

Confirmed against the real log: 302 entries, consistent, and byte-identical to what the splitter regenerates.

Finding nothing is a failure, not a pass

Stated explicitly and given a test, because the shape keeps recurring: an empty decisions directory refuses. A gate with nothing to check has not passed, it has failed to run.

That is the same defect as D303 one layer up - a probe reporting a field it initialised itself - and as a run filter whose negative turned out to be a fact about the filter. Three instances in a week is a pattern, and the cheap defence is the same in all three: ask whether the reading could have arisen without the thing being measured doing anything.

Watched failing, twice, and one of them was mine

Hiding one entry from the index: D303-…md: no row in docs/DECISIONS.md, exit 1. Restoring from the backup: consistent, exit 0.

The first version matched the bare string decisions/, which appears in the front matter describing the layout, then ran to the next ) - producing a "link" spanning six rows. The unit test written to prove it ignored prose caught it before the gate was believed. The parser now anchors on ](decisions/ and rejects a name containing a newline or a bracket.

What it found on the first honest run

Eight rows with no title at all - [](decisions/D302-….md). The splitter reads a title from # D<NNN> - Title, and nine entries had been written # D302: Title. Headings normalised; the gate now refuses an untitled row, because an index of unlabelled links is precisely what an index exists not to be.

Numbering

Taken as D314, not 304. Worklogs 136-145 cite the ten numbers from 304 upward in their titles and no such files exist - doccheck has been reporting it. Writing into that range would silently give those citations a wrong target, which is worse than the gap. The gap stays and is now recorded here.