Surfaced while fixing #12472 (PR #12759), which repaired the phantom literal-vs-computed pin in scripts/check-cli-command-ids.mjs. Filed unassigned and not touched there — that card's declared file surface is one gate, and this is a class observation across eleven others. Not a live defect: every declaration in the tree is currently spelled as a literal.
The mechanism, measured on this tree
extractWatchHints in scripts/pm/dispatch-gates.mjs reads source text, so a ROOT_DIR_WATCH_HINTS declaration written as a literal contributes a hint and the same declaration computed from the population constant contributes nothing. Measured directly against the extractor on scripts/check-cli-command-ids.mjs:
| declaration spelling | subtree hints recovered |
|---|
| literal | ["scripts/**"] |
| computed from the population constant | [] |
A gate that loses its hint becomes unnameable by every dispatch brief and scores a quiet green for every card in the tree. That is the harm #12472 documents.
The population
Swept the 13 gates carrying a ROOT_DIR_WATCH_HINTS declaration under scripts/. Exactly two carry an own-source readFileSync(fileURLToPath(import.meta.url)) pin holding the declaration to a literal spelling:
The remaining 11 have no such pin at all:
check-agent-test-spelling · check-comment-mask-adoption · check-driver-conformance
check-entry-guard · check-examples-live-imports · check-parse-guard
check-pnpm-filter-targets · check-published-files · check-role-word
check-skill-compatibility-version · check-skill-frame-sync
Nothing local to those files would redden if an author rewrote the declaration as a mapped expression over the population constant — which is a natural-looking tidy-up, since in every case the hint is literally the population root plus a subtree glob.
What is NOT measured here, and should be checked first
I did not measure whether the repo-level ledger gates already catch this from the other side. node scripts/pm/bare-root-worklist.mjs --self-test and pnpm check:pm-dispatch-gates both reason about gates whose population is unspelled, and it is plausible that computing a declaration away trips one of them as a STALE or CONTRADICTED verdict. If it does, this card is already covered and should be closed as such — that check is the first step, not the remedy.
Reproduce by mutating one declaration in a worktree and running both ledger gates.
If it is genuinely uncovered
The remedy the repo already prefers is one shared guard closing the whole class rather than eleven copies of a per-file pin: a check that, for every gate declaring ROOT_DIR_WATCH_HINTS, locates the declaration statement and asserts each declared hint appears inside that statement as a quoted literal. #12759 implements exactly that shape for one file and its ablation is recorded there, so the predicate is already written and measured; generalising it is mostly relocation.
Note the scoping detail that cost #12472 its enforcement: searching the whole file is not sufficient, because a gate may spell its own hint again in a neighbouring runtime-value assertion, and a whole-file includes then finds that copy and stays green. The search has to be scoped to the declaration statement.
Measured on objectstack-ai/objectstack at 168941cea.
Surfaced while fixing #12472 (PR #12759), which repaired the phantom literal-vs-computed pin in
scripts/check-cli-command-ids.mjs. Filed unassigned and not touched there — that card's declared file surface is one gate, and this is a class observation across eleven others. Not a live defect: every declaration in the tree is currently spelled as a literal.The mechanism, measured on this tree
extractWatchHintsinscripts/pm/dispatch-gates.mjsreads source text, so aROOT_DIR_WATCH_HINTSdeclaration written as a literal contributes a hint and the same declaration computed from the population constant contributes nothing. Measured directly against the extractor onscripts/check-cli-command-ids.mjs:["scripts/**"][]A gate that loses its hint becomes unnameable by every dispatch brief and scores a quiet green for every card in the tree. That is the harm #12472 documents.
The population
Swept the 13 gates carrying a
ROOT_DIR_WATCH_HINTSdeclaration underscripts/. Exactly two carry an own-sourcereadFileSync(fileURLToPath(import.meta.url))pin holding the declaration to a literal spelling:scripts/check-cli-command-ids.mjs— the pin was phantom; fixed in fix(scripts): make check-cli-command-ids' literal-declaration self-test able to fail #12759scripts/check-objectql-double-limit.mjs— cleared, hint spelled once, assembled needleThe remaining 11 have no such pin at all:
Nothing local to those files would redden if an author rewrote the declaration as a mapped expression over the population constant — which is a natural-looking tidy-up, since in every case the hint is literally the population root plus a subtree glob.
What is NOT measured here, and should be checked first
I did not measure whether the repo-level ledger gates already catch this from the other side.
node scripts/pm/bare-root-worklist.mjs --self-testandpnpm check:pm-dispatch-gatesboth reason about gates whose population is unspelled, and it is plausible that computing a declaration away trips one of them as a STALE or CONTRADICTED verdict. If it does, this card is already covered and should be closed as such — that check is the first step, not the remedy.Reproduce by mutating one declaration in a worktree and running both ledger gates.
If it is genuinely uncovered
The remedy the repo already prefers is one shared guard closing the whole class rather than eleven copies of a per-file pin: a check that, for every gate declaring
ROOT_DIR_WATCH_HINTS, locates the declaration statement and asserts each declared hint appears inside that statement as a quoted literal. #12759 implements exactly that shape for one file and its ablation is recorded there, so the predicate is already written and measured; generalising it is mostly relocation.Note the scoping detail that cost #12472 its enforcement: searching the whole file is not sufficient, because a gate may spell its own hint again in a neighbouring runtime-value assertion, and a whole-file
includesthen finds that copy and stays green. The search has to be scoped to the declaration statement.Measured on
objectstack-ai/objectstackat168941cea.