fix: claude CLI version resolves in the runner parent, never on a test thread

Eng-review finding: getClaudeCliVersion's fallback is a SYNCHRONOUS
spawnSync on the same thread that polls concurrent PTY/session tests — the
judgePtyState blocking class this overhaul kills elsewhere. The paid runner
parent now resolves it once (cached) and stamps GSTACK_CLAUDE_CLI_VERSION
into every shard's env; eval-store short-circuits on the env var, and the
fallback spawn's budget tightens 10s -> 3s (bounded one-time stall, records
'unknown' on a slow CLI).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-31 04:34:57 +00:00
co-authored by Claude Fable 5
parent cfcc9ecc6f
commit 31bb69f9b4
2 changed files with 20 additions and 2 deletions
+7 -1
View File
@@ -64,7 +64,7 @@ import {
} from './test-strict-output';
import { PAID_TEST_GLOBS, isPaidTestFile } from '../test/helpers/paid-test-set';
import { PERIODIC_CI_EXCLUDE } from '../test/helpers/periodic-exclude-data';
import { getProjectEvalDir } from '../test/helpers/eval-store';
import { getProjectEvalDir, getClaudeCliVersion } from '../test/helpers/eval-store';
import { preflightAnthropicApi } from '../test/helpers/anthropic-preflight';
import {
detectBaseBranch,
@@ -493,6 +493,12 @@ export async function runPaidShard(
if (options.evalDirBase) {
env.GSTACK_EVAL_DIR = path.join(options.evalDirBase, 'shards', shardSlug(files));
}
// Resolve `claude --version` ONCE in the parent (cached across shards) and
// hand it to every child: eval-store's fallback is a synchronous spawn on
// the same thread that polls PTY sessions, so children must never pay it.
if (!env.GSTACK_CLAUDE_CLI_VERSION) {
env.GSTACK_CLAUDE_CLI_VERSION = getClaudeCliVersion();
}
const startedAt = Date.now();
log(`${label} START ${files.join(' ')} (timeout ${Math.round(timeoutMs / 1000)}s)`);