Skip to content

docs(cli): narrow the vitest cost header to what check-test-source-alias measures - #12494

Merged
os-litant merged 2 commits into
mainfrom
claude/issue-12460-vitest-config-cost-header
Aug 26, 2026
Merged

docs(cli): narrow the vitest cost header to what check-test-source-alias measures#12494
os-litant merged 2 commits into
mainfrom
claude/issue-12460-vitest-config-cost-header

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#12460

Option A per triage and the dispatching PM's ruling: narrow packages/cli/vitest.config.ts's cost header to what scripts/check-test-source-alias.mjs actually measures. Comment text only, one file, zero behaviour change.

The premise the ruling hangs on, measured FROM THE GATE

The PM's clause 3 named a falsifiable premise — the gate adjudicates in-process import resolution and says nothing about what a spawned child process resolves — and required it be measured rather than assumed, with instructions to stop and report if it came out the other way. It holds, three independent ways.

1. What the gate collects, read from its code.testReachableWorkspaceImports() walks a package's test files plus everything they pull in transitively, and the only thing it harvests per file is fileRuntimeImports(file)extractRuntimeImports(), whose entire population is one regex over comment-stripped source:

constIMPORT_PATTERNS=/(?:^|[\s;})])(?:import|export)\s+([\s\S]*?)\s*from\s*['"]([^'"]+)['"]|import\s*\(\)|require\s*\(\)|/g;

Those specifiers are then kept only when they name a workspace dep whose own entry resolves under dist/ (resolvesToArtifact), and resolved through the package's own resolve.alias table (resolveThroughAliases, pointsAtSource). A path handed to spawn() is not an import specifier and reaches none of that machinery — there is no spawn, child_process, execFile or fork anywhere in the gate's 2809 lines except in prose.

2. The gate says so itself, in a section header quoted verbatim in the new comment:

