Add PreToolUse and PostToolUse hook events for code quality enforcement

Resolved 💬 14 comments Opened Mar 15, 2026 by NavinAgrawal Closed Apr 15, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex v0.114.0 added experimental hooks with SessionStart and Stop events (PR #13276). This is a great foundation, but the two most impactful hook events are missing: PreToolUse and PostToolUse.

Without these, it is impossible to enforce code quality gates, block destructive commands, or validate tool outputs - capabilities that are production-critical for teams with shared coding standards.

What I need

| Event | Purpose | Example |
|-------|---------|---------|
| PreToolUse | Validate/block BEFORE a tool runs | Block rm -rf ~/, git push --force main, git reset --hard. Block commits with secrets. Require plan approval before exiting plan mode. |
| PostToolUse | Validate/block AFTER a tool runs | Block shallow test patterns (assert True, XCTAssertTrue(true)). Block f-string loggers in Python. Warn about console.log in JS/TS. |

Real hooks I have ready to go

I have 5 production enforcement hooks written and working in Claude Code that I cannot use in Codex:

  1. block-shallow-tests.sh - PostToolUse on Write/Edit of test files. Catches 15+ worthless test patterns across Python, Swift, and TypeScript. Blocks the edit with exit code 2.
  2. block-fstring-loggers.sh - PostToolUse on Write/Edit of .py files. Catches logger.info(f"...") (should use %s lazy format) and datetime.utcnow() (deprecated). Blocks the edit.
  3. block-dangerous-bash.sh - PreToolUse on Bash. Blocks rm -rf ~/, git push --force main/master, git reset --hard, git clean -f. Exit code 2.
  4. commit-guard.sh - PreToolUse on Bash git commit. Scans staged files for hardcoded secrets, http:// URLs, console.log. Hard-blocks on secrets (exit 2), warns on others.
  5. require-plan-approval.sh - PreToolUse on ExitPlanMode. Blocks auto-exit from plan mode so user can review.

These all use the same JSON stdin/stdout protocol as the existing SessionStart/Stop hooks. The matcher syntax from Claude Code (tool == "Bash" && tool_input.command matches "^git\\s+commit") would be ideal but even a simple tool-name matcher would work.

Proposed schema additions

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "tool == \"Bash\"",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/block-dangerous-bash.sh",
            "timeout": 5
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "tool == \"Write\" && tool_input.file_path matches \"test_\"",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/block-shallow-tests.sh",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Input schema for PreToolUse would need tool_name and tool_input fields. Output schema needs a decision field with "allow" or "block" values. Exit code 2 = block is the Claude Code convention and works well.

Why this matters

  • Codex runs with sandbox_mode = "danger-full-access" for trusted projects. Without PreToolUse hooks, there is no safety net for destructive commands.
  • Code quality enforcement (test patterns, logging standards) currently only works in Claude Code. Teams using both tools get inconsistent quality.
  • The hooks engine infrastructure from PR #13276 already supports the pattern - this is adding two new event types to an existing framework.

Environment

  • Codex CLI: 0.114.0
  • macOS 15.4 (Darwin 25.3.0)
  • 5 enforcement hooks ready, tested in Claude Code, waiting for Codex support

View original on GitHub ↗

14 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • ##14203
  • ##13991

Powered by Codex Action

raye-deng · 4 months ago

This is exactly the hook model we've been using in our CI pipeline. PreToolUse and PostToolUse are the two events that make quality enforcement actually practical.

In our case, we use them to catch a specific class of AI-code defects that traditional CI completely misses:

  • PostToolUse on file writes: After an AI agent writes a file, we scan it for hallucinated imports (packages that don't exist on npm/PyPI). These pass TypeScript compilation and unit tests but crash in production.
  • PostToolUse on test generation: We flag shallow test patterns (assert True, trivial mocks) that give a false sense of coverage.

The SessionStart/Stop hooks are useful for orchestration, but without PreToolUse/PostToolUse, you can only enforce quality at the boundaries (before session starts, after it ends) — not at the point of action where the defects are actually introduced.

We open-sourced the scanning logic as a standalone tool that works as a PR-level check. For anyone wanting to see what these PostToolUse quality gates look like in practice:

npx @opencodereview/cli scan . --sla L1

It detects hallucinated packages, deprecated API usage, and over-engineering patterns — the stuff that SonarQube and ESLint literally cannot see.

HeMuling · 3 months ago

I wonder if openai team had decided to support this feature or not?

Here's another case that these hooks might be useful: https://github.com/rtk-ai/rtk

Specifically:

  • RTK rewrites common development commands to reduce LLM token consumption by roughly 60–90%.
  • RTK already supports Claude Code and OpenCode, because Claude Code provides a PreToolUse hook and OpenCode provides tool.execute.before.
  • Codex currently supports neither of these. Because of that, I previously added an experimental RTK integration that relies on Codex subprocess configuration to rewrite commands instead: https://github.com/rtk-ai/rtk/pull/642

Native support for a PreToolUse-style hook in Codex would be much cleaner.

If this is not something you plan to support, I would still appreciate guidance on whether it makes sense for me to continue maintaining the experimental RTK workaround.

rurban · 3 months ago
Zeoy2020 · 3 months ago

need it

ppiankov · 3 months ago

Adding another concrete use case: pastewatch — a secret redaction tool that prevents credentials from reaching AI APIs.

We use PreToolUse hooks on Claude Code and Cline today to intercept Read/Write/Edit tool calls. When the target file contains secrets (API keys, DB credentials, tokens), the hook blocks native file access and redirects the agent to use MCP tools that return redacted placeholders instead.

Without PreToolUse, agents bypass MCP and send raw secrets to the API. Our API proxy catches these at the network boundary, but hook-level enforcement is defense in depth — it prevents the leak before the request is even constructed.

What we need:

  • PreToolUse with tool name matching (e.g., shell_command, read_file, write_file)
  • Ability to block execution (exit code or JSON response)
  • Hook stdout/stderr visible to the agent (so it knows why and what to do instead)

We currently support structural enforcement on Claude Code and Cline, with advisory-only on Codex CLI. PreToolUse hooks would let us upgrade Codex to structural enforcement.

Ref: anomalyco/opencode#12472 — same request for OpenCode, with a community PR submitted.

gemini133 · 3 months ago

<img width="755" height="333" alt="Image" src="https://github.com/user-attachments/assets/487c2684-9986-4d15-9187-e6178afd8244" />

https://developers.openai.com/codex/hooks

it's built?

gemini133 · 3 months ago

@HeMuling
codex v0.117.0 has pretooluse hook added but it doesn't support updatedInput in the response yet.

TyceHerrman · 3 months ago

Yea this seems like it could be closed. https://github.com/openai/codex/issues/16732 could be the spiritual successor for tracking expansion of pretooluse/posttooluse functionality (specifically matcher patterns).

abhinav-oai contributor · 3 months ago

We now support the PreToolUse and PostToolUse hooks to intercept the Bash tool - https://developers.openai.com/codex/hooks#pretooluse

Closing this issue out

qdrddr · 2 months ago

I want to define before_llm and after_llm hooks that let me inject additional context before the model runs and then validate afterward that the model complied with those injected constraints. For example, I could prepend a directive such as “use only these tools:” followed by an allowed‑tools list, and then verify that the model’s generated output intends to call only the permitted tools.

abhinav-oai contributor · 2 months ago

@qdrddr what about using the UserPromptSubmit and Stop hook? The former will run before every turn and the latter at the end of each turn.

qdrddr · 2 months ago

Hm. I'll look at UserPromptSubmit
While the after LLM could be PreToolUse
Thanks @abhinav-oai

oxysoft · 2 months ago

Indexed this hook ticket in the umbrella tracker: #21753

Goal: collect the scattered Codex hook requests and bugs into one parity matrix for Full Claude Code Hook Parity (29+), while preserving this issue as the detailed thread for its specific behavior.