You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Parent: #654
Target branch: next
Depends on: #688 merged into next
Blocks: #654 completion, merge of #681 and #680, and start of #657
Outcome
Make the repository’s ordinary complete-suite commands fail whenever Vitest logs a forks-worker startup/handshake failure, even if the forks pool respawns a worker and Vitest later exits zero with a green summary.
The protected prerelease workflow already enforces this at release time through assert-clean-vitest-log.mjs. This issue extends the same evidence standard to normal developer and protected-CI test commands so a green summary cannot conceal the symptom tracked by #654.
vitest.config.ts uses the forks pool with maxWorkers: 4 and no configured test.retry;
one local npm run test:run invocation logged Failed to start forks worker / Timeout waiting for worker to respond for eight files;
the same invocation later counted those files as passed after internal worker respawn;
final result: 182 files, 2,131 tests passed, two skipped, zero assertion failures;
therefore command exit code zero and a green final tally do not prove worker startup was clean;
raw GitHub Actions logs from the dedicated-runner attempts were searched directly and contained zero occurrences, so the dedicated-runner distinction remains valid.
Known signatures:
Failed to start forks worker
Timeout waiting for worker to respond
Scope
1. Inventory the authoritative test entrypoints
Identify every command and workflow that runs the complete unit suite or coverage suite, including:
package.json scripts;
pull-request and push CI;
prerelease validation;
stable release validation;
developer documentation;
any benchmark/release wrapper that assumes a green Vitest summary means a clean run.
Determine which command is the authoritative complete-suite gate.
The repository must end with one clear ordinary command contract rather than release-only enforcement.
2. Design a cross-platform suite runner
Use a Node-based wrapper or equivalent cross-platform mechanism.
The runner must:
spawn the intended Vitest command;
stream stdout and stderr to the terminal in real time;
retain complete output in a temporary log;
preserve the child process exit status and signal;
scan the complete log for known worker-start signatures;
fail when the child fails;
fail when the scanner finds a signature even if the child exits zero;
return zero only when the child succeeds and the log is clean;
report exact signature, count, and matching lines with context;
clean up temporary files on success while retaining or exposing them on failure according to documented policy;
behave consistently on Ubuntu, macOS, and Windows;
forward relevant arguments and termination signals safely.
Do not use Bash-only PIPESTATUS as the ordinary cross-platform implementation.
3. Reuse one scanner contract
Do not create divergent signature lists for local, CI, stable release, and prerelease validation.
Choose and document one source of truth for known absorbed-failure signatures.
Possible directions:
move the existing scanner from .github/scripts/ into a general repository script and update release workflows;
keep the scanner module where it is but expose a stable reusable API and ordinary runner;
another evidence-supported structure with one canonical signature policy.
Do not weaken the prerelease workflow protection already merged through #688.
4. Wire ordinary commands and protected CI
The normal commands used by developers and CI must enforce the scanner.
Prefer preserving familiar public script names:
npm run test:run
npm run test:coverage
Internal raw Vitest scripts may be introduced with explicit names if needed, but users and protected CI must not accidentally call the unguarded form.
Update every protected workflow that should use the authoritative command.
Do not duplicate expensive complete-suite execution merely to scan logs.
5. Diagnostics and artifacts
When protected CI fails:
retain the complete raw log as a bounded diagnostic artifact;
name it with run, attempt, OS, Node version, and suite kind;
print signature counts in the job summary or log;
distinguish ordinary test failure from absorbed worker-start detection;
do not upload secrets, npm credentials, or arbitrary environment dumps.
For local runs, print the temporary log path on failure.
Explicit non-goals
Do not add automatic retries.
Do not make Vitest’s internal respawn behavior count as success.
Do not increase timeouts merely to avoid signatures.
Do not force --maxWorkers=1 globally.
Do not skip or quarantine tests.
Do not change graph, retrieval, context-pack, extraction, watcher, MCP, installer, or product behavior.
Do not claim that this detector alone establishes the root cause of local worker startup starvation.
Required tests
Scanner and wrapper
clean log plus child exit zero → success;
worker-start signature plus child exit zero → failure;
handshake-timeout signature plus child exit zero → failure;
both signatures → failure with both counts;
child exit non-zero and clean log → original failure preserved;
child exit non-zero plus signature → both causes reported;
child terminated by signal → signal-aware failure;
missing/unreadable log → fail closed;
similar unrelated text → no false positive;
output is streamed while retained;
arguments are forwarded safely;
spaces and Unicode in temporary paths;
cleanup/retention behavior;
Windows process invocation and path handling.
Workflow and script policy
npm run test:run uses the guarded runner;
npm run test:coverage uses the guarded runner;
protected CI uses the authoritative guarded commands;
prerelease and stable release validation use the same canonical detector;
no protected workflow invokes the raw unguarded complete suite accidentally;
failure diagnostic artifacts are bounded and named deterministically;
no retries, test skips, or worker reductions are introduced.
Validation
At minimum run:
npm ci
npm run typecheck
npm run build
npm run test:run
npm run test:coverage
npm run verify:pack-parity
npm pack --dry-run
npm run registry:validate
npm run release:verify
Also run deterministic injected probes:
a fake child that prints a green Vitest summary plus a worker-start signature and exits zero;
a fake child that exits non-zero without a signature;
a clean fake child;
signal termination where supported.
Run protected CI across Ubuntu, macOS, and Windows on supported Node 20/22 lines.
For each lane report separately:
job conclusion;
raw worker-start signature count;
raw handshake-timeout signature count;
control sample detection result;
test and coverage exit statuses.
Acceptance criteria
One authoritative ordinary complete-suite contract is documented and used by protected CI.
npm run test:run fails on an absorbed worker-start signature even when Vitest exits zero.
npm run test:coverage has the same behavior.
Child exit codes and signals are preserved accurately.
Full output remains visible and diagnostic logs are retained on failure.
Local and workflow enforcement share one canonical scanner/signature policy.
No unguarded complete-suite path remains in protected workflows.
Cross-platform tests pass on Ubuntu, macOS, and Windows.
No retry, skip, timeout inflation, or global single-worker workaround is introduced.
Exact-head six-lane CI passes with zero raw signature occurrences.
Injected controls prove the detector is active in every supported lane.
No unrelated product or roadmap scope enters the diff.
Rollback
Restore the previous script wiring while retaining the detector and raw evidence for diagnosis. A rollback must not claim that green Vitest summaries prove clean worker startup. If the wrapper itself is defective, repair or replace it before #654 can complete.
Agent handoff
Start from current origin/next after PR #688. Inventory every full-suite invocation before changing scripts. Implement one cross-platform authoritative runner and one canonical signature policy. Return the command graph before/after, injected-control evidence, child-status behavior, files changed, exact protected lanes, raw-log counts, and remaining uncertainty. Stop after this issue.
Parent: #654
Target branch:
nextDepends on: #688 merged into
nextBlocks: #654 completion, merge of #681 and #680, and start of #657
Outcome
Make the repository’s ordinary complete-suite commands fail whenever Vitest logs a forks-worker startup/handshake failure, even if the forks pool respawns a worker and Vitest later exits zero with a green summary.
The protected prerelease workflow already enforces this at release time through
assert-clean-vitest-log.mjs. This issue extends the same evidence standard to normal developer and protected-CI test commands so a green summary cannot conceal the symptom tracked by #654.Confirmed evidence
The #654 investigation established:
vitest.config.tsuses the forks pool withmaxWorkers: 4and no configuredtest.retry;npm run test:runinvocation loggedFailed to start forks worker/Timeout waiting for worker to respondfor eight files;Known signatures:
Scope
1. Inventory the authoritative test entrypoints
Identify every command and workflow that runs the complete unit suite or coverage suite, including:
package.jsonscripts;Determine which command is the authoritative complete-suite gate.
The repository must end with one clear ordinary command contract rather than release-only enforcement.
2. Design a cross-platform suite runner
Use a Node-based wrapper or equivalent cross-platform mechanism.
The runner must:
Do not use Bash-only
PIPESTATUSas the ordinary cross-platform implementation.3. Reuse one scanner contract
Do not create divergent signature lists for local, CI, stable release, and prerelease validation.
Choose and document one source of truth for known absorbed-failure signatures.
Possible directions:
.github/scripts/into a general repository script and update release workflows;Do not weaken the prerelease workflow protection already merged through #688.
4. Wire ordinary commands and protected CI
The normal commands used by developers and CI must enforce the scanner.
Prefer preserving familiar public script names:
Internal raw Vitest scripts may be introduced with explicit names if needed, but users and protected CI must not accidentally call the unguarded form.
Update every protected workflow that should use the authoritative command.
Do not duplicate expensive complete-suite execution merely to scan logs.
5. Diagnostics and artifacts
When protected CI fails:
For local runs, print the temporary log path on failure.
Explicit non-goals
--maxWorkers=1globally.Required tests
Scanner and wrapper
Workflow and script policy
npm run test:runuses the guarded runner;npm run test:coverageuses the guarded runner;Validation
At minimum run:
Also run deterministic injected probes:
Run protected CI across Ubuntu, macOS, and Windows on supported Node 20/22 lines.
For each lane report separately:
Acceptance criteria
npm run test:runfails on an absorbed worker-start signature even when Vitest exits zero.npm run test:coveragehas the same behavior.Rollback
Restore the previous script wiring while retaining the detector and raw evidence for diagnosis. A rollback must not claim that green Vitest summaries prove clean worker startup. If the wrapper itself is defective, repair or replace it before #654 can complete.
Agent handoff
Start from current
origin/nextafter PR #688. Inventory every full-suite invocation before changing scripts. Implement one cross-platform authoritative runner and one canonical signature policy. Return the command graph before/after, injected-control evidence, child-status behavior, files changed, exact protected lanes, raw-log counts, and remaining uncertainty. Stop after this issue.