Filed by the domain:devx @ objectstack execution seat (session_012GKcPZbMoGq7WPzKLfRBTU) at 2026-09-08T04:3xZ, out of the contract-review-tier re-review of PR #16754 (closes #16496). ⛔ Left unlabelled for triage to route and rank.
The instance
PR #16754 ships scripts/ci/select-gate-families.sh, which lets a merge group skip a gate family when the changed paths do not touch what that family reads. Its safety property is that a key set must never be narrower than the gate's true read-set — a narrower key set silently skips a gate on a change that would have reddened it.
8ccf7a1df (PR #16740, for #16132) merged 2026-09-08T03:19Z — about two hours after #16754's branch point — and added to the dispatch-gates self-test a live census that reads the CONTENT of every tracked .sh file (it asserts the new shell-comment mask never adds a hint: shellGrew === 0, plus two aggregate-direction assertions).
The selector at f12f2e1c7 has no *.sh rule in family_reads's pm_dispatch_gates arm. So a modification of a .sh under packages/** (outside */scripts/*), apps/**, examples/**, docs/** or content/** classifies to a class that skips a 597-second gate which reads it.
Why it is latent today, and ⛔ why that is not a reason to leave it
- All 27 tracked
.sh files on origin/main classify to scripts / agent-config / verify-lock, arms where pm_dispatch_gates already runs.
- A new
.sh anywhere arrives as status A, and A runs every family.
- ⇒ Triggering it needs someone to add a
.sh in one of those directories — running every family at that moment — and then modify it later.
That window is narrow enough that the re-review judged it non-blocking and this seat landed #16754 rather than spending a patch round on it. It is not narrow enough to leave unfiled: latent means will be live later, with nobody watching.
The one-line repair, for whoever takes this: a *.sh) return 0 ;; arm beside the existing */.gitignore rule in family_reads's pm_dispatch_gates branch (select-gate-families.sh, ~line 320, before the class switch), plus one self-test case.
⭐ The structural defect, which is the actual subject of this card
Fixing the .sh arm fixes today's instance and leaves the mechanism intact: nothing pins the selector's key sets to the gates' live read-sets. The key sets are a hand-maintained transcription, and the read-sets move — this one moved within two hours of the selector being written, by an unrelated PR in the same lane, and was caught only because a contract-review reviewer happened to re-derive it.
This is the same defect class this lane has now filed repeatedly: a transcribed fact with nothing comparing it to the thing it transcribes (see #15231, #15864, #16007 — self-test counts; #16132 — watch-hint population). Here the stakes are higher, because the transcription being stale silently disarms a required merge gate rather than printing a wrong number.
Worth considering as the repair, ⛔ not a prescription:
- a gate that derives each family's read-set from the gate's own source or declaration and fails when the selector's key set is not a superset; or
- making the selector consult a read-set the gate itself exports, so there is one home for the fact rather than two.
The first is the shape this repo has used for exactly this problem before (check:declared-population-live).
Re-check commands
grep -n 'gitignore' scripts/ci/select-gate-families.sh
grep -c 'shellGrew' scripts/pm/dispatch-gates.mjs
git ls-files '*.sh' | wc -l
At filing, on origin/main after #16740 landed: the .gitignore arm is present and there is no *.sh sibling; shellGrew appears in dispatch-gates.mjs; 27 tracked .sh files. ⛔ Re-derive all three before acting — #16754 has since landed and the line numbers will have moved.
Refs #16496 · PR #16754 · #16132 · PR #16740.
Generated by Claude Code
Filed by the
domain:devx @ objectstackexecution seat (session_012GKcPZbMoGq7WPzKLfRBTU) at 2026-09-08T04:3xZ, out of the contract-review-tier re-review of PR #16754 (closes #16496). ⛔ Left unlabelled for triage to route and rank.The instance
PR #16754 ships
scripts/ci/select-gate-families.sh, which lets a merge group skip a gate family when the changed paths do not touch what that family reads. Its safety property is that a key set must never be narrower than the gate's true read-set — a narrower key set silently skips a gate on a change that would have reddened it.8ccf7a1df(PR #16740, for #16132) merged 2026-09-08T03:19Z — about two hours after #16754's branch point — and added to thedispatch-gatesself-test a live census that reads the CONTENT of every tracked.shfile (it asserts the new shell-comment mask never adds a hint:shellGrew === 0, plus two aggregate-direction assertions).The selector at
f12f2e1c7has no*.shrule infamily_reads'spm_dispatch_gatesarm. So a modification of a.shunderpackages/**(outside*/scripts/*),apps/**,examples/**,docs/**orcontent/**classifies to a class that skips a 597-second gate which reads it.Why it is latent today, and ⛔ why that is not a reason to leave it
.shfiles onorigin/mainclassify toscripts/agent-config/verify-lock, arms wherepm_dispatch_gatesalready runs..shanywhere arrives as statusA, andAruns every family..shin one of those directories — running every family at that moment — and then modify it later.That window is narrow enough that the re-review judged it non-blocking and this seat landed #16754 rather than spending a patch round on it. It is not narrow enough to leave unfiled: latent means will be live later, with nobody watching.
The one-line repair, for whoever takes this: a
*.sh) return 0 ;;arm beside the existing*/.gitignorerule infamily_reads'spm_dispatch_gatesbranch (select-gate-families.sh, ~line 320, before the class switch), plus one self-test case.⭐ The structural defect, which is the actual subject of this card
Fixing the
.sharm fixes today's instance and leaves the mechanism intact: nothing pins the selector's key sets to the gates' live read-sets. The key sets are a hand-maintained transcription, and the read-sets move — this one moved within two hours of the selector being written, by an unrelated PR in the same lane, and was caught only because a contract-review reviewer happened to re-derive it.This is the same defect class this lane has now filed repeatedly: a transcribed fact with nothing comparing it to the thing it transcribes (see #15231, #15864, #16007 — self-test counts; #16132 — watch-hint population). Here the stakes are higher, because the transcription being stale silently disarms a required merge gate rather than printing a wrong number.
Worth considering as the repair, ⛔ not a prescription:
The first is the shape this repo has used for exactly this problem before (
check:declared-population-live).Re-check commands
At filing, on
origin/mainafter #16740 landed: the.gitignorearm is present and there is no*.shsibling;shellGrewappears indispatch-gates.mjs; 27 tracked.shfiles. ⛔ Re-derive all three before acting — #16754 has since landed and the line numbers will have moved.Refs #16496 · PR #16754 · #16132 · PR #16740.
Generated by Claude Code