Files
orca/src/main/codex/codex-structured-dispatch-boundary.test.ts
T
Brennan Benson 1aa943798a fix(codex): a Codex Stop is the interrupt alone, so it no longer says "Cancellation was not confirmed" (#23850)
* fix(native-chat): a Codex Stop that ended its turn no longer reads "not confirmed"

Codex answers a turn's interrupt only as that turn ends, then sends the turn's
own end. Orca also required its sweep of the turn's processes to prove them
gone, and when that sweep could not read the process table it wrote
"Cancellation was not confirmed." a few milliseconds before the turn's
interrupted end arrived. A Stop that named its turn said "The provider had
already finished this turn." in the same case.

Codex's answer is now what confirms the Stop. The sweep still runs and still
holds the turn's end until it finishes, but its result is logged, not shown.
A Stop Codex never answers, which is a turn that never ends, still reads
"Cancellation was not confirmed."

* docs(codex): say why an interrupted turn's un-echoed send is withdrawn, for a steer and for a turn's own input

* fix(codex): a Codex Stop is the interrupt alone

A Codex Stop sent turn/interrupt and, alongside it, swept the turn's
processes: it compared a snapshot of the app-server's descendants taken at
each send and compaction against a fresh one and killed what was new, then
waited for those processes to exit. The turn's end was held back until the
sweep finished.

Codex already owns this. It kills a turn's one-shot commands on interrupt
and deliberately keeps unified-exec background terminals running across one,
so the sweep killed work Codex means to keep, read the process table on
every send, and delayed the interrupted end behind a kill-and-wait.

A Stop is now turn/interrupt only. Codex's answer confirms it and the turn's
end publishes the moment it arrives, through the same path as any other
notification. A long-running command started in that turn keeps running
until the thread ends, as it does in Codex itself.

Removed: the turn-process module and its integration test, the snapshot
taken at dispatch and compaction, the held turn/completed, the adapter
dependencies that injected both, and the prompt-claim re-check that only
covered the wait for the snapshot.

* docs(crash-reporting): justify the self-kill ring size by the documented window-close burst
2026-09-29 18:13:18 -07:00

31 lines
1.1 KiB
TypeScript

import { expect, it, vi } from 'vitest'
import { AgentSessionPreDispatchError } from '../native-chat/agent-session-wire/structured-agent-session-operation-settlement'
import {
acquiredCodexAdapter,
CODEX_TEST_USER_MESSAGE,
fakeCodexAppServer
} from './codex-structured-dispatch-test-support'
it('checks continuation authority before writing turn/start', async () => {
const codex = fakeCodexAppServer()
const adapter = await acquiredCodexAdapter({ codex, settlements: [] })
const beforeDispatch = vi.fn(async () => {
throw new AgentSessionPreDispatchError('agent_session_restart_work_superseded')
})
try {
await expect(
adapter.dispatch({
sessionId: 'session-1',
clientMessageId: 'continuation',
body: CODEX_TEST_USER_MESSAGE,
fence: 7,
beforeDispatch
})
).rejects.toBeInstanceOf(AgentSessionPreDispatchError)
expect(beforeDispatch).toHaveBeenCalledOnce()
expect(codex.connections[0]?.calls.some((call) => call.method === 'turn/start')).toBe(false)
} finally {
await adapter.closeAll()
}
})