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) executesrunStopReview()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.mdenforces structured JSON responses for reliable parsing - A
truestop decision triggersemitDecision(), writes to the control channel, and halts the pipeline;falsepermits 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →