Skip to content

[finding] bare-root-worklist records check-declaration-mirrors as REFUSE-UNSPELLABLE on a ground the vocabulary no longer holds — the extension filter IS spellable #15602

Description

@claude

Filed by the os-dev agent working #15553 (PR #15601), from a measurement taken while landing that card. Filed unassigned, finding, for triage to price.

The record

scripts/pm/bare-root-worklist.mjs:781 records, under "Refused: the population is a filter the idiom cannot spell":

['scripts/check-declaration-mirrors.mjs SCRIPTS_DIR scripts', {
  verdict: 'REFUSE-UNSPELLABLE',
  why: 'a RECURSIVE walk admitted by EXTENSION — every `scripts/**/*.d.mts`, 2 of 261 (0.77%) …
        What cannot be spelled here is the EXTENSION filter, not a non-recursive walk …',
}]

What is no longer true

The hint vocabulary spells extensions. Measured on ab5c01379:

hintCovers('scripts/**/*.d.mts', 'scripts/js-comment-mask.d.mts')  -> true
hintCovers('scripts/**/*.d.mts', 'scripts/js-comment-mask.mjs')    -> false
hintCovers('scripts/**/*.d.mts', 'scripts/foo.json')               -> false

judgedAsPattern routes a glob in a non-final segment to triggerCovers rather than to the deletion-collapse, so an extension filter is expressible and precise. scripts/check-self-test-wired.mjs has carried ['scripts/**/*.mjs', 'scripts/**/*.mts', 'scripts/**/*.sh'] for some time, and PR #15590 added a second carrier.

PR #15601 acts on that: check-declaration-mirrors.mjs now declares ['scripts/**/*.d.mts', 'scripts/**/*.mjs']. The row's recorded reason therefore states a refusal the tree has withdrawn — and the numbers in it are stale in both terms as well (the walk finds 4 mirrors today, not 2, and scripts/ holds 331 tracked files, not 261).

Why nothing reds

--self-test stays green and that is correct behaviour, not a hole in it: contradicted fires only on a row the sweep finds REACHABLE, i.e. one whose gate declares a hint reaching an arbitrary file at the top of the root. Neither new hint does, so the row stays UNCOVERED, keeps its key, and none of STALE / FRESH / CONTRADICTED sees it. Verified after the declaration landed:

node scripts/pm/bare-root-worklist.mjs --self-test  -> exit 0
OK  self-test: 54 live row(s), 46 unreachable as spelled, 46 recorded verdict(s) —
    none stale, none missing, none contradicted.

This is the class the file's own docblock warns about by name: "a why is prose this tool never reads, so a recorded verdict can keep its key, its reachability and its verdict while the DERIVATION moves out from under the reason it states" — and, separately, "only re-measuring catches this class", which the same docblock says of this very row's history.

What a fix owes (direction, not prescription)

The row now matches the shape the map already defines for it: a gate that took the escape and whose bare root is still not covered is DECLARED-NARROWER, which is where check:skill-refs and check:objectql-double-limit landed under the 2026-08-26 authorisation sentence ("bringing a verdict back to truth after its definitional basis moved is not loosening the map"). That verdict requires a spelling entry in SPELLINGS, held LIVE / PRECISE / COMPLETE and SET-EQUAL to the gate's declared array in both directions, with any deliberate omission named in omits — so it is a real edit with pins attached, on a shrink-only map, not a one-word swap.

Two things a fixer should decide rather than inherit:

  • the scripts/**/*.mjs half is 1.9% precise (214 tracked files reached, 4 read), so omits / the PRECISE pin has to be faced head-on rather than assumed;
  • the numbers in the why must be re-measured together — the file's own rule is that refreshing a denominator alone mints a ratio nothing ever measured.

⛔ Left to a card that owns that file: re-deciding a verdict on a shrink-only map is ceremonied, and #15601's scope was the gate's own declaration.


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

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions