Skip to content

Add synchronous ACP harness tool interception - #2372

Open
xeophon wants to merge 12 commits into
mainfrom
agent/native-tool-interception
Open

Add synchronous ACP harness tool interception#2372
xeophon wants to merge 12 commits into
mainfrom
agent/native-tool-interception

Conversation

@xeophon

@xeophon xeophon commented Aug 15, 2026

Copy link
Copy Markdown
Member

Overview

Add synchronous native tool interception to ACP-backed coding harnesses while retaining Bash as the built-in reference path. Task request policies can block proposed tools before execution and replace completed results before the harness advances to the next model turn.

Details

  • Add a rollout-scoped tool-policy endpoint with a capability separate from model inference and task state.
  • Route Claude Code SDK hooks through LiveACPClient permission metadata, keeping the policy bearer out of the agent process.
  • Connect Codex through trusted native PreToolUse and PostToolUse hooks while codex-acp continues to own the ACP session.
  • Connect Pi through its built-in awaited tool_call, tool_result, and message_end extension events.
  • Preserve approved results exactly in the canonical trace, serialize concurrent callbacks, and fail the rollout if a required native hook is skipped.
  • Keep generic ACP tool updates observational; a harness advertises interception only when it owns an awaited execution boundary.

Note

High Risk
Touches security-critical policy enforcement: a new tool-only bearer, credential handoff into agent processes, and fail-closed native hooks that can allow, rewrite, or stop tool execution. Bugs here can leak secrets or skip policy on coding-agent tools.

Overview
Task request policies can now block tools before they run and rewrite results before the next model turn, on both in-process loops and ACP agents.

The interception slot gains a separate tool_secret. /tool is no longer reachable with the model bearer. Harnesses take (url, secret) instead of a URL, and SUPPORTS_TOOL_INTERCEPTION splits into pre/post flags. Session state keys approved results by assistant node + call id, serializes concurrent hooks, and raises HarnessError if a required native boundary is skipped or the delivered result does not match.

In-process harnesses (bash, browser, null, mini-swe) inject a shared HTTP client and receive the secret over stdin via Runtime.run_with_input. ACP agents get per-product bridges: Claude SDK hooks via ACP permission metadata, Codex through a trusted Code Mode websocket proxy, Pi/OpenClaw/Pool via native plugins or command hooks. Generic ACP notifications stay observational. Node is bumped to 22.21 so env proxies work.

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

Note

Add synchronous tool interception across harnesses and session

  • Replaces SUPPORTS_TOOL_INTERCEPTION with separate SUPPORTS_PRE_TOOL_INTERCEPTION and SUPPORTS_POST_TOOL_INTERCEPTION flags on harnesses, allowing each phase to be advertised independently.
  • Introduces ToolInterceptionClient and read_tool_secret in direct.py for synchronous HTTP policy calls, delivering a one-shot secret over stdin.
  • Adds per-harness interception wiring (hooks, plugins, or injected code) for Bash, BrowserUse, Null, Pi, OpenClaw, Pool, Codex, ClaudeCode, and MiniSWEAgent.
  • Updates session.py and rollout.py to validate native tool interception results, enforce tool ID/name invariants, and propagate fatal_error before non-fatal errors.
  • Risk: interception.base.Slot type alias changed from a 3-tuple to a 4-tuple with an added tool_secret; all consumers must handle the new element.

Macroscope summarized 52b803e.

Comment thread verifiers/v1/session.py Outdated
Comment thread verifiers/v1/interception/tool_hook.mjs Outdated
Comment thread verifiers/v1/harnesses/pi/harness.py Outdated
Comment thread verifiers/v1/harnesses/openclaw/tool_interception.mjs Outdated
Comment thread verifiers/v1/harnesses/openclaw/tool_interception.mjs
Comment thread verifiers/v1/harnesses/claude_code/harness.py
Comment thread verifiers/v1/harnesses/pi/harness.py
@macroscopeapp

macroscopeapp Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a complex synchronous tool-policy feature across shared rollout infrastructure and multiple third-party harness adapters, including new credential and proxy paths. Its runtime and security impact is broad, with unresolved concerns involving Codex protocol handling, Pool credential exposure, and OpenClaw scope.

Not approved because:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@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: 4edcd30858

ℹ️ 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/claude_code/harness.py Outdated
Comment thread verifiers/v1/harnesses/pi/harness.py Outdated
Comment thread pyproject.toml Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from 4edcd30 to 68941f5 Compare August 16, 2026 06:51
Comment thread verifiers/v1/session.py
Comment thread verifiers/v1/harnesses/bash/harness.py Outdated

@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: 68941f52ef

ℹ️ 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/session.py Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from 68941f5 to e34d4e0 Compare August 17, 2026 12:19
Comment thread verifiers/v1/harnesses/bash/harness.py Outdated

@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: e34d4e0758

ℹ️ 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/session.py Outdated
Comment thread environments/tool_interception/tool_interception/taskset.py Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from e34d4e0 to df227d6 Compare August 17, 2026 12:38
Comment thread verifiers/v1/session.py Outdated
Comment thread environments/tool_interception/tool_interception/taskset.py Outdated

@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: df227d6ee3

ℹ️ 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/session.py Outdated
Comment thread verifiers/v1/interception/tool.py Outdated
Comment thread verifiers/v1/session.py
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from df227d6 to cccba87 Compare August 17, 2026 13:07

@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: cccba87422

ℹ️ 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/interception/tool_hook.mjs Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from cccba87 to 4726f72 Compare August 17, 2026 13:39

@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: 4726f72bce

ℹ️ 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/interception/tool_hook.mjs Outdated
Comment thread environments/tool_interception/tool_interception/taskset.py Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from 4726f72 to a6d70fd Compare August 17, 2026 14:26

@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: a6d70fd828

ℹ️ 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/claude_code/harness.py Outdated
Comment thread verifiers/v1/interception/hermes_tool_hook.py Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from a6d70fd to 38186a5 Compare August 17, 2026 14:46
Comment thread verifiers/v1/interception/tool_hook.mjs Outdated
Comment thread verifiers/v1/interception/tool_hook.mjs Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch 2 times, most recently from bfc6b6d to 90bb79a Compare August 17, 2026 15:43
Comment thread verifiers/v1/runtimes/base.py Outdated
Comment thread verifiers/v1/session.py Outdated
Comment thread environments/bash_interception/bash_interception/taskset.py
Comment thread verifiers/v1/interception/tool_hook.mjs Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from 90bb79a to f251c8a Compare August 17, 2026 15:45

@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: 4050c7f1b2

ℹ️ 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/session.py Outdated
Comment thread verifiers/v1/harnesses/pi/tool_hook.mjs

@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: 0a04144d22

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

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@xeophon xeophon changed the title Add synchronous Pi tool interception Add synchronous ACP harness tool interception Aug 18, 2026
Comment thread verifiers/v1/harnesses/codex/harness.py Outdated
Comment thread verifiers/v1/harnesses/codex/tool_hook.mjs Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from d22f55d to f1dbb9a Compare August 20, 2026 12:21
Comment thread verifiers/v1/harnesses/codex/tool_hook.mjs Outdated
Comment thread verifiers/v1/harnesses/pi/tool_hook.mjs
Comment thread verifiers/v1/harnesses/pi/tool_hook.mjs
Comment thread verifiers/v1/harnesses/codex/harness.py Outdated
@xeophon
xeophon force-pushed the agent/native-tool-interception branch from 3325ab5 to fe0623c Compare August 23, 2026 10:35
Comment thread verifiers/v1/harnesses/pool/tool_hook.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 3 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 fe0623c. Configure here.

Comment thread verifiers/v1/rollout.py
},
},
}
)

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 terminate treated as wait

High Severity

session/terminate is handled with tool name wait and, on block, answered as wait/completed. Post interception only recognizes wait/completed, so terminate allow/block paths can bind the wrong call, skip the post hook, or fail the rollout’s prepared-result check.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fe0623c. Configure here.

SUPPORTS_MCP = True
SUPPORTS_SKILLS = True
SUPPORTS_PRE_TOOL_INTERCEPTION = True
SUPPORTS_POST_TOOL_INTERCEPTION = True

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

OpenClaw interception still enabled

High Severity

OpenClaw still sets SUPPORTS_PRE_TOOL_INTERCEPTION and SUPPORTS_POST_TOOL_INTERCEPTION and ships configure_tool_interception plus the plugin. The PR scope reduction said native OpenClaw interception was removed and those flags stay false, so policy-backed OpenClaw rollouts still take an out-of-scope path.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fe0623c. Configure here.

@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: fe0623c78e

ℹ️ 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/pool/harness.py Outdated
Comment on lines +124 to +125
credentialsPath = f"{stateDir}/{uuid.uuid4().hex}.credentials"
payload = json.dumps({"url": url, "secret": secret}).encode()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove Pool policy credentials from the agent workspace

The fresh Pool adapter now stores the /tool URL and bearer in a file under the agent-visible .vf-pool workspace, and tool_hook.py reopens that same file for every hook, so it remains present throughout the rollout. When the model invokes Pool's shell or read tools, those same-UID processes can enumerate and read the file despite mode 0600, then forge policy requests or exfiltrate the capability; keep this credential in a trusted proxy or another channel unavailable to model-controlled tools.

Useful? React with 👍 / 👎.

Comment thread verifiers/v1/session.py
# stable shape so the next model request can be verified exactly.
if (
content == "nonempty_text"
and (phase != "before" or candidate != message)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 High v1/session.py:613

A successful no-output command is rejected in the after phase when content == "nonempty_text", even though no replacement was made, causing the Pool bridge to terminate the rollout. The phase != "before" clause makes the check run for unchanged post-tool results; apply the non-empty constraint only when candidate != message.

Suggested change
and (phase != "before" or candidate != message)
and candidate != message
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/session.py around line 613:

A successful no-output command is rejected in the `after` phase when `content == "nonempty_text"`, even though no replacement was made, causing the Pool bridge to terminate the rollout. The `phase != "before"` clause makes the check run for unchanged post-tool results; apply the non-empty constraint only when `candidate != message`.

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.

1 participant