Repository navigation
Keep agents with live background work out of hibernation - #15278
teamleaderleo merged 6 commits into
Conversation
A pane whose agent still has a background shell, Monitor or async subagent passes every hibernation check today, so teardown terminates that work with the agent. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Hibernation treated a pane as done once the Stop hook said idle, then terminated the agent's whole descendant scope. Background shells, Monitor loops and async subagents that the Stop payload did not report were killed. Two guards now keep such panes awake: - Process scope: a shell under the agent that started more than 30 s after the agent (launch-time children such as MCP servers are the baseline) marks the scope unsafe to terminate. This covers the planner, the confirmation re-check and the final pre-signal validation, for scheduled and pressure reclaim alike. - Transcript: before the teardown snapshot, the Claude transcript tail is scanned for background launches (toolUseResult backgroundTaskId, Monitor taskId, async Agent launches) without a terminal <task-notification>. Launches from before the current agent process started are ignored. The pane gets the existing retry marker instead of being torn down. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 10 minutes. View limit detailsLimit details: You’ve used all 10 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (11)
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. Comment |
|
All contributors have signed the CLA ✍️ ✅ |
- Only a Monitor result (taskId with timeoutMs/persistent) counts as a Monitor launch; todo tools also return a taskId. - A TaskStop result finishes the stopped task even without a notification. - With no live agent process there is nothing to kill, so recorded launches no longer keep an exited pane awake. - Only shells whose parent is the agent count as work; an MCP server's sh -c under node does not. - Prefilter lines on launch-specific keys and build date formatters once. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Review (subagent, correctness first):
Fixed in 45a8ecd (Tighten background-work detection after review):
Left:
I re-ran the updated scanner on 72 local transcripts. The pending sets match work that is still running (subagent transcripts written minutes earlier, or live background shells). |
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
Catch-up merge by scripts/ci/catch_up_pr.py (RFC manaflow-ai#14631). Merged by scripts/merge-main.sh: origin/main at 0c753fe. Resolved conflicts: - cmux.xcodeproj/project.pbxproj: union of added entries, then normalize-pbxproj.py Catch-up-previous-head: 45a8ecd Catch-up-base: 0c753fe
Catch-up merge by scripts/ci/catch_up_pr.py (RFC manaflow-ai#14631). Merged by scripts/merge-main.sh: origin/main at 94a6387. Resolved conflicts: - cmux.xcodeproj/project.pbxproj: union of added entries, then normalize-pbxproj.py Catch-up-previous-head: 32d6b13 Catch-up-base: 94a6387
CI failure attributionCI passes on Written by |
Catch-up merge by scripts/ci/catch_up_pr.py (RFC manaflow-ai#14631). Merged by scripts/merge-main.sh: origin/main at 478e323. Resolved conflicts: - cmux.xcodeproj/project.pbxproj: union of added entries, then normalize-pbxproj.py Catch-up-previous-head: 0b83c89 Catch-up-base: 478e323 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Merge receipt for |
0e44675 test: bound remote bootstrap subprocess waits (manaflow-ai#15608) a192a14 fix(agent-chat): show ACP plans as structured step lists (manaflow-ai#15889) d7f59a3 ci: place attempt 2 like attempt 1, owned minis first (manaflow-ai#15406) d87c3be feat(agent-chat): register Cursor Agent as an ACP provider (manaflow-ai#15877) 1bd5083 fix: preserve Codex provider for workspace auto-naming (manaflow-ai#15635) 03e1245 fix(worktree-seed): budget each pattern and refuse dangling escapes (manaflow-ai#15860) 5c28fcb fix(agent-chat): stop a disposed ACP session from resurrecting its agent (manaflow-ai#15872) 11216d2 Fix Codex Agent Chat Stop interrupt request (manaflow-ai#15837) d6b8c15 ci: watch Unix cmux-tui installer changes (manaflow-ai#15874) 0fc35d6 feat(agent-chat): register goose as an ACP provider (manaflow-ai#15871) 7f27bfc cmux ssh: security hardening from the ssh audit (manaflow-ai#15768) 8599250 fix(agent-chat): launch gemini with --experimental-acp (manaflow-ai#15868) 849376a docs: classify contributor issue difficulty (manaflow-ai#15627) 2761cc9 Keep agents with live background work out of hibernation (manaflow-ai#15278) eae02a6 Cloud: rebake the devbox ladder with cmux-tui 02dac3c (manaflow-ai#15866) 7ed2f6b ci: bound open pull-request media revisions (manaflow-ai#15861) 13c417c Notify on SubagentStop in the notifications hook docs (manaflow-ai#15854) 5cfc6a6 fix: make cmux-tui installs immutable across release uploads (manaflow-ai#15859) 4eee1b1 fix: preserve longest Claude upstream cooldown (manaflow-ai#15856) 204b936 Pin Cloud panes to the daemon's terminal grid (manaflow-ai#15792) fc13b7c cmux-tui: fix the replay row scroll and stale hook fence tests breaking the full gate (manaflow-ai#15240) 87d66af Add Cloud to the menu bar extra and a main-menu Cloud menu (manaflow-ai#15822) # Conflicts: # .github/workflows/ci-failure-attribution.yml # .github/workflows/ci-macos.yml # .github/workflows/ci-owned-pool-rescue.yml # .github/workflows/ci-queue-janitor.yml # .github/workflows/ci.yml # .github/workflows/cmux-tui-artifacts.yml # .github/workflows/cmux-tui-build-package.yml # .github/workflows/cmux-tui-sdks.yml # .github/workflows/pr-media-prune.yml # .github/workflows/remote-daemon.yml
Summary
Agent Hibernation could kill work an agent was still waiting on. The only background-work signal was Claude's Stop payload (
background_tasksrunning orsession_crons). A pane that Stop reported idle, whose agent still had arun_in_backgroundshell, a Monitor loop or an async subagent, passed every check. Teardown then sent SIGTERM to the agent's whole descendant scope, background work included.Two guards now keep such panes awake.
zsh,bash,sh,fish, ...) under the agent that started more than 30 s after the agent marks the scope unsafe to terminate. Children started at launch, such as MCP servers and launch hooks, are the baseline and don't count. This runs insideagentHibernationProcessScope, so it reaches three checks: the planner, the confirmation re-check, and the fresh-index validation just before any signal. It applies to scheduled and memory-pressure reclaim alike.toolUseResult.backgroundTaskIdfor Bash,taskIdfor Monitor,isAsync+async_launchedfor Agent) with no terminal<task-notification>naming the same tool-use id or task id.<status>, so they don't count as completion.The transcript scan covers async subagents, which run inside the Claude process and have no process of their own. The process check covers older Claude builds and shells the transcript doesn't describe.
I checked the transcript format against local transcripts from Claude Code 2.1.283 (about 3k notifications). A batched "4 background agents stopped" notification lists only
<task-id>s, which is why completion also matches by task id. On live sessions the scanner reported exactly the subagents and shells that were still writing output.Part of the hibernation safety work tracked in manaflow-ai/cmuxterm-hq#880.
Testing
123ca0ffaddsAgentHibernationBackgroundWorkTests, written againstmain's API. Expected onmain:lateShellUnderTheAgentMakesTheScopeUnsafe,unfinishedBackgroundBashBlocksTheTeardownSnapshotandunfinishedAsyncAgentBlocksTheTeardownSnapshotfail.9ac1df0aadds the fix. It tightens those tests to expect.backgroundWorkPendingand adds pure scanner cases: batched task-id notifications, the pre-start cutoff, Monitor events and quoted notifications.python3 scripts/verify-local.pypasses: syntax, project, wiring, test wiring, feature flags.Changelog
Fixed: Agent Hibernation no longer terminates an agent that still has a background command, Monitor or subagent running
Checklist
docs/agent-hooks.mdeligibility list)🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Stops hibernation from tearing down agents that still have background work running. Previously a pane was only kept awake if Claude's Stop payload reported running background tasks, so agents with live background shells, Monitor loops, or async subagents passed every check and teardown terminated that work.
Adds two guards that keep such panes out of hibernation:
sh -cunder node isn't agent work. Applies to the planner, confirmation re-check, and final pre-signal validation for scheduled and memory-pressure reclaim.run_in_backgroundBash, MonitortaskIdwith Monitor-only keys, async Agent launches — with no terminal<task-notification>for the same tool-use or task id. Todo tool results that also carry ataskIddon't count as launches, a TaskStop result finishes the stopped task without a notification, Monitor events and quoted notifications don't count as completion, and launches predating the current agent process are ignored. With no live agent process there is nothing to kill, so recorded launches don't keep an exited pane awake. A pane with pending work gets the existing retry marker instead of being torn down.Written for commit 7046d32. Summary will update on new commits.