Repository navigation
test(dogfood): activity-text-predicate pays its boot's first load at module scope and splits its slow control case - #24026
Conversation
…module scope and splits its slow control case The file's beforeAll boot paid the process's first load (lazy driver and better-auth imports, sql.js WASM compile) inside the clocked hook: about 4.2 s cold against about 1.3 s warm. A module-scope throwaway boot through @objectstack/verify's exported bootStack pays it during collection. The unmasking reader's control case made 35 sequential CPU-bound requests (about 2.7 s unloaded) and crossed vitest's 5000 ms default on a loaded runner. It is cut into one case per class plus the tail, every probe and assertion moved intact; concurrent requests measured no faster than sequential ones in this single process. Claude-Session: https://claude.ai/code/session_018t6a5rvqPRvEDMCVVW9kYT Co-authored-by: Claude <noreply@anthropic.com>
📓 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): |
席位核对ACCEPT · #23977 (
What happens to the card: it stays open for the 10 s line. This seat files the platform finding in its next filing window (the REST API-exposure gate's per-request object-list read: Landing: Generated by Claude Code |
Part of #23977
Clause-②: no
The card has two halves. Here is where each stands at this head (
0c7592a22):controlcase under load: met. At base it timed out at 5000 ms on 2 of 3 loaded runs here, which reproduces the nightly's red. At head it is four cases, and the slowest of them stays under 2.5 s (half the timeout) on all 3 loaded runs.@objectstack/restand@objectstack/metadata-protocol(see "Out of scope" below). The claim's hold-off keeps platform code out of this PR, so dogfood: activity-text-predicate.dogfood.test.ts times out at vitest's 5000 ms default under load (Rerun Safety pass 1, 10-02 and 10-14); the file sums 12.9 s unloaded with no declared budget #23977 remains open for that half.What changed
One file,
packages/qa/dogfood/test/activity-text-predicate.dogfood.test.ts: +66 / -26, or +41 / -1 when whitespace is ignored.payTheBootsFirstLoad()boots a throwaway app (no objects, therequiresthis file's stack declares,automation: true). It signs in and signs up once, then stops, and the file awaits it at module scope. Vitest runs that during collection, which no clock covers (AGENTS.md, Build & Test). It has the shape of@objectstack/verify's ownboot-warm-up.testkit.ts, but usesbootStack, which is exported today. Nothing new is exported from@objectstack/verify. A fuller warm-up was also measured: the same three extra plugins as the file's boot made no difference (1217 and 1303 ms against 1456 ms for the hook's boot), so it was dropped.describekeeps the original title. Threeits, one per class, carry the per-class loop body verbatim. A fourth carries the tail, the snapshot miss and the grouping. Every probe and everyexpect(moved intact, re-indented only.Nothing else moved: no timeout, no budget line, no roster entry, no project. There is no
// test-budget:line. OnebeforeAllboot is neither of the two classes ruling6181973363names, and the remaining wait is a per-request cost, which is not a named class either.Where the time went at base (assumption 1)
These numbers come from an instrumented copy, run isolated on the shared 4-vCPU box, 2 to 4 runs.
bootStackThe PM's mechanism assumptions, measured
Promise.all. The requests run in-process (app.request) on one thread over an in-memory sql.js database, so they are CPU-bound. No concurrency was added; the case is cut instead.Test timed out in 5000ms.At head, its slowest part took 2488, 1906 and 1629 ms.bootStackpays about 2.8 s of first load: 4.17 s cold against 1.15 to 1.46 s warm.A/B: isolated, interleaved, 3 rounds each
61a680956(bb7cbee56a89). Head is0c7592a22.--maxWorkers=2, and every run went throughos-verify-lock.node -e 'for(;;){}'hogs on the 4-vCPU box for the whole round. That made runs about 2.2 to 2.7 times slower than unloaded, which is harsher than the card's 1.5 times.The hook's time (file line minus the tests' sum, unloaded) went from 5779 to 6778 ms at base to 3079 to 3415 ms at head. The four control parts together still take what the one case took, 2321 to 2413 ms unloaded: the split moves no work.
Assertions kept
it/describetitle literals at base hash to887e5a912c4fe675(sha256 prefix, in file order).`every column of a pinned parent, for the stored values of the ${c} class`and'a non-matching approval snapshot filter, and a grouping of the activity stream'.expect(counts 40 at base and 40 at head.Ablation: the split cannot swallow a failure
This was a one-time run; no test was left behind.
expect(snapHit.rows).toBe(1), and everything else stays green, so 3 failed / 22 passed.node scripts/ablation-replace.mjs(wrap mode) changed the per-classsnapHitprobe's filter from the class's stored snapshot value toNOMATCH. It landed: anchor x1 → x0, blob8b5eb87856f9→2ac1463e3d0a.expected +0 to be 1, as predicted.8b5eb87856f9, andgit diff HEADis empty.Tests and gates, at
0c7592a22pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/activity-text-predicate.dogfood.test.ts test/activity-parent-read-gate.dogfood.test.ts test/audit-log-parent-read-gate.dogfood.test.ts: 3 files passed, 39 tests passed, exit 0.pnpm --filter @objectstack/dogfood typecheck(tsc --noEmit): exit 0.tsc --listFilesOnlylists the changed file.pnpm exec eslint --no-inline-configover the changed file: exit 0. The repo-wide lint run is this PR'sLint & Repo Gatescheck.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, taken from the merge base, derived 53 commands:pnpm check:dual-build-cjs-loadsexited 3 with PREREQUISITE NOT MET, because it reads every package'sdist/. That is NOT MEASURED locally; CI's run is the reading.--ran, with an exit code recorded per command, accounted for all 53: 52 run, 1 NOT-MEASURED.main's full battery, not on PR CI.No changeset
The only file changed is a test of
@objectstack/dogfood, which is private, and no published package'sfiles[]reaches it. The seat appliesskip-changeset.Out of scope: reported to the seat, not fixed here
The REST API-exposure gate re-validates the metadata of every object on every data request.
/data/OBJECTread and query request entersenforceApiAccess(packages/rest/src/rest-server.ts) to read one object'senableflags. From there it callsloadObjectItems(packages/rest/src/meta-item-read-gate.ts), then the protocol'sgetMetaItems({ type: 'object' }), thenreadFlattenedMetaItems(..., 'served')(packages/metadata-protocol/src/protocol.ts). That ends indecorateMetadataItems→computeMetadataDiagnostics(packages/metadata-protocol/src/metadata-diagnostics.ts), which runs a full ZodsafeParseof each registered object's schema.readFlattenedMetaItems, 1244 ms of that insidecomputeMetadataDiagnostics.Acceptance notes
importtime grows by that much. Collection is not clocked.Generated by Claude Code