Skip to content

ci(test-source-alias): follow a changed test into the source it loads, and red a cold literal import() paid there - #30969

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-ey752d
Nov 6, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-ey752d

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:devx#1 · os-elon-musk · session_016WV4d1Nibc5bxtbQZv6ssS

Fixes #30909
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:check:test-source-alias 的时钟窗口规则新增第三个读取器:顺着测试收集期的导入链走进同包被测源码,找出藏在函数体里的字面量 import()(该包经 dist/ 解析的那批 specifier),要求测试在模块顶部预热或 mock;只判本次改动新增或修改的测试文件。
  • 为什么改:rest test: the record-currency backfill door's capability control case times out at 5 s in Test Core (6/8) (from PR #30809) #30873 的测试经 rest-server.ts 走到回填路由里的 await import('@objectstack/objectql'),冷加载 3.2 秒落在 5000 毫秒窗口里,把无关 PR 的 Test Core 打红;门禁当时 exit 0。
  • 风险与回滚:只改一个门禁脚本,不动产品代码与测试;误报方向是让作者多写一行模块顶部 import。回滚即 revert。全量扫描耗时 32 秒 → 24 秒(加了解析缓存)。
  • 先看:① sourceReachFindings 与 reachEdgesOf(可达与预热的判定);② 入口处 changedFilesSinceMergeBase(只判改动测试、找不到 merge base 判红);③ 头部新节 "The source reach" 里为什么不对全部测试判红的实测。
  • 两分钟验证:git show 98f640d5:packages/rest/src/meta-write-door-capability-enumeration.test.ts > packages/rest/src/meta-write-door-capability-enumeration.test.ts && node scripts/check-test-source-alias.mjs,预期 exit 1 并点名 meta-record-currency-backfill-route.ts:177;之后 git checkout HEAD -- packages/rest/src/meta-write-door-capability-enumeration.test.ts。
  • 需要你做的:无,席位落地。

What changes

