Skip to content

Commit 3d8d2f1

Browse files
os-litantclaude
andauthored
docs(cli): narrow the vitest cost header to what check-test-source-alias measures (#12494)
The header closed by calling a swap of the serve e2e spawns to the built entry "exactly the source-vs-dist trade check-test-source-alias.mjs exists to refuse". The gate does not adjudicate that trade: it resolves the import specifiers reachable from a package's test files through the package's own resolve.alias table, which is a verdict about in-process import resolution, and its own header hands the spawned-child axis to a different mechanism. Measured: re-running the gate on the commit that swapped all three spawners and on its parent returns a byte-identical verdict and a byte-identical measured population. Two further statements the swap falsified are tensed to the past rather than deleted: the 2026-08-20 cost table's present-tense claim that all 20 spawner files run `bin/run-dev.js` through `tsx`, and the per-spawn floor table's "(the source entry these use)". Comment text only; no behaviour change. Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8425c17 commit 3d8d2f1

1 file changed

Lines changed: 50 additions & 14 deletions

File tree

packages/cli/vitest.config.ts

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,17 @@
9797
//
9898
// The cost is test-body work, and it is concentrated, not uniform: median file
9999
// 0.03s, 105 of 137 files under 2s, top 20 files = 87.7% of the wall. The 20
100-
// files that spawn the real CLI as a subprocess (`bin/run-dev.js` through
101-
// `tsx`, against a `mkdtemp` project) are 56.1% of the file wall (300.1s) while
102-
// carrying 177 of 1498 tests. Each spawn re-executes the CLI's module graph in
103-
// a COLD process, which is the standing theory after all — relocated out of
104-
// vitest's worker, where neither its transform cache nor its module registry
105-
// can reach it. Floor per spawn, doing nothing but printing a version:
106-
//
107-
// tsx bin/run-dev.js --version 6.5-6.8s (the source entry these use)
100+
// files that spawned the real CLI as a subprocess (all 20 of them
101+
// `bin/run-dev.js` through `tsx` on that date, against a `mkdtemp` project)
102+
// were 56.1% of the file wall (300.1s) while carrying 177 of 1498 tests —
103+
// three have since moved to the built entry (#11707; last section of this
104+
// header) and the split has not been re-measured. Each spawn re-executes the
105+
// CLI's module graph in a COLD process, which is the standing theory after
106+
// all — relocated out of vitest's worker, where neither its transform cache
107+
// nor its module registry can reach it. Floor per spawn, doing nothing but
108+
// printing a version:
109+
//
110+
// tsx bin/run-dev.js --version 6.5-6.8s (the source entry all 20 used)
108111
// node bin/run.js --version 2.9-3.2s (the built entry)
109112
// node -e 0 0.031s (process floor)
110113
//
@@ -173,12 +176,45 @@
173176
// `packages/cli` has no `vi.mock` of `@objectstack/types` (its only mock targets
174177
// are `../utils/optional-package.js`, `node:fs/promises` and
175178
// `@objectstack/cloud-connection`) — but neither is free, and a package added
176-
// here later must be re-checked for both. Swapping the spawns to
177-
// the built entry would halve per-spawn boot and is exactly the source-vs-dist
178-
// trade `scripts/check-test-source-alias.mjs` exists to refuse — see the note
179-
// above on why a test that passes GREEN against a stale artifact is the
180-
// dangerous outcome. Before adding a `test` block for speed, re-measure: if
181-
// `tests` is still the dominant term, the block is not the lever.
179+
// here later must be re-checked for both.
180+
//
181+
// ## WHY THE SPAWN SWAP IS NOT THIS GATE'S TRADE TO REFUSE (#11707, #12460)
182+
//
183+
// This file used to close by calling a swap of the spawns to the built entry
184+
// “exactly the source-vs-dist trade `scripts/check-test-source-alias.mjs`
185+
// exists to refuse”. It is not one, and naming a gate for a verdict it never
186+
// reaches reads as verification while verifying nothing. What that gate does
187+
// measure: the specifiers written in `import` / `export … from` / `import()` /
188+
// `require()` statements reachable from a package's test files, kept when they
189+
// name a workspace dep whose own entry point resolves under `dist/`, then
190+
// resolved through THIS config's `resolve.alias` table. That is a verdict about
191+
// IN-PROCESS import resolution. It says nothing about which entry a test hands
192+
// to `spawn()`, and its own header signs that second axis over to a different
193+
// mechanism (“A SECOND resolution hazard, which this gate does NOT cover”,
194+
// #11412). The `plugin-auth` entry below is this file's worked example: it
195+
// satisfies the gate while being inert for the child, whose own `exports`
196+
// lookup reaches `dist/` either way.
197+
//
198+
// So the swap was available, and #11707 took it — 2.06x faster in test time,
199+
// measured there. Four files in `test/` consume `packages/cli/dist` today:
200+
// `serve-node-env-production-default` (since #11113) and the three spawners
201+
// #11707 moved onto `node bin/run.js` with `NODE_ENV` unset
202+
// (`serve-mcp-stdio-answers`, `serve-mcp-capability-collision`,
203+
// `serve-stdio-stdout-purity`). Re-running this gate on that commit and on its
204+
// parent returns a byte-identical verdict AND a byte-identical measured
205+
// population: it did not see the swap.
206+
//
207+
// What keeps those four honest is a declaration, not this gate. `turbo.json`
208+
// declares `@objectstack/cli#test` `dependsOn: ["build"]` (#11268), so CI
209+
// builds `dist/` before the suite runs, and each of the four refuses an unbuilt
210+
// tree in a sentence of its own. The residual — a `dist/` merely BEHIND its
211+
// source — is real, and those files state it. An in-process import has no such
212+
// declaration standing behind it, which is why the alias entries above exist
213+
// and why the gate does refuse THAT trade — see the note above on why a test
214+
// that passes GREEN against a stale artifact is the dangerous outcome.
215+
//
216+
// Before adding a `test` block for speed, re-measure: if `tests` is still the
217+
// dominant term, the block is not the lever.
182218
import { defineConfig } from 'vitest/config';
183219
import path from 'path';
184220

0 commit comments

Comments
 (0)