Repository navigation
Description
`test (windows-latest)` in `.github/workflows/test.yml` never finishes. `npm test` starts and is still running an hour later. The job has no `timeout-minutes` (smoke has 15; this one inherits the 6h Actions default), so a hang just sits there and blocks the matrix.
macOS `npm test` on the same commits is ~4 minutes.
Evidence
All three current Windows-matrix runs are stuck on the Run npm test step. Logs are not downloadable until the job ends (`BlobNotFound`).
| run | started npm test | still going at |
|---|---|---|
| 32117186703 Windows hardening | 08:36:35Z | 60+ min |
| 32121422998 #473 branch | 09:25:07Z | 12+ min and counting |
| 32121797100 main after #473 | 09:29:18Z | 8+ min and counting |
This is the first time `npm test` has been asked to run on `windows-latest` (Windows job added with #449 / hardening). It has never completed.
What `npm test` is on win32
`test:core && test:renderer && test:electron && test:memory`.
- renderer has `--test-timeout=20000`.
- `scripts/test-electron.js` on win32 runs a subset (WSL/doctor/fake-bin + several adapter files via `writeFakeBin`). It does not pass `--test-timeout`.
- Those adapter tests spawn `.cmd` fakes through `claude.js` `detached: true`. Some fakes intentionally never exit (`setInterval(() => {}, 10000)` in `writeSlowClaude` in `session-record.test.js` / `memory-record.test.js`). Cleanup is `runner.stopAll()` → `killTree` → `process.kill(-pid)` which `proc.js` already documents as falling back on Windows.
If stop does not reap the node grandchild behind the `.cmd`, the `node --test` process keeps an open stdio handle and never exits. That matches an infinite `npm test` with no failing assertion.
Same class of hole as #480 (Windows smoke pass C never sees Claude fake stdout). This one is worse for CI: the job does not fail, it just occupies a runner.
Fix bar
- Put `timeout-minutes: 20` (or similar) on the `test` job so a hang is a red X, not a 6-hour checkout.
- Pass `--test-timeout` in `scripts/test-electron.js` so a single wedged `waitFor` cannot hold the process.
- Prove `stopAll` / `killTree` actually kills a `writeFakeBin` `.cmd` → node grandchild on win32 (the slow-claude `setInterval` fake is the fixture).
- Do not "fix" this by dropping the Windows test job. The job exists so a dead win32 path cannot go silent.
Related: #480 (smoke pass C), #442 / #449 (Windows dispatch + CI job), #143 (Stop must kill the tree).
Activity
currentbits commentedon Oct 9, 2026
Fixed: test.yml sets
timeout-minutes: 25, and recent main runs pass on all OS jobs. Closing in the 2026-10-09 board cleanup (#1532).