Skip to content

docs(devx): make the vitest worker-cap citation two-way - #12566

Merged
os-litant merged 1 commit into
mainfrom
claude/issue-12529-worker-cap-citation
Aug 26, 2026
Merged

docs(devx): make the vitest worker-cap citation two-way#12566
os-litant merged 1 commit into
mainfrom
claude/issue-12529-worker-cap-citation

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#12529

Comment text only, in two files. No executable byte changes: every added and removed
line in the diff is comment text, checked mechanically rather than by eye
(git diff -U0 | grep -E '^[+-]' | grep -vE '^(\+\+\+|---)' | grep -vE '^[+-]\s*(//|\*|/\*\*)'
returns nothing). No maxWorkers / pool / poolOptions block was added anywhere, the cap
script's arithmetic is untouched, and .github/workflows/**, package.json and turbo.json
are not in the diff.

The defect, and why it was worse than an omission

packages/cli/vitest.config.ts's maxWorkers bullet closed with:

"Worker allocation is a property of the shard, decided in ci.yml, not of this config (#10149)."

.github/workflows/ci.yml:575 is pnpm turbo run test $FILTERS --concurrency=4 --summarize --log-order=stream — the flag that bullet paraphrases, and it is correct. Five lines
above it, in the same run: block and under a six-line comment explaining it,
.github/workflows/ci.yml:570 is:

export VITEST_MAX_WORKERS="$(node scripts/vitest-worker-cap.mjs)"

So since #11958 the bullet did not merely omit vitest's inner-pool cap. It sent the reader to
the exact place that cap lives and told them what they would find there, so a reader who
followed the citation walked past line 570 on the authority of line 215. Meanwhile
scripts/vitest-worker-cap.mjs's own header names packages/cli as the repo's single mention
of pool sizing — the newer document pointing back at the older one, with nobody re-reading the
older one to check that it still held.

Both ci.yml:570 and :575 were re-verified on this branch's base (52a982388) before
anything was written; both still read as above.

What changed

packages/cli/vitest.config.ts — the bullet

The outer claim is left intact. --concurrency=4 is right, and turbo's outer fan-out
really is a property of the shard; only the scope word moved, to: That OUTER fan-out — how
many package test tasks run at once — is a property of the shard, decided in ci.yml
.
Rewriting the true half would have been a regression dressed as a fix.

Three paragraphs follow it: the inner pool and where its bound comes from, why the old
phrasing was durable, and one measured consequence for anyone who still wants the lever.

The cap's call sites are deliberately not enumerated there. There are five —
package.json:13, ci.yml:570, ci.yml:1150, rerun-safety-nightly.yml:98 and :128,
re-derived here with git grep -n VITEST_MAX_WORKERS — and a list of call sites inside a
package config is the next thing to rot, which is the whole defect this PR repairs. The
comment states the mechanism and cites the script, which is single-source and carries its own
reasoning.

scripts/vitest-worker-cap.mjs — the census sentence

Its number only. The sentence is not hedged, weakened or made symmetric: apart from its count
it is accurate, and the new pointer travels in one direction (the CLI comment gains one).

Numbers re-derived here, not adopted

claimin the filemeasured on 52a982388
vitest.config.ts files in the repo4142
of those, mentioning pool sizing11packages/cli/vitest.config.ts, still a COMMENT

Two independent methods agree on 42 (git ls-tree -r --name-only HEAD and git ls-files,
both filtered on the exact basename), and the filter was reverse-checked against a term known
present in the same population rather than a substring of the term under test.

The qualitative half of the script's premise still holds, so this is a drift and not a
flip. A deliberately wider sweep than the one that produced the count
(maxWorkers|minWorkers|poolOptions|singleThread|singleFork|maxThreads|minThreads|maxForks|minForks|fileParallelism|pool|isolate)
finds only two other hits in the whole population, and neither is pool sizing:
packages/qa/dogfood/vitest.config.ts sets isolate: false, which governs module-registry
reuse per file and not how many workers exist, and
packages/services/service-datasource/vitest.config.ts uses the word "pool" in prose about a
database connection pool. So the cap is still the only inner bound.

The rot is also dated rather than assumed: 40/41 was written at d18bc3277
(2026-08-25 13:57Z) and was correct then — the population was 41 at that commit — and
packages/services/service-automation/vitest.config.ts landed at 15249270f
(2026-08-25 17:22Z), three hours later. The repaired sentence therefore carries the commit it
was counted on, and states the pair exactly once in that file, which is what its own header
(lines 35–39 / 72–80 of the sibling file) asks the next writer for.

One addition beyond the card's literal surface, flagged for review

The last of the three new paragraphs records something the card did not ask for, and it is
easy to strike if unwanted. Vitest applies VITEST_MAX_WORKERS to the resolved config, so
the exported cap overwrites a declared maxWorkers rather than being bounded by it — which
means a pin added to this file would read as taken and do nothing in exactly the runs that
matter. It is included because without it the repaired bullet leaves the opposite impression,
that a local pin would compose with the cap.

Observed on vitest 4.1.10 with a positive control, not read off the source: a real
vitest.config.ts declaring test: { maxWorkers: 8 } resolves to 8 with the variable unset
and to 2 under VITEST_MAX_WORKERS=2. The control leg is what makes the second reading mean
"the env var won" instead of "the declaration was ignored generally".

Verification

Gate families derived from the real change set with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed — the
script takes the change set from the merge base itself), which matched 20 families. All 20
were run, plus check:nul-bytes.

The union below was run after the final commit, on HEAD adb0979dd with 0 uncommitted
paths (the runner prints its own git rev-parse --short HEAD), through
scripts/pm/os-verify-lock.sh, which ended VERDICT command-exit 0 · held the lock 163s.
Exit codes were captured before any pipe. 21 of 21 exit 0, and the verdict lines quoted
below are the gates' own, not a bare $?:

check:nul-bytes exit=0 check-nul-bytes: OK (scanned 6925 text file(s) …
no raw ASCII control bytes).
check:test-source-alias exit=0 OK — 72 packages with tests scanned; 61 registered …
check:cross-package-test-inputs exit=0 OK: 20 package(s) read outside themselves, all declared …
check:i18n exit=0 OK (9 package(s) — all bundles in sync …).
check:i18n-coverage exit=0 OK (12 config(s), 602 baselined untranslated string(s),
none new).
check:slot-lookup exit=0 ratchet holds: 107 unswept site(s) in 25 file(s),
none new … baseline key set verified against 52a9823.
check:agent-test-spelling exit=0 check:cli-command-ids exit=0
check:bash32-floor exit=0 check:entry-guard exit=0
check:page-declaration-shape exit=0 check:parse-guard exit=0
check:pnpm-filter-targets exit=0 check:published-files exit=0
check:type-source-resolution exit=0 check-ci-filter-parity exit=0
check-comment-mask-adoption exit=0 check-cross-package-test-inputs exit=0
check-plugin-teardown-shape exit=0 docs-audit-affected-docs exit=0
docs-audit-drift-comment exit=0

No narrowing was claimed anywhere. Repo-wide pnpm lint (eslint . --no-inline-config,
the whole tree, not the touched files) was run on the same commit and exits 0 with no
findings.

⚠️ Two of those greens are worth naming, because their first run was neither green nor
red. check:i18n and check:i18n-coverage initially exited 1 in about a second each, with
PREREQUISITE NOT MET — the workspace CLI is not built and then COULD NOT MEASURE — 1 of 12 config(s) failed to lint. Both gates say in their own output that nothing was checked, so
those runs are not measurements and are not reported as passes. They are green above only
after turbo run build (71/71 tasks, exit 0) made them able to run at all — the second one
had to surface and clear two separate unbuilt packages before all 12 configs linted.

Changeset — skip-changeset, and the rule it was measured against

Measured rather than assumed. pr-automation.yml's changeset-check job counts
.changeset/*.md files added against the merge base with no path filter, so every PR
needs either a changeset or the skip-changeset label; and lint.yml's own note on the label
prescribes it for a PR that "releases nothing".

This PR releases nothing, and that is a property of the files rather than a judgement:
@objectstack/cli publishes ["dist","README.md","CHANGELOG.md"], so
packages/cli/vitest.config.ts ships to no consumer, and scripts/vitest-worker-cap.mjs is
repo-root tooling that belongs to no package. Both edits are comment text, so no published
byte moves either way. ⇒ skip-changeset.


Generated by Claude Code

`packages/cli/vitest.config.ts`'s maxWorkers bullet ended by saying worker
allocation is "decided in `ci.yml`", naming only turbo's outer --concurrency.
Since #11958 vitest's inner pool is bounded too, by a host-sized cap computed
in `scripts/vitest-worker-cap.mjs`. The export sits five lines above the turbo
flag in the same ci.yml run: block, so the bullet sent readers to the exact
place the cap lives and told them what they would find — the one-way citation
the cap script's own header depends on.
The bullet's outer claim is left intact; only its scope word is repaired. The
cap script's census is corrected from 40/41 to 41/42 and now carries the commit
it was counted on.
Comment text only in both files; no executable byte changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd
@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 dd4fc6c9d8f29b822e64a254b8943f66edbfc467packageMentionDocs.

@os-litantos-litant added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 26, 2026 — with Claude
@os-litant
os-litant marked this pull request as ready for review August 26, 2026 11:21
@os-litant
os-litant added this pull request to the merge queueAug 26, 2026
Merged via the queue into main with commit fbb1b9dAug 26, 2026
37 checks passed
@os-litant
os-litant deleted the claude/issue-12529-worker-cap-citation branch August 26, 2026 11:50
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-litant@claude