Skip to content

Record Stop immediately and settle subagents from exit proof - #28051

Open
brennanb2025 wants to merge 269 commits into
mainfrom
brennanb2025/agent-start-split-5-stop-workload
Open

brennanb2025 wants to merge 269 commits into
mainfrom
brennanb2025/agent-start-split-5-stop-workload

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 52 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​935 $\color{#cf222e}{\Huge{\mathbf{−}}}$​10885 $\color{#cf222e}{\Huge{\mathbf{−}}}$​9950
Prod 28 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​543 $\color{#cf222e}{\Huge{\mathbf{−}}}$​163 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​380

ELI5

Pressing Stop in a Codex chat could interrupt the reply while leaving its background server and commands running. A Stop accepted before the first reply could also be missing from the transcript, and child tasks could read stopped before Orca knew their work had exited.

Stop now ends the agent runtime for every chat agent. The conversation records the accepted request once, and the next message resumes the same conversation. A started turn stopped by the user reads Interrupted; a send withdrawn before startup retains its existing Stopped manually result beside the request. Child tasks read stopped only when the execution host has proved that both their root process and its workload exited.

What Changed

Codex first receives an interrupt. It gets up to five seconds from the Stop request to settle, then Orca closes its background server and cleans up its owned descendants using process IDs and start times. A later proven exit can settle an earlier unconfirmed close. Chat Stop and workspace Sleep both count a proven runtime root exit as stopped. Child-task outcomes have the stronger requirement: both root and workload must be proved exited. Unavailable descendant evidence leaves those outcomes unconfirmed without blocking runtime-level Sleep or a new send.

The transcript writes Cancellation requested. when Stop is accepted, including when an accepted send is still starting or has not echoed its turn yet. It stays beside that message's stopped result and is deduplicated across repeated Stop requests. Stopping a startup with no queued message adds no request row. Question and approval cards keep their current Cancel behavior. Failure to save the request row is logged and cannot prevent the Stop.

Why

An accepted Stop is user intent; an exited process is an observed fact. Keeping those separate gives immediate feedback without claiming unfinished background work has stopped. Reusing the host's existing child-work records preserves completed child outcomes and avoids a second status store.

Differences from the common pattern

  • Intended — every chat Stop ends the agent runtime. This is the agreed behavior across Orca's agents; the next send resumes the conversation.
  • Intended — five-second Codex wind-down. The budget starts at the Stop request, so a delayed interrupt does not restart the waiting period.
  • Intended — the execution host proves root and workload exit separately. Orca supports local, SSH and paired clients. A missing reply or lost connection remains unverifiable and cannot finish a child task.
  • Intended — an accepted send stopped before startup keeps request and result feedback. The request has a stable identity before the agent echoes a turn. Starting with no queued send produces no request row.

Linked Issue

Continues the Stop work tracked in #26561. The startup changes from #28046 and the Claude resumed-message repair from #30982 are already on main and included here.

Visual Proof

Real main-versus-branch Electron QA on M4Air compared main fece03b5ac4749a50f24f7ad5a148e1f0154a4c8 with head 70c552fe35f0abe6658f88b800d3cb201ba3bfa4, carrying the same isolated saved conversations through a restart and upgrade. Codex and Claude each produced two real replies after upgrade, then stopped through the UI with physical root and workload exit proof, then produced two further replies in the same native thread. Their latest turn stayed Interrupted beyond sixty seconds. Expanded turn details showed exactly one accepted request for each observed Stop. Final child cancellation also proved root and both workloads exited before the child read stopped; its completed sibling remained completed.

Screenshots and the detailed coverage limits are in the existing review status comment. The native Windows process contract passed on this head with the same saved conversation and identical 180-second workload: actual Stop ended the four observed original processes, recorded one request, and allowed a real same-thread reply. Main’s root and workload remained alive about 8.6 seconds after Stop. Independent Windows handles proved the final physical exits; normal-flow hook delivery remains unproven and an internal process-tree proof warning is retained. This short qualification does not cover every descendant or waive the full QA gaps. Overall QA remains BLOCKED. Pi native admission is blocked by the version-probe defect tracked in #30393; the installed CLI writes its version to standard error while admission reads only standard output. OpenCode ACP failed during native startup in this isolated rig; another lane ran the same version successfully, so its working provider recipe will be reused. No ACP Stop ran here. Starting Sleep was not exercised: no Send occurred before its bounded observer expired. Paired web connected to the correct isolated host, but its native chat was unavailable even through Agent Session History; native phone coverage is separate and unexercised. Repeated accepted Stop remains targeted live QA. Empty acquisition, unavailable card/scoped routes, child outcome retention and hook POST transport are verified by named automated tests listed in the review comment. The hook tests invoke generated scripts with controlled input; normal native-send hook delivery was not observed and is not claimed. Actual CLI native launch and a real reply passed; disabled search and unsupported native terminal routes remain gaps.

Testing

  • Complete real QA of every changed agent and consumer on the final head
  • Automated tests added or updated

Head 70c552fe35f0 passed 100 targeted tests across ten files. The tests cover accepted choices with missing readback, delayed interrupt, late response, opening-turn retry, legacy queued withdrawal, startup with and without an accepted send, runtime exit receipts and Sleep. Seventeen bounded source-module scenarios also passed; those traces do not replace real-agent QA. All seven exact-head workflows passed, including the full PR Checks workflow, its required aggregate and Windows load tests.

The earlier Windows setup block remains historical. The lane owner authorized a fresh QA budget, which produced the M4Air results above. The separate short native Windows process qualification passed within the stated bounds; the lane owner accepts that observed flow as passing, with the process-tree proof warning retained as a known limit. Hook transport is verified by controlled tests, with live native-send delivery unobserved. Both fresh QA rigs are cleaned and their tickets released. Overall readiness remains blocked by required agents and consumer coverage.

Review

Full review, cumulative round 2: independent runtime and host/surface reviewers verified the fixes and found no new proven behavioral defect. The architecture ruling retained host termination and separate runtime/child proof, with no new persisted state. The full graceful sequence uses one original deadline, and an empty startup produces no cancellation request row. Separate readiness and performance source scans found no new proven defect. The complete final mechanism comparison passed on this head. An inherited refusal when clearing effort to an unknown configured default is owned separately under STA-11443/STA-11451; this PR does not label it intended.

Current head includes pinned main fece03b5ac47; GitHub reports merge conflicts and brennan-ready --force --pr 28051 reports NOT READY for conflicts and the absent completion marker. Per the lane dependency ruling, the next main refresh waits for #30393 to merge, then requires new-head CI and targeted real Pi startup/Stop/resume, native phone Codex Stop, repeated Stop, starting Sleep/wake, Codex sanity and OpenCode ACP Stop/resume with the proven recipe. No completion marker or ready-to-merge claim is valid yet.

Agent skill upstream boundary

  • Not applicable; no upstream skill-installer source is copied or translated.

Notes

Process actions and exit evidence stay on the execution host. Folder workspaces and independently updated peers retain their existing routes. No new saved field or wire operation is introduced.

Checklist

  • Problem, user-facing change, mechanism and approach explained
  • Full review and readiness checks completed
  • Complete all required main-versus-branch comparisons (available screenshots are consolidated in the review comment)
  • Full workflow green on pinned head 70c552f
  • Dependency main refresh, conflict resolution and new-head checks completed

Main's rewind recovery now cuts the chat history from the journal; the read step outside the
session's serialize takes the journal to find that cut, and the apply step refuses evidence
read for a different cut. The saved-pick display keeps main's refused-model exception.
…ests

A model the Claude CLI retired is reported again, so the picker shows what the child runs and the
next send moves the chat off it. The start reads a rewind in doubt against the handle it answered
with, the record its commit then applies to. Main's tests follow the start's open: the admission
fixture holds a real turn, and a sign-in close during setup fails the open.
…ity, held-send revert

Sleep (#28445) closes a workspace's chats through the same abort a close gives a
registered start, re-aborts a start registered while it waited for the lane, and
judges its receipt once the start it aborted has settled, so only a newer start
reads as later work. Each adapter's owned-acquisition check covers the child it
owns between acquire and open. Main's Sleep cases from the deleted surface
lifetime suite move to the workspace Sleep suite, plus one for a starting agent.

Codex (#30406): the split open sends the chat's command env overrides when it
opens the thread; the adapter test keeps that assertion on the open's request.

Revert of #30134 (#30572): the event sink, exit observation, Pi held-send wrapper
and adapter heldSends overrides go with it; Pi dispatch submits through its
turns again and its idle report is wired back.
A start runs outside the chat's lane, so Sleep's step can run before the start it aborted has
settled; it then re-reads the chat once that start is done, instead of reporting it unverified.
@brennanb2025
brennanb2025 changed the base branch from brennanb2025/agent-start-split-2-codex-start to main October 19, 2026 17:54
Brings the agent-start branch's final tip into the Stop change: starts register before any await, Stop/close/quit abort a registered start, and serialize steps are pure fenced commits. The Stop's note writes keep the start-abort wiring and write at the fence a Stop-caused child end moved.
Main now carries #28046's startup design (squash-merged), so its hunks match the previous merge; this adds main's newer changes. Conflicts took the Stop branch's side, since main's text in each conflicted file equals the startup branch tip already reconciled.

Tests whose premise the Stop change moved: a Codex Stop now ends the app server, so the replayed-Stop race resumes the saved thread on a new child; a Stop before startup now records its request beside the taken-back send's stopped result. The background-task test regains the tracker import its proof cases use.
The two #29905 cases lived in the turns test this branch removed. They pin that a listed Stop never ends a helper lifetime it did not capture: a same-id restart during acceptance, or a refused helper that appears mid Stop-all, which must not close the agent.
@brennanb2025
brennanb2025 marked this pull request as ready for review October 19, 2026 18:18
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5f8f50e2-67b2-40b0-8469-698d295477c6
📥 Commits

Reviewing files that changed from the base of the PR and between 96885e1 and 70c552f.

📒 Files selected for processing: 3
  • src/main/acp/acp-structured-session-adapter.ts
  • src/main/codex/codex-structured-session-adapter.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter.ts
🚧 Files skipped from review as they are similar to previous changes: 1
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

📝 Walkthrough

Chat Stop now follows a shared child-ending rule and records cancellation-request notes across additional outcomes. Claude and Codex cancellation operations use Stop timestamps to bound interruption work. Codex shutdown now exposes root and workload close observations, which session cleanup uses when ending child-work evidence. The diff also adds and revises tests, removes numerous existing test suites, and updates runtime test inclusion and routing lists.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 70c55

The change’s Stop and shutdown behavior is supported by the inspected contracts, with no concrete merge-blocking risk identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 59.26% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 54 functions across 62 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the primary changes: immediate Stop recording and subagent settlement based on exit proof.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description is complete and directly addresses the change, rationale, linked issue, visual proof, testing, review status, scope, and checklist. It clearly records known QA gaps, merge conflicts, a…
Full details: Description check

Explanation

The description is complete and directly addresses the change, rationale, linked issue, visual proof, testing, review status, scope, and checklist. It clearly records known QA gaps, merge conflicts, and blocked readiness. The Linked Issue section uses issue reference #26561 rather than an explicit URL, but the required issue information is present.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments: 1
src/main/codex/codex-app-server-teardown.integration.test.ts: 1

147-155: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Require the detached grandchild to be reaped on supported POSIX runs.

The suite excludes Windows, and the fixture keeps the provider root alive while close() captures the process tree. The current else branch accepts an unproven result without checking the grandchild. A reaper regression can therefore pass while the grandchild remains alive. Require the exited-tree result and the grandchild's absence.

♻️ Suggested tightening
       const rootExited = await connection.close()
       expect(rootExited).toBe(true)
-      if (connection.closeResult?.tree === 'exited') {
-        await vi.waitFor(() => expect(processExists(pids.grandchild)).toBe(false))
-        expect(connection.closeResult).toMatchObject({ root: 'exited', tree: 'exited' })
-      } else {
-        expect(connection.closeResult?.tree).not.toBe('exited')
-        expect(connection.processTreeUnproven).toBe(true)
-      }
+      expect(connection.closeResult).toMatchObject({ root: 'exited', tree: 'exited' })
+      await vi.waitFor(() => expect(processExists(pids.grandchild)).toBe(false))
+      expect(connection.processTreeUnproven).toBe(false)

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b63f489d-9884-4676-85d2-cd7769633edf
📥 Commits

Reviewing files that changed from the base of the PR and between 846cba6 and 2eef2de.

📒 Files selected for processing: 77
  • config/scripts/vitest-sqlite-runtime-files.mjs
  • src/main/acp/acp-structured-host-lifecycle.test.ts
  • src/main/acp/acp-structured-host-start-aborts.test.ts
  • src/main/acp/acp-structured-session-adapter.ts
  • src/main/agent-hooks/server/server-status-application.ts
  • src/main/agent-hooks/server/server-status-update.ts
  • src/main/claude/claude-close-turn-end.test.ts
  • src/main/claude/claude-scripted-child.test-fixture.ts
  • src/main/claude/claude-structured-prompt-ownership.ts
  • src/main/claude/claude-structured-session-adapter.ts
  • src/main/codex/codex-app-server-connection-tree-unproven.test.ts
  • src/main/codex/codex-app-server-connection-types.ts
  • src/main/codex/codex-app-server-connection.test.ts
  • src/main/codex/codex-app-server-connection.ts
  • src/main/codex/codex-app-server-teardown.integration.test.ts
  • src/main/codex/codex-background-task-tracker.ts
  • src/main/codex/codex-child-work-evidence.test.ts
  • src/main/codex/codex-child-work-evidence.ts
  • src/main/codex/codex-request-end-wait.ts
  • src/main/codex/codex-structured-session-adapter.ts
  • src/main/codex/codex-structured-session-background-tasks.test.ts
  • src/main/codex/codex-structured-session-close.test.ts
  • src/main/codex/codex-structured-session-close.ts
  • src/main/codex/codex-structured-session-teardown.ts
  • src/main/codex/codex-structured-turn-cancellation.ts
  • src/main/daemon/pty-subprocess-spawn-file-foreground.test.ts
  • src/main/daemon/terminal-host-process-inspection.test.ts
  • src/main/github/github-remote-identity-parsing.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-router.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-router.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-stop.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-chat-stop.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-child-close.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-hung-start-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-codex-stop-note-end.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-codex-stop-row.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-conversation-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-create.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-listed-stop-lifetime.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-prompt-cancel.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-card-holds.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-message-rig-provider.test-fixture.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-pause-lift.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-stop-row.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-repeated-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-startup-attempt-host.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-steer-while-stopping.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-event-binding.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-event-entries.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-event-restart.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-event.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-note-opened-turn.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-note-withdrawn-send.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-receipts.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-settle-binding.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-wind-down.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stopped-history.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stopping.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-turn-stop-notes.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-turns-cancel.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-turns.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-unnamed-stop-races.test.ts
  • src/main/native-chat/agent-session-wire/structured-conversation-compaction.test.ts
  • src/main/pi/rpc-session-adapter.ts
  • src/main/providers/local-pty-child-process-verdict.test.ts
  • src/main/providers/local-pty-provider-foreground-process.test.ts
  • src/main/runtime/structured-agent-session-codex-compact-exit.test.ts
  • src/main/runtime/structured-agent-session-codex-interrupt-order.test.ts
  • src/main/runtime/structured-agent-session-codex-scripted-child.test.ts
  • src/main/runtime/structured-agent-session-codex-stopped-send-order.test.ts
  • src/main/runtime/structured-agent-session-codex-turn-end-settlement.test.ts
  • src/main/runtime/structured-agent-session-integration.test.ts
  • src/main/runtime/structured-foreground-command-strip.test.ts
  • src/renderer/src/components/terminal-pane/remote-pane-layout-push.ts
  • tests/e2e/cross-version-wire/cross-version-stop-note-test-rig.ts
💤 Files with no reviewable changes: 22
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-router.test.ts
  • src/main/codex/codex-structured-session-close.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host.test.ts
  • src/main/codex/codex-app-server-connection.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-event-entries.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-event-restart.test.ts
  • src/main/pi/rpc-session-adapter.ts
  • src/main/native-chat/agent-session-wire/structured-conversation-compaction.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-settle-binding.test.ts
  • src/main/claude/claude-structured-session-adapter.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-steer-while-stopping.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-turns.test.ts
  • src/main/codex/codex-child-work-evidence.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-event-binding.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-stop-row.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-card-holds.test.ts
  • src/main/runtime/structured-foreground-command-strip.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stopping.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-create.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-conversation-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-codex-stop-row.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-codex-stop-note-end.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.

Comment thread config/scripts/vitest-sqlite-runtime-files.mjs Outdated
@brennanb2025

brennanb2025 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

Pressing Stop could leave Codex and its commands running, omit feedback before the first reply, or mark child work stopped before its exit was known. This change records the accepted request immediately, ends the chat runtime, and resumes the same conversation on the next send. Started turns read Interrupted. A send withdrawn before startup keeps Stopped manually beside Cancellation requested. A child is marked stopped only with proof that both its runtime and workload exited.

Review rounds remain at 2. Current head 7cda070d0ade0109acb6333c5b2d64b2b81b8a51 adds only the repeated-Stop host contract test to reviewed production head bfa6885149f69b1f7f2cbc69546c573b3d1ee3bd. Required OpenCode QA remains incomplete, so this PR is not ready to merge. There are no open review P0/P1 findings. Prior production-head QA remains applicable because this commit changes no production code. The full new-head workflow has passed: 37 successful checks and 13 intentional skips, with no failed or pending checks. The PR is out of draft; the 21:23Z exact-head snapshot is MERGEABLE/CLEAN. The review repaired the shared interrupt deadline and the empty-startup request row. No production changes or additional review rounds were made during takeover.

Verified on the unchanged production code:

Flow Observed result
Codex and Pi desktop Stop/resume (ticket 1294) Main ed13ca1 created the saved conversations; a real shutdown and upgrade kept the same profile. Each agent produced two real replies, accepted one Stop/request, retained Interrupted across navigation, and produced a real reply after resuming the same native conversation. Recorded original roots and workloads exited.
Claude desktop Stop/resume (ticket 1392) Two real replies with explicit Opus/High; normal Stop wrote one request, Interrupted remained for over 60 seconds and across navigation, and the same native conversation produced a real resumed reply. Recorded original root/runtime and workload identities exited. The first missed-Stop attempt naturally finished and receives no cancellation credit.
Sleep during actual startup, then wake/send (ticket 1392) A real Send acquired an owner in starting phase. The normal sidebar Sleep control was invoked immediately after a starting-phase read; the original root exited, and wake/send produced a real reply in the same native thread. The earlier empty-tab attempt is excluded. The screenshot shows the post-Sleep effect; the timestamped feed supplies the startup evidence.
Installed native phone Stop/resume (ticket 1392) The installed 0.0.58/build 1 client loaded the exact-head host bundle, paired normally, stopped a live Codex workload, wrote one request and retained Interrupted over 60 seconds. A phone Send then produced a real reply in the same native conversation. Recorded original root/runtime/workload identities exited. This covers a mixed-version native shell and final host/JavaScript, not a newly compiled native binary.

First common observed exit samples after Stop acceptance were within 351ms for Codex, 1,304ms for Pi, 1,000ms for Claude and 2,720ms for the phone's Codex run. These are bounds from actual samples of recorded identities, not exact latency or proof about unobserved descendants. Pi's retained status was observed after 166 seconds; its provider-close-after-exit warning remains disclosed. The phone transcript retains the provider's earlier claim that its command was running; physical process observations establish that the original command exited.

Repeated-Stop qualification uses real phone QA plus an automated host contract. In ticket1491 a genuine installed-phone Stop interrupted a live Codex workload; the original recorded runtime/workload identities exited, and one next desktop Send produced the real reply QA28051-codex1491-resumed. in the same native thread. The second desktop action timed out before clicking and receives no repeated-action credit. No native interrupt entry persisted in the buffered trace, so its real invocation count is unavailable, not zero.

The new test sends two distinct Stop operation IDs while the same turn is working/stopping through the shipping host and actual Codex adapter with a fixture transport. It requires exactly one turn/interrupt, one request row, one Interrupted turn and a completed next send with a translated fixture reply. All eight tests in structured-agent-session-unnamed-stop-races.test.ts pass through the named-test queue. This proves the host/adapter contract; it does not measure a real native call count. The lane owner's accepted qualification is this contract test plus genuine phone Stop/Interrupted/real resumed reply, with no waiver or additional timing attempt.

OpenCode ACP Stop/resume remains unqualified and prevents readiness. Ticket1392 produced a real first reply but no cancellation. Ticket1465's workload failed with a quota error before a command ran, with a saved-model/native-model mismatch recorded separately. Ticket1491 selected the currently answering opencode-go/claude-haiku-5-5 through the chat picker; the same QA home's standalone CLI answered successfully, but both actual saved-chat ACP readiness sends were refused before a new native turn. Neither Stop nor resume ran. The retained native logs and Orca NDJSON trace do not expose the precise refusal; generic providerRejected is insufficient to attribute it to this PR or main. No default-effort, provider-setup or startup-race cause is established. The lane owner approved one same-profile main→PR comparison with existing diagnostic logging increased; ticket 1558 is queued. Stop/resume will run only if both builds first answer the same normal readiness prompt.

The 197-file ticket 1294 archive, 277-file ticket 1392 archive, 49-file ticket 1465 archive and all 80 payload files in ticket 1491 were independently hash-verified and audited. The accepted exact-head automated runs passed 78 named tests with five platform skips, then all 26 tests in the two existing child reconciliation/producer files. Internal edge cases are covered by tests/traces only: empty acquisition (writes no request for an empty unpublished acquisition and completed-history reinitialization), unavailable-card/scoped routes (interrupts the turn holding the card for a provider that gives no answer, stale-card dismissal and child-only interruption), child settlement (settles every child still live when the provider session ends, and keeps them all), and per-send hook payloads (delivers all eight events exactly once from a Unicode profile through %s and the UTF-8 curl-script case). Generated-script/synthetic hook payload tests do not prove real native-send delivery; two mapped Windows hook cases skipped on Mac. The accepted Windows ticket 1119 remains historical evidence; no new Windows run is claimed.

The inherited Claude unknown-default effort reset remains separately owned under STA-11451, outside this Stop change and not intended. Explicit Opus/High exercised Claude here without encountering that reset. Intended differences from the common pattern remain runtime-ending Stop, the shared five-second Codex graceful allowance, execution-host identity/exit proof, and retained request/result feedback. Deleted transport-test coverage and the redundant historical-helper test remain deferred maintenance concerns. Disappearance of command records after partial cleanup is not proof of exit.

QA setup limits are preserved: the initial driver used a prohibited clipboard route for a nonsecret draft and was stopped; that draft receives no qualification credit. A fresh normal qa-drive invocation performed the qualifying phone actions through local Orca. Both driver invocations ended without completing the whole plan. Current recorded QA identities exited, allocated ports were empty and the owned simulator shut down before ticket release. Older unrecorded inherited helpers were left untouched; this is not an exhaustive all-profile-processes cleanup claim.

The earlier ticket 1465 failure also exposed two known issues outside this Stop change: both clients displayed saved MiniMax while native execution recorded Flint, and the error displayed raw provider text and a subscription URL. The lane owner is handling the model display/recovery follow-up after #31208 and the separate failure-message issue. Neither is intended behavior or attributed to this PR; no contrary causal evidence was found.

The earlier ticket 1465 narrow retry used normal qa-drive with a passing Codex preflight and both actual clients on the unchanged final host. It made exactly one workload Send, no second Send or deliberate model substitution, and no Stop action. There were zero new host cancellation receipts or request items. Original OpenCode process exits during rig cleanup do not qualify cancellation. All recorded original identities exited, ports 9460–9479 were clear and the owned simulator was Shutdown before ticket 1465 was released. The two old inherited helpers remained untouched. Existing accepted flows were not replayed. The new archive confirms the isolated environment paths but excludes full launch arguments and private before/after real-config hash records; independent isolation certification is limited to what was included.

For Brennan's review

These are the actual main-to-final Codex/Pi screenshots. Visible status/replies and the separate process proofs establish different parts of the result.

Flow Main Final
Codex Stop Main Codex after the accepted Stop Final Codex Interrupted
Pi Stop Main Pi Interrupted Final Pi Interrupted

Final Codex real resumed reply

Final Pi real resumed reply

Additional final-head screenshots follow. Matching main cancellation screenshots are unavailable for these continuation flows; no new main comparison is claimed.

Flow Stop/Sleep result Real reply after resume/wake
Claude Claude Interrupted after the corrected Stop Claude same-conversation resumed reply
Actual-starting Sleep Workspace after normal Sleep; startup phase established separately Real same-thread reply after wake
Native phone Native phone Interrupted after Stop Native phone real same-conversation resumed reply

The following images document the two gaps, not passing qualification:

OpenCode: first reply only; Stop/resume missing Repeated Stop attempt: one Stop only
Intended OpenCode first reply; no Stop exercised Single accepted Stop; no second action delivered

The earlier ticket 1465 retry failed before either Stop action. These are the actual desktop and installed native client showing the same provider failure; they are not cancellation proof.

Ticket 1465 desktop Ticket 1465 native phone
OpenCode workload failed before Stop on desktop Same OpenCode provider failure in installed native client

Ticket 1491 evidence transfer is complete: archive size 5,002,740 bytes, SHA-256 28b9e1e7dea01bf09ebc9bfc1a612688cd0c0041a8bc7ed16ad8692afd6c9098; its manifest and all 80 payload files match. The genuine phone Stop reached Interrupted, and the next desktop Send produced the actual same-thread reply shown below. The first common exit sample for the original recorded identities was within 1,196ms of Stop acceptance; this is a sample bound, not exact latency or proof about unobserved descendants. All 32 recorded original rig identities were observed exited, allocated ports were clear and the owned simulator was Shutdown. The transfer terminal was closed and ticket 1491 released. The exact OpenCode refusal remains unavailable after the additional NDJSON audit. No completion marker is posted while OpenCode remains unqualified.

Ticket 1491 genuine phone Stop Same-thread real resumed reply
Codex Interrupted after the genuine phone Stop Actual same-thread Codex resumed reply

Ticket 1491 OpenCode readiness refusal; no Stop or resume exercised

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant