PreToolUse matcher bypassed for namespaced MultiAgentV2 spawn_agent
PreToolUse matcher bypassed for namespaced MultiAgentV2 spawn_agent
Codex version
Reproduced on codex-cli 0.146.0 and 0.147.0-alpha.4.
Problem
A managed PreToolUse hook whose matcher is spawn_agent (or its Agent
alias) blocks the non-namespaced/v1 native spawn path, but does not block the
MultiAgentV2 tool exposed as collaboration.spawn_agent. The namespaced spawn
executes even though the managed requirements and hook are loaded.
This makes a blanket native-subagent deny policy bypassable whenever
MultiAgentV2 is enabled.
Root cause
MultiAgentV2NamespaceOverride in codex-rs/core/src/tools/spec_plan.rs
forwards execution to the wrapped handler but does not forwardpre_tool_use_payload. The default runtime payload therefore uses the exposed
namespaced tool identity rather than the canonical hook identity expected by
the existing spawn_agent/Agent matcher mapping.
Minimal correction
Implement pre_tool_use_payload on MultiAgentV2NamespaceOverride, delegate
to the wrapped handler, and normalize the V2 spawn payload toHookToolName::spawn_agent(). A regression test can construct the namespaced
V2 spawn handler and assert that its pre-tool payload has canonical tool namespawn_agent and preserves the decoded input.
Verification
With that narrow patch applied to tag rust-v0.146.0:
- the focused Rust regression test passes;
- a real TUI call to
collaboration.spawn_agentreaches the managed
PreToolUse hook;
- the hook returns a blocked function-call result; and
- no child session is created.
Without the patch, equivalent live attempts on 0.146.0 and 0.147.0-alpha.4
create child sessions.