diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-host.test.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-host.test.ts index b980c4e422c..0deaf9d9140 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-host.test.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-host.test.ts @@ -639,6 +639,31 @@ describe('restart', () => { }) }) + it('answers the owner status of a starting chat once its start settles', async () => { + await attach() + await reboot(async () => ({ outcome: 'pid-absent' })) + await host.restoreReadableSessions() + const started = Promise.withResolvers() + const release = Promise.withResolvers() + const settled = acquire.getMockImplementation() + if (!settled) { + throw new Error('missing acquire implementation') + } + acquire.mockImplementationOnce(async (input) => { + started.resolve() + await release.promise + return settled(input) + }) + + const hold = host.hold(SESSION, 'surface-1') + await started.promise + const status = host.handoffStatus(SESSION) + release.resolve() + await hold + + await expect(status).resolves.toMatchObject({ owner: 'native', stage: null }) + }) + it("keeps a session whose owner cannot be probed out of a live writer's hands", async () => { await attach() const held = store.getRecord(SESSION)?.lease.runtimeFence ?? 0 diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts index 8f29c6ec322..ba508b67bcf 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts @@ -271,11 +271,14 @@ export class StructuredAgentSessionHost { async handoffStatus(sessionId: string): Promise { this.requireSession(sessionId) - const record = this.deps.store.getRecord(sessionId) - if (!record) { - throw new Error('agent_session_identity_required') - } - return structuredAgentSessionOwnerStatus(record) + // Queued behind an in-flight attach, so a starting chat answers with its settled owner. + return this.serialize(sessionId, async () => { + const record = this.deps.store.getRecord(sessionId) + if (!record) { + throw new Error('agent_session_identity_required') + } + return structuredAgentSessionOwnerStatus(record) + }) } history: StructuredAgentSessionBackgroundTaskChannel['history'] = (request) =>