From d0f4dae35091b862386ed5ee9cf74f86a39d286a Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Fri, 25 Sep 2026 00:28:09 -0700 Subject: [PATCH] fix(native-chat): stop calling a starting chat "mid-handoff" A send refused because the chat's owner is not settled showed "The session is mid-handoff ()." in the composer. With the handoff gone, the stages that reach it are a chat that is still starting, or one whose previous agent process has not yet been confirmed stopped. The message now says which of the two it is. The refusal code is unchanged. Co-Authored-By: Claude --- .../agent-session-mutation-envelope.test.ts | 20 +++++++++++++++++-- src/shared/agent-session-mutation-envelope.ts | 5 ++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/shared/agent-session-mutation-envelope.test.ts b/src/shared/agent-session-mutation-envelope.test.ts index f488e14e31e..e929d628de5 100644 --- a/src/shared/agent-session-mutation-envelope.test.ts +++ b/src/shared/agent-session-mutation-envelope.test.ts @@ -133,7 +133,7 @@ describe('admitAgentSessionMutation', () => { }) }) - it('refuses a writer mid-handoff', () => { + it('refuses a writer while the chat is still starting', () => { const admission = admitAgentSessionMutation({ ...base, lease: { ...LEASE, handoffStage: 'new-owner-proving' }, @@ -141,7 +141,23 @@ describe('admitAgentSessionMutation', () => { }) expect(admission).toMatchObject({ decision: 'refused', - refusal: { code: 'agent_session_conflict' } + refusal: { code: 'agent_session_conflict', message: 'The chat is still starting.' } + }) + }) + + it('names recovery rather than a handoff when a restart left the owner unproven', () => { + const admission = admitAgentSessionMutation({ + ...base, + lease: { ...LEASE, handoffStage: 'recovering' }, + ledger: ADMIT('f'.repeat(64)) + }) + expect(admission).toMatchObject({ + decision: 'refused', + refusal: { + code: 'agent_session_conflict', + message: + "Orca has not yet confirmed that this chat's previous agent process stopped. Reopen the chat to check again." + } }) }) diff --git a/src/shared/agent-session-mutation-envelope.ts b/src/shared/agent-session-mutation-envelope.ts index ea99929c618..97c3d10b0ae 100644 --- a/src/shared/agent-session-mutation-envelope.ts +++ b/src/shared/agent-session-mutation-envelope.ts @@ -146,7 +146,10 @@ function refuseUnlessWriterAdmitted(lease: AgentSessionLease): AgentSessionWireR if (lease.handoffStage !== null) { return { code: 'agent_session_conflict', - message: `The session is mid-handoff (${lease.handoffStage}).` + message: + lease.handoffStage === 'new-owner-proving' + ? 'The chat is still starting.' + : "Orca has not yet confirmed that this chat's previous agent process stopped. Reopen the chat to check again." } } return {