From e41f9c09d2a6ffa787ae276bdb9fd9644e4f0028 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sun, 26 Jul 2026 21:58:47 -0700 Subject: [PATCH] test(agent-hooks): pin that leadStopWithLiveSubagents is never persisted The strip in serializeStatusFile was the one part of the gate with no test. Rehydrating the flag would make the notification gate suppress the first real completion after every restart, which is the spam #4375 reports. --- src/main/agent-hooks/server.test.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main/agent-hooks/server.test.ts b/src/main/agent-hooks/server.test.ts index 6b4e12042c5..0c62843d3c2 100644 --- a/src/main/agent-hooks/server.test.ts +++ b/src/main/agent-hooks/server.test.ts @@ -6597,6 +6597,32 @@ describe('Last-status persistence', () => { } }) + it('never persists leadStopWithLiveSubagents, so a restart cannot re-suppress a completion', async () => { + const server = new AgentHookServer() + await server.start({ env: 'production', userDataPath }) + try { + await postHookEvent(server, buildBody({ hook_event_name: 'SessionStart' }), '/hook/codex') + await postHookEvent( + server, + buildBody({ + hook_event_name: 'SubagentStart', + agent_id: '11111111-2222-4333-8444-555555555555', + agent_type: 'explore' + }), + '/hook/codex' + ) + await postHookEvent(server, buildBody({ hook_event_name: 'Stop' }), '/hook/codex') + server.flushStatusPersistSync() + const persisted = JSON.parse(readFileSync(lastStatusPath(), 'utf8')) + // Why: the flag describes one live hook delivery. Rehydrating it would make the + // notification gate suppress the first real completion after every restart (#4375). + expect(persisted.entries[PANE].payload.state).toBe('done') + expect(persisted.entries[PANE].payload).not.toHaveProperty('leadStopWithLiveSubagents') + } finally { + server.stop() + } + }) + it('treats a corrupt file as empty hydration without throwing', async () => { mkdirSync(join(userDataPath, 'agent-hooks'), { recursive: true }) writeFileSync(lastStatusPath(), 'not-json{{', 'utf8')