From aaf5af2fbc87abcf9a2bbaa07fba64b0bac0e7e1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 9 Jul 2026 15:43:59 +0100 Subject: [PATCH] fix(agents): clamp zero bash job TTLs (#102855) Co-authored-by: 0668000787 --- src/agents/bash-process-registry.test.ts | 29 ++++++++++++++++++++++++ src/agents/bash-process-registry.ts | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/agents/bash-process-registry.test.ts b/src/agents/bash-process-registry.test.ts index 25974067789..2f2352a16b5 100644 --- a/src/agents/bash-process-registry.test.ts +++ b/src/agents/bash-process-registry.test.ts @@ -14,6 +14,7 @@ import { markBackgrounded, markExited, resetProcessRegistryForTests, + setJobTtlMs, tail, } from "./bash-process-registry.js"; import { createProcessSessionFixture } from "./bash-process-registry.test-helpers.js"; @@ -171,6 +172,34 @@ describe("bash process registry", () => { }, ]); }); + + it("clamps a zero retention TTL to one minute", () => { + vi.useFakeTimers(); + try { + vi.setSystemTime(new Date("2026-07-09T00:00:00Z")); + setJobTtlMs(0); + + const session = createRegistrySession({ + id: "zero-ttl", + maxOutputChars: 100, + pendingMaxOutputChars: 30_000, + backgrounded: true, + }); + addSession(session); + markExited(session, 0, null, "completed"); + + vi.advanceTimersByTime(30_000); + expect(listFinishedSessions()).toHaveLength(1); + + vi.advanceTimersByTime(60_000); + expect(listFinishedSessions()).toHaveLength(0); + } finally { + resetProcessRegistryForTests(); + setJobTtlMs(30 * 60 * 1000); + resetProcessRegistryForTests(); + vi.useRealTimers(); + } + }); }); describe("cursorKeyMode", () => { diff --git a/src/agents/bash-process-registry.ts b/src/agents/bash-process-registry.ts index ca7a0ac3618..3ed078d3138 100644 --- a/src/agents/bash-process-registry.ts +++ b/src/agents/bash-process-registry.ts @@ -17,7 +17,7 @@ const MAX_JOB_TTL_MS = 3 * 60 * 60 * 1000; // 3 hours const DEFAULT_PENDING_OUTPUT_CHARS = 30_000; function clampTtl(value: number | undefined) { - if (!value || Number.isNaN(value)) { + if (value === undefined || Number.isNaN(value)) { return DEFAULT_JOB_TTL_MS; } return Math.min(Math.max(value, MIN_JOB_TTL_MS), MAX_JOB_TTL_MS);