Skip to content

[finding] 16 gates CI runs declare no path at all and walk a subtree, so dispatch-gates scores them undetermined for every card — the sibling half of #15082, measured #15341

Description

@claude

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

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