Skip to content

fix(automation): do not resume scheduled worker sessions on restore - #506

Merged
RizRiyz merged 1 commit into
RizRiyz:mainfrom
paulork:fix/automation-worker-resume
Oct 16, 2026
Merged

RizRiyz merged 1 commit into
RizRiyz:mainfrom
paulork:fix/automation-worker-resume

Conversation

@paulork

@paulork paulork commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

A scheduled automation worker pane now restores as a plain shell. Its headless agent run is no longer reopened as an interactive session after a server restart, in that lifetime or any later one. Interactive panes, manual ORCH workers, and active_agent automations resume as before.

Follow-up to #488/#490. #488 promised to check how the optional Luvus Devin hook behaves in a scheduled run. That check, run on the merged Devin automation profile, found that the next server restart reopened the worker's session. The cause turned out to be agent-agnostic, so this PR fixes it for every agent instead of special-casing Devin.

Closes #497

What

  • src/app/board.rs: task_start marks the pane in App::automation_worker_panes when it launches TaskAgentLaunch::Automation. Manual task starts and active_agent targets are never marked.
  • src/app/mod.rs: a pane leaves the set when it closes, at the same point as backend_non_restorable. Restore reads the mark back and ignores any agent_session a marked pane still carries, for example from a hand-edited snapshot.
  • src/persist.rs:
    • PaneSnap::automation_worker (#[serde(default, skip_serializing_if = "Not::not")]), so ordinary panes keep the existing session.json shape and older snapshots still load.
    • A worker's reported run is claimed before pass 1. Pass 1 then leaves the worker unbound, exactly as it does a duplicate report, and discovery can't hand that conversation to another pane.
    • A worker without a report stays in its (agent, cwd) discovery group, so an interactive pane beside it remains ambiguous, as today. resolve_pane_sessions never binds a worker, whether by title or as "one pane, one session".
  • The live pane.report_session binding is unchanged, so Mission Control and usage still see the run. It is only kept out of resume.
  • Docs: automation guide (recovery after restart), agents guide (session resume), and website/public/agent-readme.md. Neither skill copy describes restore, so both are unchanged.

Design choices

#497 raised two open questions, each with two options. This PR deliberately takes the first option in both. Either one can be switched if you prefer the other.

  1. Persisted mark vs. leaving workers out of restore: chosen: keep the pane and persist the mark. The finished worker's screen stays visible after a restart, and ORCH needs no change. The other option would also need the pass-2 grouping above: today's backend_non_restorable path drops a pane from its discovery group, and that would let an interactive pane in workspace mode inherit the worker's conversation.
  2. An agent started by hand in a finished worker pane: chosen: the mark lasts for the pane's lifetime, so that pane doesn't resume either. It keeps the rule simple and predictable. The alternative, clearing the mark when an interactive agent appears, would be a small change.

Why

Neither api_pane_report_session nor capture_session_evidence knew that a pane was an automation worker. A worker pane could be bound in either snapshot pass: by a hook report, as measured with Devin and Claude, or by native discovery when its run was the only session in its directory, as measured with Codex. The next restart then ran <agent> --resume <id> interactively, without the worker's access policy, and kept doing so on every restart after that.

It shows up when the run finishes with no client attached, which is the usual case for a scheduled job, or when the server restarts during a run. With a TUI attached, process scans clear the binding when the agent exits. The full measurements are in #497.

The mark can't come from ORCH: pane ids are reallocated on restart, and assignee is either cleared or stale by then. A mark kept only in memory is not enough either. After one restart a restored worker screen can re-identify Codex, and the next restart would rebind it.

Screenshots

The same scheduled Codex worker in both images: workspace mode, run with no client attached, then a server restart and a TUI attach. AGENTS is filtered to Active.

Before, on main: the finished worker tab reopened codex resume by itself and is waiting at Codex's trust prompt. AGENTS shows a live blocked codex that nobody started.

pr-497-before-main

With this PR: the worker tab restores as a shell with the finished run's output. AGENTS shows only the scheduled definition.

pr-497-after-this-pr

Verification

Windows 11, base f6c68e9.

  • cargo fmt --all --check (Rust 1.99.0, the current stable used by CI)
  • cargo clippy --all-targets -- -D warnings (Rust 1.99.0, Windows)
  • New tests:
    • app::board:
      • a_scheduled_worker_does_not_save_its_reported_session_for_resume
      • a_scheduled_worker_is_not_bound_to_its_discovered_session
      • an_interactive_pane_does_not_inherit_a_workers_session
      • an_interactive_pane_keeps_its_own_session_beside_a_reported_worker
      • a_restored_scheduled_worker_stays_unbound_when_identified_again
      • a_restored_worker_keeps_its_mark_across_restarts
      • a_worker_snapshot_that_names_a_session_does_not_resume_it
      • the_worker_mark_is_saved_only_for_workers (including a snapshot without the field)
      • a_worktree_scheduled_worker_is_marked_and_not_resumed
      • a_failed_scheduled_start_leaves_no_worker_mark
      • closing_a_scheduled_worker_forgets_it
      • a_manual_task_worker_still_saves_its_reported_session
    • persist::title_resolution_tests: a_scheduled_worker_title_never_resolves_its_own_run
    • app::automation: active_agent_run_delivers_without_creating_an_orch_worker now also asserts that no pane is marked.
  • Each guarded line was reverted on its own, and at least one of the tests above failed every time. The checks were: marking at start, claiming the reported run, the pass-2 lone-worker guard, keeping an unbound worker in its group, the title guard, saving and restoring the mark, the restore filter, and close cleanup. That check also caught one design mistake before this PR: excluding a reported worker from pass 1 explicitly made an interactive pane beside it lose its own session. an_interactive_pane_keeps_its_own_session_beside_a_reported_worker covers that.
  • Existing tests unchanged and passing: reported_session_*, agent_session_persists_and_resumes, app::automation::tests, persist::title_resolution_tests.
  • cargo test --locked: on this Windows checkout the full suite stalls in five lock-heavy groups, as it does on unmodified main. With those groups skipped (integration::tests, diff::notes::tests, config::tests, cli::tests::wait_status_stream, i18n::cli), this branch reports 2152 passed and 32 failed. The 32 failures are exactly the ones unmodified main reports on this machine (CRLF docs tests, git::local, OSC 8, worktree, module titles, ipc::api streams, uhp::gateway). A few uhp::gateway and app::dispatch::tests::agents tests are flaky here under full-suite load on unmodified main too, and they pass in isolation. CI covers the full suite on Ubuntu and macOS.
  • Fork CI (run 38669110602): fmt · clippy · test (Ubuntu, including the Unix-only persist::tests), macos test, windows protocol · ConPTY, both nix flake jobs, cargo audit, npm audit, and the binary-size jobs passed.
  • cargo build --release --locked
  • npm run build in website/
  • End to end with the debug binary, in an isolated LUVUS_HOME and named sessions. The production server was not touched.
    • Claude worker (read-only, worktree) with its session reported from the worker pane, plus an interactive pane with a reported session:
      • snapshot: the worker gets agent_session: null and "automation_worker": true; the interactive pane keeps its session and gets no new field;
      • restart 1: the worker is a shell, and the interactive pane runs claude --resume '<id>';
      • inside the restored worker pane, I reported its run again, as a hook would;
      • restart 2: the worker is still a shell, it still carries the mark, and the interactive pane still resumes.
    • A Codex worker with no hook report (discovery pass), identified from its screen text: saved with agent_session: null, and restored as a shell. Before this change, the same case saved the exec rollout and restored with codex resume '<id>'.
    • A snapshot with the mark and a session: not resumed. A snapshot without the mark (written before this change): resumed, as noted below.
    • Devin 3000.11.3 with luvus integration install devin, which was the original report. The worker's SessionStart hook bound its run (authority: prior_identity) as before. The snapshot saved it as null with the mark, and two restarts left a shell with no devin --resume. The Devin config was restored byte for byte afterwards.
    • Workspace mode with Codex, beside a pane in the same directory: that pane kept its session and resumed. After the restart, the restored worker screen was re-identified as an agent, and the next snapshot still saved no session for it because the mark was persisted.
    • With a TUI attached: the worker was saved and restored the same way, and kept its mark across two snapshots.

Notes

  • A session.json written before this change has no mark, so the first restart after upgrading still reopens an already-bound worker pane interactively. From then on that pane is an ordinary interactive agent pane and keeps resuming, as it does today, until it is closed. Workers started after the upgrade are marked.
  • The worker's conversation stays in the agent's own store and can still be resumed deliberately (<agent> --resume <id>).
  • Measured on Windows only. Unix-only persist::tests run in CI.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no actionable issues were found.

Summary

Scheduled automation worker panes now restore as shells instead of reopening their agent conversations.

  • Scheduled worker panes restore as shells instead of reopening agent runs.
  • Interactive panes keep their own sessions beside scheduled workers.

Intentional limits acknowledged by paulork: older snapshots have no worker mark, and agents started manually inside marked panes do not resume automatically.

Review used code inspection; no tests were run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Scheduled worker starts] --> B[Mark worker pane]
  B --> C[Save pane and mark]
  C --> D[Exclude worker session from resume]
  D --> E[Restore plain shell]
  E --> F[Keep mark for later restarts]
  F --> C
