fix(scripts): measure-self-test-floor's probe reads NOT MEASURED when the baseline run already fails (#15391) - #15455
Merged
Conversation
…fails `probeEarlyReturn` awarded HELD/ACCIDENT from the mutated run alone. When the UNMUTATED file already exits non-zero the tree cannot run it at all, so the mutation had nothing to defeat -- but both runs exit non-zero and both print a module-resolution stack, so the mutated run "speaks" and the row read HELD. A checkout without `pnpm install` therefore reported the flattering answer for every file it could not load, and the same row read ACCIDENT once installed. The baseline is now a PRECONDITION, read before any reading of the mutated run: a non-zero one ends the probe as NOT MEASURED with `baseline run failed (exit N)`. The mutated run is not spawned at all -- in the shape that motivates this every row is baseline-red, so those spawns would double a whole sweep to learn nothing. The row additively publishes `baselineExit`/`baselineBytes`/ `baselineHead`; no existing key is renamed, and `--probe`'s listing and tallies fold it into the existing NOT MEASURED class. A new inline control (`UNRUNNABLE_GATE`, an unresolvable import) pins both halves: the verdict is NOT MEASURED with that reason, and the fixture really is a red baseline that SPEAKS -- the shape an exit-code-and-speech reading scored HELD. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…obe-baseline-not-measured
baozhoutao
marked this pull request as ready for review
September 4, 2026 16:36
baozhoutao
enabled auto-merge
September 4, 2026 16:36
baozhoutao
deleted the
claude/issue-15391-probe-baseline-not-measured
branch
September 4, 2026 17:11
This was referenced Sep 4, 2026
This was referenced Sep 4, 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.
Fixes #15391
probeEarlyReturndecided HELD / ACCIDENT from the mutated run alone. When the UNMUTATED file already exits non-zero, this tree cannot run it at all, so the mutation had nothing to defeat — but both runs exit non-zero and both print a module-resolution stack, so the mutated run "speaks" and the row read HELD: the flattering answer, awarded for the tree being broken. The same row reads ACCIDENT once the tree is installed, so one probe row had two verdicts depending on the environment.The fix
The baseline is now a precondition, not a data point. It is read before any reading of the mutated run, and a non-zero one ends the probe as
NOT MEASUREDwith the reasonbaseline run failed (exit N).The mutated run is not spawned at all in that case. That is the deliberate half of the choice the card left open: in the shape that motivates this (a checkout whose dependencies are absent) every row is baseline-red, so running each doomed mutation would double a whole sweep of spawns to learn nothing.
--probe's human listing and its tallies fold the row into the existingNOT MEASUREDclass with that reason — no new class, no renamed key. The row additively publishesbaselineExit,baselineBytesandbaselineHead;baselineHeadis usually the whole diagnosis (Cannot find package ...reads as "run pnpm install").Before / after — the row from the card
Reproduced on this tree by making the audits census file's
typescriptimport unresolvable (the dependency the card's stack trace names). Restore proven bygit hash-objectequality with the HEAD blob and an emptygit diff HEAD.f01adfa5c)verdictHELDNOT MEASUREDwhybaseline run failed (exit 1)entryrunSelfTestrunSelfTestbaselineExit11mutatedExit1mutatedBytes965mutatedHeadnode:internal/modules/package_json_reader:314mutatedSpoketruebaselineBytes942baselineHeadnode:internal/modules/package_json_reader:314The new inline control
UNRUNNABLE_GATE— a fixture whose first statement is an import no registry can supply, so neither run ever reaches its (perfectly ordinary, injectable) self-test. Two assertions, because one alone would pass for the wrong reason:NOT MEASUREDand the reason is the baseline one — which pins which NOT MEASURED branch fired, not merely that some branch did;baselineExitnon-zero,baselineBytespositive,baselineHeadnon-empty) — exactly the shape an exit-code-and-speech reading scored HELD.Controls run inline on every invocation, as this file's already do; it ships no
--self-testmode to add them to.Ablation. Neutralising the new guard turns the controls red, and they name the defect:
Mutation and restore were both proven on disk (anchor grep counts each way; restore equal to the HEAD blob by hash, with an empty
git diff HEAD). Nodist/is involved — this script runs as source, so there is no rebuild leg.Whole-population check
--probe --jsonover all 170 rows, basef01adfa5cvs this branch, in an installed tree:baselineExit: 0 — which is why those two agree. The whole payload is byte-for-byte identical between the two runs, so no row moved for any other reason either;check-nul-bytes.mjs(compare in place),check-watch-hint-literal.mjs(bind, then compare),check-ratchet-remedy-authority.mjs(a reached-verdict flag).A plain
--jsonrun exits 0, so the inline controls pass.Gates
Run at
484688f09, exit codes captured before any pipe. All 22 commands of the derived family (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack) exit 0, pluscheck:pm-dispatch-gates(✓ dispatch-gates self-test: 1402 cases pass., under the shared verify lock),check-self-test-workflow-commands.mjsand its--self-test,check:declared-population-live, the verify-lock and os-regen-merge self-tests, and whole-repopnpm lint(exit 0, full population — no narrowing). No gate exited 3, so nothing here is NOT MEASURED.check-self-test-wiredstill places this file on itsinlineroute:✓ check-self-test-wired: every one of the 169 script(s) CI runs that ship a --self-test has that self-test run by CI.origin/mainwas merged in ata256cd45fso the gate-family derivation would read a tree someone is actually on; the family it derives is identical either way.Scope
#15371(helper-spelling coverage) and#15421are queued behind this on the same file and are deliberately untouched here.🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code