Skip to content

Commit 45a085a

Browse files
test(rest): pay the objectql load at module top in the meta write-door enumeration (#30908)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} --> _Requested by **Elon** · [project thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DK1ucKWSZvMt4XmKXJG4zqA)_ domain:server#1 · os-elon-musk · session_016WV4cyFzEX3mhkfxdV1M8E Fixes #30873 Clause-②: no Metadata-protocol: none Claim: 6681653863 (re-posted with this branch as 6681707609) · Branch: `claude/project-thread-7l5fxn` ## 维护者速读 - 改了什么:只改一个测试文件 `packages/rest/src/meta-write-door-capability-enumeration.test.ts`,在文件顶部加一行 `import '@objectstack/objectql';` 和说明注释。没有改任何断言,没有改任何源码。 - 为什么改:「币种代码回填」接口的对照用例是这个文件里唯一会越过权限闸门、走到接口里那句 `import('@objectstack/objectql')` 的用例。这个包第一次加载要冷编译整个查询引擎,空闲时 3.2 秒,全算在该用例 5 秒的超时窗口里;机器一忙就超时,Test Core (6/8) 变红,把无关的 PR 踢出合并队列。把第一次加载挪到模块顶部,它就在收集阶段完成,收集阶段不计超时。 - 风险与回滚:极小。纯测试代码,不发布任何文件;该用例仍然在两个挂载点、两种身份下各打一次,仍然要求 `501 NOT_IMPLEMENTED`。回滚即撤 PR。 - 先看:`packages/rest/src/meta-write-door-capability-enumeration.test.ts` 顶部新增的那一行 import 和注释;对照用例本身(文件末尾 `the control: its own capability`)一字未动。 - 两分钟验证:`pnpm --filter @objectstack/rest exec vitest run --project local src/meta-write-door-capability-enumeration.test.ts`,预期 66/66 通过,该用例约 5 ms(之前约 3.3 秒)。 - 需要你做的:无,席位落地。 ## What changes `packages/rest/src/meta-write-door-capability-enumeration.test.ts` only, +10 / -0: a module-top `import '@objectstack/objectql';` under a comment carrying the measured reason. No assertion, no case and no source file changes. The `#30675` control case ("its own capability (and `isSystem`) passes the gate, on both bases") is the one case in this file that gets past a gate into the record-currency backfill door, which loads `backfillRecordCurrencyCodes` through a guarded `import('@objectstack/objectql')`. In this package that specifier resolves through the workspace link to `packages/objectql/dist/`, so the first load is a cold vite transform of the engine's module graph. It was paid inside the case's 5000 ms `testTimeout`. Loaded at module top, it is paid during collection, which no vitest timeout clocks (the convention in AGENTS.md § Build & Test and in `scripts/check-test-source-alias.mjs`'s clocked-window section; `analytics-dataset-body-door.test.ts` in this package is the same shape). The door's own `import()` then resolves to the module already loaded. The case is unchanged: it still knocks on both bases (`/api/v1` and the scoped `/api/v1/environments/:environmentId`) as both a `setup.write` holder and `isSystem`, and still expects `501 NOT_IMPLEMENTED` with the nested `NOT_IMPLEMENTED` code, which is the answer that tells the gate's verdict apart from its refusal. `@objectstack/objectql` is already in `@objectstack/rest`'s `KNOWN_UNALIASED_TEST_IMPORTS` set (other tests here import it statically), so no ledger moves. ## Why Card #30873: Test Core (6/8) on PR #30870 (a translations-only `service-settings` PR) timed out on this case twice, job 127778628692 on `9c22c667` and job 127785162372 on `9e0f2cd6`, `Test timed out in 5000ms`, while every other case in the file passed. Where the time goes, measured on `origin/main` `98f640d5` in this container (4 vCPU) with a throwaway probe test (not committed) that times each step inside a vitest worker of this package: | Step | Idle, two runs | |---|---| | first `import('@objectstack/objectql')` | 3201 / 3257 ms | | second `import('@objectstack/objectql')` | 0 / 0 ms | | first `new RestServer(...)` + `registerRoutes()` (scoping `auto`) | 11 / 10 ms | | each later boot | 0-1 ms | So of the case's ~3.3 s idle, about 3.2 s is the cold load; the four boots cost about 13 ms together and the handler past the gate is negligible. The case pays the import on its first knock only, which is why the other three knocks in the same case are cheap. The other cases in the same describe do not share the cost: the anonymous case and the refusal case are answered 401 / 403 before the door resolves an engine or reaches the import (2-6 ms each, before and after). The route's own test file, `meta-record-currency-backfill-route.test.ts`, already imports `ObjectQL` from `@objectstack/objectql` at module top. No timeout was raised, and none is needed (below). ## Tests Before is `origin/main` `98f640d5`, after is this branch. Same container, 4 CPUs. "Loaded" pins vitest to CPUs 0-1 beside four `node -e 'for(;;){}'` busy loops pinned to the same two CPUs (PIDs recorded, killed by a trap). Command: `pnpm exec vitest run --project local src/meta-write-door-capability-enumeration.test.ts` in `packages/rest`. | | The control case | Sum of the 66 cases | Result | |---|---|---|---| | Before, idle (3 runs) | 3314 / 3308 / 3986 ms | 3402 / 3401 / 4099 ms | 66/66 pass | | Before, loaded (3 runs) | 5016 / 5023 / 5026 ms | 5282 / 5224 / 5250 ms | **1 failed, 65 passed, `Test timed out in 5000ms`, 3 of 3 runs** | | After, idle (3 runs) | 5 / 5 / 5 ms | 94 / 89 / 113 ms | 66/66 pass | | After, loaded (3 runs) | 13 / 12 / 15 ms | 239 / 236 / 221 ms | 66/66 pass | Every other case is under 20 ms idle before and after (the slowest is the anti-drift enumeration case, 14-19 ms idle, 29-34 ms loaded after). <details><summary>Where the load went: vitest's own Duration line, one run each</summary> The load is moved out of the clocked window, not removed: the file's total wall is about the same, and the seconds move from `tests` to `import` (collection). - Before, idle: `Duration 8.86s (transform 6.43s, setup 0ms, import 5.24s, tests 3.47s)`, 66 passed. - After, idle: `Duration 8.50s (transform 6.23s, setup 0ms, import 8.26s, tests 91ms)`, 66 passed. - Before, loaded: `Duration 16.05s (transform 12.65s, setup 0ms, import 10.16s, tests 5.31s)`, 1 failed, 65 passed: `FAIL |local| … > the control: its own capability (and isSystem) passes the gate, on both bases`, `Error: Test timed out in 5000ms.` - After, loaded: `Duration 25.33s (transform 18.05s, setup 0ms, import 24.49s, tests 343ms)`, 66 passed. The loaded collection is slow and noisy on two contended cores; no vitest timeout covers it. The before-idle Duration run was taken by writing the `98f640d5` blob of the test file over the committed fix, running it, and restoring with `git checkout HEAD --`; the restored file's hash equals the HEAD blob and `git diff HEAD` is empty. </details> No ablation: the diff changes no behaviour a test pins (it moves where a module is first loaded; every assertion is byte-identical to `main`). ## Acceptance notes - A test-only change: `@objectstack/rest`'s `files` is `dist`, `README.md` and `CHANGELOG.md`, and after `pnpm --filter @objectstack/rest build` the new comment has 0 hits under `packages/rest/dist` (positive control: `_migrate-record-currency-codes`, 2 hits). Nothing published moves. No changeset, labelled `skip-changeset`. - `pnpm check:test-source-alias` did not flag the old shape and could not: its clocked-window rule reads load sites in TEST files (plus one hop through a same-package helper that imports a non-literal specifier), while this load sat in the door's source, reached from a test's clocked window through a route handler. Reported to the seat as a finding; not changed here (outside this card's file surface). ## Verification All on the final head `73062e5028` (one commit on `origin/main` `98f640d5`, which had not moved when this PR opened; the delta against `main` is the one file, +10 / -0), after a whole-tree `turbo run build --filter=!@objectstack/docs` (118/118 tasks, lock VERDICT command-exit 0). - `pnpm --filter @objectstack/rest test` (the `local` project) under the verify lock: Test Files 393 passed (393), Tests 7456 passed, 332 skipped (7788), VERDICT command-exit 0. The `repo` project (`test:repo`) is left to CI: this file is not in `vitest.repo-tests.json`. - `pnpm --filter @objectstack/rest typecheck` (`tsc --noEmit` plus `check:test-typecheck`, which compiles the test layer under `tsconfig.test.json`): VERDICT command-exit 0, 0 errors. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 49 families on `73062e5028`. Each ran sequentially with its exit code captured before any pipe: 48 exit 0 on the first pass and `pnpm check:dual-build-cjs-loads` exit 3 (PREREQUISITE NOT MET, no dist for 46 packages); after the whole-tree build it ran again, exit 0. `pnpm lint`: exit 0. - `dispatch-gates --ran`: "49 derived famil(ies) accounted for — 49 run, 0 NOT-MEASURED", with `pnpm lint` listed as outside the derivation. - Every family CI runs on this PR is read from the PR's check runs, not re-run here. ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (No `packages/spec` change.) - [x] 2. Every name I added uses the casing for its kind. (No name added.) - [x] 3. No formatter ran; `pnpm lint` passes. - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (Nothing publishes: test-only, `skip-changeset`.) - [x] 6. `packages/spec` touched: its generated artifacts are regenerated and committed. (Not touched.) - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English. - [x] The *Before Submitting* list in CONTRIBUTING.md is done. --- _Generated by [Claude Code](https://claude.ai/code/session_016WV4cyFzEX3mhkfxdV1M8E)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7d9682f commit 45a085a

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

‎packages/rest/src/meta-write-door-capability-enumeration.test.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@
5555
* already run would still be the bug and would still pass a status-only check.
5656
*/
5757

58+
// [#30873] Paid at module scope so the first load lands during collection, not
59+
// inside a clocked window (`pnpm check:test-source-alias`). The `#30675` control
60+
// at the end of this file is the one case here that gets past a gate to the
61+
// record-currency backfill door's guarded `import('@objectstack/objectql')`, which
62+
// resolves through `dist/` and costs a cold transform of the engine's module
63+
// graph. Measured on 4 vCPU before this line: the import 3.2 s idle, the case
64+
// 3.3-4.0 s idle (every other case under 20 ms) and `Test timed out in 5000ms`
65+
// 3 of 3 on two loaded cores. Loaded here, the door's import is a cache hit.
66+
import '@objectstack/objectql';
67+
5868
import { describe, it, expect, vi, beforeEach } from 'vitest';
5969
import { ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_STATUS } from '@objectstack/core';
6070
import { RestServer } from './rest-server.js';

0 commit comments

Comments
 (0)