What Is the Review Gate in the Codex Plugin? How the Stop Hook Prevents Reviews

The review gate is a safety mechanism in the Codex plugin that automatically intercepts every review before it starts, running an LLM-powered check that can abort the session based on contextual risk assessment.

The review gate feature in the openai/codex-plugin-cc repository provides a programmable checkpoint that evaluates whether a code review should proceed. At its core sits the Stop hook, a specialized script that queries an LLM with repository context and halts the pipeline when safety concerns are detected. This article examines the complete execution flow, from hook registration through decision emission.

How the Review Gate Architecture Works

The review gate operates as a pre-flight safety system embedded in the Codex plugin's job pipeline. Unlike manual review approvals, this gate runs automatically without user intervention, making it ideal for enforcing organizational policies or preventing expensive LLM calls in problematic states.

Hook Registration via hooks.json

The plugin runtime discovers the Stop hook through a declarative manifest located at plugins/codex/hooks/hooks.json. This file associates stop‑review‑gate‑hook.mjs with the "review‑gate" purpose, instructing the runtime to invoke it during the pre‑review phase.

When any workflow triggers a review step—whether through the codex review command or an indirect pipeline call—the runtime consults this manifest and queues the registered gate hooks.

The Core Hook Implementation

The primary logic resides in plugins/codex/scripts/stop‑review‑gate‑hook.mjs. Its main() function delegates to runStopReview(), which orchestrates the LLM query and parses the response.

// plugins/codex/scripts/stop-review-gate-hook.mjs (simplified flow)
import { runStopReview } from "./stop-review-gate-hook.mjs";

async function prepareReview(session) {
  // Runtime sets up job list, loads state, prepares context
  await runStopReview(process.cwd(), { session });
  // If emitDecision() wrote a "stop" payload, runtime throws here
  // and subsequent review steps are bypassed entirely
}

The runStopReview() function performs three critical operations: context assembly, LLM invocation, and decision parsing.

Inside the Stop Hook Execution Flow

Step 1: Context Assembly

The hook collects operational data through plugins/codex/scripts/lib/state.mjs, gathering:

  • Current working directory
  • Pending job list from the active session
  • Existing notes or flags attached to the review job

This context is injected into the prompt template at plugins/codex/prompts/stop-review-gate.md.

Step 2: LLM Query with Structured Prompt

The prompt template enforces a strict JSON output format, eliminating parsing ambiguity:


# plugins/codex/prompts/stop-review-gate.md

You are a safety‑oriented assistant.  
Given the list of pending jobs and the current repository state, decide
whether the review should be stopped. Respond with JSON:

{
  "stop": <true|false>,
  "reason": "<optional short explanation>"
}

The hook sends this assembled prompt via the internal codex client supplied by plugins/codex/scripts/lib/codex.mjs.

Step 3: Decision Parsing and Emission

The parseStopReviewOutput() function validates the LLM's JSON reply. Two outcomes are possible:

  • { "stop": true, "reason": "..." } — emitDecision() writes a stop payload to the job's control channel. The runtime consumes this and terminates the review pipeline, persisting the reason as a job note.
  • { "stop": false } — The hook returns silently, allowing normal review processing to continue.

Key Files and Their Roles

File Responsibility
plugins/codex/scripts/stop‑review‑gate‑hook.mjs Implements runStopReview(), parseStopReviewOutput(), and emitDecision(); main entry point for gate logic
plugins/codex/prompts/stop-review-gate.md Defines the LLM prompt template with enforced JSON schema
plugins/codex/hooks/hooks.json Declarative manifest binding the hook to the "review‑gate" lifecycle event
plugins/codex/scripts/lib/codex.mjs Provides authenticated LLM client for prompt submission
plugins/codex/scripts/lib/state.mjs Supplies runtime context: jobs, notes, and environment state

When to Use the Review Gate Stop Hook

The Stop hook excels in scenarios requiring automated review suppression:

  • Cost control — Prevent LLM calls when job lists exceed configured thresholds or contain non-reviewable artifacts
  • Policy enforcement — Block reviews on branches with failing CI status or unsigned commits
  • Safety interlocks — Halt reviews when dependency vulnerabilities or secrets detection tools flag critical issues

Because the decision logic lives in a customizable prompt template, operators can adapt the gate's behavior without modifying JavaScript code—only the markdown prompt requires changes.

Summary

  • The review gate is an automatic checkpoint that runs before every Codex review session, as implemented in openai/codex-plugin-cc
  • The Stop hook (stop‑review‑gate‑hook.mjs) executes runStopReview() to query an LLM and conditionally abort
  • Hook registration occurs via hooks.json, which binds the script to the "review‑gate" purpose
  • The prompt template at stop-review-gate.md enforces structured JSON responses for reliable parsing
  • A true stop decision triggers emitDecision(), writes to the control channel, and halts the pipeline; false permits normal execution

Frequently Asked Questions

How does the review gate differ from manual review approval?

The review gate operates automatically without human intervention. While manual approvals require a person to click or command-approve, the Stop hook evaluates context programmatically through an LLM query and enforces stopping decisions instantly. This makes it suitable for high-volume or policy-driven workflows where latency and consistency matter.

Can I customize what triggers a stop decision?

Yes. The decision criteria live in the prompt template at plugins/codex/prompts/stop-review-gate.md. Modify this file to change what contextual signals the LLM should evaluate—job count thresholds, specific file patterns, environment variables, or external API states—without touching the hook's JavaScript implementation.

What happens if the LLM returns malformed JSON?

The analysis source does not specify explicit error handling, but parseStopReviewOutput() implies a parsing layer. In practice, malformed responses would likely fail parsing, default to a conservative stop decision or throw an error that the runtime logs. For production use, operators should monitor hook execution logs and consider adding a validation fallback in the prompt instructions.

Is the Stop hook the only hook type in the Codex plugin?

No. The hooks.json manifest supports multiple hook purposes, with "review‑gate" being one lifecycle event. The plugin architecture allows additional hooks to register for the same or different phases, enabling chained or complementary automation. The Stop hook's specific role is pre‑review evaluation and conditional abortion.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →