Skip to content

[finding] bare-root-worklist pins a recorded spelling in hintCovers' terms only for SINGLE-hint rows — five DECLARED-NARROWER rows are re-measured by nothing #14233

Description

@claude

Measured while working #13813 (PR #14231). Filed unassigned, not graded.

What is unpinned

scripts/pm/bare-root-worklist.mjs argues, in its own docblock, that the whole licence for
recording "a precise live spelling exists" is that something re-measures the spelling:

a vocabulary value recording "a precise live spelling exists" whose spelling nothing
re-measures is the allowlist #10840 refused by name.

That pin is the SPELLINGS loop in --self-test, which asserts LIVE / PRECISE / COMPLETE for
each recorded spelling in hintCovers' own terms. It is a real pin and it works.

⭐ But SPELLINGS holds one hint per entry, and a row carries one spelling name. So a
gate whose population needs more than one hint cannot record a spelling at all, and its row is
pinned by nothing in this file. Five DECLARED-NARROWER rows are in exactly that state today:

row hints the gate declares
check:logger-receiver-detach SCAN_ROOTS packages 6 (three extensions x two roots)
check:logger-receiver-detach SCAN_ROOTS examples (same declaration)
check:logger-receiver-detach SCAN_ROOTS apps (same declaration)
check:dual-build-cjs-loads SCAN_ROOT packages 2
check:ratchet-remedy-authority SCRIPTS_DIR scripts 2 (one per admitted extension)

The verdict is not wrong on any of them, and the omission is deliberate and stated in each row.
What is missing is the re-measurement the file's own argument says the record depends on.

Why the gate-side self-tests do not close it

Each of those gates does pin its declaration from its own side, and each pin is deliberately
written without importing scripts/pm/dispatch-gates.mjs — because the import specifier would
itself be a path literal, handing the gate that module's declared population as if it were its own.
check-logger-receiver-detach.mjs records that refusal in as many words, and #13813's gate repeats
it.

⇒ Every one of those pins is therefore a local segment matcher, never hintCovers. They hold
"the declaration is a function of the constants the walk is a function of", which is the drift they
exist for. They cannot hold "and hintCovers still reaches these files."

The two claims come apart, and not hypothetically — the whole reason this card's parent row was
re-decided is that hintCovers moved under it twice (#12300, then #13448) while every local
assertion about the declared value stayed green. A regression in the other direction is the same
shape: scripts/*.mjs reaches 183 files today, and if a future change to judgedAsPattern sent it
back through collapseHint it would reach zerocollapseHint('scripts/*.mjs') still returns
scripts/.mjs today — with the gate's own self-test, check:watch-hint-literal and
check:declared-population-live all green. Only check:declared-population-live asks the
reachability question at all, and it is per-FAMILY: one live literal rescues the family, so a
partial death is invisible there too.

Shape of a remedy (not proposed as an implementation)

The narrow version is a SPELLINGS entry that holds a list of segment arrays rather than one,
with holds asked of the union — the pin loop then covers multi-hint rows unchanged. That is a
change to the pin harness in a governance file this lane does not write code in, which is why this
is recorded rather than fixed.

⚠️ What I am not claiming: I have not audited whether the other four rows' declarations are
still live in hintCovers' terms — only that nothing in the tree asserts it. The count says
nothing about which.


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