From 9471b345e7d720f19234e068f46760bd4b671cee Mon Sep 17 00:00:00 2001 From: Merge Sim Date: Thu, 10 Sep 2026 14:32:10 -0700 Subject: [PATCH] fix(agent-status): preserve unverifiable remote rows --- ...ntime-hook-agent-status-projection.test.ts | 24 +++++++++++++++++++ ...refresh-floating-workspace-pty-liveness.ts | 9 ++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/main/runtime/orca-runtime-hook-agent-status-projection.test.ts b/src/main/runtime/orca-runtime-hook-agent-status-projection.test.ts index 7a11501db38..9fab2267d25 100644 --- a/src/main/runtime/orca-runtime-hook-agent-status-projection.test.ts +++ b/src/main/runtime/orca-runtime-hook-agent-status-projection.test.ts @@ -395,6 +395,30 @@ describe('headless hook agent-status projection (#11761)', () => { statusWiring.statusStore.stop() }) + it('keeps an unverifiable remote row when its disconnected PTY record is pruned', async () => { + const statusWiring = makeAgentStatusStoreWiring() + const runtime = await createRuntimeWithHookRows([], statusWiring) + const internals = runtime as unknown as { + ptysById: Map + dropDisconnectedPtyRecord: (ptyId: string) => void + } + const pty = internals.ptysById.get(PTY_ID)! + pty.connectionId = 'ssh-target' + runtime.onPtyData( + PTY_ID, + '\x1b]9999;{"state":"working","prompt":"remote work","agentType":"claude"}\x07', + 1 + ) + pty.connected = false + + internals.dropDisconnectedPtyRecord(PTY_ID) + + expect(statusWiring.statusStore.getStatusSnapshot()).toEqual([ + expect.objectContaining({ connectionId: 'ssh-target', prompt: 'remote work' }) + ]) + statusWiring.statusStore.stop() + }) + it('evicts a dismissed handle-joined remnant on certified PTY exit', async () => { const statusWiring = makeAgentStatusStoreWiring() const runtime = await createRuntimeWithHookRows([], statusWiring) diff --git a/src/main/runtime/orca-runtime-refresh-floating-workspace-pty-liveness.ts b/src/main/runtime/orca-runtime-refresh-floating-workspace-pty-liveness.ts index da257921f2b..de98831cdd5 100644 --- a/src/main/runtime/orca-runtime-refresh-floating-workspace-pty-liveness.ts +++ b/src/main/runtime/orca-runtime-refresh-floating-workspace-pty-liveness.ts @@ -119,7 +119,14 @@ export class OrcaRuntimeWithRefreshFloatingWorkspacePtyLiveness extends OrcaRunt protected dropDisconnectedPtyRecord(ptyId: string): void { // Why: pruning can remove a PTY without the normal exit callback. - this.reconcileAgentStatusForEndedProcessFn?.(this.collectAgentStatusPaneKeysForPty(ptyId)) + const pty = this.ptysById.get(ptyId) + // Remote disconnect is unverifiable; its host-owned status survives until certified exit. + const processDeathCertified = + pty?.connectionId === null || + this.ptyLivenessVerdictByPtyId.get(ptyId)?.verdict.status === 'exited' + if (processDeathCertified) { + this.reconcileAgentStatusForEndedProcessFn?.(this.collectAgentStatusPaneKeysForPty(ptyId)) + } this.advancePtyLifecycleGeneration(ptyId) this.pairedRendererSessionOwnedPtyIds.delete(ptyId) this.ptysById.delete(ptyId)