fix(native-chat): revalidate restored and retried owners

This commit is contained in:
Brennan Benson
2026-08-12 18:39:16 -07:00
parent 35fb039187
commit a03beee134
9 changed files with 85 additions and 31 deletions
@@ -159,6 +159,26 @@ describe('admission through the store', () => {
)
})
it('admits proof input for the exact proven live owner during restore', () => {
publish(
agentSessionLeaseFixture({
ownerProcess: {
hostId: 'local',
pid: 4200,
processStartTimeMs: 10,
spawnToken: 'live-proof-token'
},
reservedSpawnToken: 'live-proof-token'
})
)
expect(gate.admitProof(PTY_ID, { sessionId: SESSION_ID, spawnToken: 'live-proof-token' })).toBe(
true
)
expect(gate.admitProof(PTY_ID, { sessionId: SESSION_ID, spawnToken: 'wrong-token' })).toBe(
false
)
})
it('refuses when the record vanished from the store', () => {
const admission = gate.admit(PTY_ID)
expect(admission.admitted).toBe(false)
@@ -73,14 +73,21 @@ export class AgentSessionPtyWriteGate {
admitProof(ptyId: string, authority: { sessionId: string; spawnToken: string }): boolean {
const binding = this.binding(ptyId)
const lease = binding?.record?.lease
const provingReservation =
lease?.claimStatus === 'reserved' &&
lease.handoffStage === 'new-owner-proving' &&
lease.reservedSpawnToken === authority.spawnToken &&
(lease.ownerProcess === null || lease.ownerProcess.spawnToken === authority.spawnToken)
const reprovingLiveOwner =
lease?.claimStatus === 'live' &&
lease.handoffStage === null &&
lease.ownerProcess?.spawnToken === authority.spawnToken &&
lease.provenHandleLinkId !== null
return Boolean(
binding?.sessionId === authority.sessionId &&
binding.record?.sessionId === authority.sessionId &&
lease?.runtimeKind === 'tui' &&
lease.claimStatus === 'reserved' &&
lease.handoffStage === 'new-owner-proving' &&
lease.reservedSpawnToken === authority.spawnToken &&
(lease.ownerProcess === null || lease.ownerProcess.spawnToken === authority.spawnToken) &&
(provingReservation || reprovingLiveOwner) &&
!lease.unreconciled
)
}
@@ -1,6 +1,7 @@
import { describe, expect, it, vi } from 'vitest'
import type { StructuredAgentSessionHandoffTransport } from '../native-chat/agent-session-wire/structured-agent-session-handoff-types'
import { createEphemeralAgentSessionClaimSigner } from './agent-session-claim-identity'
import { agentSessionPtyWriteGate } from './agent-session-pty-write-gate'
import { OrcaRuntimeService } from './orca-runtime'
const {
@@ -157,6 +158,8 @@ describe('structured TUI launch tab binding', () => {
})
expect(resolvePinnedCodexRolloutProof).toHaveBeenCalledWith(namespace.providerRoot, 'thread-1')
expect(writeAgentSessionProof).not.toHaveBeenCalled()
expect(agentSessionPtyWriteGate.boundSessionId('pty-cold-owner')).toBe('session-1')
agentSessionPtyWriteGate.unbindPty('pty-cold-owner')
})
it('proves the published launch tab before returning its revealed renderer binding', async () => {
+1
View File
@@ -9310,6 +9310,7 @@ export class OrcaRuntimeService {
if (!candidate?.tabId || !candidate.paneKey || !handle) {
throw new Error('The owning agent terminal could not be recovered.')
}
agentSessionPtyWriteGate.bindPty(candidate.ptyId, record.sessionId)
const proof = durableOwner
? await this.resolveRecoveredStructuredTuiTranscript({
handle,