From 6046f328350027e2e2f37640ad2968f86b5d4e83 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Thu, 20 Aug 2026 20:27:03 -0700 Subject: [PATCH] fix(update): fail closed on unreadable TUI identity --- src/infra/local-tui-processes.test.ts | 16 ++++++++++++++++ src/infra/local-tui-processes.ts | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/infra/local-tui-processes.test.ts b/src/infra/local-tui-processes.test.ts index e347a1edf970..1f72d63607a5 100644 --- a/src/infra/local-tui-processes.test.ts +++ b/src/infra/local-tui-processes.test.ts @@ -134,6 +134,22 @@ describe("local TUI processes", () => { ).resolves.toEqual({ stopped: [], failed: [101] }); }); + it("fails closed when a live process identity can no longer be read", async () => { + const controller = { kill: vi.fn(() => true) }; + let reads = 0; + + await expect( + terminateLocalTuiProcesses({ + processes: [{ pid: 101, command: "openclaw-tui", startTime: "start" }], + controller, + graceMs: 0, + killGraceMs: 0, + readStartTime: () => (++reads === 1 ? "start" : undefined), + }), + ).resolves.toEqual({ stopped: [], failed: [101] }); + expect(controller.kill).not.toHaveBeenCalledWith(101, "SIGKILL"); + }); + it("refuses shared update mutation when a matched client survives", async () => { const processes = [{ pid: 101, command: "openclaw --profile work tui" }]; diff --git a/src/infra/local-tui-processes.ts b/src/infra/local-tui-processes.ts index 7e21691ba04d..d108789e27b1 100644 --- a/src/infra/local-tui-processes.ts +++ b/src/infra/local-tui-processes.ts @@ -182,7 +182,12 @@ export async function terminateLocalTuiProcesses(params: { stopped.push(proc.pid); continue; } - if (!proc.startTime || readStartTime(proc.pid) !== proc.startTime) { + const currentStartTime = readStartTime(proc.pid); + if (!currentStartTime) { + failed.push(proc.pid); + continue; + } + if (currentStartTime !== proc.startTime) { stopped.push(proc.pid); continue; }