Loading

Reviews (1) · Last reviewed commit: "fix(automation): do not resume scheduled..." · Reviewed by Greptile

@github-actions github-actions Bot added area: agents Agent detection, lifecycle, resume, fork, hooks, and skills area: server Server, IPC, sessions, persistence, and logging area: orchestration Tasks, leases, boards, and worktrees area: website Website and public documentation bug Something isn't working labels Oct 15, 2026
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

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: 43d34f3e-d08e-41b9-91ae-d4eeb8e32397
📥 Commits

Reviewing files that changed from the base of the PR and between 52def96 and 9ecf17a.

📒 Files selected for processing: 7
  • src/app/automation.rs
  • src/app/board.rs
  • src/app/mod.rs
  • src/persist.rs
  • website/public/agent-readme.md
  • website/src/content/docs/docs/guides/agents.mdx
  • website/src/content/docs/docs/guides/automation.mdx

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

📝 Summary

Summary by CodeRabbit

  • Behavior Changes
    • Scheduled automation worker panes now restore as plain shells after a server restart instead of reopening their agent conversations. Those conversations remain available to resume using the agent’s resume command.
    • Worker panes no longer claim saved agent sessions that could otherwise be associated with interactive panes.
  • Documentation
    • Updated the agent and automation guides with details on session restoration and resuming conversations.

