Repository navigation
Commit 45a085a
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
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
58 | 68 | | |
59 | 69 | | |
60 | 70 | | |
| |||
0 commit comments