From 2d0d546734a4a56e9497be96524529efc504a93a Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 20 Jul 2026 14:06:30 +0000 Subject: [PATCH] fix(cli): stamp quarantined runs with seed epoch Co-Authored-By: Paperclip --- cli/src/__tests__/worktree.test.ts | 8 ++++++++ cli/src/commands/worktree.ts | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/cli/src/__tests__/worktree.test.ts b/cli/src/__tests__/worktree.test.ts index a67dffe5d16..7330ec785cc 100644 --- a/cli/src/__tests__/worktree.test.ts +++ b/cli/src/__tests__/worktree.test.ts @@ -1410,11 +1410,19 @@ describe("worktree helpers", () => { for (const run of quarantinedRuns) { expect(run.status).toBe("cancelled"); expect(run.errorCode).toBe("worktree_seed_quarantine"); + expect(run.seedEpoch).toEqual(expect.any(String)); expect(run.processPid).toBeNull(); expect(run.processGroupId).toBeNull(); expect(run.finishedAt).toBeInstanceOf(Date); } + const [seededSettings] = await db.select().from(instanceSettings); + const seededExperimental = seededSettings?.experimental as Record; + expect(quarantinedRuns.map((run) => run.seedEpoch)).toEqual([ + seededExperimental.worktreeRunExecutionSeedEpoch, + seededExperimental.worktreeRunExecutionSeedEpoch, + ]); + const [succeededRun] = await db.select().from(heartbeatRuns).where(eq(heartbeatRuns.id, succeededRunId)); expect(succeededRun?.status).toBe("succeeded"); expect(succeededRun?.wakeupRequestId).toBe(completedWakeupId); diff --git a/cli/src/commands/worktree.ts b/cli/src/commands/worktree.ts index 5efcea5db2c..529f7be44d0 100644 --- a/cli/src/commands/worktree.ts +++ b/cli/src/commands/worktree.ts @@ -1336,6 +1336,27 @@ export async function quarantineSeededWorktreeExecutionState( try { await db.transaction(async (tx) => { const now = new Date(); + const [settingsRow] = await tx + .select({ id: instanceSettings.id, experimental: instanceSettings.experimental }) + .from(instanceSettings) + .where(eq(instanceSettings.singletonKey, "default")) + .limit(1); + const experimental = isRecord(settingsRow?.experimental) ? settingsRow.experimental : {}; + const existingSeedEpoch = experimental.worktreeRunExecutionSeedEpoch; + const seedEpoch = typeof existingSeedEpoch === "string" && existingSeedEpoch.length > 0 + ? existingSeedEpoch + : randomUUID(); + + if (settingsRow && seedEpoch !== existingSeedEpoch) { + await tx + .update(instanceSettings) + .set({ + experimental: { ...experimental, worktreeRunExecutionSeedEpoch: seedEpoch }, + updatedAt: now, + }) + .where(eq(instanceSettings.id, settingsRow.id)); + } + const pendingWakeups = await tx .select({ id: agentWakeupRequests.id }) .from(agentWakeupRequests) @@ -1354,6 +1375,7 @@ export async function quarantineSeededWorktreeExecutionState( .set({ status: "cancelled", errorCode: WORKTREE_SEED_QUARANTINE_ERROR_CODE, + seedEpoch, processPid: null, processGroupId: null, scheduledRetryAt: null,