Scheduled automation worker panes are marked at launch and recorded in snapshots. Session resolution prevents their agent sessions from binding to workers or neighboring panes. Restoration opens marked panes as shells. Tests and documentation cover the behavior.

Changes: Scheduled worker session restoration

Layer / File(s) Summary
Mark scheduled worker panes
src/app/board.rs, src/app/mod.rs, src/app/automation.rs
Successful scheduled launches add panes to the runtime worker set. Pane cleanup removes the mark. Tests cover scheduled and worktree launches, failed starts, manual workers, and active-agent delivery.
Persist worker identity and filter session resolution
src/persist.rs, src/app/mod.rs, src/app/board.rs, website/public/agent-readme.md, website/src/content/docs/docs/guides/agents.mdx, website/src/content/docs/docs/guides/automation.mdx
Snapshots record worker identity, and session resolution excludes worker sessions from restoration and discovery assignments. Restoration retains the mark and restores workers without an agent session. Tests and guides cover persistence, compatibility, and restart behavior.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant task_start
  participant App
  participant PaneSnap
  participant resolve_pane_sessions
  participant App_restore
  task_start->>App: mark scheduled worker pane
  App->>PaneSnap: save worker mark
  PaneSnap->>resolve_pane_sessions: provide worker identity and session evidence
  resolve_pane_sessions->>App_restore: omit worker agent session
  App_restore->>App: restore worker as shell and retain mark
Loading

Suggested reviewers: rizriyz

Merge Risk: ⚪ Minimal · up to 9ecf1

Scheduled workers are intended to restore as shells, and no actionable merge-blocking issue remains after normal checks.

Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 76.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 25 functions across 3 files. (4 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Issue #497 requires scheduled automation workers to avoid interactive session resume after restart while preserving live reporting and preventing session reassignment. task_start marks only `TaskAge…
Out of Scope Changes check Passed The changes stay within issue #497. The added tests verify the worker distinction and preserve manual ORCH and active_agent behavior. The documentation updates describe the new restore behavior. No …
Title check Passed The title clearly and concisely describes the primary change: scheduled worker sessions are not resumed during restore.
Description check Passed The description covers the user-facing result, behavior changes, rationale, verification, screenshots, compatibility details, and known limitations. It is detailed and aligned with the repository temp…
Full details: Docstring Coverage

Explanation

Docstring coverage is 76.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 25 functions across 3 files. (4 skipped: 3 unsupported, 1 too large.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • 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 requested a review from RizRiyz October 15, 2026 14:03

@RizRiyz RizRiyz left a comment •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@paulork thank you for working on this task, looks good for me

@RizRiyz
RizRiyz merged commit 0062178 into RizRiyz:main Oct 16, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: agents Agent detection, lifecycle, resume, fork, hooks, and skills area: orchestration Tasks, leases, boards, and worktrees area: server Server, IPC, sessions, persistence, and logging area: website Website and public documentation bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduled automation workers resume their agent session interactively after a server restart

2 participants