docs(901): pay for the two corrections by tightening the prose around them

The two corrections added four prose lines to a record already one line over
the 60-line advisory ceiling. Recover what can be recovered without losing
substance: reflow the paragraphs, drop the padding ("and it fails silently"
→ ", silently"; "the count rises" → "and rises"), and cut one restatement.

It lands at 65 lines, not 60. That is a deliberate stop: the remaining
candidates are the *why* behind non-obvious choices — which the repo's own
docs rule says to keep — and `decisions_validate` reports the constant itself
as drifted from the distribution it is supposed to mark the tail of (p90=104,
p95=142, 50 of 222 records over it). The validator passes.

Refs #901

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QqCpYFsKgnAnx6jVwrKiV
This commit is contained in:
2026-09-05 15:59:16 +02:00
co-authored by Claude Fable 5.1
parent 0977f04174
commit 761a71278d
@@ -16,11 +16,11 @@ respelling — and each defeat looks local, one more case to handle, so the sequ
someone stops it. Measured 2026-08-30 across two unrelated subjects: a guard parsing shell text to
decide whether a command runs the SPA suite was wrong **nine** ways from one mechanism (#887), its
replacement — a partial match of `web/vite.config.ts`**seven** further ways, and a lexical rule
over a hook preamble **five** (#891). Every fix was locally correct and none of the three sequences
over a hook preamble **five** (#891). Every fix was locally correct; none of the three sequences
converged. All three ended in the same move: a pin cannot be defeated by a respelling of what it
COMPARES, since it need not RECOGNISE one in order to reject it. What stays exposed is whatever it
does not compare nothing for a whole-file pin, and exactly the reach of the SELECTOR for a pin
scoped by one, which is why `mechanics:` states the hook pin's.
does not compare: nothing for a whole-file pin, and the SELECTOR's reach for a pin scoped by one —
which is why `mechanics:` states the hook pin's.
**Why the pin is the DEFAULT and not the remedy — the first thing #901 left open.** The rejected
alternative is the tempting one: write the shape-matcher, and pin only once it has been defeated. It
@@ -28,50 +28,50 @@ is rejected because of what the trigger event is made of. A shape-matcher's fail
GREEN, which the guard by construction does not report; the defeat therefore arrives from a reviewer
or from an incident, so its absence measures who has looked rather than what the input can be. Both
measurements above are that asymmetry: neither predicate withdrew because a count got high, and both
had the precedent available for every round. The second reason is that switching later is not the
same price as starting there. A withdrawal costs the rounds already spent AND the proofs calibrated
against the narrow clause (rider 2), so "pin it when it breaks" understates its own bill.
had the precedent available for every round. The second reason is that switching later costs more
than starting there: a withdrawal costs the rounds already spent AND the proofs calibrated against
the narrow clause (rider 2), so "pin it when it breaks" understates its own bill.
**What a shape-matcher's exception argument must contain — the second thing #901 left open.** The
four requirements are chosen so a reviewer can REFUSE one: each is a thing the author either wrote or
did not. Two alternatives are rejected. A NUMERIC bar ("survives N adversarial spellings") measures
the reviewer's imagination rather than the input space, and the count rises while the defect stands —
it would have licensed #887's parser through most of nine rounds. A REVIEWER SIGN-OFF bar is worse:
it makes the exception depend on the very signal the threshold says arrives late. What survives is
four requirements are chosen so a reviewer can REFUSE one: each is a thing the author either wrote
or did not. Two alternatives are rejected. A NUMERIC bar ("survives N adversarial spellings")
measures the reviewer's imagination, not the input space, and rises while the defect stands — it
would have licensed #887's parser through most of nine rounds. A REVIEWER SIGN-OFF bar is worse: it
makes the exception depend on the very signal the threshold says arrives late. What survives is
requirement 2, the only candidate that is a claim about the ARTIFACT rather than about the effort
spent on it, and requirement 3, which forces the fail-direction claim to be executed, not reasoned.
**Rider 1 — a pin assumes it pins the artifact that still DECIDES.** This is where the pinned form
fails, and it fails silently, so it is the question to ask of every new pin. In #887 every hole
found after the first withdrawal was authority moving where the pin was not looking: another FILE
(vitest prefers `vitest.config.*`, and `vite build` prefers `vite.config.js`/`.mjs` to the pinned
`.ts` — an ordering that belongs to a vite VERSION, so the release it was read at is dated in
`docs/guard-inventory.md`'s `test_image_build_delegates_the_spa_suite.py` row rather than copied
here), another OCCURRENCE in the same file, another WORKFLOW (a `needs:` edge naming a different job
called `test`), a HOOK the pinned command invokes (a vite plugin's `buildStart`, an npm
`prebuild`/`preinstall` script). A pin removes the SPELLING problem outright and reduces the MEANING
problem to a list that can be worked through; a pin sold as immune to both stops being re-examined.
fails, silently, so it is the question to ask of every new pin. In #887 every hole found after the
first withdrawal was authority moving where the pin was not looking: another FILE (vitest prefers
`vitest.config.*`; `vite build` prefers `vite.config.js`/`.mjs` to the pinned `.ts` — a
VERSION-bound ordering, so the vite release it was read at is dated in `docs/guard-inventory.md`'s
`test_image_build_delegates_the_spa_suite.py` row rather than copied here), another OCCURRENCE in
the same file, another WORKFLOW (a `needs:` edge naming a different job called `test`), a HOOK the
pinned command invokes (a vite plugin's `buildStart`, an npm `prebuild`/`preinstall` script). A pin
removes the SPELLING problem outright and reduces the MEANING problem to a list that can be worked
through; a pin sold as immune to both stops being re-examined.
**Rider 2 — widening a clause can retire its own evidence.** A canary asserting that a finer mutation
still SURVIVES is calibrated against a deliberately coarse clause. Widen that clause and the canary
does not go red, it goes vacuous — indistinguishable from a passing proof at the point of reading —
so the widening commit re-derives every proof calibrated against the narrow form. Same shape as the
`DETECTOR` grade in `testing.mutation-claims-are-executed`: a surviving mutation is worth something
only while the precondition that made it survive still holds.
**Rider 2 — widening a clause can retire its own evidence.** A canary asserting that a finer
mutation still SURVIVES is calibrated against a deliberately coarse clause. Widen that clause and
the canary does not go red, it goes vacuous — indistinguishable from a passing proof at the point of
reading — so the widening commit re-derives every proof calibrated against the narrow form. Same
shape as the `DETECTOR` grade in `testing.mutation-claims-are-executed`: a surviving mutation is
worth something only while the precondition that made it survive still holds.
**Where this sits against its neighbours, so it is not read as a duplicate.** The two incidents keep
their own records — `ci.image-build-delegates-the-spa-suite` and
`process.hook-resolves-inputs-from-repo-root` — and this is the class they instantiate, while
`testing.guard-derives-population-from-source` answers the case where the authoritative source is
MISSING (create one, never approximate it with a predicate over text) and this one the case where
the artifact IS present and authoritative and what is approximated is its GRAMMAR.
MISSING (create one, never approximate it with a predicate over text); this one, the case where the
artifact IS present and authoritative and its GRAMMAR is what gets approximated.
`docs/defect-shapes-773.md` does NOT carry this rule: its §3.6 partition lists the nearest class,
string-predicate churn, as `no detector proposed`, and §3.7 argues that class away as a cross-cutting
property. Only §4's closing meta-finding supports the FORM — a class-level rule beats one record per
instance — so the rule itself is new here, and resolvable BY TOPIC, where `docs/guard-inventory.md`
string-predicate churn, as `no detector proposed`, and §3.7 argues that class away as a
cross-cutting property. Only §4's meta-finding supports the FORM — a class-level rule beats one
record per instance — so the rule is new here, resolvable BY TOPIC where `docs/guard-inventory.md`
carries its precedent per incident, findable only inside one.
**What this does not cover.** Predicates over structured input a real parser produces — an AST, the
git index, parsed workflow YAML consumed as data — are not approximations and keep their shape
matching. And a pin is not mandatory for an artifact edited continuously by many hands: that is
requirement 4's own escape hatch, and a pin reddening as background noise is a guard nobody reads.
requirement 4's own escape hatch, and a pin reddening as background noise is a guard nobody reads.