── A SECOND resolution hazard, which this gate does NOT cover (#11412) ────

3. The decisive measurement — the gate cannot see the swap.#12459 landed as 262145bef, whose parent e9147336d is the same tree with all three spawners still on tsx bin/run-dev.js. Running the gate in a worktree at each:

treeverdict--list (its whole measured population)
e9147336d — spawns → source entryOK — 72 packages … 61 registered … 45 published subpath(s)
262145bef — spawns → built entrybyte-identical stringdiff = IDENTICAL, stdout and stderr

The commit that performs exactly the trade the header called "the source-vs-dist trade this gate exists to refuse" moves neither the gate's verdict nor one byte of what it measured.

Positive control, so that is not a vacuous zero. Two of them. --self-test is green, and its assertions include the red path firing ('violating package with no config was not reported'). And on this very file: neutralising the plugin-auth alias entry — mutation confirmed on disk by blob hash (f4be6348…8aec83dd…) and by grep count (find entries 1 → 0, marker 0 → 1) — turns the gate red:

check-test-source-alias FAILED
✗ @objectstack/cli: NEW unaliased artifact import(s) since this entry was measured: @objectstack/plugin-auth.

So the gate is live, it reads this config, and it responds sharply to a change in the axis it owns — and not at all to the spawn swap. That is the whole content of the correction. Restore leg proved after: git diff HEAD empty for the target and the blob back to f4be6348…, marker count 0.

Which sentences fell under which heading

The PM's clause 2 asked for this distinction to stay visible in the diff, so:

(i) Narrowed — the requirement, option A. The closing claim that swapping the spawns to the built entry "is exactly the source-vs-dist trade scripts/check-test-source-alias.mjs exists to refuse". Replaced by a new section that states what the gate measures, names the in-process/spawned-child boundary with the gate's own words, and points at the plugin-auth entry below as this file's worked example of the distinction (it satisfies the gate while being inert for the child). The old sentence survives as a quotation, tensed — "This file used to close by calling … 'exactly the source-vs-dist trade … exists to refuse'. It is not one" — so the record of what was wrong is not deleted.

(ii) Falsified sentences tensed — clause 2, and not option B. Two further statements in this file were made false by #12459 and are repaired the way PR #12459 repaired its own falsified paragraph (state the count, keep the history in the past tense, name why the new state is safe):

  • the 2026-08-20 cost measurement said "The 20 files that spawn the real CLI as a subprocess (bin/run-dev.js through tsx …) are 56.1% of the file wall" — present tense, no longer true of three of them. Now past-tensed with the date carried ("all 20 of them … on that date"), plus the count that changed and an explicit note that the split has not been re-measured.
  • the per-spawn floor table annotated tsx bin/run-dev.js as "(the source entry these use)" → "(the source entry all 20 used)".

(iii) The one B-shaped sentence, folded in because the paragraph needs it. The PM allowed B's sentence where it reads clearer, and #12459's standard requires naming why the new state is safe: one paragraph records that what makes the four dist-consuming files safe is the @objectstack/cli#testdependsOn: ["build"] declaration (#11268) and each file's own unbuilt-tree refusal — not this gate — and that the residual dist/-behind-source risk is real and stated in those files. This is not a restatement of the #11707 policy debate.

Not touched: every other section of the header, and all four resolve.alias entries and the test.server.deps.external block.

Zero behaviour change, proven rather than asserted

esbuild.transformSync(loader:'ts') strips comments, so an identical emit is proof the change is comment-only. Same esbuild (0.28.2), both trees:

emit before (origin/main): ef9c1bf1b255306065fe081b2ecae28feba4c145fedb622ef9ea34a99e3d599a 2023 bytes
emit after (this branch): ef9c1bf1b255306065fe081b2ecae28feba4c145fedb622ef9ea34a99e3d599a 2023 bytes
IDENTICAL EMIT

git diff -U0 filtered to non-comment lines is likewise empty.

Verification

All of the below on dfa75300a (branch head, origin/mainabc12cb07 merged in), each run under this container's shared verify lock, exit codes captured before any pipe:

  • pnpm check:test-source-alias--self-test OK, then OK — 72 packages with tests scanned; 61 registered as still resolving a workspace dep through dist/; 45 published subpath(s) resolved through every alias table.
  • pnpm check:nul-bytes--self-test: 75 assertions, then OK (scanned 6899 text file(s); no raw ASCII control bytes)
  • pnpm lint (eslint . --no-inline-config, whole repo, not narrowed) — exit 0, zero bytes of output
  • green, exit 0 each: check:cross-package-test-inputs, check:page-declaration-shape, check:published-files, check:slot-lookup, check:type-source-resolution, check-ci-filter-parity.mjs, check-comment-mask-adoption.mjs, check-cross-package-test-inputs.mjs, check-plugin-teardown-shape.mjs, docs-audit/check-affected-docs.mjs, docs-audit/check-drift-comment.mjs

Families re-derived on this head with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no stale-tree warning): 14 local families, of which 13 ran green above.

check:i18n and check:i18n-coverage are NOT MEASURED, not red. Both exit 1 on this worktree solely because packages/cli/dist is unbuilt, and both say so in their own words — "Nothing was checked: no bundle was compared and no config was parsed" / "Nothing was measured: no config was linted and no count was compared." They are recorded as unmeasured rather than bought with a ~7-minute cold closure build, because the identical-emit proof above shows their input did not change: this diff alters no byte that survives compilation. CI builds the CLI and runs both.

No suite run: packages/cli's own suite is ~495s and nothing in it can observe a comment. That the config still parses and resolves is covered by the identical emit plus every gate above that parses packages/**/*.ts.

No changeset — comment text in a test config; nothing published changes. skip-changeset applied.


Generated by Claude Code

…ias measures
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.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Aug 26, 2026 — with Claude
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/cli/vitest.config.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/cli/vitest.config.ts) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 23 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 904c0afe486b9edb0aeb5d07294fffe53e2f9045packageMentionDocs.

@os-litant
os-litant marked this pull request as ready for review August 26, 2026 06:18
@os-litant
os-litant added this pull request to the merge queueAug 26, 2026
Merged via the queue into main with commit 3d8d2f1Aug 26, 2026
40 checks passed
@os-litant
os-litant deleted the claude/issue-12460-vitest-config-cost-header branch August 26, 2026 06:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-litant@claude