From 3ec20bc33f6ec384662c127360175c176da445e1 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Mon, 31 Aug 2026 05:02:08 +0000 Subject: [PATCH] fix: paid shards get per-shard TMPDIR + CHROMIUM_PROFILE isolation and a kill-path cleanup backstop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The free runner treats this isolation as MANDATORY (two concurrent shards on one Chromium profile kill each other's browser; shared tmp cross-contaminates) — the paid lane had none of it. Doubly load-bearing here: a shard that hits its 30-min wall is group-SIGKILLed, so per-test afterAll cleanup never runs; the rmSync backstop is the only thing keeping wedged runs from accumulating full git-repo workspaces in the shared tmpdir forever. This is the DAG prerequisite for raising EVALS_JOBS (next commit) — more concurrency on shared state amplifies exactly the shared-tree race class opus-47 exhibited. Co-Authored-By: Claude Fable 5 --- scripts/test-paid-shards.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/scripts/test-paid-shards.ts b/scripts/test-paid-shards.ts index bcbcf5851..cf488116b 100644 --- a/scripts/test-paid-shards.ts +++ b/scripts/test-paid-shards.ts @@ -499,6 +499,22 @@ export async function runPaidShard( if (!env.GSTACK_CLAUDE_CLI_VERSION) { env.GSTACK_CLAUDE_CLI_VERSION = getClaudeCliVersion(); } + // Per-shard temp + Chromium-profile isolation — the free runner treats + // this as mandatory (test-free-shards.ts: two concurrent shards on one + // profile dir kill each other's browser; shared tmp cross-contaminates), + // and the paid lane had NONE of it. Doubly load-bearing here: when a + // shard hits its 30-min wall the group-SIGKILL means per-test afterAll + // cleanup never runs — the rmSync backstop below is the only thing + // stopping wedged runs from accumulating full git-repo workspaces in the + // shared tmpdir forever. Prerequisite for raising EVALS_JOBS (more + // concurrency on shared state amplifies exactly the opus-47 race class). + const stateDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-paid-shard-')); + const childTmp = path.join(stateDir, 'tmp'); + fs.mkdirSync(childTmp); + env.TMPDIR = childTmp; + env.TEMP = childTmp; + env.TMP = childTmp; + env.CHROMIUM_PROFILE = path.join(stateDir, 'chromium-profile'); const startedAt = Date.now(); log(`${label} START ${files.join(' ')} (timeout ${Math.round(timeoutMs / 1000)}s)`); @@ -553,6 +569,12 @@ export async function runPaidShard( } finally { // Close the spool even when the spawn itself failed. await new Promise((resolve) => logStream.end(() => resolve())); + try { + fs.rmSync(stateDir, { recursive: true, force: true }); + } catch { + // Best-effort: a locked file must not turn a real verdict into an + // exception (same posture as the free runner's cleanup). + } } const summary = classifier.end();