Repository navigation
feat(scripts): a test file of either ruled class is listed over its own declared budget, not the 10 s line - #23595
Merged
objectstack-fleet[bot] merged 1 commit intoOct 15, 2026
Conversation
…wn declared budget, not the 10 s line The refresh diff reads one header line, `// test-budget: SECONDS — CLASS: REASON`, from each test file its window read over 10 s, and lists that file only above the budget it declares. A malformed declaration refuses the diff, naming the file and the line; a file no longer in the tree stays under the 10 s line and is named. Claude-Session: https://claude.ai/code/session_01ESFcvW3staenyBCGq7kcDH Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
席位核对 ·
|
objectstack-fleet
Bot
deleted the
claude/issue-23534-test-budget-declaration
branch
October 15, 2026 03:32
This was referenced Oct 15, 2026
Merged
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 #23534
Clause-②: no
The refresh diff (
scripts/measure-test-shard-timings.mjs --diff) now reads a test file's own measured budget and lists that file only above it, as ruling record 6181973363 (letter B, both classes) binds. A file without the line stays under the 10 s line, exactly as before. TheAGENTS.mdsentence is its own Tier H draft PR (linked from the card); this PR does not wait for it.The declaration
One line in the test file's header:
TEST_BUDGET_CLASSES):spawns the real producer once per single-cause fixturewhole-package import//line at column 0 in the file's header. The header is the leading run of blank lines,//lines and block comments, up to the first line of code. The script header (readTestBudget's docblock) states the same grammar.Refused loudly, never skipped: any comment line whose text opens with
test-budget:counts as a declaration attempt, in any case and also spelledtest budgetortest_budget. Such a line is refused when it does not match the grammar, when it is a second one, or when it sits below the header. The refusal throws, so--diffexits non-zero, and the message namespath:line. A file the window has over 10 s is the only file asked: a declaration cannot lift a file the line does not list.What the body shows
| scripts/liveness/check-liveness.test.ts (local) | @objectstack/spec | r1 | 640.00 (declared 620) | 1 / 1 |. The runs-over count is taken against the declared budget.902.10 s of its 1130 s).PM mechanism assumptions, measured
shard-timings-refresh.ymlchecks out the full tree (actions/checkout, line 260). It runsnode scripts/measure-test-shard-timings.mjs --diff …from the repo root (line 799). No step between them switches or narrows the tree: the onlygit switchis at line 995, after the body is composed. The script resolves files through its ownREPO_ROOT.{pkg, file, project}.fileis the path vitest printed, relative to the package directory (its root). The project is a separate field.scripts/build-schemas-check-mode.test.ts (repo)under@objectstack/spec.packageDirForName) plusfile.--diffon this tree, with captures naming those rows, foundpackages/spec/scripts/build-schemas-check-mode.test.tsand read it (no declaration, so 902.10 s is listed against 10 s, as today). It named the missingsrc/nope-renamed.test.tsas "no file at packages/spec/src/nope-renamed.test.ts in this checkout", and an unknown package as "no workspace package by that name". Exit 0.dispatch-gates: no-path-populationline said--diffreads only argv paths. That is false now.--self-test"reads no tracked file". That was already false onmain: the self-test's workspace-resolution cases index every package manifest and count@objectstack/driver-turso's test files. That is also why an instrumented copy needspackages/beside it.--commandsderives the same 32 commands the dispatch lead listed, andpnpm check:pm-dispatch-gatesexits 0.70d4c063, an instrumented copy measured the registered counts asself-test56,env-carried slices11,minimum executed runs14,suite-duration ceilings14 andrefresh diff and per-file budget22. Each equals its pin, and the floor is 5. This PR adds a sixth battery,per-file budget declarations (ruling 6181973363): 14 cases registered and pinned at 14, floor 5 to 6. The handshake (SELF_TEST_VERDICT) is unchanged. The new cases run in memory and in a temp dir. The CLI case passesdiffMainapackageDirresolver pointed at the temp dir, so no tracked file is read.whole-packge import(a typo). It exited 1, wrote no body, and its stderr openedError: packages/spec/src/shared/alias-integrity.test.ts:2: the class "whole-packge import" is neither class the ruling names. …. The workflow's|| DIFF_EXIT=$?(lines 799–819) puts "Regression readings: NOT MEASURED -- the diff refused" plus that stderr into the refresh PR body. The same replica, with the two spec files declared at 1130 and 620, exited 0. It heldbuild-schemas-check-mode.test.ts(902.10 s of 1130 s) out of the list and listedcheck-liveness.test.tsat640.00 (declared 620).FILE_BUDGET_SECONDS = 10and the self-test's!== 10assertion are unchanged. Nopackages/spec/**file and no.github/workflows/**file is touched. The declarations themselves belong to the spec lane on #23180, which is not addressed here.Tests
node scripts/measure-test-shard-timings.mjs --self-testprintedmeasure-test-shard-timings: self-test OK, exit 0. Six batteries registered 56/11/14/14/22/14 against pins 56/11/14/14/22/14.{ packageDir: () => null }so it stays off the tracked tree.40215f6c, throughscripts/ablation-replace.mjs):if (!TEST_BUDGET_CLASSES.includes(cls)) refuse(…)). The anchor count went 1 to 0 and the blobe224fd82to0ea2558b.Error: budget: a class naming neither read as null.git checkout HEAD --: blobe224fd82matches HEAD,git diff HEADis empty, the anchor count is back to 1, and the self-test is OK again. No permanent mutation test.pnpm exec eslint --no-inline-config scripts/measure-test-shard-timings.mjsexited 0. The config resolves for the path (--print-config).Gates (local, at
40215f6c, the final head)node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 32 commands from git off merge base70d4c063. All 32 ran and all 32 exited 0, each exit captured before any pipe.pnpm check:pm-dispatch-gates(detached, exit 0:dispatch-gates self-test (fast tier): 1841 cases pass),check:nul-bytes,check:cross-package-test-inputs,check:entry-guard, the four self-test-wiring and anchor gates with their self-tests, and the three shard-timing self-tests.--ranprinted✓ dispatch-gates --ran: 32 derived famil(ies) accounted for — 32 run, 0 NOT-MEASURED (a DERIVED zero …).pull_requestdry run is the end-to-end reading of the workflow path.Size
+358 / −27 in one file, against the ruling's estimate of about 60 lines. The breakdown:
Acceptance notes (not filed)
Stale workflow prose. The workflow's header prose still says "every test file over 10 s of wall in the window" (lines 178–181) and "a test file over 10 s of wall is a card for the owning lane" (190–191). It is a description, not a mechanism. Editing it is a governed
.github/workflows/**change, so it is not made here. Carrier: none.Stale self-test docblock. The self-test's docblock still reads "This file declares ONE battery". It was stale before this PR, which adds a sixth battery. Carrier: none.
Sibling self-test reads the workspace index.
scripts/ci/select-shard-timings-run.mjs --self-testspawns the real--diffwith a fixture package@objectstack/a. That run now reads the workspace index to look up the fixture's declaration: it finds none, the 10 s line holds, and its assertions are unchanged (it passed above). Carrier: none.No PR-time parse of a declaration. A declaration is parsed only by the weekly refresh, so a malformed line in a test file lands green and refuses the next refresh. No new gate is added, by default. The spec lane can check its lines locally:
node -e "import('./scripts/measure-test-shard-timings.mjs').then((m) => console.log(m.readTestBudget(require('fs').readFileSync(process.argv[1], 'utf8'), process.argv[1])))" packages/spec/scripts/build-schemas-check-mode.test.tsGenerated by Claude Code