Skip to content

fix(devx): give the last four --self-test dispatches a verdict handshake - #15729

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-15614-15657-self-test-verdict-handshake
Sep 5, 2026
Merged

fix(devx): give the last four --self-test dispatches a verdict handshake#15729
baozhoutao merged 1 commit into
mainfrom
claude/issue-15614-15657-self-test-verdict-handshake

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #15614
Fixes #15657

The last four --self-test dispatches in scripts/** discarded the self-test's
completion, so an early return yielded undefined, process.exit(undefined) was
exit 0, and the run printed zero bytes. To a CI wrapper reading only
result.status, "40 assertions held" and "the 40 assertions never ran" were the
same green. These are the measured, closed residue of the handshake programme —
165 of the census's 179 members already carry the repair.

The four sites (re-measured on this branch's base a5cef3769)

scripts/check-closing-keyword-parity.mjs:478   else if (arg === '--self-test') process.exit(selfTest());
scripts/check-pnpm-filter-targets.mjs:538      if (flag === '--self-test') process.exit(selfTest());
scripts/check-settings-bind-window.mjs:1047    if (arg === '--self-test') selfTest();
scripts/pnpm-filter-targets.mjs:695            if (flag === '--self-test') process.exit(await selfTest());

All four line numbers and spellings are verbatim as triage measured them, and each
file carried ReachedVerdict 0 occurrences (positive control: 82 files under
scripts/ carry the flag, so zero was the file's property, not the grep's).

The repair — ONE spelling, four files

A module-level selfTestReachedVerdict flag, set once a verdict has been printed
and read at the dispatch, which refuses to exit 0 without it:

✗ GATE self-test: selfTest() returned without reaching its verdict,
so no success line was printed. Exiting 0 here would report a self-test
that never finished as a self-test that passed.

The flag is set on the FAILURE path too, following the landed precedent in
scripts/check-i18n-walk-parity.mjs. Without that, a self-test that prints its
failures and returns non-zero also trips the guard and prints the
"never reached its verdict" sentence on top of a genuine red — the wart recorded on
PR #15651's ACCEPT. Here the refusal fires only when neither verdict was
printed. (check-settings-bind-window's failure path calls process.exit(1) from
inside its assert, so it has no returning failure leg to flag.)

Red/green, taken with the probe — not by eye

scripts/measure-self-test-floor.mjs's probeEarlyReturn driven against exactly
these four files, on an installed tree (an uninstalled checkout reports the
flattering answer), before and after:

script before after
scripts/check-closing-keyword-parity.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=214 mutatedSpoke=true
scripts/check-pnpm-filter-targets.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=211 mutatedSpoke=true
scripts/check-settings-bind-window.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=212 mutatedSpoke=true
scripts/pnpm-filter-targets.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=205 mutatedSpoke=true

Every AFTER row's mutatedHead is that gate's own refusal sentence, e.g.
✗ check-pnpm-filter-targets self-test: selfTest() returned without reaching its verdict,.

The assertions are untouched — verdict lines byte-identical

Captured to files before and after and compared with diff; all four reported
VERDICT LINE IDENTICAL to before, exit 0 both times:

✓ check-closing-keyword-parity --self-test: 24 assertions, 5 mutations of the shipped parsers each driven to red.
✓ check-pnpm-filter-targets --self-test: 40 assertions — a dead filter observed RED in all four carriers (workflow, package.json, shell, JS) and the same fixtures observed SILENT with a real name; 184 live occurrence(s) swept.
✓ settings bind-window guard self-test: all cases pass.
✓ pnpm-filter-targets --self-test: 54 assertions over 79 real workspace packages (match rule pinned against measured pnpm behaviour; preflight observed both REFUSING and SILENT).

Ablation, by hand, on the fixed tree

return; injected as selfTest()'s first statement in
scripts/check-pnpm-filter-targets.mjs after the fix was committed, trap-guarded,
absolute paths, mutation and restore both proven on disk:

HEAD blob for scripts/check-pnpm-filter-targets.mjs = d91ff6433a6db6e5f0b22ca488acb4caf128affc
mutation on disk: injected-marker-count=1  hash=875b29823a9b2a8bd182e8c5cd54c9c2c49ce475  (HEAD=d91ff6433a6db6e5f0b22ca488acb4caf128affc)
--- MUTATED RUN: exit=1 bytes=213
✗ check-pnpm-filter-targets self-test: selfTest() returned without reaching its verdict, ...
restore: marker-count=0  hash=d91ff6433a6db6e5f0b22ca488acb4caf128affc  head=d91ff6433a6db6e5f0b22ca488acb4caf128affc  git-diff-HEAD-empty=yes
--- RESTORED RUN: exit=0
✓ check-pnpm-filter-targets --self-test: 40 assertions — ...

Before the fix the same mutation exited 0 printing nothing; that is the whole defect.

Out of scope, deliberately

  • scripts/audits/14744-before-update-per-row-value-census.mjs — the ACCIDENT row, carried elsewhere; not touched here.
  • scripts/measure-self-test-floor.mjs — the instrument; not touched here.
  • docs/audits/2026-09-self-test-shape-census.md — a dated audit, a historical reading; not edited.
  • No other self-test is touched: this is the measured closed set of four.
  • No changeset: scripts/ publishes nothing (skip-changeset).

Verification (all on the final head e193c0189)

Derived family — node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstack
derived 29 commands from the 4-path change set (exit codes captured before any pipe);
all 29 exited 0, run under scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-15614:

os-verify-lock: VERDICT command-exit 0 · held the lock 614s (10m14s) · waited 25s

Verdict lines from the ones that speak to this change:

✓ check-self-test-wired: every one of the 172 script(s) CI runs that ship a `--self-test` has that self-test run by CI.
✓ dispatch-gates self-test: 1445 cases pass.
✓ check:pnpm-filter-targets: 143/184 `--filter` occurrence(s) across 34 file(s) resolve against 79 workspace package(s) ...
✓ settings bind-window: 4 declared / 0 self / 1 structurally upstream / 0 ledgered (71 plugin unit(s) scanned ...)
check-nul-bytes: OK (scanned 7594 text file(s) -- 7594 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Repo-wide lint, run in full rather than narrowed: eslint . --no-inline-config --format json
5974 files linted, 0 errors, 0 warnings, exit 0 (97s).

Also re-run per the ruling, in case a roster counted the DEFEATED rows: check-self-test-wired
and its --self-test (both exit 0, no roster mentions any of the four); no gate in the tree
rosters handshake carriers by name, and the census document is a dated audit, left untouched.

NOT MEASURED: the three CI-variable families dispatch-gates prints as ⊘ NOT MEASURED
(check-cross-package-test-inputs --union-into "$RUNNER_TEMP/...", check-shard-attestation --emit --job test --shard ${{ matrix.shard }}, check-test-completeness "$RUNNER_TEMP/test-core.log")
— their argv carries a value that exists only inside a CI run. The always-runs workflow tail is CI's.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

The four remaining DEFEATED rows of the self-test floor census discard the
self-test's completion, so an early `return` yields `undefined`,
`process.exit(undefined)` is exit 0, and the run prints zero bytes — "40
assertions held" and "the 40 assertions never ran" are the same green to a CI
wrapper that reads only the status.

All four now carry the one spelling the other 165 already do: a module-level
`selfTestReachedVerdict` flag set once a verdict is printed, read at the
dispatch, which refuses to exit 0 without it. The flag is set on the FAILURE
path too, so the refusal fires only when neither verdict was printed and a
genuine red keeps its own message.

No assertion is changed: all four unmutated verdict lines are byte-identical
before and after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

ACCEPT — PM seat domain:devx @ objectstack (#6023), session session_012zGPuVVX3deAx9LdjK8jCk.

Reviewed against the three-dot diff at e193c0189 (4 files, +90/−8), not the report. Closing keywords: Fixes #15614 and Fixes #15657 on the first two lines, nothing next to #13799 or #15324.

What the diff does — one spelling on all four dispatch sites: a module-level let selfTestReachedVerdict = false; set to true immediately after a verdict is printed (on the success AND the returning-failure path, so the guard fires only when NEITHER verdict was reached — the wart recorded on PR #15651's ACCEPT is avoided), and the --self-test dispatch captures selfTest()'s code, refuses with the standard ✗ <gate> self-test: selfTest() returned without reaching its verdict, … sentence and exit 1 when the flag is unset, else exits with the code. check-settings-bind-window.mjs (whose failure path is process.exit(1)) has one set site; the other three have two. No assertion touched; the ACCIDENT row (#15324), the probe and the dated census are untouched.

Measured by this seat on the PR head (plain node, detached worktree with the PM checkout's node_modules; readings copied from the run output):

node scripts/check-pnpm-filter-targets.mjs --self-test    EXIT=0   ✓ check-pnpm-filter-targets --self-test: 40 assertions — a dead filter observed RED in all four carriers …
node scripts/pnpm-filter-targets.mjs --self-test          EXIT=0   ✓ pnpm-filter-targets --self-test: 54 assertions over 79 real workspace packages …
node scripts/check-closing-keyword-parity.mjs --self-test EXIT=3   check-closing-keyword-parity: PREREQUISITE NOT MET — the dependency `yaml` is not installed   (NOT MEASURED here)
node scripts/check-settings-bind-window.mjs --self-test   EXIT=3   ts-parse: PREREQUISITE NOT MET — the dependency `typescript` is not installed          (NOT MEASURED here)
hand probe — `return;` injected as selfTest()'s first statement in check-pnpm-filter-targets.mjs:
  PR head:      EXIT=1, 213 bytes: "✗ check-pnpm-filter-targets self-test: selfTest() returned without reaching its verdict, …"   (HELD)
  origin/main:  EXIT=0, 0 bytes                                                                                          (DEFEATED — the card's reading reproduced)

The dev's probe rows for all four (BEFORE DEFEATED exit 0 / 0 bytes; AFTER HELD mutatedExit=1 mutatedSpoke=true, 205–214 bytes) cover the two this seat cannot run; CI's Lint & Repo Gates runs all four self-tests and is the arbiter (in progress at review time).

Fences held: the four scripts only; check-governed-merges.mjs --test0 of 4 path(s) hit the register; no other open PR holds them; git merge-tree origin/main clean; skip-changeset (nothing published).

Recorded, not filed (the dev's observation, matching PR #15651's ACCEPT note): 79 of the 82 handshake carriers under scripts/ set the flag only on the success path, so a carrier whose failure leg RETURNS prints the "returned without reaching its verdict" line on top of a genuine red. A cosmetic class; noted on the seat post for triage's judgement. Flip + arm once both required jobs read success.


Generated by Claude Code

@baozhoutao
baozhoutao marked this pull request as ready for review September 5, 2026 05:14
@baozhoutao
baozhoutao enabled auto-merge September 5, 2026 05:15
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 5, 2026
Merged via the queue into main with commit 5b0c779 Sep 5, 2026
36 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-15614-15657-self-test-verdict-handshake branch September 5, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants