You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
dispatch-gates self-test: the --changed --commands CONTROL reds on any branch with no diff against origin/main — every fresh worktree's baseline run #15278
dispatch-gates.mjs's self-test carries this control (line numbers as of a23603ea9):
constchangedCommandsRun=runCli(['--changed','--commands']);t('CONTROL: --changed --commands is legal and answers, so the moved usage line describes a real combination',changedCommandsRun.status===0&&(changedCommandsRun.stdout??'').length>0,);
--changed derives its change set from git. On a branch whose tip equals its merge base
with origin/main, that derivation refuses by design and exits 2:
dispatch-gates: this branch changes nothing against 'origin/main' (merge base …) — nothing to derive.
So status === 0 is false and the control fails — not because the combination is illegal,
which is what the case is about, but because this particular tree has no diff.
Measured
On a worktree cut from origin/main at a23603ea9 with zero edits:
✗ CONTROL: --changed --commands is legal and answers, so the moved usage line describes a real combination
✗ dispatch-gates self-test: 1 of 1353 case(s) failed.
The same tree, after one unrelated commit, runs 1363 cases pass with exit 0. Nothing but
the presence of a commit moved it.
Why it is worth fixing
CI never sees this: a PR branch always has a diff, so the case is green there. What it hits
is the first thing a developer does in a fresh worktree — run the gate to get a baseline
before editing. The self-test then reports a red that is about the worktree, and a reader
has no way to tell it from a real one. It cost one round of investigation on the card this
was found under before it was traced.
It is the same class as the .changeset/*.md population control (a self-test case whose
verdict is a property of the tree rather than of the tool), but a different trigger, and the
right shape is a judgment call rather than a mechanical edit — which is why it was recorded
here instead of being carried in that card's PR.
Shape of the fix (not a ruling)
The control wants to show that --changed combines with --commands. That claim can be
made without depending on the caller's tree: exit 2 with the "changes nothing" refusal
is itself proof the combination parsed and reached the derivation — an illegal combination
would be rejected by argv parsing, with a different code and message. Alternatively, report
NOT MEASURED when the branch has no diff, naming that as the reason.
Found while working #15255 (the .changeset/*.md population control), 2026-09-04.
Premise falsified by measurement — CI DOES see this: every push-to-main Lint & Repo Gates run since the control landed is red at step 31
The card says "CI never sees this: a PR branch always has a diff, so the case is green there." That holds for pull_request and merge_group runs (a queue branch has a diff), but the push run on main has none — HEAD equals origin/main, --changed refuses with exit 2, the control fails.
Measured from GET /actions/workflows/lint.yml/runs?event=push&branch=main (cancelled = superseded by the next push under concurrency; every run that completed is listed):
main push
Lint & Repo Gates
note
101ad2cc1 … 4428dd575 (09-03 19:41Z → 22:39Z)
success ×4
before the control
369da918d (09-03 23:23Z, #15105 — the commit that added the control)
Failing step confirmed on three of them by job read (3a4373f4c job 100985021378, 5b09356b7, fbecffe1d): step 31 PM dispatch-gates self-test, Process completed with exit code 1. The merge_group run of the same 3a4373f4c head (job 100979536132) is green — which is why the queue keeps merging while main's own status has been red for ~11 hours.
Reproduced by this seat on a checkout equal to origin/main (ed217e697, then 3a4373f4c): 1 of 1381 case(s) failed, the only ✗ being this control; the direct invocation prints the changes nothing against 'origin/main' … nothing to derive refusal and exits 2.
Consequences beyond the fresh-worktree baseline:main's commit status is red on every push, so anything that reads the base branch's health (the "red on the base branch too" triage rule, check-required-contexts' assumptions, the release line's green-main precondition) is reading a false signal, and a real main red would now be invisible in the noise.
Grading:domain:devx + tooling + pm:queue, dispatched now as S — the file is scripts/pm/** (not governed); the only open PR touching dispatch-gates.mjs (#15301) adds one unrelated ledger row.
Shape ruled for the dispatch (the card's first option): the control asserts that the flag combination PARSES and REACHES the derivation, so it accepts eitherstatus === 0 with stdout, orstatus === 2 with the changes nothing against refusal on stderr — and gains a positive control that an illegal combination is refused with a different status and message, so the case stays load-bearing. No --self-test case is weakened to pass; the case is corrected to test its own claim.
Claim: PM seat domain:devx @ objectstack (#6023), session session_012zGPuVVX3deAx9LdjK8jCk, dispatching to an os-dev subagent on branch claude/issue-15278-changed-commands-control (S). Assignee field was empty at the read immediately before this write.
{
"issue": 15278,
"status": "done",
"branch": "claude/issue-15278-changed-commands-control",
"pr": "https://github.com/objectstack-ai/objectstack/pull/15320",
"premise_still_valid": true,
"summary": "The control in scripts/pm/dispatch-gates.mjs now asserts what it claims — that `--changed --commands` PARSES and REACHES the derivation — by accepting either exit 0 with a command list on stdout OR exit 2 carrying the no-diff refusal on stderr. The refusal is matched on a new module constant NO_DIFF_REFUSAL that the derivation's own print site interpolates, so the pin follows the message rather than a retyped copy of it. A positive control puts an ILLEGAL combination (`--changed` with a path, refused by argv before any derivation, at the same exit 2 with a different sentence) through the SAME predicate and requires it to FAIL, so no parse failure can satisfy the corrected control. Usage-line assertions untouched, no case weakened or deleted, no COMPOUND_ANCHOR_LEDGER row needed (the new identifiers carry no selfTest-shaped name and the new run reuses the existing seamCard variable, adding no path literal). Case count 1381 to 1382. The card's own premise held; its sub-claim 'CI never sees this' was already falsified by the PM's comment 5539149925 and I reproduced that exact shape (HEAD == origin/main) before touching anything. Two notes for the PM: (1) the branch is based on 3a4373f4c and origin/main has since moved to 8b54e9de5, whose only derivation-surface change is scripts/check-turbo-task-graph.mjs — outside this card's derived family, so the branch was left unrebased; (2) the shared primary checkout /home/user/objectstack carries a STALE local `main` branch ref (c074c57e, 2026-08-30) beside a current origin/main, so a `git clone` of that path lands on a two-month-old main — worth knowing before anyone else clones it for a no-diff reproduction; it is a container fact, not a repo defect, so no issue was filed.",
"tests": "All readings taken with exit codes captured before any pipe, and every gate verdict quoted from the gate's own verdict line.\n(1) REPRODUCE, before the edit, on a checkout whose HEAD equals origin/main at 3a4373f4c (the push-to-main shape, in a separate clone so the shared refs were never touched): `node scripts/pm/dispatch-gates.mjs --changed --commands` exits 2 printing `dispatch-gates: this branch changes nothing against 'origin/main' (merge base 3a4373f4c) — nothing to derive.`; the full self-test prints `✗ CONTROL: --changed --commands is legal and answers, so the moved usage line describes a real combination` and `✗ dispatch-gates self-test: 1 of 1381 case(s) failed.` — that one ✗ is the only one in the run (grep over the log: 1 case line + 1 summary line).\n(2) AFTER, branch (a) — tree HAS a diff: `pnpm check:pm-dispatch-gates` (lint.yml step 31) under the shared verify lock prints `✓ dispatch-gates self-test: 1382 cases pass.`, `os-verify-lock: VERDICT command-exit 0 · held the lock 371s`, wrapper exit 0, zero ✗ lines; both new cases green: `✓ CONTROL: --changed --commands parses and REACHES the derivation …` and `✓ …and that same predicate REJECTS the illegal --changed-with-a-path combination …`.\n(3) AFTER, branch (b) — the no-diff path actually exercised: a separate clone detached at commit 209f5c596 with its OWN refs/remotes/origin/main pointed at that commit (shared repo refs untouched), so HEAD == origin/main and the derivation refuses; direct probe exits 2 with the same refusal sentence, and the full self-test prints `✓ dispatch-gates self-test: 1382 cases pass.` with `VERDICT command-exit 0 · held the lock 357s` — i.e. the exact tree shape that was red before is green now.\n(4) ABLATION — no build step exists to state: dispatch-gates.mjs is a plain node ESM script run from source (imports only node: builtins and two sibling scripts), there is no dist/ and no packaged consumer, so the ablation's 'rebuild' leg is N/A and the run reads the mutated source directly; the mutation was instead confirmed ON DISK before the run rather than inferred from an editor's exit code — `else if (wantsChanged && argvPaths.length > 0)` present count 1 to 0, injected `else if (false && wantsChanged` 0 to 1, worktree blob 5ec8448acca501ca75459d5b0a6d950e3b5231fd to af5175a39e21110e6c986cb30be7f85dbf7aed82, `node --check` exit 0, and a probe of the formerly-illegal `--changed --commands PATH` exiting 0 with 19 stdout lines where it exited 2 before. The self-test then printed `✗ …and that same predicate REJECTS the illegal --changed-with-a-path combination …` and `✗ dispatch-gates self-test: 1 of 1382 case(s) failed.` — exactly one case, the positive control, and the corrected control itself stayed green. Restore ran from a `trap '…' EXIT INT TERM` using `git checkout HEAD -- ABSOLUTE_PATH` (repo root resolved with `git rev-parse --show-toplevel`), and is proven by observation, not by an exit code: `git diff HEAD` empty, `git diff --quiet` exit 0, `git status --porcelain` empty, worktree blob back to the HEAD blob 5ec8448acca501ca75459d5b0a6d950e3b5231fd, target line count back to 1 and injected line count back to 0.\n(5) DERIVED FAMILY, re-derived at the final commit 209f5c596 with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (21 commands; the run also printed a STALE TREE warning naming scripts/check-turbo-task-graph.mjs, which is not in this card's family). All 21 run, each exit captured individually: check-ci-filter-parity, check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-self-test-wired (+ --self-test), check-whole-set-label-write (+ --self-test), check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:declared-population-live (`✓ check:declared-population-live — 201 of 252 famil(ies) declare a path population, and every one of them reaches this tree's 8305 tracked file(s).`), check:entry-guard, check:nul-bytes (`check-nul-bytes: OK (scanned 8298 text file(s) … no raw ASCII control bytes).`), check:parse-guard, check:pnpm-filter-targets, check:ratchet-remedy-authority, check:refd-timer-probe, check:watch-hint-literal — every one exit 0; check:pm-dispatch-gates is run (2) above, green at this same commit and tree. Plus the always-runs tail the dispatch named: check-self-test-workflow-commands.mjs and its --self-test, both exit 0.\n(6) `pnpm lint` WHOLE repo (eslint . --no-inline-config) exit 0 — no narrowing claimed and none taken.\nNot measured here, by the dispatch contract: CI's own convergence on PR 15320. Reported at draft-PR time.",
"mcp_calls": "4 — issue_read get, issue_read get_comments, create_pull_request, add_issue_comment (this report). Everything else went through git and repo-scoped REST (probe: GET /repos/objectstack-ai/objectstack returned 200), including the label write.",
"open_questions": [],
"out_of_scope_findings": []
}
Reviewed on the branch (origin/main...claude/issue-15278-changed-commands-control), not the self-report:
One file, scripts/pm/dispatch-gates.mjs, +55/−3. The control now asserts its own claim: reachedDerivation(run) = exit 0 with a command list or exit 2 whose stderr carries NO_DIFF_REFUSAL — a new module constant (:19615) that the derivation's print site interpolates (:19817), so the case and the message cannot drift apart. The positive control runs --changed --commands <path> through the SAME predicate and requires it to FAIL (exit 2, the argv sentence --changed derives the paths itself, and NOT the no-diff sentence) — a parse refusal can never satisfy the corrected control. No other case touched; the usage-line assertions are untouched; no COMPOUND_ANCHOR_LEDGER row is owed (no selfTest-shaped name, no new path literal). No TDZ: the const sits before the if (invokedDirectly) dispatch (:19650).
The red reproduced by this seat before the fix (comment 5539149925): a checkout equal to origin/main → 1 of 1381 case(s) failed, the only ✗ being this control; the direct invocation prints the refusal and exits 2.
Green after, path (a), run by this seat on a detached review worktree at 209f5c596 (a tree with a diff): node scripts/pm/dispatch-gates.mjs --self-test → exit 0, 1382 cases pass, both new lines ✓ (…parses and REACHES the derivation…, …REJECTS the illegal --changed-with-a-path combination…).
Path (b), the push-to-main shape, exercised by the dev in a clone whose own origin/main ref was pointed at the commit (HEAD == origin/main): direct probe exit 2 with the refusal, full self-test 1382 cases pass under the verify lock — the exact tree shape that was red is green. The ablation (the illegal combination made legal on disk, blob hash moved) reds exactly the positive control and nothing else; restore proven by hash equality + empty diff.
CI on 209f5c596: 22 success / 11 skipped, Lint & Repo Gates in progress with step 31 PM dispatch-gates self-test already success; skip-changeset + size/s; Fixes #15278 in the PR body only.
The proof that matters lands after the merge: the next push run of lint.yml on main must be green at step 31 — this seat reads it from /actions/workflows/lint.yml/runs?event=push&branch=main and records it here before stripping labels. #15312 (same file, serial-queued) is dispatched once this merges.
Push run 33871119985 (lint.yml, event=push, branch=main, head 2ed6be649, the third push after #15320's merge — the two before it were cancelled by concurrency before reaching the step): step 31 PM dispatch-gates self-test → success (/actions/runs/33871119985/jobs, Lint & Repo Gates job, step completed 12:1xZ).
Control: the last completed push run before the fix, 33867807567 (6e67b86c0, 11:24Z), reads step 31 failure — the same shape every completed push run had from 369da918d (09-03 23:23Z) onward.
So the sequence on main is: 4 green (before #15105) → 20 red (the control) → green at the first completed push after #15320. Card stays closed; pm:dispatched and the assignee were stripped at merge time. The seat post (#6023) records the run id.
Activity
claude commentedon Sep 4, 2026
Premise falsified by measurement — CI DOES see this: every push-to-main
Lint & Repo Gatesrun since the control landed is red at step 31The card says "CI never sees this: a PR branch always has a diff, so the case is green there." That holds for
pull_requestandmerge_groupruns (a queue branch has a diff), but thepushrun onmainhas none —HEADequalsorigin/main,--changedrefuses with exit 2, the control fails.Measured from
GET /actions/workflows/lint.yml/runs?event=push&branch=main(cancelled = superseded by the next push under concurrency; every run that completed is listed):101ad2cc1…4428dd575(09-03 19:41Z → 22:39Z)369da918d(09-03 23:23Z, #15105 — the commit that added the control)35e94c96b,97a22639b,f594e70d7,2cc461030,fcc42e6c1,1876d5dfd,ebb082204,5c584231a,c351a84da,919beca43,50d6c924b,9c1bcda38,1bc3c092a,460134af8,4dd5041bd,0e24b0c2c,fbecffe1d,5b09356b7,3a4373f4c(09-03 23:52Z → 09-04 09:57Z)Failing step confirmed on three of them by job read (
3a4373f4cjob100985021378,5b09356b7,fbecffe1d): step 31PM dispatch-gates self-test,Process completed with exit code 1. Themerge_grouprun of the same3a4373f4chead (job100979536132) is green — which is why the queue keeps merging whilemain's own status has been red for ~11 hours.Reproduced by this seat on a checkout equal to
origin/main(ed217e697, then3a4373f4c):1 of 1381 case(s) failed, the only ✗ being this control; the direct invocation prints thechanges nothing against 'origin/main' … nothing to deriverefusal and exits 2.Consequences beyond the fresh-worktree baseline:
main's commit status is red on every push, so anything that reads the base branch's health (the "red on the base branch too" triage rule,check-required-contexts' assumptions, the release line's green-main precondition) is reading a false signal, and a real main red would now be invisible in the noise.Grading:
domain:devx+tooling+pm:queue, dispatched now as S — the file isscripts/pm/**(not governed); the only open PR touchingdispatch-gates.mjs(#15301) adds one unrelated ledger row.Shape ruled for the dispatch (the card's first option): the control asserts that the flag combination PARSES and REACHES the derivation, so it accepts either
status === 0with stdout, orstatus === 2with thechanges nothing againstrefusal on stderr — and gains a positive control that an illegal combination is refused with a different status and message, so the case stays load-bearing. No--self-testcase is weakened to pass; the case is corrected to test its own claim.Generated by Claude Code
claude commentedon Sep 4, 2026
Claim: PM seat
domain:devx @ objectstack(#6023), sessionsession_012zGPuVVX3deAx9LdjK8jCk, dispatching to anos-devsubagent on branchclaude/issue-15278-changed-commands-control(S). Assignee field was empty at the read immediately before this write.Generated by Claude Code
claude commentedon Sep 4, 2026
os-dev-report
{ "issue": 15278, "status": "done", "branch": "claude/issue-15278-changed-commands-control", "pr": "https://github.com/objectstack-ai/objectstack/pull/15320", "premise_still_valid": true, "summary": "The control in scripts/pm/dispatch-gates.mjs now asserts what it claims — that `--changed --commands` PARSES and REACHES the derivation — by accepting either exit 0 with a command list on stdout OR exit 2 carrying the no-diff refusal on stderr. The refusal is matched on a new module constant NO_DIFF_REFUSAL that the derivation's own print site interpolates, so the pin follows the message rather than a retyped copy of it. A positive control puts an ILLEGAL combination (`--changed` with a path, refused by argv before any derivation, at the same exit 2 with a different sentence) through the SAME predicate and requires it to FAIL, so no parse failure can satisfy the corrected control. Usage-line assertions untouched, no case weakened or deleted, no COMPOUND_ANCHOR_LEDGER row needed (the new identifiers carry no selfTest-shaped name and the new run reuses the existing seamCard variable, adding no path literal). Case count 1381 to 1382. The card's own premise held; its sub-claim 'CI never sees this' was already falsified by the PM's comment 5539149925 and I reproduced that exact shape (HEAD == origin/main) before touching anything. Two notes for the PM: (1) the branch is based on 3a4373f4c and origin/main has since moved to 8b54e9de5, whose only derivation-surface change is scripts/check-turbo-task-graph.mjs — outside this card's derived family, so the branch was left unrebased; (2) the shared primary checkout /home/user/objectstack carries a STALE local `main` branch ref (c074c57e, 2026-08-30) beside a current origin/main, so a `git clone` of that path lands on a two-month-old main — worth knowing before anyone else clones it for a no-diff reproduction; it is a container fact, not a repo defect, so no issue was filed.", "tests": "All readings taken with exit codes captured before any pipe, and every gate verdict quoted from the gate's own verdict line.\n(1) REPRODUCE, before the edit, on a checkout whose HEAD equals origin/main at 3a4373f4c (the push-to-main shape, in a separate clone so the shared refs were never touched): `node scripts/pm/dispatch-gates.mjs --changed --commands` exits 2 printing `dispatch-gates: this branch changes nothing against 'origin/main' (merge base 3a4373f4c) — nothing to derive.`; the full self-test prints `✗ CONTROL: --changed --commands is legal and answers, so the moved usage line describes a real combination` and `✗ dispatch-gates self-test: 1 of 1381 case(s) failed.` — that one ✗ is the only one in the run (grep over the log: 1 case line + 1 summary line).\n(2) AFTER, branch (a) — tree HAS a diff: `pnpm check:pm-dispatch-gates` (lint.yml step 31) under the shared verify lock prints `✓ dispatch-gates self-test: 1382 cases pass.`, `os-verify-lock: VERDICT command-exit 0 · held the lock 371s`, wrapper exit 0, zero ✗ lines; both new cases green: `✓ CONTROL: --changed --commands parses and REACHES the derivation …` and `✓ …and that same predicate REJECTS the illegal --changed-with-a-path combination …`.\n(3) AFTER, branch (b) — the no-diff path actually exercised: a separate clone detached at commit 209f5c596 with its OWN refs/remotes/origin/main pointed at that commit (shared repo refs untouched), so HEAD == origin/main and the derivation refuses; direct probe exits 2 with the same refusal sentence, and the full self-test prints `✓ dispatch-gates self-test: 1382 cases pass.` with `VERDICT command-exit 0 · held the lock 357s` — i.e. the exact tree shape that was red before is green now.\n(4) ABLATION — no build step exists to state: dispatch-gates.mjs is a plain node ESM script run from source (imports only node: builtins and two sibling scripts), there is no dist/ and no packaged consumer, so the ablation's 'rebuild' leg is N/A and the run reads the mutated source directly; the mutation was instead confirmed ON DISK before the run rather than inferred from an editor's exit code — `else if (wantsChanged && argvPaths.length > 0)` present count 1 to 0, injected `else if (false && wantsChanged` 0 to 1, worktree blob 5ec8448acca501ca75459d5b0a6d950e3b5231fd to af5175a39e21110e6c986cb30be7f85dbf7aed82, `node --check` exit 0, and a probe of the formerly-illegal `--changed --commands PATH` exiting 0 with 19 stdout lines where it exited 2 before. The self-test then printed `✗ …and that same predicate REJECTS the illegal --changed-with-a-path combination …` and `✗ dispatch-gates self-test: 1 of 1382 case(s) failed.` — exactly one case, the positive control, and the corrected control itself stayed green. Restore ran from a `trap '…' EXIT INT TERM` using `git checkout HEAD -- ABSOLUTE_PATH` (repo root resolved with `git rev-parse --show-toplevel`), and is proven by observation, not by an exit code: `git diff HEAD` empty, `git diff --quiet` exit 0, `git status --porcelain` empty, worktree blob back to the HEAD blob 5ec8448acca501ca75459d5b0a6d950e3b5231fd, target line count back to 1 and injected line count back to 0.\n(5) DERIVED FAMILY, re-derived at the final commit 209f5c596 with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (21 commands; the run also printed a STALE TREE warning naming scripts/check-turbo-task-graph.mjs, which is not in this card's family). All 21 run, each exit captured individually: check-ci-filter-parity, check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-self-test-wired (+ --self-test), check-whole-set-label-write (+ --self-test), check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:declared-population-live (`✓ check:declared-population-live — 201 of 252 famil(ies) declare a path population, and every one of them reaches this tree's 8305 tracked file(s).`), check:entry-guard, check:nul-bytes (`check-nul-bytes: OK (scanned 8298 text file(s) … no raw ASCII control bytes).`), check:parse-guard, check:pnpm-filter-targets, check:ratchet-remedy-authority, check:refd-timer-probe, check:watch-hint-literal — every one exit 0; check:pm-dispatch-gates is run (2) above, green at this same commit and tree. Plus the always-runs tail the dispatch named: check-self-test-workflow-commands.mjs and its --self-test, both exit 0.\n(6) `pnpm lint` WHOLE repo (eslint . --no-inline-config) exit 0 — no narrowing claimed and none taken.\nNot measured here, by the dispatch contract: CI's own convergence on PR 15320. Reported at draft-PR time.", "mcp_calls": "4 — issue_read get, issue_read get_comments, create_pull_request, add_issue_comment (this report). Everything else went through git and repo-scoped REST (probe: GET /repos/objectstack-ai/objectstack returned 200), including the label write.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
claude commentedon Sep 4, 2026
ACCEPT → PR #15320 (head
209f5c596)Reviewed on the branch (
origin/main...claude/issue-15278-changed-commands-control), not the self-report:scripts/pm/dispatch-gates.mjs, +55/−3. The control now asserts its own claim:reachedDerivation(run)= exit 0 with a command list or exit 2 whose stderr carriesNO_DIFF_REFUSAL— a new module constant (:19615) that the derivation's print site interpolates (:19817), so the case and the message cannot drift apart. The positive control runs--changed --commands <path>through the SAME predicate and requires it to FAIL (exit 2, the argv sentence--changed derives the paths itself, and NOT the no-diff sentence) — a parse refusal can never satisfy the corrected control. No other case touched; the usage-line assertions are untouched; noCOMPOUND_ANCHOR_LEDGERrow is owed (no selfTest-shaped name, no new path literal). No TDZ: the const sits before theif (invokedDirectly)dispatch (:19650).5539149925): a checkout equal toorigin/main→1 of 1381 case(s) failed, the only ✗ being this control; the direct invocation prints the refusal and exits 2.209f5c596(a tree with a diff):node scripts/pm/dispatch-gates.mjs --self-test→ exit 0, 1382 cases pass, both new lines ✓ (…parses and REACHES the derivation…,…REJECTS the illegal --changed-with-a-path combination…).origin/mainref was pointed at the commit (HEAD == origin/main): direct probe exit 2 with the refusal, full self-test1382 cases passunder the verify lock — the exact tree shape that was red is green. The ablation (the illegal combination made legal on disk, blob hash moved) reds exactly the positive control and nothing else; restore proven by hash equality + empty diff.209f5c596: 22 success / 11 skipped,Lint & Repo Gatesin progress with step 31PM dispatch-gates self-testalreadysuccess;skip-changeset+size/s;Fixes #15278in the PR body only.The proof that matters lands after the merge: the next
pushrun oflint.ymlonmainmust be green at step 31 — this seat reads it from/actions/workflows/lint.yml/runs?event=push&branch=mainand records it here before stripping labels. #15312 (same file, serial-queued) is dispatched once this merges.Flipping ready + arming auto-merge over MCP now.
Generated by Claude Code
claude commentedon Sep 4, 2026
PROOF —
main's push run is green at step 31 againPush run
33871119985(lint.yml,event=push,branch=main, head2ed6be649, the third push after #15320's merge — the two before it were cancelled by concurrency before reaching the step): step 31PM dispatch-gates self-test→success(/actions/runs/33871119985/jobs, Lint & Repo Gates job, step completed 12:1xZ).Control: the last completed push run before the fix,
33867807567(6e67b86c0, 11:24Z), reads step 31failure— the same shape every completed push run had from369da918d(09-03 23:23Z) onward.So the sequence on
mainis: 4 green (before #15105) → 20 red (the control) → green at the first completed push after #15320. Card stays closed;pm:dispatchedand the assignee were stripped at merge time. The seat post (#6023) records the run id.Generated by Claude Code