Skip to content

feat(v1): run Codex and Claude through ACP - #2257

Merged
hallerite merged 10 commits into
mainfrom
codex/acp-harness-adapters
Aug 5, 2026
Merged

feat(v1): run Codex and Claude through ACP#2257
hallerite merged 10 commits into
mainfrom
codex/acp-harness-adapters

Conversation

@xeophon

@xeophon xeophon commented Aug 5, 2026

Copy link
Copy Markdown
Member

Overview

Run the Codex and Claude Code harnesses through maintained ACP adapters so they use the same saved-session continuation path as the existing ACP harnesses.

Details

  • replace the Codex-specific exec resume --last flow with the Codex App Server ACP adapter
  • enable resumable Claude Code exchanges through the Claude Agent SDK ACP adapter
  • use the compatible Codex and Claude executables supplied by the pinned adapter packages
  • pass Claude MCP servers through ACP while preserving Codex's native required and timeout settings
  • preserve per-trace state, system prompts, disabled tools, model/provider routing, and Codex authentication
  • allow ACP session metadata for adapter-specific launch options
  • share the pinned Node runtime used by the Codex, Claude, and Pi adapters
  • discover Claude skills from its standard project directory
  • cover Codex and Claude in the existing ACP continuation E2E matrix

The remaining harnesses keep their current transports: Hermes, Kimi, Pi, Pool, and OpenClaw already use ACP, while the in-house/stateless harnesses and Terminus 2 do not have equivalent maintained resumable ACP adapters.


Note

Medium Risk
Large harness transport swap for two heavily used agents adds runtime dependency on npm/Node and changes resume semantics away from Codex's native exec resume --last flow.

Overview
Codex and Claude Code no longer invoke their own CLIs directly; both install pinned npm ACP packages and run through the shared ACP harness path (persistent session where the runtime supports live processes, session_path for one-shot resume on launch).

The ACP stack gains optional session_meta, threaded through config JSON into new_session / resume_session / load_session, and treated as part of persistent session identity so mid-rollout config changes fail fast. Claude passes MCP strictness, disallowed tools, and appended system prompt via that metadata; Codex keeps interception routing, MCP timeouts, feature flags, and namespace hashing via env/CODEX_CONFIG instead of CLI -c flags.

A new ensure_node helper centralizes Node 22.19+ install under /var/tmp/vf-node; Pi drops its duplicate Node bootstrap and uses it. Claude skills discovery moves to .claude/skills; Claude SUPPORTS_RESUME flips on.

E2e ACP_RESUME_PLACEMENTS adds docker rows for codex and claude-code; test helpers rename _pair/_m to public pair / mark.

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

Note

Run Codex and Claude Code harnesses through the ACP adapter

  • Rewrites codex/harness.py and claude_code/harness.py to invoke agents via npm-installed ACP adapters (@agentclientprotocol/codex-acp and the Claude Agent SDK) instead of direct binary or app invocation.
  • Adds a shared node.py utility (ensure_node) so harnesses install a consistent Node.js runtime; pi/harness.py is updated to use it too.
  • Adds session_meta support throughout the ACP layer (acp/init.py, runner.py) so harnesses can pass per-session options (disabled tools, system prompt, MCP config) to the agent process.
  • Both harnesses persist ACP session state per-trace to support resume across segments, and clean up per-trace config directories on teardown.
  • E2E tests in test_e2e.py now include ACP resume coverage for codex and claude-code in the docker runtime.

Macroscope summarized 4aa588a.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 245129a234

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/acp/runner.py Outdated
Comment thread verifiers/v1/harnesses/codex/harness.py
@macroscopeapp

macroscopeapp Bot commented Aug 5, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new feature changing how Codex and Claude Code agents are run (via ACP adapters). Additionally, there are two unresolved high-severity review comments identifying security concerns in the new Node.js installation logic - specifically around potential arbitrary code execution from shared paths and indefinite hangs from orphaned lock files.

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

Comment thread verifiers/v1/harnesses/claude_code/harness.py

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9136e1d803

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/harnesses/codex/harness.py Outdated
Comment thread verifiers/v1/harnesses/claude_code/harness.py Outdated
Comment thread verifiers/v1/harnesses/codex/harness.py
Comment thread verifiers/v1/harnesses/codex/harness.py

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b95444dfa2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/harnesses/codex/harness.py
@xeophon
xeophon requested a review from hallerite August 5, 2026 17:02
@xeophon
xeophon force-pushed the codex/acp-harness-adapters branch from b95444d to 98eb1a5 Compare August 5, 2026 17:18
command -v curl >/dev/null 2>&1 \
|| { apt-get update -qq && apt-get install -y -qq curl ca-certificates >/dev/null; }
case "$(uname -s)" in Linux) node_os=linux ;; Darwin) node_os=darwin ;; *) echo "unsupported os: $(uname -s)" >&2; exit 1 ;; esac
if [ ! -x "$node/bin/node" ] || [ "$("$node/bin/node" --version 2>/dev/null)" != "v$VF_NODE_VERSION" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High harnesses/node.py:28

The installer executes a pre-existing /var/tmp/vf-node/bin/node binary before verifying it owns or created the NODE_DIR directory. On a shared host, another user can pre-create /var/tmp/vf-node/bin/node with an executable payload, and the next ensure_node call runs that payload with the verifier worker's privileges — both in the node_ok version check and the if [ ! -x "$node/bin/node" ] guard. Consider creating $node under a user-private path or securely initializing the directory with verified ownership before executing any binary from it.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/harnesses/node.py around line 28:

The installer executes a pre-existing `/var/tmp/vf-node/bin/node` binary before verifying it owns or created the `NODE_DIR` directory. On a shared host, another user can pre-create `/var/tmp/vf-node/bin/node` with an executable payload, and the next `ensure_node` call runs that payload with the verifier worker's privileges — both in the `node_ok` version check and the `if [ ! -x "$node/bin/node" ]` guard. Consider creating `$node` under a user-private path or securely initializing the directory with verified ownership before executing any binary from it.

async def ensure_node(runtime: Runtime) -> None:
"""Install the shared Node runtime used by ACP adapter harnesses."""
lock = f"{NODE_DIR}.install.lock"
guarded = (

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High harnesses/node.py:43

If a Node install process is killed before its EXIT trap runs and its PID is later reused by an unrelated long-lived process, every subsequent ensure_node call hangs indefinitely on the orphaned /var/tmp/vf-node.install.lock. The stale-lock recovery in the spin loop checks only kill -0 "$owner", so any live process with that PID keeps the loop waiting forever. Consider replacing the PID-based heuristic with flock or adding bounded retry/timeout logic so an orphaned lock is eventually reclaimed.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/harnesses/node.py around line 43:

If a Node install process is killed before its `EXIT` trap runs and its PID is later reused by an unrelated long-lived process, every subsequent `ensure_node` call hangs indefinitely on the orphaned `/var/tmp/vf-node.install.lock`. The stale-lock recovery in the spin loop checks only `kill -0 "$owner"`, so any live process with that PID keeps the loop waiting forever. Consider replacing the PID-based heuristic with `flock` or adding bounded retry/timeout logic so an orphaned lock is eventually reclaimed.

@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 2 potential issues.

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 98eb1a5. Configure here.

Comment thread verifiers/v1/harnesses/codex/harness.py
Comment thread verifiers/v1/harnesses/codex/harness.py
@hallerite
hallerite merged commit 7e00369 into main Aug 5, 2026
12 of 13 checks passed
@hallerite
hallerite deleted the codex/acp-harness-adapters branch August 5, 2026 18:37
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