Repository navigation
test(runtime): keep module loads out of three slow test files' clocked windows (runtime row of #23181) - #23204
Merged
objectstack-fleet[bot] merged 2 commits intoOct 13, 2026
Conversation
…ree slow files' clocked windows declared-capability-absence-warn-once: one module graph at module top; each boot mounts the dispatcher under its own route prefix instead of vi.resetModules() plus a fresh import per test, so each test still meets a registry that never saw its route keys without re-evaluating ~730 modules. stored-metadata-reader-contexts.pin / stored-metadata-body-boundary.pin: pay the two default-datasource drivers' first transform at module load, as datasource-visibility.test.ts does, instead of inside beforeAll's bootstrap. Claude-Session: https://claude.ai/code/session_01VoSxBQujKLZKPwK2u5ehQ6 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VoSxBQujKLZKPwK2u5ehQ6 Co-authored-by: Claude <noreply@anthropic.com>
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): |
objectstack-fleet
Bot
deleted the
claude/issue-23181-s1-runtime-test-budget
branch
October 13, 2026 09:16
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 #23181
Clause-②: no
The
@objectstack/runtimerow of #23181 (slice 1): three test files the hourly full battery read over 10 s of wall. This PR edits those three test files only: no runtime source, no vitest config, no timeout value, no test removed or moved.Rows
src/declared-capability-absence-warn-once.test.ts38325245250)src/stored-metadata-reader-contexts.pin.test.ts38314183560)src/stored-metadata-body-boundary.pin.test.ts38210849670)shard-timings-refresh.yml,measure-test-shard-timings --diff) reads all three; if it names a pin file again, the remaining cost is outside the test (Acceptance notes)."Isolated" is the file run alone, five times, with the agent-detection variables unset so vitest picks the
defaultreporter CI reads; the number is the file line'sresult.duration(hooks plus tests, collection excluded). The pin files' before and after runs were interleaved (base, after, base, after), with the base bytes run from an untracked copy byte-identical to the merge base's blob (9423d04d44for body-boundary). Every after run sat below every before run. This is a shared 4-core box, so read the ratios as well as the absolutes.Where the time went, and the change
declared-capability-absence-warn-once.test.tsvi.resetModules()and re-imported the dispatcher andsendError, re-evaluating the same 733 modules (spec/src422,core/src93,platform-objects/src71,runtime/src64,rest/src24,types/src22, plus the inlinedobjectqlandmetadata-protocoldist bundles): about 0.9 s per test isolated, 1.1 to 1.4 s per test in the whole-package run. In isolation the first test also paid the graph's cold transform inside its clock (17.0 s; vitesttransform15.5 to 17.0 s).scripts/check-test-source-alias.mjs). The per-test isolation the reset bought is kept by the route key instead. The dedupe registry is keyed onMETHODplus the mounted route pattern (parked byobservability/instrument.ts), so eachboot()mounts the dispatcher under its own prefix (/t1/api/v1,/t2/api/v1, and so on). Every key a test touches is one the registry has never reported, the same precondition a fresh process gives those keys. Handler lookups go throughroute('GET /notifications'); asserted paths throughpath('/notifications').Duration22.2 to 23.5 s before, 17.4 to 19.7 s after (isolated).stored-metadata-reader-contexts.pin.test.tsandstored-metadata-body-boundary.pin.test.tsbeforeAll(already shared), then the tests. On the base bytes of the reader file (3 runs),beforeAlltook 2.7 to 3.1 s wall against 3.1 to 3.4 s CPU, and the tests 2.6 to 2.9 s wall against 5.5 to 6.2 s CPU. CPU at or above wall in both windows means no idle wait to remove.bootstrap()is about 2.0 s, of which the objectql plugin'sstart()is 0.54 to 0.58 s and init/ready the rest. The twowaitForpolls (100 ms interval, for a/meta-authored action or hook to bind through the event-driven resync) settle in 153 to 274 ms per test, and in 826 ms for the body-boundary file's hook bind, whose probe runs three hook bodies per attempt.bootstrap()first-evaluates two workspace modules insidebeforeAll,driver-sqlite-wasm/distanddriver-sql/dist, reached throughservice-datasource's lazyimport(). These are the transform-queue-exposed kind of load the clocked-window rule is about. Every other first load in the boot is a native external (better-auth, knex, sql.js, nanoid), and better-auth is not a runtime dependency, so a module-top import of it would be a phantom dependency.import '@objectstack/driver-sqlite-wasm'andimport '@objectstack/driver-sql', the shapedatasource-visibility.test.tsalready carries. Both pairs were already registered for runtime inKNOWN_UNALIASED_TEST_IMPORTS. Measured:bootstrap()2.0 to 2.1 s became 1.5 to 1.8 s in a probe; the files went 12% and 17% faster isolated.Every assertion kept
it/describetitle lines are hash-identical at the merge base and head (reader 21itsites / 27 tests, body-boundary 5 / 7, warn-once 7 / 7). The two pin files gained two import lines and a comment; no test body changed.expect(calls before and after, and each test proves the same thing:reports a declared 501 ONCE across N requests, at warn, naming the missing service: five requests to a route the registry never saw, onewarn, zeroerror. The asserted path is this boot's mounted pattern.a SECOND, DIFFERENT route still reports — the dedupe key is the route: two never-seen routes, one line each, same code and prose.an UNDECLARED 500 on the same door is still loud, once per request: three faults, threeerrorlines, nowarn.a declared absence and a fault coexist in one process without either changing the other: onewarnand twoerroron one mount.the envelope the dispatcher answers is classified identically by the REST envelope writer: the dispatcher andsendErrorstill share one@objectstack/typesregistry (one module graph), and both lines name the service and the suppression.answers the same bytes it answered before this change, on every request: request 1 is still the reported occurrence on a never-seen route, so the first-versus-suppressed byte comparison still holds.answers the same bytes for a fault, too: unchanged.One-shot proofs (run from the committed state, not kept as tests)
Both went through
scripts/ablation-replace.mjs(anchor hit counted, blob hash moved, restore proven by the head blob hash and an emptygit diff HEAD), against the warn-once file at8d5fab4bdc:/api/v1prefix): 3 failed, 4 passed.a SECOND, DIFFERENT route…got 1 line where 2 were expected,…coexist…0 where 1 was, andthe envelope…(door 1) 0 where 1 was. That is the order-dependence the reset used to prevent, so the prefix is load-bearing. Bloba643630be43dtoe35018939f4d, restored toa643630be43d.packages/types/src/server-fault-log.ts, thehas(key)early return; aliased to source for this suite, so no build leg): 3 failed.reports … ONCE…got 5 lines where 1 was expected,a SECOND…4 where 2 were, and…coexist…2 where 1 was. The file still pins the dedupe itself. Blob7ed86cc374e8to758f68960025, restored.Verification at
8d5fab4bdc(branch merged withmainatd4aaeaf0e2)pnpm --filter @objectstack/runtime test:Test Files 364 passed (364),Tests 5178 passed | 19 skipped (5197), lock verdictcommand-exit 0.pnpm --filter @objectstack/runtime typecheck: exit 0.tsc --noEmitis clean, andcheck:test-typecheck: OK. The three files are in thetsconfig.test.jsonprogram (3 of 367 runtime test files) and carry no entry intest-typecheck-debt.json.pnpm lintinvokes it with--no-inline-config --format json, over the 3 files: 3 files, 0 errors, 0 warnings, 0 fatal.--print-configresolves each file to an active config (not ignored).eslint.config.mjsenables no type-aware linting (noparserOptions.project, no typed rules; its own comment says so), so this diff cannot move any untouched file's verdict.node scripts/pm/dispatch-gates.mjs --commands: 50 commands, run as printed with exit codes captured before any pipe. 49 exit 0 with their own pass lines.pnpm check:dual-build-cjs-loadsfirst answeredPREREQUISITE NOT MET(exit 3: 38 packages had nodist/). After a full build (74/74 tasks), the same command answered exit 0: 108 require entry points across 67 packages load.--ran: 50 derived, 50 run, 0 NOT-MEASURED, 0 UNRUN. (Corrected by the seat from the dev's report; the PR body had been written before that run.)filesisdist,README.md,CHANGELOG.md. A string unique to this change has 0 hits in them; a control string fromdispatcher-plugin.tshas 1 hit indist/index.js. Labelskip-changeset.Acceptance notes
turbo --concurrency=4multiplies exactly that. The card's readings sit 2.3x to 2.9x over this box's whole-package run. Neither lever is a fixed delay or poll the test waits on, so neither is in this slice: a cheaper boot, or reusing compiled WASM across invocations while keeping separate instances. Observation only; carrier: none.main), on a shared box (the after run queued 187 s behind sibling work), and with a changed file order (vitest schedules by previous duration, and warn-once is no longer the slowest file). The module-top imports cannot add clocked time, since they move evaluation into collection. The interleaved isolated runs are the comparison.vi.setConfig({ testTimeout: 30_000 })was raised for the per-test reload this PR removes. It is left as it stands, because this slice's claim excludes timeout values. Its comment now says why it was raised, so whoever next owns the file can drop it.@objectstack/runtimeCI reads (Test Core) will be the first contended reading of the new shapes. The hourly timing refresh is the pin.Generated by Claude Code