Skip to content

[finding] check:slot-lookup is a shrink-only ratchet with NO self-test, and the wiring gate cannot see the gap #12052

Description

@yinlianghui

Blocked-by: #11681

Filed unassigned as a finding — recording only, not graded. Surfaced while deriving the
population for #11694 (PR #12050), which enumerated every shrink-only ratchet under
scripts/ and read each one's self-test. ⛔ Nothing here blocks that PR; the gate does not
carry #11694's defect, because it has no self-test to carry it in.

The gap

scripts/check-slot-lookup-ratchet.mjs is a shrink-only ratchet — it maintains
scripts/slot-lookup-baseline.json and its header calls the baseline monotonic. Of the 33
shrink-only ratchets #11694 derived under scripts/, it is one of only two with no
selfTest() at all
, and the only one of those two that is a gate (the other,
scripts/regen-artifacts.mjs, is a generator).

Its wiring carries no self-test invocation either — from root package.json:

"check:slot-lookup": "node scripts/check-slot-lookup-ratchet.mjs"

Every sibling ratchet spells this as node scripts/<gate>.mjs --self-test && node scripts/<gate>.mjs.

Why the wiring gate does not catch it

scripts/check-self-test-wired.mjs (#11150) deliberately enforces the mechanically
decidable superset
, stated in its own header: "every script CI runs that ships a
--self-test must have that self-test run by CI too."
A gate that ships none is outside
that rule by construction — the superset is about the invocation, not about the existence.
Its header is explicit that membership in the family "turns on whether a rule has a
MUST-BE-REACHED WITNESS recorded in the tree" and that "no static classifier decides it",
which is exactly why the absence here is invisible rather than merely unenforced.

So the standing situation: a ratchet whose rule can be weakened with no instrument
watching. That is the failure mode check-self-test-wired.mjs's own header opens with —
"green means the finding set is empty; weakening the rule can only SHRINK that set; and the
empty set is the fixed point of shrinking" — applied to a gate its superset cannot reach.

Why Blocked-by: #11681 rather than a fix now

#11681 is queued to change this gate's rule (check:slot-lookup enforces that a lookup
is TYPED, never that the named type is COMPLETE). A self-test written against today's rule
would be rewritten by that card, and the useful self-test is the one that pins whichever
rule #11681 lands. Sequencing it after #11681 costs nothing and avoids writing the
instrument twice.

⛔ Not graded, no domain:* set, no pm:queue — triage's to route, including "won't fix,
recorded". Note the file is currently in a hot-file serial queue: #11694 (PR #12050) landed
a change to a different gate in the same sweep, and #11681 is queued behind it.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions