Skip to content

feat(v1): add rollout-scoped harness sessions - #2141

Closed
hallerite wants to merge 5 commits into
mainfrom
codex/harness-session
Closed

feat(v1): add rollout-scoped harness sessions#2141
hallerite wants to merge 5 commits into
mainfrom
codex/harness-session

Conversation

@hallerite

@hallerite hallerite commented Jul 26, 2026

Copy link
Copy Markdown
Member

Counter-proposal to #2116.

What changed

  • Adds an internal, rollout-scoped HarnessSession with turn() and close().
  • Makes RolloutRun create, retain, and close that handle around the full interaction.
  • Keeps existing harnesses on a default launch/resume adapter, so taskset and harness authors do not need to migrate.
  • Adds an ACP-backed session implementation that owns one live agent process, ACP connection, and ACP session across turns.
  • Moves RLM to rlm-harness --acp, preserving its conversation and IPython state across segments while exposing MCP servers as RLM skills.

Why this shape

PR #2116 attaches persistence to individual ACP.run() calls through a sidecar_path, leaving RLM responsible for choosing and cleaning up that transport detail. This proposal makes the rollout lifecycle session-shaped instead: RolloutRun owns the handle, while RLM only selects an ACP-backed implementation.

The current Runtime contract still returns completed ProgramResults and cannot expose a provider-neutral live bidirectional process. ACP therefore still uses a private runtime-local socket supervisor underneath. That mechanism is hidden behind the session implementation, so a future Runtime.open_process() primitive can replace it without changing rollout orchestration or RLM again.

The lifecycle also closes the session before interception/tool teardown and scoring, treats teardown failures as best-effort after generation has completed, and fixes the unresolved #2116 disconnect race by cancelling and awaiting the tracked ACP prompt before the request wrapper releases session ownership.

Validation

  • uv run pytest tests/ — 909 passed, 64 skipped (live-key cases)
  • uv run pre-commit run --all-files
  • uv run --python 3.13 ty check verifiers
  • focused Unix-socket cancellation check: disconnect waits for prompt cancellation before ACP close

Note

Add rollout-scoped persistent harness sessions to the ACP runner

  • Introduces HarnessSession in harness.py as a rollout-scoped abstraction that manages per-turn execution, error handling, and teardown across a rollout's lifetime.
  • Extends ACP in acp/init.py with a session() factory and sidecar lifecycle management (start, probe, route, shutdown) over a Unix domain socket.
  • Adds a LiveACPSession and a serve_session sidecar server in _runner.py, implementing a framed JSON IPC protocol and CLI operations: once, serve, request, shutdown, and probe.
  • Updates RLMHarness in harnesses/rlm/harness.py to use persistent ACP sessions via open_session(), store RLM state in a per-trace private directory, and clean it up on rollout teardown.
  • RolloutRun in rollout.py now opens a harness session at rollout start and routes each segment through session.turn(), with cancellation-safe abort and close paths.
  • Risk: sidecar processes are now long-lived per rollout; a failure to shut them down (e.g. under cancellation) may leak subprocess and socket resources.

Macroscope summarized b8e442c.


Note

Medium Risk
Long-lived ACP sidecars per rollout and new teardown paths under cancellation; failed shutdown can leave sockets/processes until retry, but generation errors are no longer masked by close failures.

Overview
Rollout orchestration is now session-shaped: RolloutRun opens a HarnessSession at boot, drives each segment via session.turn(), and closes it (with cancellation-safe retry) before scoring and teardown. The default session still maps to launch/resume; stateful harnesses override open_session().

ACP gains a runtime-local Unix-socket sidecar (serve / request / probe / shutdown) so one agent process and ACP connection survive across turns. ACPHarnessSession owns the sidecar per rollout; disconnect during an active prompt cancels the tracked prompt before teardown.

RLM switches from direct CLI to rlm-harness at a pinned commit, runs via rlm --acp, wires MCP through the ACP session (not RLM_MCP_CONFIG), and stores state under .vf-rlm/<trace.id>/ with cleanup() on rollout end. Docs and e2e add RLM to ACP resume coverage and assert compaction metrics.

Reviewed by Cursor Bugbot for commit b8e442c. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread verifiers/v1/harness.py
Comment thread verifiers/v1/harness.py
Comment thread verifiers/v1/acp/_runner.py
Comment thread verifiers/v1/acp/_runner.py
@hallerite
hallerite marked this pull request as ready for review July 26, 2026 22:41
Comment thread verifiers/v1/acp/__init__.py
@macroscopeapp

macroscopeapp Bot commented Jul 26, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR adds a significant new feature (rollout-scoped ACP sessions) with new abstractions, Unix socket IPC, and sidecar process management. The scope and complexity of new runtime behavior, plus an unresolved comment about error handling in the probe operation, warrant human review.

No code changes detected at b8e442c. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

Comment thread verifiers/v1/acp/__init__.py
Comment thread verifiers/v1/acp/__init__.py
Comment thread verifiers/v1/rollout.py

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7832cb5. Configure here.

Comment thread verifiers/v1/acp/_runner.py Outdated
@hallerite
hallerite force-pushed the codex/harness-session branch from 36a3732 to b8e442c Compare July 27, 2026 12:25

@mikasenghaas mikasenghaas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Keeps existing harnesses on a default launch/resume adapter, so taskset and harness authors do not need to migrate.

not a huge fan of dual apis. would prefer we break this and tell ppl to migrate. also, frankly dont believe we have many user-authored harnesses

@hallerite

Copy link
Copy Markdown
Member Author

solved with #2249

@hallerite hallerite closed this Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants