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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions