Problem
On Codex, a first tool use triggers a frustrating register-and-retry loop:
- Agent reads a file -> PreToolUse blocks: `ArmorCodex intent mismatch: parameters not allowed for Bash`
- Agent registers a plan with `action: "exec_command"` (Codex's API tool name)
- PreToolUse blocks: `ArmorIQ intent drift: tool not in plan (Bash)` -- because Codex reports the shell tool as `Bash` at the hook layer, and `normalizeToolName` only lowercases, so `exec_command != bash`
- Agent re-registers with `action: "Bash"` -> finally allowed
This wastes turns and makes the plugin feel like it's fighting the user.
Root cause
plugins/armorcodex/scripts/lib/common.mjs normalizeToolName only trims+lowercases; no alias between Codex's shell tool names (exec_command/shell/local_shell/unified_exec) and Bash.
- The
register_intent_plan directive (engine.mjs) says "action = tool name" without telling the model the canonical names, so it guesses exec_command.
Fix
- Alias the Codex shell family to
bash in normalizeToolName so a plan declaring any of them matches the actual Bash tool call (and policy rules for bash cover the shell family).
- Make the
register_intent_plan directive name the canonical tools (Bash for shell, apply_patch for edits, exact MCP tool name), and tell the agent to register all tools up front with metadata.inputs: {}.
- Tests in
tests/tool-alias.test.mjs.
Refs
Part of the ArmorCodex parity work (#41). Fix on branch feat/armor-policy-parity.
Problem
On Codex, a first tool use triggers a frustrating register-and-retry loop:
This wastes turns and makes the plugin feel like it's fighting the user.
Root cause
plugins/armorcodex/scripts/lib/common.mjsnormalizeToolNameonly trims+lowercases; no alias between Codex's shell tool names (exec_command/shell/local_shell/unified_exec) andBash.register_intent_plandirective (engine.mjs) says "action = tool name" without telling the model the canonical names, so it guessesexec_command.Fix
bashinnormalizeToolNameso a plan declaring any of them matches the actualBashtool call (and policy rules forbashcover the shell family).register_intent_plandirective name the canonical tools (Bashfor shell,apply_patchfor edits, exact MCP tool name), and tell the agent to register all tools up front withmetadata.inputs: {}.tests/tool-alias.test.mjs.Refs
Part of the ArmorCodex parity work (#41). Fix on branch feat/armor-policy-parity.