test(scripts): give 30 more self-tests a battery roster and floor - #14896
Merged
Conversation
Batch 1c of #13799: PR #13487's roster-and-floor shape, exactly as batch 1 landed it, transplanted onto the `scripts/**` self-tests that already carry its shape -- a block-bodied assertion helper inside the self-test body, at least two named section banners, and a body-level verdict site. Per file: a module-level frozen `SELF_TEST_BATTERIES` roster of NAMES with a per-battery floor, `SELF_TEST_BATTERY_FLOOR` pinning the roster's own size, `UNATTRIBUTED_BATTERY`, a `battery('<banner text>')` opener at each existing section banner, one `registerCase()` at the head of the existing assertion helper, and the floor evaluated immediately before the existing verdict so its messages enter the file's own failure sink. 432 batteries, 2591 cases. No case is rewritten, none reordered and no assertion changes meaning: every file's `--self-test` exits 0 with byte-identical stdout AND stderr before and after. The roster block goes after the import block in every file, which is TDZ-safe by construction. 15 of the 45 files the dispatch named do not meet that criterion when measured against the tree and are left for a later batch rather than improvised; the reason per file is in the PR body. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YWBXxmS9sXHoqnozSNwHnE
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
This was referenced Sep 3, 2026
baozhoutao
marked this pull request as ready for review
September 3, 2026 11:01
baozhoutao
enabled auto-merge
September 3, 2026 11:02
os-litant
pushed a commit
that referenced
this pull request
Sep 3, 2026
Two conflicts, both against main commits that landed after this branch's merge base 5ff5f95: - .claude/skills/pm-dispatch/references/lanes/services.md: main's 365141f (#14856) edited the very bullet this branch deletes (the bullet moved to references/platform-readings.md). Settled to OUR side: the bullet stays deleted and the move stands. The FACT main corrected in that bullet (the i18n gates answer PREREQUISITE NOT MET with exit 3, not 1) is carried into the moved text by the follow-up commit, so this merge commit's non-conflict content stays a pure merge of the two parents. - scripts/check-ratchet-remedy-authority.mjs: main's a610775 (#14896) added the self-test battery roster and floor at the spot where this branch's section (21) sits. Settled by keeping BOTH: section (21) opens with battery('(21) ...'), is declared in SELF_TEST_BATTERIES at its case count (2), and sits before the floor-evaluation block; the roster's own size pin SELF_TEST_BATTERY_FLOOR moves 20 -> 21 by the header's own convention (the roster size is pinned at the declared count). The exception phrase stays assembled, never spelled, in author-facing text, and the gate's run line is byte-identical to main's. scripts/pm/check-skill-line-ratchet.mjs auto-merged with main's c47a5ac (#14853) verdict handshake; the two run-path verdict lines this branch adds are outside that handshake, which covers selfTest()'s sentinel return only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
This was referenced Sep 3, 2026
baozhoutao
pushed a commit
that referenced
this pull request
Sep 4, 2026
… hoisted battery (#13799) The self-test decided success by `failures.length === 0` alone, so "every case held" and "the cases never ran" printed the same line. It carries no named section banner, and a comment is not promoted to a section head, so it declares ONE battery opened at the top of the body -- the hoisted shape PRs #14896 and #15003 landed for exactly this case. Floor 8, measured rather than transcribed: the roster was probed with a deliberately unreachable pin and the floor's own report named the registered count. Behaviour is unchanged -- `--self-test` stdout and stderr are byte-identical against origin/main, exit 0 both sides. Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk Co-authored-by: Claude <noreply@anthropic.com>
baozhoutao
pushed a commit
that referenced
this pull request
Sep 4, 2026
…e-limit self-tests (#13799) Both decided success by `failures.length === 0` alone. Neither carries the two named section banners the sectioning criterion needs, and a comment is not promoted to a section head, so each declares ONE battery opened at the top of its self-test body -- the hoisted shape PRs #14896 and #15003 landed. Floors 47 and 47, measured by probing the roster with an unreachable pin and reading the count the floor's own report names. `--self-test` stdout and stderr are byte-identical against origin/main for both, exit 0 on both sides. Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk Co-authored-by: Claude <noreply@anthropic.com>
baozhoutao
pushed a commit
that referenced
this pull request
Sep 4, 2026
…tered battery
The 22 bare `if (...) throw ...` assertions in `selfTest()` are each wrapped
verbatim in the `check(() => { ... })` thunk PR #15198 landed: the condition is
carried in untouched, so no `!` can be dropped while the case still registers
and still passes. Zero named section banners, so one hoisted battery (the
PR #14896 / #15003 / #15217 shape), floored at the measured 22 with the roster's
own size pinned at 1. The floor throws, matching this file's own sink, and is
evaluated before the verdict so the success line can only be printed by a run
that actually ran its cases.
Part of #13799
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 9, 2026
…isted battery each (objectstack-ai#13799 batch 5) (objectstack-ai#15217) * tooling(scripts): floor the check-dts-emitted self-test with a single hoisted battery (objectstack-ai#13799) The self-test decided success by `failures.length === 0` alone, so "every case held" and "the cases never ran" printed the same line. It carries no named section banner, and a comment is not promoted to a section head, so it declares ONE battery opened at the top of the body -- the hoisted shape PRs objectstack-ai#14896 and objectstack-ai#15003 landed for exactly this case. Floor 8, measured rather than transcribed: the roster was probed with a deliberately unreachable pin and the floor's own report named the registered count. Behaviour is unchanged -- `--self-test` stdout and stderr are byte-identical against origin/main, exit 0 both sides. Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk Co-authored-by: Claude <noreply@anthropic.com> * tooling(scripts): floor the logger-receiver-detach and objectql-double-limit self-tests (objectstack-ai#13799) Both decided success by `failures.length === 0` alone. Neither carries the two named section banners the sectioning criterion needs, and a comment is not promoted to a section head, so each declares ONE battery opened at the top of its self-test body -- the hoisted shape PRs objectstack-ai#14896 and objectstack-ai#15003 landed. Floors 47 and 47, measured by probing the roster with an unreachable pin and reading the count the floor's own report names. `--self-test` stdout and stderr are byte-identical against origin/main for both, exit 0 on both sides. Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk Co-authored-by: Claude <noreply@anthropic.com> * tooling(scripts): floor the spec-parsed-alias and stack-collection-maps self-tests (objectstack-ai#13799) check-spec-parsed-alias decided success by `failures.length === 0` alone. check-stack-collection-maps already COUNTED its assertions and printed the number -- but nothing compared it, so a case block that stopped running shrank the printed count and the gate stayed green: evidence, not proof. Neither carries the two named section banners the sectioning criterion needs, and a comment is not promoted to a section head, so each declares ONE battery opened at the top of its self-test body. Both floors measured at 18. The two hand-written verdict counts agree with the registered count on this tree (`18 assertions passed`, `18 assertions over synthetic sources`), so neither had drifted. `--self-test` stdout and stderr are byte-identical against origin/main for both, exit 0 on both sides. Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk Co-authored-by: Claude <noreply@anthropic.com> * tooling(scripts): floor the tenant-chokepoint and label-desc-cap self-tests (objectstack-ai#13799) Both decided success by their sink alone (`failures.length === 0`, `failed === 0`), so "every case held" and "the cases never ran" printed the same line. tenant-chokepoint's blocks are headed by unmarked prose and label-desc-cap carries one banner, below the two the sectioning criterion needs; a comment is not promoted to a section head and a lone banner is not split, so each declares ONE battery opened at the top of its self-test body. label-desc-cap's sink is a counter rather than a list, so its floor prints the breach and folds it into `failed` -- the same refusal in that file's own idiom. Floors 17 and 44, measured by probing the roster with an unreachable pin. `--self-test` stdout and stderr are byte-identical against origin/main for both, exit 0 on both sides. Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk Co-authored-by: Claude <noreply@anthropic.com> * tooling(scripts): floor the whole-set-label-write and wildcard-fallthrough self-tests (objectstack-ai#13799) Neither carries the two named section banners the sectioning criterion needs, so each declares ONE battery opened at the top of its self-test body. Floors 41 and 18, measured by probing the roster with an unreachable pin. whole-set-label-write registers from `expect()` only. Its two trailing ledger loops walk WHOLE_SET_ACTIONS and ALLOWLIST and push straight to `failures`; they are left unregistered ON PURPOSE, because ALLOWLIST is meant to shrink and a floor that moved with it would red every legitimate removal -- the one habit these floors exist to prevent. The comment above the roster says so in place. wildcard-fallthrough refuses in place rather than collecting, so its floor refuses in place too.⚠️ Its verdict prints a TRANSCRIBED `17 cases` while the body has 18 assert call sites and registers 18 -- the literal had already drifted one low. It is left untouched so this change stays a pure no-op on output, and filed separately; the floor is what makes the drift harmless. `--self-test` stdout and stderr are byte-identical against origin/main for both, exit 0 on both sides. Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 9, 2026
…ecipe-A self-tests (objectstack-ai#15307) * test(scripts): floor measure-test-shard-timings' self-test on a registered battery The 22 bare `if (...) throw ...` assertions in `selfTest()` are each wrapped verbatim in the `check(() => { ... })` thunk PR objectstack-ai#15198 landed: the condition is carried in untouched, so no `!` can be dropped while the case still registers and still passes. Zero named section banners, so one hoisted battery (the PR objectstack-ai#14896 / objectstack-ai#15003 / objectstack-ai#15217 shape), floored at the measured 22 with the roster's own size pinned at 1. The floor throws, matching this file's own sink, and is evaluated before the verdict so the success line can only be printed by a run that actually ran its cases. Part of objectstack-ai#13799 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk * test(scripts): floor measure-position-name-fold-census' self-test on a registered battery The 13 `if (...) problems.push(...)` assertion sites in `selfTest()` are each wrapped verbatim in the `check(() => { ... })` thunk PR objectstack-ai#15198 landed. The sink here is FAILURE-ONLY, so routing `problems.push` itself through `registerCase()` would have inverted the floor rather than installing it: a green run would register nothing and the battery would read DID NOT RUN. Zero named banners, so one hoisted battery, floored at the 24 registrations measured on a run (four of the thirteen sites sit inside loops: 9 + 4 + 4 + 2 + 5). The floor lives inside the `!quiet` branch. `main()` gates the PRODUCTION census on `selfTest({ quiet: true })`, which prints no verdict and so makes no claim for a floor to guard; evaluating it there would let a roster edit change what a census run outputs. Both production modes are byte-identical to the base tree. One site stays outside the roster and says so in place: the `catch` arm of the AUDIT_CONTROLS loop ends in `continue`, illegal inside the thunk's arrow function, and rewriting that control flow is exactly what the verbatim rule forbids. Its sibling in the same loop body is floored, so a loop that stops running still reds. Part of objectstack-ai#13799 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk * test(scripts): floor check-override-consistency's self-test on its table rows Recipe A as the pilot PR objectstack-ai#15271 settled it: each of the 17 row labels of the literal `cases` table is a declared battery with a floor of 1, `registerCase(name)` is the first statement of the driving loop body, and the roster is a LITERAL the table is cross-checked against so a deleted or renamed row names ITSELF rather than deleting its own floor. Roster size pinned at 17; duplicate labels are refused from both sides. The three `// --- ... ---` comments inside the array are grouping rules, not section heads. The boolean `passed` becomes a `failures` counter so the red line can carry the recipe's wording, `N failure(s) (cases and floor)`; no assertion condition is touched and the green line is byte-identical to the base tree's. Part of objectstack-ai#13799 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk * test(scripts): floor check-skill-line-ratchet's self-test on all 155 table rows Recipe A per the pilot PR objectstack-ai#15271: every row label is a declared battery with a floor of 1, `registerCase(name)` is the first statement of the driving loop, the roster is a LITERAL cross-checked against the table, size pinned at 155. The only deleted line is the red-run verdict, reworded to the recipe's `N failure(s) (cases and floor)`; the green line stays byte-identical. The batch-8 census flagged this table's four `...(() => { ... })()` spreads as an IIFE-produced block whose rows could not take a literal roster key. Measured, that premise does not hold here: each IIFE is a SCOPING device that declares local fixture consts and then returns an array of LITERAL [label, actual, expected] rows. No label is a template string or computed, and no row comes from a map/push/loop. Three independent readings agree on 155 -- labels extracted from source, literal row starts, and the `cases.length` the green line prints on a run -- so ALL 155 rows are floored with no residue, rather than the partition the row anticipated. Part of objectstack-ai#13799 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --------- Co-authored-by: Claude <noreply@anthropic.com>
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 1c, Tier B — batch-1 shape)
PR #13487's roster-and-floor shape, exactly as batch 1 landed it in PR #14851, transplanted onto the
scripts/**self-tests that already carry that shape. 432 batteries / 2591 cases pinned across 30 files.Per file, and nothing else:
SELF_TEST_BATTERIESroster of names with a per-battery floor,SELF_TEST_BATTERY_FLOORpinning the roster's own size, andUNATTRIBUTED_BATTERY, placed after the import block (batch 1b's uniform placement — TDZ-safe by construction);battery('BANNER TEXT')at each existing section banner, named verbatim from the banner;registerCase()at the head of the existing in-body assertion helper;⛔ No case is rewritten, none reordered, no assertion changes meaning. ⛔ No TOTAL is pinned.
The file surface: 30 floored, 15 dropped with the measured reason
The dispatch named 45 files (the batch-1b report's "HAS a block-bodied in-body assertion helper" list). That list was derived on the helper half of the batch-1 criterion only. Re-measured against the tree on all three halves — a block-bodied in-body assertion helper and at least two named section banners and a body-level verdict site — 30 qualify.
The banner criterion, as measured
A named section banner is a comment block at statement position inside the self-test body (innermost open bracket is a brace, never a square bracket or a paren) whose head carries a section marker: a horizontal rule, a box (a bare rule line, then the title, then a rule), or an enumerator (
// 1. name,// 3 — name,// G1: name,// TSO-6048: name). A comment with no marker is a paragraph explaining the next statement, not a section head; reading one as a section head is a judgement per comment, which a verbatim transplant does not make.The bracket half of that rule is load-bearing and was measured: in
scripts/docs-audit/affected-docs.mjsa brace-only depth count put four banners inside an array literal, where abattery()statement is a syntax error — the Tier-C shape the batch-1b report names. The probe pass caught it; the renderer now refuses that position.Floored (30)
scripts/check-adr-0087-registration.mjsscripts/check-auth-mount-ledger.mjsscripts/check-ci-filter-parity.mjsscripts/check-comment-mask-adoption.mjsscripts/check-console-injection.mjsscripts/check-cross-repo-closer-outcome.mjsscripts/check-dev-prereqs.mjsscripts/check-dispatcher-error-vocabulary.mjsscripts/check-doc-frontmatter.mjsscripts/check-docs-locale-catch-all.mjsscripts/check-docs-section-name.mjsscripts/check-engine-split-ratio.mjsscripts/check-error-status-conformance.mjsscripts/check-i18n-stale-fill.mjsscripts/check-init-service-contract.mjsscripts/check-keyed-text-bounds.mjsscripts/check-merge-queue-triage-outcome.mjsscripts/check-overlay-whitelist-table.mjsscripts/check-quick-reference-counts.mjsscripts/check-ratchet-remedy-authority.mjsscripts/check-required-contexts.mjsscripts/check-route-envelope.mjsscripts/check-section-landing-index.mjsscripts/check-stall-guard-budget.mjsscripts/check-system-context-census.mjsscripts/check-undeclared-dep-imports.mjsscripts/check-vendor-version-stamps.mjsscripts/docs-audit/affected-docs.mjsscripts/release-github-releases.mjsscripts/sync-template-versions.mjsFive files run cases before their first banner (
check-dispatcher-error-vocabulary,check-i18n-stale-fill,check-route-envelope,check-vendor-version-stamps,docs-audit/affected-docs); their first battery is opened at the top of the body and that banner then carries no second opener — the PR #13487 precedent's own shape, as batch 1b did it. Banners that registered no case are not declared as batteries and get no opener: a battery is a section that actually runs cases.Dropped (15) — left for a later batch rather than improvised
scripts/check-declaration-mirrors.mjsconst ok = (label, cond) => cases.push({ label, cond });(L411) — with no block body to hold registerCase(). That is the class-1 blocker, not the batch-1 shape.scripts/check-dts-emitted.mjsscripts/check-logger-receiver-detach.mjsscripts/check-objectql-double-limit.mjsscripts/check-skill-compatibility-version.mjsscripts/check-skill-frame-freshness.mjscases.push({ ... })sites, so there is no single block body for registerCase(). The only block-bodied helper,linear(), is a fixture builder.scripts/check-spec-parsed-alias.mjs// GOOD:,// BAD (rule 1)), not sections.scripts/check-stack-collection-maps.mjsscripts/check-startup-registry-verdict.mjsscripts/check-tenant-chokepoint.mjsscripts/check-turbo-task-graph.mjsselfTest()returns a failures array and the verdict is printed by a SEPARATErunSelfTest()(L892). That is the class-3 shape.scripts/check-whole-set-label-write.mjsscripts/check-wildcard-fallthrough.mjsscripts/js-comment-mask.mjsscripts/publish-smoke-pack.mjsShrink-only ledgers: scanned, none found in this batch
Every battery that iterates a module-level constant was enumerated (28 battery/ledger pairs across 13 files) and each underlying list read:
CATEGORIES,SHAPES,MUTATIONS,ROOTS,TEXT_STAMPS,EXPECTED_TEXT_FAMILY,FLOORS,REQUIRED_CONTEXTS,INSTRUCTION_SURFACES,RETIRED_CONTEXT_NAMES,EXPRESS_RESPONSE_MODULES,DECLARED_COUNTS,UNENFORCED_TEXT_COUNTS,ROOT_DIR_WATCH_HINTS,YAML_CENSUS_ANCHORS. None is shrink-only, and the two that read closest to it are not one-case-per-row:UNENFORCED_TEXT_COUNTSis asserted structurally (two cases, with the row count inside the case rather than as case multiplicity), andRETIRED_CONTEXT_NAMESonly ever grows. So no floor in this batch moves with a list a legitimate edit shortens.Evidence
Behaviour is unchanged, per file
For all 30:
node FILE --self-testbefore and after, exit code captured by redirect before any pipe. 30/30 exit 0 both sides, andcmp -sreports stdout and stderr byte-identical on every one. (Both readings are from the tree afterpnpm install; without it seven files exit 3 on a missing-distprerequisite and two onERR_MODULE_NOT_FOUND, which is a container state, not a verdict.)Census
node scripts/measure-self-test-floor.mjs --json:2263ca4d6f248bc953Three set-equality assertions, computed in python, all
True:NONEbefore andROSTERafter;git diff --name-onlyequals the worklist exactly.And the 128 still
NONEdecompose exactly — a disjoint partition whose union is the set, asserted in python, not read by eye:The 30 floored here intersect PR #14851's 40, PR #14872's 18, PR #14853's 24, the i18n pair and the open-PR exclusions in zero files.
Ablations — four, each from the committed implementation
Each leg carries a
traprestore on absolute paths; the mutation is proved on disk by an anchored grep count plusgit hash-objectagainst the HEAD blob, and the restore by an emptygit diff HEAD— never by an exit code. Nodistis on the resolution path of any of the four, so no rebuild leg applies to them.scripts/check-auth-mount-ledger.mjs, the 2ok(deriveBasePath(cases (grep 2 → 0;cd7b24ab→b8493fe3). Exit 0 → 1: battery "The base path is DERIVED, and its absence is not an empty population." DID NOT RUN — 0 cases registered, 2 pinned. The verdict below would have claimed those cases hold.scripts/check-engine-split-ratio.mjs(grep 1 → 0;d92d2186→06deaef8). Exit 1 naming both halves: SELF_TEST_BATTERIES declares 1 batteries, below the pinned 2 and battery "pure rendering" registered 5 case(s) but is not declared in SELF_TEST_BATTERIES.registerCase()removed from the sink helper —scripts/check-quick-reference-counts.mjs(grep 1 → 0;ce2b2de3→a29feeba). Exit 1 with every original case still passing: all 22 batteries report DID NOT RUN.battery()opener deleted —scripts/docs-audit/affected-docs.mjs(grep 1 → 0;965c95f0→255698df). Exit 1: battery "anchor PROVENANCE ([decision] docs-audit: a data-property anchor is both the noisiest and the most valuable anchor the tool mints — 70 of 402 rows, and no cheap discriminator survives measurement #12824)" DID NOT RUN — 0 cases registered, 12 pinned.A fifth attempt aborted before running — the anchor matched zero lines and the guard refused rather than reporting a clean measurement, which is the failure shape the ablation contract exists to catch.
Gates
Derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no paths passed; the script reads the change set from git — 30 paths vs merge base2263ca4d6). 55 commands derived +check:declared-population-live+check:pm-dispatch-gates+check:nul-bytes= 58 run. Exit codes captured by redirect before any pipe.check:ratchet-remedy-authority0,check:declared-population-live0 (158 of 202 famil(ies) declare a path population, and every one of them reaches this tree's 8079 tracked file(s)).check:pm-dispatch-gates— exit 0, dispatch-gates self-test: 1241 cases pass. No compound-anchor red: this batch introduces no top-levelfunctiondeclaration at all, so theSELF_TEST_DECLanchor sees nothing new. Thebattery/registerCaseclosures are function-scoped and the three new module-level names areconsts, which the anchor does not match.check-test-completeness— exit 3, NOT MEASURED by the gate's own instruction, not a red.check-dev-prereqsexit 1 (The workspace is not built — 1 unmet precondition, not a list of problems) → 0 afterpnpm exec turbo run build --filter=./packages/* --filter=./packages/*/*underscripts/pm/os-verify-lock.sh(VERDICT command-exit 0, held 6m32s);check-engine-split-ratioexit 2 (this clone is shallow … a ratio derived here would be real, plausible and WRONG) → 0 aftergit fetch --shallow-since=2026-05-29 origin main. Neither is a verdict about this diff, and neither was read as a pass before it was re-run.pnpm lint(whole repo,eslint . --no-inline-config) — exit 0 onf248bc953. No narrowing claimed.grep -naP) clean;check:nul-bytesexit 0.The build left the tracked tree unchanged (
git status --porcelainempty).scripts/**only ⇒skip-changeset.Generated by Claude Code