Skip to content

Add reusable interception guards - #2167

Closed
xeophon wants to merge 17 commits into
agent/intercept-terminalfrom
agent/intercept-policies
Closed

Add reusable interception guards#2167
xeophon wants to merge 17 commits into
agent/intercept-terminalfrom
agent/intercept-policies

Conversation

@xeophon

@xeophon xeophon commented Jul 29, 2026

Copy link
Copy Markdown
Member

Overview

This adds reusable guards for common tool checks and a minimal trace-based interface for custom guards.

A custom @vf.intercept handler receives one vf.Trace. During interception, trace.messages contains the current exchange and trace.last_message is the candidate crossing the model boundary. Returning trace.replace(content) creates an inert replacement of the same message kind.

What this PR adds

  • trace.messages, trace.last_message, and trace.replace(content) for custom handlers.
  • Typed same-kind message rewrites.
  • Ordinary judge classification recorded through the same trace.
  • Exact alias and glob matching for tool names.
  • Reusable guards for tool calls, shell commands, web search, and code search.
  • Provider-hosted tool filtering.
  • A Codex option that installs the code-search guard.

Stack

This is PR 4 of 5. Each PR is based on the one before it and is intended to merge in order.

  1. Stream replay safety — keep an explicitly retried streamed request on the same model response.
  2. Request and response interception — run @vf.intercept before model requests and before responses reach the harness, and make rewrites canonical.
  3. Terminal interception — let a guard end a rollout with a final reason and reward.
  4. Reusable guards — add common tool guards and make custom handlers operate directly on vf.Trace.
  5. Example environment — show deterministic and judge-backed trace guards directly with @vf.intercept in a runnable taskset.

Comment thread verifiers/v1/intercepts/tools.py Outdated
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.py Outdated
Comment thread verifiers/v1/intercepts/tools.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: 36407cf3a0

ℹ️ 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/intercepts/tools.py
Comment thread verifiers/v1/dialects/base.py
@macroscopeapp

macroscopeapp Bot commented Jul 29, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

This PR introduces new interception guards with complex shell parsing logic. Multiple unresolved P1/P2 review comments identify security bypass vulnerabilities in the command parsing (process substitution, bash -c --, code_interpreter payloads). The security-relevant nature of these guards combined with identified bypass issues warrants human review.

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

Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/dialects/base.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: 74f1e493a5

ℹ️ 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/dialects/base.py
Comment thread verifiers/v1/dialects/base.py
Comment thread verifiers/v1/intercepts/tools.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: 093b0cb96a

ℹ️ 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/intercepts/tools.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: d7aeccfdfd

ℹ️ 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/intercepts/tools.py Outdated
Comment thread verifiers/v1/intercepts/tools.py
@xeophon xeophon changed the title Add reusable interception policies Add reusable interception guards Jul 29, 2026
Comment thread verifiers/v1/intercepts/tools.py Outdated
Comment thread verifiers/v1/intercepts/tools.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: fd22cb5334

ℹ️ 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/intercepts/tools.py Outdated
Comment thread verifiers/v1/dialects/base.py
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.py Outdated
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.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: aab863436d

ℹ️ 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/dialects/base.py Outdated
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/dialects/base.py
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.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: 7576740771

ℹ️ 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/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.py
Comment thread verifiers/v1/intercepts/tools.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: c968feef7e

ℹ️ 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/intercepts/tools.py
@xeophon
xeophon force-pushed the agent/intercept-terminal branch from ec20775 to 04864d3 Compare July 29, 2026 18:09
@xeophon
xeophon force-pushed the agent/intercept-policies branch from 658f576 to cec154b Compare July 29, 2026 18:09

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

ℹ️ 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".

continue
segments = [[]]
for token in tokens:
if token and set(token) <= set("{};&|()"):

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 Parse commands inside process substitutions

When a restricted executable is launched through Bash process substitution, such as cat <(rm -rf /tmp/x), the punctuation splitter retains <( in the outer segment and never emits rm as a separate invocation. As a result, intercept_shell_commands("rm") allows the deletion to execute; the same bypass affects intercept_code_search() for inputs such as cat <(rg secret .). Parse the command body of <(...) and >(...) as an independent pending invocation.

Useful? React with 👍 / 👎.

has_command = any(
key in source
for source in sources
for key in ("command", "commands", "cmd")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include code-interpreter payloads in command extraction

When a code_interpreter_call contains shell syntax in its code field, such as {"code":"!rm -rf /tmp/x"}, alias normalization sends it through the Bash guard, but command extraction only recognizes command, commands, and cmd, so intercept_shell_commands("rm") receives an empty string; intercept_code_search() similarly misses !rg secret .. Fresh evidence beyond the earlier intercept_tool_calls case is that its new raw_fallback=True does not apply to these two commands_only=True paths, so include the code payload or stop classifying code-interpreter calls as shell-shaped.

Useful? React with 👍 / 👎.

@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: 54a609e04c

ℹ️ 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 on lines +302 to +303
elif index + 1 < len(segment):
pending.append(segment[index + 1])

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 Skip -- before the nested shell command

When a guarded command is launched as bash -c -- 'rm -rf /tmp/x' (or bash -lc -- 'rg secret .'), Bash treats the argument after -- as the -c command, but this branch queues -- itself and never inspects the actual payload. bash --help documents the invocation form as -c command, and Bash 5.2 confirms that the examples execute, so both shell-command and code-search guards are bypassed. Fresh evidence beyond the earlier nested-shell finding is this still-unhandled end-of-options form; skip the optional -- before queuing the command string.

Useful? React with 👍 / 👎.

@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 54a609e. Configure here.

elif kind != "function_call" and kind.endswith(("_call", "_tool_result")):
name = item.get("name") or kind.removesuffix("_tool_result").removesuffix(
"_call"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Custom tool calls counted twice

Low Severity

_tool_calls skips function_call items in provider_state because they already live in tool_calls, but still ingests custom_tool_call. Dialects put both kinds into tool_calls and keep the raw items in provider_state, so custom calls are duplicated. That can inflate call lists and make containing checks match on the extra copy.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 54a609e. Configure here.

"stderr": "",
"outcome": {"type": "exit", "exit_code": 0},
}
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Blocked shell reports success

Medium Severity

Rewriting a shell_call_output always sets exit_code to 0, so a blocked command looks successful. Guards that rewrite bash tool results (rather than terminate) can leave the model believing the command worked despite the block text in stdout.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 54a609e. Configure here.

@xeophon

xeophon commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

Superseded by #2178, which replaces this guard layer with the reworked interception surface (typed rules, prebuilt guards, backend simplifications).

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