From e15c50df4c3df1f9178fd8c487f6760531e23206 Mon Sep 17 00:00:00 2001 From: xlurie <42911814+xlurie@users.noreply.github.com> Date: Fri, 30 Oct 2026 23:13:16 +0200 Subject: [PATCH] fix(server): restart continuation checks before repeating side effects A server restart can cut a turn while a command is still running, and the command can outlive the server (on Windows the provider's child process is orphaned and finishes). "Continue where you left off." gave the resumed agent no hint of that, so it could start a deploy, push or script a second time. The restart continuation prompt now says the last turn was cut short and that a command it started may have finished or still be running, and asks the agent to confirm a state-changing action did not take effect and is not still running before repeating it, or to say so when it cannot tell. Claude Opus 5.5, Claude Code --- .../src/orchestration-v2/RestartContinuation.test.ts | 8 ++++++-- apps/server/src/orchestration-v2/RestartContinuation.ts | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/server/src/orchestration-v2/RestartContinuation.test.ts b/apps/server/src/orchestration-v2/RestartContinuation.test.ts index d2224720b89f1..a318130500b3b 100644 --- a/apps/server/src/orchestration-v2/RestartContinuation.test.ts +++ b/apps/server/src/orchestration-v2/RestartContinuation.test.ts @@ -915,7 +915,9 @@ it.effect("continues a cut run past queued follow-ups, which stay held", () => ...cut, runs: [...cut.runs, queuedFollowUp], } as unknown as OrchestrationV2ThreadProjection); - assert.deepEqual(texts, ["Continue where you left off."]); + assert.deepEqual(texts, [ + "Continue where you left off. Your last turn was cut short, so a command or other action it started may have finished or may still be running. Before you repeat one that changes state, confirm it did not take effect and is not still running; if you cannot tell, say so instead of repeating it.", + ]); }), ); @@ -945,7 +947,9 @@ it.effect("continues a resumed queued run that ran after an earlier continuation ...cut, runs: [...cut.runs, finishedContinuation], } as unknown as OrchestrationV2ThreadProjection); - assert.deepEqual(texts, ["Continue where you left off."]); + assert.deepEqual(texts, [ + "Continue where you left off. Your last turn was cut short, so a command or other action it started may have finished or may still be running. Before you repeat one that changes state, confirm it did not take effect and is not still running; if you cannot tell, say so instead of repeating it.", + ]); }), ); diff --git a/apps/server/src/orchestration-v2/RestartContinuation.ts b/apps/server/src/orchestration-v2/RestartContinuation.ts index e4d7ac2b7f900..8741fb7bc5993 100644 --- a/apps/server/src/orchestration-v2/RestartContinuation.ts +++ b/apps/server/src/orchestration-v2/RestartContinuation.ts @@ -30,7 +30,8 @@ import { restartContinuationNote, } from "./RestartBackgroundNote.ts"; -const CONTINUE_PROMPT = "Continue where you left off."; +const CONTINUE_PROMPT = + "Continue where you left off. Your last turn was cut short, so a command or other action it started may have finished or may still be running. Before you repeat one that changes state, confirm it did not take effect and is not still running; if you cannot tell, say so instead of repeating it."; const MAX_CONTINUATION_CHAIN = 3; const CONTINUATION_LOOP_WINDOW_MS = 5 * 60 * 1_000;