diff --git a/src/gateway/live-agent-probes.test.ts b/src/gateway/live-agent-probes.test.ts index 0471bee5f6a..56669ea39a5 100644 --- a/src/gateway/live-agent-probes.test.ts +++ b/src/gateway/live-agent-probes.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import { assertCronJobMatches, assertLiveImageProbeReply, @@ -73,6 +73,22 @@ describe("live-agent-probes", () => { expect(args.job?.sessionKey).toBe("agent:codex:acp:test"); }); + it("builds a cron probe spec when the process clock is outside the Date range", () => { + const dateNowSpy = vi.spyOn(Date, "now").mockReturnValue(8_640_000_000_000_001); + + try { + const spec = createLiveCronProbeSpec(); + const args = JSON.parse(spec.argsJson) as { + job?: { schedule?: { at?: string } }; + }; + + expect(spec.at).toBe("1970-01-01T00:00:00.000Z"); + expect(args.job?.schedule?.at).toBe("1970-01-01T00:00:00.000Z"); + } finally { + dateNowSpy.mockRestore(); + } + }); + it("validates cron cli job shape for the shared live probe", () => { expect( assertCronJobMatches({ diff --git a/src/gateway/live-agent-probes.ts b/src/gateway/live-agent-probes.ts index 550beba933e..ad63ee94d3d 100644 --- a/src/gateway/live-agent-probes.ts +++ b/src/gateway/live-agent-probes.ts @@ -1,9 +1,14 @@ import { execFile } from "node:child_process"; import { randomBytes } from "node:crypto"; import { promisify } from "node:util"; +import { + resolveExpiresAtMsFromDurationSeconds, + resolveTimestampMsToIsoString, +} from "../shared/number-coercion.js"; import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; const execFileAsync = promisify(execFile); +const LIVE_CRON_PROBE_DELAY_SECONDS = 7 * 24 * 60 * 60; type CronListCliResult = { jobs?: Array<{ @@ -64,7 +69,9 @@ export function createLiveCronProbeSpec( const normalizedNonce = normalizeOptionalLowercaseString(nonce) ?? ""; const name = `live-mcp-${normalizedNonce}`; const message = `probe-${normalizedNonce}`; - const at = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(); + const at = resolveTimestampMsToIsoString( + resolveExpiresAtMsFromDurationSeconds(LIVE_CRON_PROBE_DELAY_SECONDS) ?? Date.now(), + ); const argsJson = JSON.stringify({ action: "add", job: {