Codex apply_patch adapter drops edit content, silently defeating contentPatterns block guardrails on new files
Summary
The README's "Works with Codex Too" section states that edit blocking for block-enforced skills runs identically under both Claude Code and Codex (the only documented parity gap being the missing Skill tool event). I found a second, undocumented parity gap: content-based guardrails don't fire under Codex when creating new files.
Root cause
.codex/hooks/_codex-adapter.sh translates Codex's apply_patch into a synthetic Edit event containing only {tool_input: {file_path: ...}} — it does not include the patch content (new_string/content).
skill-verification-guard.ts's getEditContent() relies on those fields to get the edit text for contentPatterns matching. When they're absent, it falls back to readFileSync(filePath) — but for an apply_patch "Add File" operation, the target file doesn't exist yet at PreToolUse time, so existsSync(filePath) is false and the fallback also comes back empty. contentMatch therefore stays false.
Since shouldTrigger = pathMatch && (contentMatch || !fileTriggers.contentPatterns), any guardrail configured with contentPatterns (in this repo, frontend-dev-guidelines's MUI detection is the only enforcement: block guardrail with contentPatterns) never triggers when Codex creates a new matching file — even though the same operation via Claude Code's native Write tool (which does supply content directly) would block it.
Reproduction
- Install this repo's
.claude/+.codex/into a project with thefrontend-dev-guidelinesguardrail configured. - Under Claude Code: ask it to create a new
.tsxfile containing MUI-triggering code → blocked as expected. - Under Codex (same prompt, same trigger content) → not blocked, because the adapter never forwards the new file's content to the guard.
Suggested fix
Have _codex-adapter.sh include the patch body (or at least the new-file content for "Add File" operations) in the synthesized event's tool_input, so getEditContent() has something to match against without needing to read a file that doesn't exist yet.
Related
Separate from the already-documented Skill-tool-event parity gap in the README — this one isn't currently disclosed anywhere.
Source: diet103/claude-code-infrastructure-showcase