Skip to content

Add PreToolUse and PostToolUse hook events for code quality enforcement #14754

Closed

Description

@NavinAgrawal

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 start of hooks engine #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

Activity

  1. added
    enhancementNew feature or request
    CLIIssues related to the Codex CLI
    tool-callsIssues related to tool calling
    on Mar 15, 2026
  2. github-actions commented on Mar 15, 2026

    @github-actions
    Contributor
  3. raye-deng commented on Mar 15, 2026

    @raye-deng

    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.

  4. added
    agentIssues related to the core agent loop
    and removed
    CLIIssues related to the Codex CLI
    tool-callsIssues related to tool calling
    on Mar 15, 2026
  5. JuncongHe commented on Mar 24, 2026

    @JuncongHe

    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: feat(init): add experimental Codex adapter via subprocess-local PATH shims rtk-ai/rtk#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.

  6. rurban commented on Mar 26, 2026

    @rurban
  7. Zeoy2020 commented on Mar 26, 2026

    @Zeoy2020

    need it

  8. ppiankov commented on Mar 28, 2026

    @ppiankov

    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.

  9. gemini133 commented on Mar 28, 2026

    @gemini133
  10. gemini133 commented on Mar 29, 2026

    @gemini133

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

  11. added
    hooksIssues related to event hooks
    and removed
    agentIssues related to the core agent loop
    on Apr 2, 2026
  12. TyceHerrman commented on Apr 14, 2026

    @TyceHerrman

    Yea this seems like it could be closed. #16732 could be the spiritual successor for tracking expansion of pretooluse/posttooluse functionality (specifically matcher patterns).

  13. abhinav-oai commented on Apr 15, 2026

    @abhinav-oai
    Contributor

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

    Closing this issue out

  14. qdrddr commented on Apr 30, 2026

    @qdrddr

    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.

  15. abhinav-oai commented on Apr 30, 2026

    @abhinav-oai
    Contributor

    @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.

  16. qdrddr commented on Apr 30, 2026

    @qdrddr

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

  17. oxysoft commented on May 8, 2026

    @oxysoft

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthooksIssues related to event hooks

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions