feat(v1): run RLM over persistent ACP#2116
Conversation
ApprovabilityVerdict: Needs human review This PR introduces significant new async/concurrency functionality for persistent ACP sessions. An unresolved high-severity review comment identifies a race condition in the disconnect handling logic where the session may close while an ACP prompt is still unwinding. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7caf113. Configure here.
| # consuming tokens without a client. | ||
| prompt_task.cancel() | ||
| await asyncio.gather(prompt_task, return_exceptions=True) | ||
| await stop_session() |
There was a problem hiding this comment.
Disconnect cancels prompt tracking early
High Severity
On client disconnect, the handler cancels prompt_task (run_prompt) before stop_session. That hits run_prompt's finally, which clears active_prompt without waiting for session.run to finish, so stop_session no longer sees the in-flight prompt and can close the session while the ACP prompt is still unwinding—the race this shutdown path was meant to prevent.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7caf113. Configure here.


Keeps ACP agents alive for the duration of a v1 interaction and moves RLM onto its native ACP transport.
RLM now preserves conversation and IPython state across segments, while MCP servers remain model-facing Python skills behind
ipython.Tested with:
uv run pytest tests/— 909 passed, 64 skippeduv run pre-commit run --all-filesNote
Run RLM harness over a persistent ACP sidecar per trace
rlm --acp) backed by a long-lived Unix-socket sidecar per trace instead of invoking the CLI in one-shot mode per prompt._runner.pygains aPersistentSessionclass and aserve_sidecarUnix-socket server that serializes prompts over a single agent process and session across segments.acp/__init__.pyextendsACP.runwith asidecar_pathparameter that starts the sidecar on first use, routes subsequent prompts through it, and appends sidecar logs to stderr on failure;ACP.closeshuts the sidecar down and removes its state directory.RLM_HOMEis now stored under.vf-rlm/<trace.id>/home, enablingmeta.jsonmetrics (e.g.turns_since_last_compaction) to persist and be read after the sidecar is stopped.RLMHarness.cleanupto recover correctly.Macroscope summarized 7caf113.
Note
Medium Risk
New long-lived sidecar lifecycle and RLM execution path affect multi-segment rollouts; client disconnect during a prompt tears down the session and can discard in-progress work.
Overview
RLM now runs through rlm-harness on native ACP (
rlm --acp) instead of a one-shot CLI invocation. MCP servers are wired through ACP; the oldRLM_MCP_CONFIGpath is removed. Per-trace state lives under.vf-rlm/{trace.id}/(RLM_HOMEand a privateacp.socksidecar).The shared ACP layer gains an optional persistent sidecar: probe/start a background
serveprocess, send each segment viarequest, andclose/shutdownwith log tailing on failures._runner.pyadds a UNIX-socket server withPersistentSession(one agent process for many prompts), plusonce/serve/request/shutdown/probecommands.E2E adds rlm to ACP resume coverage and asserts RLM compaction metrics on resumed runs. Docs pin the default rlm-harness git ref and describe the ACP + IPython skill model.
Reviewed by Cursor Bugbot for commit 7caf113. Bugbot is set up for automated code reviews on this repo. Configure here.