Repository navigation
feat(agents): ask to resume claude and codex turns stopped by reload or quit - #1235
Conversation
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Review findings from my AI agent at f9c3ea0: one P2 and two optional P3 improvements, detailed inline. The P2 scenario concerns multiple communities with different connection states; it was established by static tracing, not live reproduction. TypeScript passed, but the test runs did not establish a clean full-package pass. Browser validation was blocked before launch by a Keychain-dependent startup path; no browser scenarios ran.
salman1993
left a comment
There was a problem hiding this comment.
🤖 Reviewed f9c3ea0 on Salman’s behalf, limited to significant behavior issues. One recovery-decision bug is detailed inline; I have not duplicated the existing findings.
Validation: 322 existing focused service, notice and Claude/Codex runtime tests passed in a temporary source snapshot. Two additional clock-controlled service cases reproduce the finding, both before answering the notice and after choosing Don’t resume. Native Cmd-R/Quit and visual acceptance were not exercised.
Goose scope: Goose remains excluded from interrupted-turn recovery. It also stops with the page, but its conversation/session mappings currently live only in memory, so supporting it requires more than setting resumes: true.
f9c3ea0 to
eadd3a2
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/accessibility) reviews.
One P2 correctness finding is inline: resumed mentions need chronological delivery. Source assessment: 8.5/10; resolving that ordering defect is the concrete path to the repository’s 9/10 bar. The earlier per-agent consent and replay-suppression findings are addressed in this revision. The documented decisions on retry backoff and deleted-agent cleanup are preserved.
Minor description correction: the “Not covered” bullet says a deleted agent’s saved entry remains until Don’t resume is chosen. Deleted agents are absent from the notice, and the action now only covers named agents, so that entry actually remains without a dismissal path. Please align the sentence with the limitation already explained in the author’s reply; this does not request a cleanup behavior change.
Reviewed head: 2b7bb99
Target base: bc921c5
Feature merge-base: 724ae9c
Validation: immutable source and callers reviewed; diff whitespace check passed. Public PR description and commit messages inspected; no attached images or disclosure finding. No tests, builds, app launches or CI assessment performed in this source-only review, and the ordering scenario was not reproduced at runtime. Native acceptance documented in the PR predates this head’s consent/replay changes. Both themes, narrow/wide widths, enlarged text and keyboard F6/Tab/action/focus-return coverage remain unverified here; please name completed keyboard checks or list them as deferred. Automated counts in the description were not independently verified. This COMMENT is not an approval or merge-readiness claim.
|
🤖 [P2] Another app copy can erase a live turn’s recovery record At When one copy is executing a mention, a second copy sharing storage but denied the agent’s claim still shows its interruption notice. Choosing Don’t resume erases the working copy’s recovery marker; reloading the holder then offers no recovery, despite no provider completion. Separate programs holding different agents can also overwrite each other’s entries. Reproduced with shared-store service probes and the actual frontend/production broker in Chromium and WebKit. Browser claims, providers and upstream were modeled; two native processes were not exercised. Use per-agent persistence keys following |
|
🤖 Addressed in 38b2688. Another app copy can erase a live turn's recovery record (P2)
Description notes from the Star Lord review
|
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (lifecycle/storage/performance), Mantis (correctness/security/concurrency), and Groot (product/accessibility) reviews.
One new P2 is inline: refresh the interrupted-turn snapshot when agent ownership changes. Source assessment: 8.5/10; fixing that recovery-notice defect is the concrete path to the repository’s 9/10 bar.
The prior chronological-delivery finding is addressed: resumed mentions now sort oldest first, with deterministic ID ties and a newest-first regression fixture. The per-agent persistence and non-holder preservation changes address the shared-storage concern in source. This follow-up checks those fixes and their introduced behavior; the previously declined retry/backoff and deleted-entry cleanup changes remain outside scope.
Reviewed head: 38b2688
Target base: bc921c5
Feature merge-base: 724ae9c
Follow-up comparison: 2b7bb99 → reviewed head.
Validation: immutable source, callers and regression-test source reviewed; follow-up diff whitespace check passed. Public PR description and follow-up commit material inspected; no attached images or disclosure finding. No tests, builds, app launches, performance measurements or CI assessment were performed, and the ownership scenario was not reproduced at runtime. The description correctly identifies current-head native acceptance, two-process behavior, themes/widths/enlarged text, and F6/Tab/action/focus-return checks as deferred. Shared ToastNotice/Button ownership is preserved; live error/retry focus remains unverified. This COMMENT is not an approval or merge-readiness claim.
Cmd-R and Quit kill every process the page started, so a Claude or Codex turn in flight died with it. Now the runner saves each mention turn of a type that `resumes` in localStorage while it works. On the next start Agents lists those agents as `interrupted` and a toast asks the owner to Resume or not; nothing restarts unless they choose to. Resume reads each mention again from the relay and gives it to `run` marked `resumed`, which Claude and Codex turn into a note to carry on in the saved session. A turn stays saved until its resumed turn settles or is dropped, so closing again first loses none, and a failed read is retried. The host no longer sends a process's exit to a page that reloaded. That page could still run until it unloaded, take the SIGTERM (143) for a failed turn, post "I couldn't finish that", and forget the turn. Co-authored-by: murderbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
read() merges this device's outbox into the result as copies, and a copy has no event proof. the owner's mention sent from the same desktop is still in the outbox after a reload, so resumeTurns dropped it at hasEventProof and forgot the turn. readRemote returns only the verified relay answer. Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kalvin Chau <kalvin@block.xyz>
a saved mention could still run as an ordinary turn: a replay or live delivery of it before the owner answered, or after don't resume, went through heard() without the resumed flag. heard() now drops mentions the page started with saved, so only resumeTurns gives them. resume and don't resume applied to every saved agent, including ones whose community was down and so missing from the notice. both now take the notice's agents; the rest wait for their own prompt. Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kalvin Chau <kalvin@block.xyz>
each agent's saved turns now live in their own key (buzz.agents.interrupted.v1:<pubkey>), and a runner writes only the agent it changed. one shared blob let a program overwrite another's agents from its startup snapshot. only the copy that holds an agent lists it in the notice and may forget its turns, and losing custody no longer forgets a resumed turn, so a non-holder can no longer erase the holder's recovery record. resumed mentions are queued oldest first. the relay answers newest first, which put an earlier request after its correction. Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kalvin Chau <kalvin@block.xyz>
the notice lists an agent only while this copy holds it, but claim and release change that asynchronously without rebuilding the snapshot. a copy that took an agent over on a tick offered no resume until some unrelated update. claim and release now tell the service when holding an agent with saved turns changes. Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kalvin Chau <kalvin@block.xyz>
38b2688 to
6a54927
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/accessibility) reviews.
No new actionable findings in this follow-up. Source assessment: 9/10. The prior custody-refresh P2 is addressed: claim completion (including its error path) and release notify the service when holding an agent with saved turns changes; the service recomputes the interrupted list. The new controlled-clock regression covers takeover on a later tick without an unrelated refresh. The four earlier feature patches are unchanged by the rebase, as checked with range-diff. Accepted retry/backoff and deleted-agent limitations remain unchanged.
Reviewed head: 6a54927
Target base: abdc0e4
Follow-up: custody-refresh fix after previously reviewed 38b2688.
Validation: immutable source, callers and regression-test source reviewed; diff whitespace check passed. Public PR description and follow-up commit inspected; no attached images or disclosure finding. One hosted-check snapshot showed CI required successful, with Windows native validation and browser flake checks skipped. We ran no tests, builds, apps or performance measurements. Current-head native two-process takeover, reload/quit acceptance, themes/widths/enlarged text, and keyboard/action/error-retry focus behavior remain unverified here and are explicitly deferred in the description. Shared ToastNotice/Button ownership is preserved. This COMMENT is not an approval or merge-readiness claim.
…-sessions * origin/main: (23 commits) Add Marketplace tab and shared agent profile panels (#1411) fix: publish scoped typing indicators from conversation composers (#1435) feat: add configurable composer and pane focus shortcuts (#1418) perf(messages): reuse captured video opening frames on remount (#1437) FOR OCT 22: let agents clone and push their channel's repository (#1324) perf(relay): keep row profile map identity while new authors load (#1431) perf: avoid redundant relay channel derivation (#1412) Normalize dialog sizing, headers, spacing, and motion (#1403) Polish agent activity pills and popover actions (#1429) feat(agents): ask to resume claude and codex turns stopped by reload or quit (#1235) test(sign-out): join listed paths with / so the tests pass on Windows (#1247) fix(deps): remove distrusted emsign certificate roots (#1436) fix(plugins): distinguish usage and costs from agent activity (#1392) refactor(design-system): extract named Appearance palettes and revise plugin gradients (#1339) fix(channels): cancel inert activity popover opens (#1426) fix(codex): set up Codex in a dialog from the agent creation card, as Claude does (#1419) Add community-local settings (#1363) Fix sidebar and pane header alignment (#1409) Show recorded Codex scripts in Activity (#1413) fix(agents): restore emoji avatars in the agent avatar picker (#1404) ... # Conflicts: # crates/agent-controller/src/app_agent.rs
…-sessions * origin/main: (23 commits) Add Marketplace tab and shared agent profile panels (#1411) fix: publish scoped typing indicators from conversation composers (#1435) feat: add configurable composer and pane focus shortcuts (#1418) perf(messages): reuse captured video opening frames on remount (#1437) FOR OCT 22: let agents clone and push their channel's repository (#1324) perf(relay): keep row profile map identity while new authors load (#1431) perf: avoid redundant relay channel derivation (#1412) Normalize dialog sizing, headers, spacing, and motion (#1403) Polish agent activity pills and popover actions (#1429) feat(agents): ask to resume claude and codex turns stopped by reload or quit (#1235) test(sign-out): join listed paths with / so the tests pass on Windows (#1247) fix(deps): remove distrusted emsign certificate roots (#1436) fix(plugins): distinguish usage and costs from agent activity (#1392) refactor(design-system): extract named Appearance palettes and revise plugin gradients (#1339) fix(channels): cancel inert activity popover opens (#1426) fix(codex): set up Codex in a dialog from the agent creation card, as Claude does (#1419) Add community-local settings (#1363) Fix sidebar and pane header alignment (#1409) Show recorded Codex scripts in Activity (#1413) fix(agents): restore emoji avatars in the agent avatar picker (#1404) ... Co-authored-by: Will Pfleger <wpfleger@block.xyz> Signed-off-by: Will Pfleger <wpfleger@block.xyz>
* origin/main: (56 commits) Polish huddle portraits and thread layout (block#1406) fix(goose): keep long model names inside the Settings model row (block#1432) feat(agents): show a timestamp on each activity feed entry (block#1443) feat(agents): add buttons to compact and start new session (block#1434) feat(activity): request and show Claude Code and Codex thinking (block#1452) add inline renaming for Solo sidebar chats (block#1345) fix(goose): say why the profile has no model to choose (block#1445) Add Marketplace tab and shared agent profile panels (block#1411) fix: publish scoped typing indicators from conversation composers (block#1435) feat: add configurable composer and pane focus shortcuts (block#1418) perf(messages): reuse captured video opening frames on remount (block#1437) FOR OCT 22: let agents clone and push their channel's repository (block#1324) perf(relay): keep row profile map identity while new authors load (block#1431) perf: avoid redundant relay channel derivation (block#1412) Normalize dialog sizing, headers, spacing, and motion (block#1403) Polish agent activity pills and popover actions (block#1429) feat(agents): ask to resume claude and codex turns stopped by reload or quit (block#1235) test(sign-out): join listed paths with / so the tests pass on Windows (block#1247) fix(deps): remove distrusted emsign certificate roots (block#1436) fix(plugins): distinguish usage and costs from agent activity (block#1392) ... Signed-off-by: Nikolaj Goodger <ngoodger@squareup.com>
Cmd-R and Quit kill every process the page started, so any Claude or Codex turn in flight died with it. After this change Buzz remembers those turns. On the next start it asks whether to resume them, and nothing restarts unless the owner says so.
What changes
stop_all, so it is covered too.resumes(Claude and Codex here), the runner saves each mention turn's event id and channel in agent storage while the turn works. Each agent has its own key (buzz.agents.interrupted.v1:<pubkey>, like catch-up progress), and a runner writes only the agent it changed, so one program never overwrites another program's agents. The entry is cleared when the turn settles.interruptedin the Agents snapshot, and an info toast (InterruptedNotice, built on the sharedToastNotice) asks Resume or Don't resume. There is no close button: the owner picks one.session.readRemoteonce its community connects, then hands them torunoldest first withresumed: true. Oldest first is the order they were sent, so a later correction comes after the request it corrects. The relay answers newest first. Claude and Codex add a note telling the agent to carry on in its saved session and not repeat what it already did or sent.heard()), both before the owner answers and after Don't resume, so it never runs as an ordinary turn without theresumednote.readRemoterather thanread:readmerges this device's outbox into the result as copies, and a copy carries no event proof. After a reload, a mention the owner sent from the same desktop is still in the outbox, so withreadit was dropped athasEventProof. The turn was then forgotten and nothing resumed.Not covered
Testing
Automated
service.test.ts, under "a turn closing or reloading the app stopped", covers:InterruptedNotice.test.tsxcovers:host_processtests pass 12/12, including no exit afterstop_all.tsc --noEmitis clean.biomeis clean on the changed files.mainat abdc0e4.vitest run src/features/agents src/bundled/agents src/bundled/claude-code src/bundled/codex src/apppasses 1544 tests, with 1 skipped.host_processtests pass 12/12.Human testing (native,
just desktop)The test used one Claude agent and one Codex agent. Both were given the same mention: count to 60, posting each multiple of 10 as its own message, with
sleep 15between posts.readRemotefix:hasEventProofrejected it. That led to the fix above.just desktop, after the fix: tested and verified.readRemote. They have not been repeated on the later review-fix commits: per-agent scoping, replay suppression, per-agent keys, the holder-only notice, ordering and the custody refresh.