One file, scripts/check-test-source-alias.mjs.

  • A third reader for the clocked-window rule, "the source reach". From each test file it follows every same-package file the test loads during COLLECTION (a static import or a module-scope dynamic one), transitively, never across a bare specifier. A literal dynamic load of a specifier the package resolves through dist/ (the rule's existing population, unchanged) inside a function body of a reached file is a finding against the test, unless a file in the same reach loads that specifier at module scope or the test vi.mocks / vi.doMocks it. The remedy is the line the rule already prints: a module-top import 'SPEC' in the test file. The failure names the specifier, every site of it in the reach, and the import chain to the first one.
  • Scope: the test files a change adds or edits. Measured from the merge base with origin/main (committed, staged, unstaged and untracked alike); --changed-from REF names another base and --reach-all runs the census over every test file. No merge base is a failure, never a pass. On a main push the base is HEAD and the half judges nothing; on a PR or a queue build it judges that change's test files. The Lint · CI, release & engine gates job already checks out with fetch-depth: 0, so no workflow edit.
  • Why not every test file. Static reach is not execution: rest-server.ts registers every route, so every rest test that builds a RestServer reaches every handler's guarded import while only the cases that call that handler pay it. Over every test file at main 0e88208, the reach flags 2307 test files / 5491 (test, specifier) pairs, from only 89 source sites in 53 files. The header's new section "The source reach" records this and the boundaries.
  • Speed. Each file's edges are read once per scan, a file with no dynamic form skips masking, and relative resolution is cached; the full scan measured 32.0 s before and 24.3 s after on this container (4 vCPU), the census over every file 34.8 s.
  • Self-test: a new battery, "the source reach: a load the source under test pays (check:test-source-alias misses a literal dynamic import in the source under test, so a cold dist load inside a test window passes the gate #30909)", 12 cases over six fixtures: the 98f640d shape (test → hub → route, two collection-time hops) reported with its site and chain; the remedy, a load warm elsewhere in the reach, a vi.mock, and a lazy relative hop all silent; one finding per specifier when the direct reader already reports it; the scope judged in and out; the direct reader left unscoped. SELF_TEST_BATTERY_FLOOR 11 → 12.

Tests

  • node scripts/check-test-source-alias.mjs --self-test → check-test-source-alias --self-test OK.
  • Three mutations, each committed-then-restored with git checkout HEAD -- and git diff HEAD empty: dropping the warm-set check reds two cases (remedy, warm-in-reach); dropping the scope filter reds both scope cases; dropping the mock read reds the mock case.
  • Negative control (the card's ask): with packages/rest/src/meta-write-door-capability-enumeration.test.ts at its 98f640d5 blob, node scripts/check-test-source-alias.mjs exits 1:
packages/rest/src/meta-write-door-capability-enumeration.test.ts:60: reaches `import('@objectstack/objectql')` in the source under test, at packages/rest/src/meta-object-state-routes.ts:235, packages/rest/src/meta-record-currency-backfill-route.ts:177 —
    inside a function body, a CLOCKED window for whichever case first calls it.
    Reached during collection through (the first site): packages/rest/src/meta-write-door-capability-enumeration.test.ts → packages/rest/src/rest-server.ts → packages/rest/src/meta-object-state-routes.ts

Restored with git checkout HEAD --, git status --porcelain clean of it; the same command then exits 0.

Acceptance notes

  • How many existing test files the extended rule flags: 0 under the CI scope (no test file changes here). Over every test file (--reach-all, main 0e88208): 2307. By package: ui/packages/app-shell 932, packages/runtime 387, ui/packages/components 287, packages/metadata-protocol 200, packages/rest 187, packages/cli 179, packages/services/service-datasource 64, packages/verify 37, packages/metadata 18, packages/cloud-connection 6, ui/scripts/__tests__ 6, packages/plugins/plugin-dev 4. Reproduce the full list with node scripts/check-test-source-alias.mjs --reach-all. They are not fixed here (over the card's "fix if small" bound): each is fixed with one module-top line when a change next touches it.
  • In packages/rest only two specifiers stay cold, @objectstack/objectql and @objectstack/spec/ui. The card's other latent sites (@objectstack/spec/api in batch-routes.ts / crud-routes.ts, @objectstack/spec/system in form-routes.ts / meta-item-read-gate.ts) are not flagged: another file in the same reach already imports those subpaths statically, so they are paid during collection today.
  • Boundaries (header): a lazy relative hop is not followed; a module-top import of another workspace package whose dist/ loads the specifier is not credited (the loud direction); a mock counts whether or not it calls importOriginal; a source edit that adds a cold site reds no unchanged test.
  • No timeout raised; no test file touched, so ci(test-core): three different cases hit the vitest 5 s default timeout under load in 24 h; measure the shards and fix the timeout class, not one case at a time #30901's lane (PR test(formula): judge each distinct sweep refusal once, and give the validateExpression sweep a measured budget #30919, packages/formula only) does not overlap.

Verification

All on head efd622a9 (this branch merged with origin/main 6ddf827), this container, 4 vCPU.

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 31 families for the one changed path; all 31 ran sequentially, each exit code captured before any pipe; 31 exit 0. --ran: "31 derived famil(ies) accounted for — 31 run, 0 NOT-MEASURED".
  • pnpm exec eslint scripts/check-test-source-alias.mjs exit 0.
  • node scripts/check-test-source-alias.mjs: exit 0, "the source reach judged 0 test file(s) changed since 6ddf827", 24.3 s. --reach-all: exit 1, 5491 findings over 2307 test files (the same counts as at 0e88208), 34.8 s.
  • Negative control repeated on this head: the 98f640d5 blob (hash 76ae2b895f) exits 1 with the finding quoted under Tests; restored blob hash equals the HEAD blob.
gates-ran-efd622a9
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs --self-test :: exit 0
node scripts/check-self-test-wired.mjs :: exit 0
node scripts/check-self-test-wired.mjs --self-test :: exit 0
node scripts/check-self-test-workflow-commands.mjs :: exit 0
node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0
node scripts/check-whole-set-label-write.mjs :: exit 0
node scripts/check-whole-set-label-write.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0
pnpm check:agent-test-spelling :: exit 0
pnpm check:bash32-floor :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:cli-command-ids :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:entry-guard :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:parse-guard :: exit 0
pnpm check:pm-dispatch-gates :: exit 0
pnpm check:pnpm-filter-targets :: exit 0
pnpm check:pnpm-flag-spellings :: exit 0
pnpm check:ratchet-remedy-authority :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:scripts-symbol-anchors :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:watch-hint-literal :: exit 0

Generated by Claude Code

@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 6, 2026
@github-actions github-actions Bot added the size/m label Nov 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw

席位核对 · ACCEPT · #30909 · 2026-11-06T14:39Z

Head-sha: efd622a9737e1c36c70d4cf0cc269d77a25fe5d6

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 6, 2026 14:40
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 6, 2026 14:40
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit acd190b Nov 6, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-ey752d branch November 6, 2026 15:33
os-elon-musk pushed a commit that referenced this pull request Nov 6, 2026
… collection

The source-reach half of check:test-source-alias (on main since #30969)
judges this edited file: its cases reach the protocol's lazy
import('@objectstack/lint') (metadata-diagnostics.ts) inside a clocked
window. Import ./lint-root-preload.testkit.js at module top, as the
sibling protocol test files do.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cxRibYnMTw289qPx3H
os-elon-musk pushed a commit that referenced this pull request Nov 6, 2026
The host crypto provider test imports `serve.ts`, which reaches eight
packages through function-body `import()` calls. check-test-source-alias's
source-reach half (#30969) asks a changed test file to pay those first loads
during collection, so the file now imports them for their side effects at
module top, as the other serve-reaching cli tests do (#10126). serve.ts keeps
its dynamic imports.

Also notes in serve.ts that the host provider's init-done reading assumes
`ctx.getKernel`.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4czs7cUFAphQEUFSrcz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check:test-source-alias misses a literal dynamic import in the source under test, so a cold dist load inside a test window passes the gate

2 participants