Files
orca/src/shared/structured-agent-session-send-evidence.test.ts
T
Neil 0d74111ee8 test(remote-runtime): pin the 12 hand-kept error-code lists to their callers' policy (#30246)
Each list that decides delivered / undelivered / recoverable / definitive by code now has a
test naming its codes, the message fragments it relies on, and nearby codes it must not
treat the same. Includes the #30146 shape: a client-minted runtime_manually_disconnected
keeps a user's close for replay. Tests only; no production change.
2026-10-18 00:24:34 -07:00

160 lines
5.4 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import type { AgentJournalSubmission } from './agent-session-journal-types'
import type { AgentSessionWireRefusal } from './agent-session-wire'
import {
structuredAgentSessionSendEvidence,
type StructuredAgentSessionSendAnswer
} from './structured-agent-session-send-evidence'
function refused(code: string, reason?: string): StructuredAgentSessionSendAnswer {
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: test fixture names codes from the wire list.
const refusal = {
code,
message: code,
...(reason ? { details: { reason } } : {})
} as AgentSessionWireRefusal
return { kind: 'result', result: { ok: false, refusal } }
}
const recorded: StructuredAgentSessionSendAnswer = {
kind: 'result',
result: {
ok: true,
replayed: false,
fence: 1,
cursor: { epoch: 'e', sequence: 1 },
value: { clientMessageId: 'm', queued: { messageId: 'm', position: 0, state: 'waiting' } }
}
}
function withRow(fields: Partial<AgentJournalSubmission>): StructuredAgentSessionSendAnswer {
return {
kind: 'result',
result: {
ok: true,
replayed: false,
fence: 1,
cursor: { epoch: 'e', sequence: 1 },
value: {
clientMessageId: 'm',
submission: {
clientMessageId: 'm',
fence: 1,
payloadFingerprint: 'fp',
dispatchState: 'accepted',
providerItemId: null,
reason: null,
submittedAt: 1,
resolvedAt: 1,
...fields
}
}
}
}
}
function thrown(rpcCode: string | undefined): StructuredAgentSessionSendAnswer {
return { kind: 'thrown', error: new Error(rpcCode ?? 'socket closed'), rpcCode }
}
describe('structuredAgentSessionSendEvidence', () => {
it('reads any ok answer as the host holding the message', () => {
expect(structuredAgentSessionSendEvidence(recorded).kind).toBe('recorded')
})
it('reads a row the host returns, in any state, as its own from then on', () => {
for (const dispatchState of ['pending', 'accepted', 'rejected', 'unknown'] as const) {
expect(structuredAgentSessionSendEvidence(withRow({ dispatchState })).kind).toBe('recorded')
}
// A restart lost its outcome, or a queued card's hand-off: a record, never a probe.
const rows: Partial<AgentJournalSubmission>[] = [
{ dispatchState: 'unknown', recovered: true, reason: 'host_restarted' },
{ dispatchState: 'rejected', clientMessageId: 'other', queuedMessageId: 'm' },
{ dispatchState: 'rejected', keptAsQueuedMessageId: 'm' }
]
for (const row of rows) {
expect(structuredAgentSessionSendEvidence(withRow(row)).kind).toBe('recorded')
}
})
it('reads a made-up row for an id the host journal lost as unconfirmed, not recorded', () => {
expect(
structuredAgentSessionSendEvidence(
withRow({
dispatchState: 'unknown',
reason: 'durable_send_submission_missing',
recovered: true
})
).kind
).toBe('uncertain')
})
it('reads no thrown error as proof: a timeout, a closed socket or a thrown refusal', () => {
for (const rpcCode of [
'runtime_timeout',
'remote_runtime_unavailable',
'runtime_unavailable',
undefined
]) {
expect(structuredAgentSessionSendEvidence(thrown(rpcCode)).kind).toBe('uncertain')
}
for (const rpcCode of [
'runtime_manually_disconnected',
'runtime_rpc_queue_overloaded',
'remote_runtime_busy',
'forbidden',
'capability_unsupported'
]) {
expect(structuredAgentSessionSendEvidence(thrown(rpcCode)).kind).toBe('uncertain')
}
const thrownRefusal = {
response: { error: { data: { refusal: { code: 'agent_session_journal_unreadable' } } } }
}
expect(
structuredAgentSessionSendEvidence({
kind: 'thrown',
error: thrownRefusal,
rpcCode: 'invalid_argument'
}).kind
).toBe('uncertain')
})
// Pins the full turned-away list (round-2 S5): every other code, client-minted ones included, is uncertain.
it('treats a call the host turned away before running it as never written', () => {
for (const rpcCode of [
'method_not_found',
'method_not_supported',
'invalid_argument',
'unauthorized'
]) {
expect(structuredAgentSessionSendEvidence(thrown(rpcCode)).kind).toBe('not-recorded')
}
})
it('reads an unknown outcome or a lost result as unconfirmed, and an unconfirmed rewind as not sent', () => {
for (const reason of ['outcomeUnknown', 'resultLost']) {
expect(
structuredAgentSessionSendEvidence(refused('agent_session_operation_unknown', reason)).kind
).toBe('uncertain')
}
expect(
structuredAgentSessionSendEvidence(
refused('agent_session_operation_unknown', 'rewindUnconfirmed')
).kind
).toBe('not-recorded')
})
// The one request is the only one that carried the id, so a refusal of it proves nothing ran.
it('reads any other refusal as never written', () => {
for (const answer of [
refused('agent_session_ownership_unknown', 'sessionNotAttached'),
refused('agent_session_conflict'),
refused('agent_session_operation_capacity'),
refused('agent_session_journal_unreadable'),
refused('agent_session_operation_expired', 'operationExpired')
]) {
expect(structuredAgentSessionSendEvidence(answer).kind).toBe('not-recorded')
}
})
})