fix: report the real cause when check-env.cjs's npm-version check fails

Discovered blocking this PR's own Windows CI (unrelated to this PR's
actual diff, fixed inline per this repo's no-defer policy): PR #4552's
"full test (windows-latest, 24, shard 2/3)" job failed
tests/check-env.test.cjs's npm-version subtest with "npm binary not
found on PATH" under chunk 5/9's heavy load (51 concurrent files,
5+ minutes). Root-caused via the CI log: the check's spawnSync call
used a 10s timeout, and every failure mode -- ENOENT, a signal-killed
timeout, a non-zero exit, a thrown spawn error -- collapsed into that
one message (only `res.status === 0 && res.stdout` was checked), so a
genuine npm.cmd cold-start timeout under contention was indistinguishable
from npm actually being absent.

Extracted the reason-selection into describeNpmVersionCheckFailure, a
pure function in the new scripts/lib/npm-version-check-diagnosis.cjs
(kept out of check-env.cjs itself, which runs its CLI unconditionally
on require with no `require.main === module` guard, so the pure logic
can be unit-tested without triggering a real environment check).
Reports ENOENT, signal-kill, non-zero-exit, and thrown-error cases
distinctly. Does NOT raise the 10s timeout itself -- a slow subprocess
under contention is a cost to reduce, not a tolerance to widen.

Also fixed a stale tsconfig.build.tsbuildinfo incremental-build cache
discovered while verifying this change: npm run build:lib was silently
omitting gsd-core/bin/lib/markdown-table.cjs (a real, needed compiled
module -- src/state-document.cts requires it), which only surfaced via
npm run lint:generated-sync's gen-health-docs check failing with
Cannot find module. Deleting the cache and rebuilding fresh restored
it; docs/INVENTORY-MANIFEST.json needed no net change once the build
was genuinely complete.

Manually verified describeNpmVersionCheckFailure's five branches
directly (ENOENT, signal-kill, non-zero exit, thrown error, defensive
default) before wiring the test file, since this repo blocks local
node --test. Re-ran node scripts/check-env.cjs directly to confirm the
real success path is unaffected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sim
2026-09-09 00:27:32 -04:00
parent ba25e3989d
commit 0aeafc6425
5 changed files with 116 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
---
type: Security
pr: 0
pr: 4552
---
**Pinned the transitive `hono` dependency to `>=4.13.5`** — fixes a moderate-severity path-traversal/DoS advisory chain (GHSA-gqvv-2mrq-wpjv, GHSA-g6gw-c38x-mqfc, GHSA-crvj-82cr-hjcx) in `hono <4.13.5`, pulled in transitively via `@anthropic-ai/claude-agent-sdk` -> `@modelcontextprotocol/sdk`. Discovered blocking `tests/npm-integrity-gate.test.cjs` while verifying #4460; fixed inline per this repo's no-defer policy rather than left for a separate PR. (#4460)

View File

@@ -0,0 +1,5 @@
---
type: Fixed
pr: 4552
---
**`npm run check:env`'s npm-version check no longer misreports a timeout as a missing binary** — every `spawnSync` failure mode (ENOENT, a signal-killed timeout under load, a non-zero exit, a thrown spawn error) used to collapse into one message, "npm binary not found on PATH." Discovered live: an unrelated PR's Windows CI shard failed this check under heavy concurrent test load, and the message made a real timeout indistinguishable from npm genuinely being absent. The reason is now reported accurately; the check's own 10s timeout is unchanged. (#4460)