diff --git a/src/main/codex/codex-structured-prompt-ownership.ts b/src/main/codex/codex-structured-prompt-ownership.ts index ff42a105fc6..69c9556bade 100644 --- a/src/main/codex/codex-structured-prompt-ownership.ts +++ b/src/main/codex/codex-structured-prompt-ownership.ts @@ -21,8 +21,9 @@ function providerTurnId(session: CodexSession, turnId: string): string | undefin return session.translator ? session.translator.commandProviderTurnId(turnId) : turnId } -/** How long a Stop waits for Codex to open the turn it answered a send into. Under the quit - * path's eviction budget, which a close or quit queued behind the Stop spends. */ +/** How long a Stop waits for Codex to open the turn it answered a send into. A close or quit queued + * behind the Stop spends this out of the eviction budget, so a full wait plus a slow provider + * close can overrun it; the next launch's recovery then settles the lease. */ export const CODEX_STOP_TURN_OPEN_WAIT_MS = 5_000 /** diff --git a/src/main/codex/codex-structured-turn-open-wait.ts b/src/main/codex/codex-structured-turn-open-wait.ts index 63e37294005..1e303a58fba 100644 --- a/src/main/codex/codex-structured-turn-open-wait.ts +++ b/src/main/codex/codex-structured-turn-open-wait.ts @@ -34,6 +34,8 @@ export function createCodexTurnOpenWaits(): CodexTurnOpenWaits { resolve() } const bound = setTimeout(endWait, withinMs) + // A Stop's wait must never be what keeps the process alive at quit. + bound.unref?.() waits.set(endWait, turnId) }), observe: (threadId, method, params) => {