test(scripts): batch 10d — floor check-regen-pending on its three named callees - #15338
Merged
baozhoutao merged 3 commits intoSep 4, 2026
Merged
Conversation
…ed callees `noDist && noTree && armed && table && fixture` was the only success condition, so "every sub-check held" and "the sub-checks never ran" printed the same line. Pin the registered NAMES, not a number: a roster of the three callees the `--self-test` dispatch invokes, floor 1 each, `registerCase()` as each callee's first statement, and the floor evaluated at the verdict site inside the `--self-test` branch only. The dispatch becomes a literal list of function references mapped through `run()`, so the invoked names are data the floor cross-checks the roster against in both directions. Evaluation order and completeness are unchanged: the original invoked all three eagerly and reduced booleans with `&&`, so the short-circuit was never over calls. The two assertions written inline in the dispatch stay outside the roster with the gap written at the site; the callees' inner sinks are not batteries — the battery is the unit the dispatch names. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
The floor above produces a real failure, but the verdict spelled it as `process.exit(failures === 0 ? 0 : 1)` — the ternary this file already carried. `scripts/measure-self-test-floor.mjs` reads a floor as sound only when the code PRODUCES a failure (`process.exit(1)`, `exitCode = 1`, `failures.push`, a throw), deliberately refusing to key on the roster's name alone, so the file classified NONE with a sound roster above it. Make the failure path an explicit branch ending in `process.exit(1)`. The success line's text and the whole green-path output are unchanged byte for byte; only the red path's spelling moves. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…tch10d-regen-pending-callees
This was referenced Sep 4, 2026
baozhoutao
marked this pull request as ready for review
September 4, 2026 12:37
baozhoutao
enabled auto-merge
September 4, 2026 12:37
baozhoutao
deleted the
claude/issue-13799-batch10d-regen-pending-callees
branch
September 4, 2026 13:15
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 #13799
Batch 10d, Tier C recipe A — copying the settled pilot PR #15326 (
scripts/git-merge-regen.mjs) onto the other half ofcheck:merge-driver. One file:scripts/check-regen-pending.mjs.What was wrong
noDist && noTree && armed && table && fixturewas this self-test's ONLY success condition, so "every sub-check held" and "the sub-checks never ran" printed the same line. A callee whose body stops doing its work still returns whatever its last surviving statement produces, and the green verdict then claims the whole deferred-merge wiring is sound.The floor
One battery per NAMED CALLEE — the unit the
--self-testdispatch names. Roster is the literal three, floor 1 each, size pin 3:prePushIsArmedSelfTestdecisionTableSelfTestfixtureSelfTestcheck()helper, 14 callsregisterCase('CALLEE_NAME')is the FIRST statement of each callee, above any early return, so what the ledger records is that the callee RAN. The floor is evaluated at the verdict site immediately before the success line, inside the--self-testbranch only — the production path (main(), spawned bypre-commit/pre-push) never reads the ledger.Size pin measured, not assumed. Pinned at 9999 first and the breach read back:
SELF_TEST_BATTERIES declares 3 batteries, below the pinned 9999. Then set to 3.No new
COMPOUND_ANCHOR_LEDGERrow is owed — the three callee names already spell self-test and already carry their rows, and an object KEY is not a column-0 declaration. Verified rather than assumed:check:pm-dispatch-gatesgreen, 1382 cases.Red-path declaration (the pilot ACCEPT's condition on Q2)
MEASURED: the original dispatch did NOT short-circuit over calls, so nothing on the red path changed. The original invoked all three callees eagerly — one
constbinding per callee, executed unconditionally — and only THEN reduced the five booleans with&&. The short-circuit was always over VALUES, never over calls.callees.map(...)runs the same three in the same order: nothing that used to run stops, and nothing that used to be skipped now runs.The one red-path change is the verdict LINE's wording, which is this card's ruling 5: the red line now takes
N failure(s) (cases and floor). The green line is unchanged text, and the whole green path is byte-identical —cmpof stdout and of stderr against the installed base worktree at the same pin, both identical, exit 0.Each list entry carries the section banner that already sat immediately above its call, so the interleaved output is preserved exactly.
What is deliberately NOT a battery
noDist,noTree) stay OUTSIDE the roster, per ruling Q1 = A. They are not callees, so the dispatch names no unit for them and there is no name the source already carries; inventing a label would put a hand-written string into a roster whose whole property is that every entry is read off a declaration, and hoisting them is a reshape for its own card. The gap is written at the site and costs this: those two lines can stop running and this floor will not say so.registerCase()still first is GREEN. Floor 1 records that the dispatch REACHED the callee, not that the callee did its work — the same semantics the pilot carries.Second commit: the verdict's failure spelling
scripts/measure-self-test-floor.mjsclassifies a floor as sound only when the code PRODUCES a failure (process.exit(1),exitCode = 1,failures.push, a throw), deliberately refusing to key on the roster's name alone. This file's pre-existingprocess.exit(ok ? 0 : 1)ternary matched none of them, so the file still classified NONE with a sound roster above it. The failure path is now an explicit branch ending inprocess.exit(1). Green-path output is unchanged byte for byte.Deletions — dispatch/verdict lines only
The three banner +
const NAME = callee()pairs (replaced by the literal list and its map),const ok = noDist && noTree && ..., the red verdict line's old text, and theprocess.exit(ok ? 0 : 1)ternary. Nothing else was removed.Verification
Union re-run on the final commit,
git rev-parse --short HEAD=2bacfdda1(includes a clean merge oforigin/main, which our file was untouched by; spec rebuilt after the merge).Ablations — mutation proven on disk by blob-hash movement plus grep counts, restore by
git checkout HEAD -- ABSOLUTE_PATHproven by hash equality and an emptygit diff HEAD, all undertrap ... EXIT INT TERM. This file is executed directly from source by node (check:merge-driverspawnsnode scripts/check-regen-pending.mjs --self-test), so there is nodist/leg to rebuild.registerCase()removedDID NOT RUN, with that callee's own check-mark line still printed (the vacuous green this floor exists for)DID NOT RUN+ "which the dispatch block does not invoke" (3 failures)registerCase()moved below a forced early returnDID NOT RUNregisterCase()first, same forced early returnGates — exit codes captured before any pipe. The derived family from
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no hand-built list; changeset read by the tool itself: 1 path), all 24 commands run, all exit 0, plus the always-runs tail (check-self-test-workflow-commands.mjsand its--self-test,check:declared-population-live) — 26 green, 0 red.Verdict lines quoted from the gates themselves:
check:merge-driver(this file's own suite, both halves):✓ merge driver wiring is consistent (24 path(s) deliberately excluded).and✓ check-regen-pending self-test passed.check:pm-dispatch-gates:✓ dispatch-gates self-test: 1382 cases pass.check:watch-hint-literal:✓ check-watch-hint-literal: 49 declaration(s) across 4 rostered name(s) ... and no unrostered spelling of the idiom in the tree.—extractWatchHintsbehaviour identical.check:ratchet-remedy-authority:OK check-ratchet-remedy-authority: 202 scripts swept ...check:nul-bytes:✓ check-nul-bytes --self-test: 75 assertions over a temp git repo (real scan() path)Instrument (
node scripts/measure-self-test-floor.mjs --json), before vs after on the same tree: ROSTER 156 to 157, NONE 13 to 12, COUNT 1 unchanged, 170 rows both times.scripts/check-regen-pending.mjsis the only file whose verdict moved (NONE to ROSTER); nothing entered the population and nothing left it. This file leaves NONE.Importers —
git grep -l check-regen-pending, every one green:packages/spec/scripts/build-docs.ts(check:docs),packages/spec/scripts/check-generated.ts(check:generated),packages/spec/scripts/lib/dist-freshness.tsandschema-tree-freshness.test.ts(vitest, 2 files / 21 tests passed),scripts/check-exported-any-returns.mts(check:exported-any),scripts/pm/dispatch-gates.mjs(check:pm-dispatch-gates), the two.githooksspawn sites (leg f above), andpackage.json'scheck:merge-driver.Whole-repo
pnpm lint: exit 0, run in full — no narrowing claimed.skip-changeset: this diff publishes nothing from any released package (one repo-root gate script).🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code