Skip to content

test(cli): drop the tsx launcher from three 10-13 s cli files, budget seven distinct floors - #28630

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-f1dr10
Nov 1, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-f1dr10

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

Part of #23181 (slice 31). The card stays open for later slices: this one takes only the eight remaining packages/cli files from 10 s to 13 s in slice 23's table.

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:packages/cli 里 CI 读数 10–13 s、还没有预算头的 8 个测试文件。其中 3 个原来经 node_modules/.bin/tsx 包装层起 CLI 源码入口,现在直接用 process.execPath 起同一个 bin/run-dev.js(参数、cwd、env、超时都不变),本地快 16%–28%。7 个文件在第 2 行加 // test-budget: 20 头;translation-contributed-nav 换入口后预计已在 10 s 以下,不加头。
  • 为什么改:卡 test budget (domain:cli): 119 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23181 的测试提速职责:超过 10 s 的测试文件要么提速,要么按裁决 6181973363 B 声明预算。逐个数过:每个 spawn 或 doctor 运行都是不同的(命令、参数、夹具)组合,没有能合并的重复,也没有只读文件的子进程可以改成进程内读取,所以能省的只有 tsx 包装层,其余是真实工作的地板。
  • 风险与回滚:只改测试文件,不发布任何东西(cli 的 files[] 只有 dist、README、CHANGELOG);没有删、没有放宽任何断言,用例名和数量不变;回滚即 revert。
  • 先看:packages/cli/test/create-objectstack-stack-reach.test.ts(tsx → process.execPath + 头);packages/cli/src/commands/doctor-ledger-read-failure.test.ts(只加头,原因写在头里)。
  • 两分钟验证:pnpm --filter @objectstack/cli exec vitest run test/translation-contributed-nav-validate-door.test.ts test/i18n-extract-companion-orphan.test.ts → 6/6 通过。
  • 需要你做的:无,席位落地。

What changes

The eight files and their slowest reading over the five scheduled ci.yml runs 41199450735, 41217827347, 41237094739, 41255489006, 41271604267 (slice 23's offender table: the default reporter's per-file module line in the Test Core shard logs). Local per-case readings from --reporter=verbose, one box, one lock hold.

file CI max tests spawns / runs distinct triples cause fix
test/authoring-rule-command-parity.test.ts 12.5 s (41271604267) 11 3 source-CLI spawns, already on process.execPath 3 os lint, os validate, os build over the one planted-defect stack, in one case (7.6 s locally); the exit code is the contract, so it must be a real process. The nine rule cases run in process, 0.3 s together header 20
test/create-objectstack-stack-reach.test.ts 12.4 s (41255489006) 4 1 on-ramp scaffold child + 3 source-CLI spawns through the tsx launcher, already in one beforeAll 4 a chain over one scaffolded project: os g object, os g flow --object, os validate; each step reads what the last one wrote spawn with process.execPath; header 20
src/commands/doctor-ledger-read-failure.test.ts 12.3 s (41199450735) 27 15 in-process os doctor runs (3 on a module graph re-imported after vi.resetModules to swap the ledger reader) 15 each run shells out to pnpm -v (0.25–0.48 s), tsc -v (0.08–0.20 s) and git --version, and bundles its own config: 0.35–0.9 s per case, more on the first. One run per ledger fixture or flag; the fourteen row-builder cases are pure header 20
src/commands/doctor-ledger-posture-independence.test.ts 12.2 s (41255489006) 18 20 in-process os doctor runs 20 the same per-run cost, one run per posture × ledger fixture × flag header 20
src/commands/doctor-node-env-default.test.ts 11.4 s (41271604267) 34 15 in-process os doctor runs 15 the same per-run cost; the first run reads 3.0 s (the cold config-loader load). One run per NODE_ENV value, project shape and flag; the twenty-one row-builder cases are pure header 20
test/i18n-extract-companion-orphan.test.ts 11.3 s (41271604267) 4 4 source-CLI spawns through the tsx launcher 4 os i18n extract on the apps-only stack, its --check over a seeded legacy companion, and the full stack under --objects-only and --no-objects-only; each case reads the real directory its run wrote spawn with process.execPath; header 20
test/hook-timeout-override-refusal.test.ts 11.3 s (41255489006) 4 4 vitest list children of this package, already on process.execPath 4 --hookTimeout, --teardownTimeout, no override, --testTimeout: four different config-load questions (7.4 s locally) header 20
test/translation-contributed-nav-validate-door.test.ts 10.5 s (41255489006) 2 2 source-CLI spawns through the tsx launcher 2 os validate --json on the card's fixture and on its control spawn with process.execPath; no header (see below)

Why the floor is distinct real work. No file repeats a (command, flags, fixture) triple. The spawning files already share their setup where they can (create-objectstack-stack-reach in one beforeAll), and no child only reads a file that an in-process read could replace. In the doctor files every Doctor.run is its case's subject, with its own fixture, posture or flag. So seven files take the ruling 6181973363 letter B header: N = the slowest CI reading × 1.25, rounded up to 10 s (12.5, 12.4, 12.3, 12.2, 11.4, 11.3, 11.3 → 20), class spawns the real producer once per single-cause fixture. Each reason names the spawns or runs and the CI run its reading came from. All seven parse with readTestBudget (scripts/measure-test-shard-timings.mjs): line 2, 20 s, that class.

The one lever inside the floor. Three files spawned bin/run-dev.js through node_modules/.bin/tsx, a launcher that is its own node process in front of the CLI. They now spawn the same entry with process.execPath, as authoring-rule-command-parity, the migrate family (slice 12) and slice 25's files already do: same entry, same src/, same childEnv(), argv, cwd and timeouts. create-objectstack-stack-reach and i18n-extract-companion-orphan keep their header, because the switch projects their CI reading to about 9.3–9.5 s, inside the run-to-run spread of the 10 s line. translation-contributed-nav-validate-door projects to about 7.6 s, so it takes no header.

