fix(acp): prevent orphaned claude-agent-acp processes after session kill (#4691) - #4698
Conversation
β¦ill (#4691) - orphan reaper: exclude terminal sessions (killed, completed, crashed) from getActiveSessionIds so orphaned ACP runtimes for killed sessions are detected and reaped (Issue #4691) - shutdownRuntime: catch session/close request failures and still proceed to client.shutdown(), preventing orphaned child processes when the ACP bridge is unresponsive - boot-shutdown: shut down ACP runtimes before killing sessions during graceful shutdown - dead-detector: add shutdownAcpRuntime hook to handleDeadSession before killSession (optional, wired in future refactor) - regression test: 4 new tests covering orphan reaper filtering and shutdownRuntime resilience
479b099 to
22b04b8
Compare
There was a problem hiding this comment.
TypeScript errors in test file β build is broken.
The new regression test src/__tests__/fix-4691-orphaned-acp-processes.test.ts has 4 tsc --noEmit errors that block the build across all platforms (ubuntu, mac, windows, helm-smoke):
- Line 16:
AcpBackendRuntimeis not exported from../services/acp/backend/runtime.js. You likely need to export it or use a different type. - Line 17:
AcpSessionRecordis not exported from../services/acp/backend.js. Same fix β export the type or avoid the import. - Lines 33 & 48: The
logmock is missingbusandlogproperties fromStructuredLogger. The mock needs to match the full interface.
Non-test code review (the actual fix):
server-bootstrap.tsβ correct: filtering terminal sessions from the orphan reaper is the right fix.runtime.tsβ correct: wrappingsession/closein try-catch and ensuringclient.shutdown()always runs is the right resilience pattern.boot-shutdown.tsβ correct: shutting down ACP runtimes before killing sessions prevents orphans during graceful shutdown.dead-detector.tsβ correct: adding the optional hook is clean and respects the 500-line gate.
Please fix the 4 TypeScript errors and push. The fix itself is solid.
There was a problem hiding this comment.
β All gates pass.
- TypeScript errors in regression test fixed (correct imports from types.js modules, proper log mock typing)
- Orphan reaper fix correctly filters terminal sessions from getActiveSessionIds
- shutdownRuntime resilience pattern is correct: session/close wrapped in try-catch, client.shutdown() always runs, finally block guarantees cleanup
- boot-shutdown ordering and dead-detector hook are clean and respect the 500-line gate
- CI all green, targeted tests present, tsc clean
LGTM.
|
[OpenClaw agent ag-themis β independent security review]\n\nβ Retroactive LGTM (post-merge security audit).\n\nReliability/DoS assessment:\n- now wraps in try-catch and proceeds to regardless β prevents orphaned processes when the ACP bridge is unresponsive. Good resilience pattern.\n- The outer catch block also attempts to refresh state, with an inner catch that silently falls back to last-known state. No information leakage.\n- orphan reaper correctly filters terminal sessions (, , ) from β allows orphaned ACP runtimes for killed sessions to be detected and reaped.\n- ordering change (shutdown ACP runtimes before killing sessions) is correct for graceful shutdown.\n- adds an optional hook β no new attack surface, just an extension point.\n\nNo new auth/permission/secrets/routes/SSRF surface. Error logging uses and β these are protocol-level errors from the ACP client, not expected to contain tokens. No concern.\n\nVerdict: Security-neutral reliability improvement. No blocker.\n\nNote: This PR merged without a prior Themis review. Retroactive audit complete. No concerns. |
|
[OpenClaw agent ag-themis β independent security review] β Retroactive LGTM (post-merge security audit). Reliability/DoS assessment:
No new auth/permission/secrets/routes/SSRF surface. Error logging uses String(closeError) and String(shutdownError) β these are protocol-level errors from the ACP client, not expected to contain tokens. No concern. Verdict: Security-neutral reliability improvement. No blocker. Note: This PR merged without a prior Themis review. Retroactive audit complete. No concerns. |
Problem
When sessions are killed (via API or CLI), the ACP bridge child processes are not always cleaned up. The orphan reaper, which is the safety net for this, was not detecting orphaned runtimes for killed sessions because it treated killed sessions as still active.
Root Cause
Fix
Verification
Residual Risk