Repository navigation
fix(native-chat): list chat statuses after a restart without opening any chat - #26439
Draft
brennanb2025 wants to merge 7 commits into
Draft
brennanb2025 wants to merge 7 commits into
brennanb2025 wants to merge 7 commits into
Conversation
…any chat Each native chat's last status is saved in last-status.json beside the CLI agents' rows, on status and verdict edges only. Startup shows those saved statuses, settles at once only the chats a restart cut mid-turn (with the same verdict the journal's open writes), and lists chat tabs from saved records instead of replaying every listed chat's history.
Startup no longer replays every listed chat, which was what re-drove orchestration mail parked for an idle chat. After the lease check it now also opens the chats the orchestration database's pending-mail scans name, and nothing else, so each one's idle edge points its mail again.
…aved statuses until their chat goes Addresses review findings on the saved native chat statuses. - No age limit on a saved chat status: a chat's record, its tab and its next save bound each entry, so a week-old chat keeps its status and a week-old cut chat is still settled at startup. - A chat a restart cut shows nothing saved; its startup open publishes the verdict its own settle wrote, so the row never shows a different one first. - The agent status store saves what it ingests and compares against what it loaded, so restoring statuses at startup writes nothing. - Only the journal's half of a summary is saved; the record supplies the rest. - One restored-mailbox scan, one filter for the tab list and the restore, and a newer build's entries and files are written back untouched.
Neither is part of this change; restoring them keeps the branch off main's edits.
Contributor
Author
Review summary (head 19c2c43)Verdict at f6c45b2: fix first. The reviewer agreed with the core shape: statuses saved in Findings and fixes
New tests (each fails without its fix)
Ablations27 rules, each broken in turn: all 27 went red. 10 cover these fixes and 17 are the original rules still in force. Two needed their test or patch corrected before they went red for the right reason:
Verification
|
8 of 9 tasks
Re-applies saved native chat statuses onto main's agent status store: chat saves and drops go through the throttled background writer (#26822), the newer-build-file guard moves into the snapshot writer, the sink wiring moves to agent-hook-runtime-deps, and permissionMode joins the record-owned summary fields. host.restoreReadableSessions stays public as on main, so tests that only renamed its call keep main's text; startup reaches the saved-status restore through the host's restore collaborator.
The agent status store kept every saved native chat status raw so an entry a newer build wrote went back to disk untouched. Users never downgrade Orca, so each entry is now parsed on load and a malformed one is dropped; the saved-status reader returns parsed statuses only. The cross-version test that had the last release read this build's file goes with it. The startup test's "Couldn't confirm" case now puts the owner on another host: on main a local owner's runtime is replaced by the restart, which proves the turn interrupted.
One whole-flow restart test: a previous run's agent status store saves the chat's status, the restarted host shows a settled chat's Done, Failed or idle status without opening its history, and settles a chat cut mid-turn to Interrupted (proven death) or Couldn't confirm (owner on another host). The parked-mail restart test and one store test (a chat's save with status hooks off keeps the CLI agents' rows) stay. The unit tests of parsing, the restore helper and the owed-mail scan go, and existing tests keep main's text apart from the renamed restore call.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ELI5
When Orca starts, it used to open and replay the full history of every chat that has a tab, just to learn each chat's status. That made startup slow, and statuses filled in late. Now Orca saves each chat's last status the same way it already saves terminal agents' statuses, and shows the saved status at startup without opening anything. A chat that was mid-reply when Orca quit, crashed or updated reads "Interrupted" (or "Couldn't confirm" when Orca can't prove the agent stopped). It never reads as still working.
What Changed
The problem
orca worktree ps. With many tabs, startup was slow and statuses arrived late.Before and after, for the user
The mechanism
last-status.json) already saves terminal agents' rows. It now also saves each native chat's last status summary, under its ownstructuredSessionskey.orca worktree ps, the power-save blocker and stats all see an idle row, never live work.restoreReadableSessions, which no production code called; tests reach it throughcollaboratorsForTests().Every saved entry has a way to die: its chat's record is deleted, the host lets go of the chat (its tab closed), the chat is unlisted at startup, or its next save replaces it. There is no age limit: a chat untouched for weeks keeps its status, and a cut chat is settled however long Orca was closed.
Decisions
Parked mail
With the startup replay gone, mail parked for an idle chat could strand.
Known gaps
Why
Differences from the common pattern
Linked Issue
Supersedes #23978's listing (included here). Replaces the closed #24233.
Visual Proof
Pending: live QA in the rendered app (sidebar, phone and paired desktop after a restart) is next and will be attached here. The behaviour is covered by the end-to-end tests below in the meantime.
Testing
New tests:
last-status.json): a chat saved as working or waiting nine days ago is settled at startup, and every row it shows carries the settled verdict and the history's prompt, never what was saved.Each rule was ablated, by breaking the line and checking that its test goes red. All 27 ablations went red, including: no age limit, cut chats showing only their settle verdict, no re-save at startup, record-owned fields from the record, one filter for list and restore, keeping a newer build's entries and file, save-on-change, no save per delta, the immediate write, the quit flush, loading with hooks off, no mail on a saved status, live publish replacing the saved one, only cut and mail-owed chats opening, closing unlisted cut chats, listing from records, the parked-mail open, and the old-build file format.
Every test file that directly imports a changed module was run (366 files), plus the cross-version suites one at a time.
src/main/claude/, the qoder real-CLI test, the Codex real-PTY test and the Claude structured-session integration test. CI covers them.Lints: full
oxlint, the changed-code quality gate, native-plugin, anti-slop and type-aware oxlint on all changed files. Typecheck is clean for node, web and cli.AI Disclosure
Review
Agent skill upstream boundary
Notes
Author: @BrennanKB5
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)