Not changed: no assertion, case name, case count, timeout, tier, project or helper. No source file, nothing under test/helpers/**.

Tests

  • A/B for the three files whose code changed. The base file (git show ce001f97:…) copied beside head as test/zzbase-*.test.ts, one box, one lock hold, N=3, each file run alone (vitest run --maxWorkers=1 FILE), base and head interleaved. Reading: the default reporter's per-file module line. Copies deleted before the gate run.

    file base (s) head (s) change
    create-objectstack-stack-reach 8.58, 7.73, 7.69 5.97, 6.15, 5.92 −24.8% (mean 8.00 → 6.01)
    translation-contributed-nav-validate-door 6.92, 6.67, 6.65 5.08, 4.92, 4.68 −27.5% (mean 6.74 → 4.89)
    i18n-extract-companion-orphan 7.03, 6.57, 6.53 5.79, 5.43, 5.68 −16.0% (mean 6.71 → 5.64)

    Every run exit 0, same test count per side (4, 2, 4). The CI projections above apply these ratios to the CI max.

  • Header-only files (authoring-rule-command-parity, the three doctor files, hook-timeout-override-refusal): no A/B, per the order. Their doctor-run counts were read by instrumenting a throwaway copy of each file (deleted): 15, 20, 15.

  • All eight on head, one run with test/vitest-tiers-partition.test.ts: 9 files, 126/126 passed; the tier partition pin is green, so the three edited files stay in integration.

  • cli unit tier (pnpm --filter @objectstack/cli exec vitest run --project unit, which holds the three doctor files and hook-timeout-override-refusal): 362/362 files, 5155/5155 tests, on the pre-merge head 0877f01c and again on 8b3bf663.

  • pnpm --filter @objectstack/cli typecheck (tsc and check:test-typecheck) exit 0 on 0877f01c and on 8b3bf663, with NODE_OPTIONS=--max-old-space-size=4096.

  • No ablation: no tested behaviour changed (test-only).

Acceptance notes

  • Doctor's tool probes are most of each doctor file. Every Doctor.run spawns pnpm -v and tsc -v (and git --version), and the three files make 50 runs between them. Memoising those probes in a test would make 47 of the runs read a probe they did not take, and every case asserts the report's gauge line, which those probes feed, so it is not a test-only lever. Noted, not filed. Carrier: none.
  • skip-changeset. Test-only. @objectstack/cli's files[] is dist, README.md, CHANGELOG.md; its build emits no *.test.ts into dist/. No files[] content changes.

Verification

All readings on head 8b3bf663: the two commits 32ad4161 (the process.execPath switch) and 0877f01c (the seven headers), plus one merge of origin/main after slices 24 (#28610), 25 (#28601) and 26 (#28599) landed, as the order asks. The merge touches none of the eight files. The A/B above was taken on 32ad4161.

  • Derived gate families: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack → 52 families (the same 52 before and after the merge), each run with its exit code captured before any pipe, after a full pnpm exec turbo run build --concurrency=2 (118 tasks, exit 0). All 52 exit 0 on 8b3bf663. --ran reconciliation: ✓ dispatch-gates --ran: 52 derived famil(ies) accounted for — 52 run, 0 NOT-MEASURED. On the pre-merge head, before the full build, check:dual-build-cjs-loads and check:i18n-coverage read exit 3 (no full build), check-plugin-teardown-shape --self-test exit 3 (its pinned fixture commit absent from the shallow clone, fetched), and check:type-check-debt exit 3 (its closure build lost the lock queue to my own build); each read exit 0 once its prerequisite was met.

  • node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD exit 0; node scripts/check-nul-bytes.mjs exit 0.

  • Hand gates: pnpm exec eslint --no-inline-config over the eight files exit 0, and node --stack-size=4000 node_modules/eslint/bin/eslint.js packages/cli --no-inline-config (the repo lint script scoped to the touched package) exit 0.

  • CI families (Test Core with the cli integration tier, lint farm, type-check lanes) are read off this PR's check-runs by the seat.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FEkQ5mugTWnXsnz9LD9BMM

…s files

create-objectstack-stack-reach, translation-contributed-nav-validate-door and
i18n-extract-companion-orphan spawned bin/run-dev.js through node_modules/.bin/tsx,
a launcher that is its own node process in front of the CLI. Spawn it with
process.execPath instead; argv, cwd, env and timeouts are unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEkQ5mugTWnXsnz9LD9BMM
… real work

authoring-rule-command-parity, hook-timeout-override-refusal and the three doctor
files (ledger-read-failure, ledger-posture-independence, node-env-default) spawn
or run the real producer once per single-cause fixture with no repeated triple;
create-objectstack-stack-reach and i18n-extract-companion-orphan keep four
distinct spawns after the process.execPath switch. Each takes a line-2
test-budget header sized from its slowest of the five scheduled CI runs x 1.25.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEkQ5mugTWnXsnz9LD9BMM
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 1, 2026
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing 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): node scripts/docs-audit/affected-docs.mjs --json 0e78922ee07bda70879a49793159804fa6b41b77 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC

席位核对 · ACCEPT · domain:server seat 1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-11-01T09:34Z

Head 8b3bf663, report 6556047151 (on #23181), claim 6555841491 (slice 31). No contract review is owed: test-only, no packages/spec/** path, no governed path, no narrowing and no Clause-②: yes.

item reading
Shape Draft, base main, Part of #23181. Exactly slice 31's eight packages/cli files, labels tests + skip-changeset. Clause-②: no, Metadata-protocol: none.
Diff check (seat) create-objectstack-stack-reach, i18n-extract-companion-orphan and translation-contributed-nav-validate-door spawn bin/run-dev.js on process.execPath instead of the tsx launcher, argv, cwd and env unchanged; the unused TSX constants are dropped and the prose says why. Line-2 // test-budget: 20 on seven files; translation-contributed-nav takes none. No assertion changes, no shared helper touched, no timeout raised.
Evidence CI green on head 8b3bf663 (35 success, 18 skipped, 0 failed; the CI and Lint & Type Check workflow runs both success). Governed check: NOT governed, 40 changed lines. The report gives 52 of 52 derived gates exit 0 on the merged head (--ran reconciled), cli unit tier 362/362 files, typecheck exit 0, and A/B N=3 of −24.8 %, −27.5 % and −16.0 % on the three switched files.
Landing 「按照 pm-dispatch 规则复核过的都授权」 (Leehom, 2026-10-25T11:35Z): ready and auto-merge through the relay, once every check on this head is green or an expected skip.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 1, 2026 09:36
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 1, 2026 09:36
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 1, 2026
Merged via the queue into main with commit e098ff4 Nov 1, 2026
54 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-f1dr10 branch November 1, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant