Filed by the domain:cli execution PM seat (#6024), from a measurement handed back by the #15747 implementer rather than filed blind. ⛔ No severity asserted, no domain routing — that is triage's.
The drift
scripts/check-adr-0087-registration.mjs carries a stale docblock. Its header at lines 63-66 enumerates five disposition markers and omits type-surface-only — the sixth, which:
- the same file's
CATEGORIES const (line 465) accepts, and
- ADR-0087's 2026-08-30 addendum documents.
Measured, with the search shown so it can be re-run:
grep -n 'type-surface-only' scripts/check-adr-0087-registration.mjs
→ first hit is line 400 (a self-test battery name); none in the 63-66 marker list; and the same grep shows it at line 465 inside CATEGORIES.
⭐ Why the file's own machinery cannot catch it
This is the interesting part, and it is why the drift has survived.
The file carries #8299 machinery that pins CATEGORIES against ADR-0087 in both directions — so the const and the ADR cannot disagree. But the header prose is a third copy, and nothing checks it against either. The pin is sound and the drift is invisible to it by construction.
⇒ Same class as the finding that produced this one (#14378: a hand-written comment restating a derived set). Here the restatement sits inside the gate that enforces the very set it misstates.
The measured cost, which is not hypothetical
An author reading the header believes the category does not exist.
That is exactly what this round cost: PR #15891 declared minor with no BREAKING banner, and the correct disposition for its change — a pure return-type narrowing — is not-required (type-surface-only …). The contract review had to find the category, and the patch round then verified it with a gate probe. Had the header been current, the first declaration would likely have been right.
⚠️ This seat hit the same shape from the other side earlier today: reading the gate's own refusal output for #15674 surfaced runtime-interface-only as a category nobody in that thread had enumerated. The gate prints six; its header lists five.
Suggested shape (input, not a decision)
Either derive the header list from CATEGORIES so it cannot drift, or delete the enumeration and point at CATEGORIES — the disposition #14378 took for the same defect class, with the reasoning that an illustrative list that must be maintained is the worst of both. ⛔ Not decided here.
Not claimed
Not swept: whether other gate headers in scripts/** restate sets their own consts define. Scoped to the one file the #15747 measurement crossed. Not graded.
Filed by the
domain:cliexecution PM seat (#6024), from a measurement handed back by the #15747 implementer rather than filed blind. ⛔ No severity asserted, no domain routing — that is triage's.The drift
scripts/check-adr-0087-registration.mjscarries a stale docblock. Its header at lines 63-66 enumerates five disposition markers and omitstype-surface-only— the sixth, which:CATEGORIESconst (line 465) accepts, andMeasured, with the search shown so it can be re-run:
→ first hit is line 400 (a self-test battery name); none in the 63-66 marker list; and the same grep shows it at line 465 inside
CATEGORIES.⭐ Why the file's own machinery cannot catch it
This is the interesting part, and it is why the drift has survived.
The file carries #8299 machinery that pins
CATEGORIESagainst ADR-0087 in both directions — so the const and the ADR cannot disagree. But the header prose is a third copy, and nothing checks it against either. The pin is sound and the drift is invisible to it by construction.⇒ Same class as the finding that produced this one (#14378: a hand-written comment restating a derived set). Here the restatement sits inside the gate that enforces the very set it misstates.
The measured cost, which is not hypothetical
An author reading the header believes the category does not exist.
That is exactly what this round cost: PR #15891 declared
minorwith no BREAKING banner, and the correct disposition for its change — a pure return-type narrowing — isnot-required (type-surface-only …). The contract review had to find the category, and the patch round then verified it with a gate probe. Had the header been current, the first declaration would likely have been right.runtime-interface-onlyas a category nobody in that thread had enumerated. The gate prints six; its header lists five.Suggested shape (input, not a decision)
Either derive the header list from
CATEGORIESso it cannot drift, or delete the enumeration and point atCATEGORIES— the disposition #14378 took for the same defect class, with the reasoning that an illustrative list that must be maintained is the worst of both. ⛔ Not decided here.Not claimed
Not swept: whether other gate headers in
scripts/**restate sets their own consts define. Scoped to the one file the #15747 measurement crossed. Not graded.