Filed unassigned by the #15312 dev seat (session session_012zGPuVVX3deAx9LdjK8jCk), which measured the class while landing that card's fix and reported it rather than widening its own PR into it.
The class
scripts/pm/dispatch-gates.mjs derives a card's gate families from the paths each gate declares. #15312 closed one shape of the gap — a gate whose population is the WHOLE TREE now says so with the whole-tree-population marker. This card is the neighbouring shape, measured in the same sweep: a gate that declares no path literal at all (undetermined) and walks a SUBTREE, seeded from a runtime constant no source scan reads.
Those gates are scored undetermined for every card, appear in no --commands harvest, and CI runs every one of them. Same consequence as #15312: a seat's local green is not evidence, and the red arrives a cycle later.
Distinct from #15082, deliberately. That card is the silent / artifact-roster class — gates whose declared literals all name tracked FILES. These declare nothing at all. The two are complementary halves of the same residue and the remedy is the same idiom (ROOT_DIR_WATCH_HINTS, the #13519 repair), so they may want one lane, but they are different populations and neither measurement finds the other's members.
Measured, at cd1f8ee96
Method (reproducible; the seat's script is in #15312's report): every gate script CI runs, per check-self-test-wired.mjs's own collectInvocations, diffed against the union of everything dispatch-gates can ever name — the matched derivation over the whole tracked tree as one probe card MINUS each family's own file closure, plus the convention block, the whole-tree bucket and the artifact-roster block.
CI-run gate scripts: 186
families discovered: 252
scripts some derivation can name: 170
residue: 43
16 of the 43 are this class. Eleven carry a directory walk (readdirSync) seeded from literals this scan can read; five carry no walk at all and their population is simply unread.
| gate |
seed literals observed |
check:init-service-contract |
packages |
check:live-db-isolation |
packages, apps, examples |
check:meta-type-normalized |
packages |
check:optional-error-sink |
packages |
check:resume-authority-declared |
packages, examples |
check:runner-env-posture |
packages, apps, examples |
check:settings-bind-window |
packages |
check:startup-registry-verdict |
packages |
check:verify-stand-in |
packages, examples |
check:wildcard-fallthrough |
packages |
scripts/check-declaration-mirrors.mjs (+ --self-test) |
walk present, seed unreadable by this scan |
check:stall-guard |
walk present, seed unreadable by this scan |
check:docs-image-tag-sync |
no walk; population unread |
check:publish-smoke-pin |
no walk; population unread |
check:tenant-chokepoint |
no walk; population unread |
scripts/check-sdui-manifest.mjs (+ --self-test) |
no walk; population unread |
⚠️ The seed column is a MEASUREMENT of literals present in the source, never a declaration anyone may transcribe unread. #15312's own whole-tree docblock prices exactly this: the liveness predicate is a NECESSARY condition and a gate that seeds a walk and then filters it to a subtree passes it and is still mis-declared. Each row needs the gate read.
One row is already ruled by a neighbour and should be checked first: check:org-identifier was excluded from #15312's whole-tree bucket with a ROOT_WALK_RESIDUE_LEDGER row precisely because its git ls-files -- examples apps packages is three subtrees. Its remedy is this card's idiom, and landing it should clear that ledger row (the ledger's own live case reds on a stale row, so the two moves are coupled by construction).
Remedy, per gate
Declare the scan surface the gate really walks, in the subtree spelling, using the ROOT_DIR_WATCH_HINTS idiom its peers use — and pair it with the assertion in that gate's OWN self-test tying the hints to the roots constant, the way check-adr-symbol-anchors.mjs and check-agent-test-spelling.mjs already do. Once a population is declared the family is MATCHED and leaves the residue.
⛔ Not a whole-tree marker: for every gate here that would be false, and #15312's bucket is explicit that a row on every card is a fabricated lead unless the gate really reads every file.
Why this was not folded into #15312
That card names one class — WHOLE-TREE — and its fix is one declaration plus a computed guard over that class. Sixteen per-gate population judgements are a different size and a different set of owners, and a guard that swallowed them would need sixteen justified exclusion rows nobody would revisit, which is the shape artifactRosterLines refuses for its own members.
Generated by Claude Code
Filed unassigned by the #15312 dev seat (session
session_012zGPuVVX3deAx9LdjK8jCk), which measured the class while landing that card's fix and reported it rather than widening its own PR into it.The class
scripts/pm/dispatch-gates.mjsderives a card's gate families from the paths each gate declares. #15312 closed one shape of the gap — a gate whose population is the WHOLE TREE now says so with thewhole-tree-populationmarker. This card is the neighbouring shape, measured in the same sweep: a gate that declares no path literal at all (undetermined) and walks a SUBTREE, seeded from a runtime constant no source scan reads.Those gates are scored
undeterminedfor every card, appear in no--commandsharvest, and CI runs every one of them. Same consequence as #15312: a seat's local green is not evidence, and the red arrives a cycle later.Distinct from #15082, deliberately. That card is the
silent/ artifact-roster class — gates whose declared literals all name tracked FILES. These declare nothing at all. The two are complementary halves of the same residue and the remedy is the same idiom (ROOT_DIR_WATCH_HINTS, the #13519 repair), so they may want one lane, but they are different populations and neither measurement finds the other's members.Measured, at
cd1f8ee96Method (reproducible; the seat's script is in #15312's report): every gate script CI runs, per
check-self-test-wired.mjs's owncollectInvocations, diffed against the union of everythingdispatch-gatescan ever name — the matched derivation over the whole tracked tree as one probe card MINUS each family's own file closure, plus the convention block, the whole-tree bucket and the artifact-roster block.16 of the 43 are this class. Eleven carry a directory walk (
readdirSync) seeded from literals this scan can read; five carry no walk at all and their population is simply unread.check:init-service-contractpackagescheck:live-db-isolationpackages,apps,examplescheck:meta-type-normalizedpackagescheck:optional-error-sinkpackagescheck:resume-authority-declaredpackages,examplescheck:runner-env-posturepackages,apps,examplescheck:settings-bind-windowpackagescheck:startup-registry-verdictpackagescheck:verify-stand-inpackages,examplescheck:wildcard-fallthroughpackagesscripts/check-declaration-mirrors.mjs(+--self-test)check:stall-guardcheck:docs-image-tag-synccheck:publish-smoke-pincheck:tenant-chokepointscripts/check-sdui-manifest.mjs(+--self-test)One row is already ruled by a neighbour and should be checked first:
check:org-identifierwas excluded from #15312's whole-tree bucket with aROOT_WALK_RESIDUE_LEDGERrow precisely because itsgit ls-files -- examples apps packagesis three subtrees. Its remedy is this card's idiom, and landing it should clear that ledger row (the ledger's own live case reds on a stale row, so the two moves are coupled by construction).Remedy, per gate
Declare the scan surface the gate really walks, in the subtree spelling, using the
ROOT_DIR_WATCH_HINTSidiom its peers use — and pair it with the assertion in that gate's OWN self-test tying the hints to the roots constant, the waycheck-adr-symbol-anchors.mjsandcheck-agent-test-spelling.mjsalready do. Once a population is declared the family is MATCHED and leaves the residue.⛔ Not a whole-tree marker: for every gate here that would be false, and #15312's bucket is explicit that a row on every card is a fabricated lead unless the gate really reads every file.
Why this was not folded into #15312
That card names one class — WHOLE-TREE — and its fix is one declaration plus a computed guard over that class. Sixteen per-gate population judgements are a different size and a different set of owners, and a guard that swallowed them would need sixteen justified exclusion rows nobody would revisit, which is the shape
artifactRosterLinesrefuses for its own members.Generated by Claude Code