ci(lint): add a .sh arm to select-gate-families's pm_dispatch_gates read-set - #16986
Merged
Merged
Conversation
… read-set The dispatch-gates self-test grew a live census that reads the CONTENT of every tracked `.sh` file (comment-masked watch-hint extraction), but the selector's pm_dispatch_gates read-set had no `*.sh` rule. A modified shell script under packages/**, apps/**, examples/**, docs/** or content/** that does not sit in a scripts/ subdirectory classified to a class whose arm skips the gate, silently disarming a required merge check for the one path shape `*/scripts/*` does not already cover. Add `case "$path" in *.sh) return 0 ;; esac` beside the existing `.gitignore` arm, before the class switch, so any `.sh` file runs the family whatever class it sits in -- a strict superset of what already ran, so it can only widen coverage, never narrow it. Add a self-test case that drives the window directly: a `packages/a/foo.sh` modified at status M now selects pm_dispatch_gates (asserted red against the unmodified script, green after), with a negative control confirming a docs-class file at status M still skips every family. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU
baozhoutao
marked this pull request as ready for review
September 8, 2026 23:53
baozhoutao
enabled auto-merge
September 8, 2026 23:53
This was referenced Sep 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #16769.
Half 1 only — half 2 stays open, the card stays queued
This PR lands only the first of the card's two halves: the one-line
*.sharmin
pm_dispatch_gates's read-set, plus a self-test case that drives the realwindow. It closes nothing. Half 2 — pinning the selector's key sets to the
gates' live read-sets so this class of drift cannot recur — is a design
question the card explicitly declines to prescribe a shape for, and stays
unaddressed here.
objectstack-ai/objectstack#16769remains open and queuedafter this merges.
What changed
family_reads'spm_dispatch_gatesbranch classified a modified (M) shellscript that is not masked source, not a
.gitignore, and sits directly underpackages/**/apps/**/examples/**(not inside a*/scripts/*subdirectory) into the
workspaceclass, whose arm returns 1 (skip) foranything but
*/package.jsonor*/scripts/*. Butscripts/pm/dispatch-gates.mjs'sself-test reads the CONTENT of every tracked
.shfile (a live censusasserting the shell-comment mask never adds a watch hint), so such a path
should always run
pm_dispatch_gates.Added
case "$path" in *.sh) return 0 ;; esacbeside the existing*/.gitignorearm, before the class switch — so any.shfile runs thefamily whatever class it sits in, matching how masked source and
.gitignoreare already handled. Updated both comments describing thisfamily's read-set in the same voice.
This is superset-only by construction: it can only make
pm_dispatch_gatesrun more often on a path that previously skipped, never less.
Self-test case, and the before/after ablation the card requires
Added
packages/a/foo.sh(workspace class, not under*/scripts/*) to theself-test's fixture tree, and a case modifying it at status
M:Run against the unmodified script (the
.sharm reverted, self-testotherwise identical) — the new case fails, demonstrating the real hole:
Run against the fixed script — the case passes and the full battery is
green:
Negative control (mandatory): the pre-existing case at
M:packages/a/src/data.json("a non-source, non-manifest workspace fileskips every family") still asserts
expect_verdicts(empty — all skip) andpasses post-fix, confirming the new arm did not escape its intended scope
into an early, over-broad
return 0. The pre-existing merge_group docs-onlycase (
docs/guide.md, statusM) likewise still assertsexpect_verdictsempty (all skip) post-fix.
Re-check commands, re-derived before and after (on
origin/main3030369e94).gitignorearm line:320 case "$path" in */.gitignore) return 0 ;; esac:323 case "$path" in */.gitignore) return 0 ;; esac(the new*.sharm now sits at:322, immediately above it)shellGrewindispatch-gates.mjs.shfilesThe card said 27 at filing, triage said 29 sixteen hours later; this run
re-derives 31. That drift is the card's own argument for half 2 — three
data points now, not two. Control: all 31 tracked
.shfiles still liveunder
scripts/**or.claude/hooks/**(classes wherepm_dispatch_gatesalready ran before this fix); files matching
^(packages|apps|examples|docs|content)/and not under*/scripts/*→ 0— the hole was real but its firing window was, and remains, shut by where
people happen to put shell scripts, not by any rule. This PR closes that
rule-level gap for the one class this half addresses.
Local checks run (this file surface has no
package.json; not a package)pnpm check:select-gate-families(= this file's own self-test): 40/40cases, 192/192 checks — before-fix red demonstrated above, after-fix green.
pnpm check:nul-bytes: OK (8403 tracked text files, 0 raw control bytes).pnpm check:scripts-symbol-anchors: OK (3041 anchors, 234 scripts).node scripts/check-self-test-wired.mjs: OK.node scripts/check-self-test-workflow-commands.mjs: OK.node scripts/check-comment-mask-corpus.mjs: OK (6389 files, 0 disagree).pnpm check:pm-dispatch-gates(scripts/pm/dispatch-gates.mjs's ownself-test, run detached per that gate's own header instruction since it
exceeds a practical foreground budget): PASS —
dispatch-gates self-test: 1561 cases pass(~530s wall time, this run).No changeset: nothing in
packages/**'s publishedfiles[]referencesscripts/ci/**; this is unpublished, repo-root CI tooling under a privatepackage, so no user-visible surface moved.
Generated by Claude Code