Repository navigation
fix(acp_client): reap agents orphaned by a host that died without close - #930
Closed
akushonkamen wants to merge 1 commit into
Closed
akushonkamen wants to merge 1 commit into
akushonkamen wants to merge 1 commit into
Conversation
launch() starts every ACP agent with start_new_session=True, so the process group hears none of raven's signals and the only teardown path is close()'s killpg. A host killed by SIGKILL, the OOM killer, or a crash never reaches close_pool, and the agent stays behind parented to init -- observed in EverMind-AI#928 running for 22 days holding 523 MiB PSS. The orphan guard closes that: launch records (pgid, agent birth, owner pid, owner birth) in a per-boot file under the temp dir, and the next launch sweeps the file first, killing the groups whose owner is gone and whose birth still matches -- so a recycled pid is neither killed nor mistaken for a live owner. close() drops its own entry. Windows rides the same record and kills via taskkill /T /F; no real Windows machine was available, so that branch is written to the EverMind-AI#918/EverMind-AI#919 standard and declared untested here. Reproduced on macOS (darwin 24.6.0 arm64) before the fix: a stub agent outlived its SIGKILLed host with ppid=1; after the fix the next launch kills the orphaned group. Co-authored-by: Claude (GLM-5.3-Flash) <noreply@anthropic.com> Signed-off-by: akushonkamen <akushonkamen@163.com>
This was referenced Oct 13, 2026
fix(acp_client): on macOS and Windows an ACP agent outlives a host that dies without closing it
#928
Closed
6 of 12 tasks
Member
|
This PR has not been verified on a real Windows machine, and its CI has been red (coverage gates and pull request title, since 2026-10-13) with no follow-up since. Closing it; #928 is now addressed by #951 (Windows) and #953 (macOS). You are welcome to open PRs against either branch: |
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.
Summary
launch()starts every ACP agent withstart_new_session=True, so the only teardown path isclose()'skillpg(raven/acp_client/client.py:261,raven/acp_client/client.py:301-315). A host that dies without reachingclose_pool— SIGKILL, OOM killer, crash — leaves the agent orphaned, parented to init. Observed in #928: an agent running for 22 days holding 523 MiB PSS.Root cause: no fallback teardown when the owning host process dies abruptly.
Fix:
launch()records(pgid, agent birth, owner pid, owner birth)to a per-boot temp file, and everylaunch()sweeps that file first. A group is killed withkillpgonly when its owner is dead (or its pid was recycled, detected via birth mismatch) and the agent's birth still matches — so a recycled pid is neither killed nor mistaken for a live owner.close()removes its own record. On Windows the same record is used and the tree is killed withtaskkill /T /F; no real Windows machine was available, so that branch is written to the #918/#919 standard and declared untested here.Process: timeline check confirmed no earlier claim/PR by this account on #928; a claim comment with AI disclosure was posted first (issuecomment-6135634396).
Type
Verification
Red (bug reproduced, pre-fix):
timeout 20 $V /tmp/repro_928.py+ps -o pid,ppid,stat -p <AGENT_PID>→ after the stub agent's host was SIGKILLed the agent stayed alive withppid=1(bug evidence; first reproduction pid 40717).Green (post-fix e2e): same script, host
kill -9ed, then$V -c "from raven.acp_client.client import sweep_orphaned_agents; print(sweep_orphaned_agents())"→KILLED [58468];ps -p 58468confirms the process is gone.New tests:
$V -m pytest tests/test_acp_orphan_sweep.py -v→ 5 passed (owner dead → group killed; live owner spared; recycled pid not killed; dead pid with birth=None; boot token).Regression subsets ($V = pre-existing venv python, Python 3.13.15):
$V -m pytest tests/test_acp_methods.py tests/test_acp_protocol.py tests/test_acp_stdio.py tests/test_acp_journal.py tests/test_acp_orphan_sweep.py -q→ 228 passed$V -m pytest tests/test_subagent_host_env.py tests/test_acp_backend_cwd.py tests/test_cli_gateway_commands.py tests/test_cli_tui_commands.py -q→ 171 passed$V -m pytest tests/test_subagent_acp_mcp_lifecycle.py -q→ 21 passedRisk
launch(), no API change;close()semantics unchanged.Related Issues
Fixes #928
AI disclosure: written with AI assistance (Claude / GLM-5.3-Flash); commit carries
Co-authored-by: Claude (GLM-5.3-Flash) <noreply@anthropic.com>.