How the Review Gate Stop Hook Executes a Targeted Codex Review on Claude's Response
The review gate Stop hook automatically intercepts Claude's final output, routes it through a specialized Codex review pipeline, and injects the structured feedback back into the conversation as a distinct assistant message.
The openai/codex-plugin-cc repository implements an automated quality assurance mechanism that evaluates Claude's responses using OpenAI's Codex model. When Claude finishes generating content, the review gate Stop hook triggers a targeted Codex review that validates the output against defined criteria before presenting results to the user.
Hook Registration and the Stop Event
The review gate Stop hook is defined in plugins/codex/scripts/stop-review-gate-hook.mjs. This module registers a listener for the stop lifecycle event, which fires immediately after Claude completes response generation.
When triggered, the hook receives the current session state from plugins/codex/scripts/lib/state.mjs, providing access to the full conversation history and metadata required to isolate the target message.
Isolating Claude's Final Output
Using the session state, the hook identifies state.lastClaudeMessage to extract Claude's most recent response. This targeted isolation ensures the review focuses exclusively on the newly generated content rather than re-evaluating previous messages in the conversation thread.
The extraction logic ensures that only the final assistant output is selected for review, preventing context pollution from earlier turns in the dialogue.
Building the Review Prompt
The hook constructs a review-oriented prompt by injecting Claude's response into the template stored at plugins/codex/prompts/stop-review-gate.md. The renderPrompt() function substitutes the response text into template variables, creating a contextualized request that instructs Codex to evaluate the output for quality, accuracy, and safety criteria.
This templating approach separates the review instructions from the execution logic, allowing prompt engineering adjustments without modifying the hook code.
Invoking the Codex Service
The prepared prompt is sent to the Codex service through the abstraction layer in plugins/codex/scripts/lib/codex.mjs. This helper module handles authentication, HTTP request construction, and response parsing, exposing a callCodex() interface that submits the review request and returns the raw evaluation data.
The helper manages low-level API interactions, ensuring consistent request formatting across the plugin.
Validating and Publishing the Review
Codex returns a structured review that must conform to the JSON schema defined in plugins/codex/schemas/review-output.schema.json. The hook validates the result against this schema to ensure required fields such as severity ratings and specific observations are present.
Upon successful validation, the hook publishes the review back into the session using addMessage() from the state module, assigning the assistant role to the review message. This makes the Codex evaluation visible in the Claude conversation as a distinct message, available to both users and downstream automation tools.
Implementation Workflow
The following JavaScript demonstrates the core orchestration logic inside stop-review-gate-hook.mjs:
// Simplified flow inside stop-review-gate-hook.mjs
import { getState, addMessage } from "./lib/state.mjs";
import { renderPrompt } from "./lib/prompts.mjs";
import { callCodex } from "./lib/codex.mjs";
import { validate } from "./../schemas/review-output.schema.json";
export async function onStop() {
const state = await getState(); // get current session
const claudeMsg = state.lastClaudeMessage; // Claude's final output
const prompt = renderPrompt("stop-review-gate", { // inject into template
response: claudeMsg.text,
});
const codexResult = await callCodex(prompt); // ask Codex for review
if (!validate(codexResult)) throw new Error("Bad review");
await addMessage({ // post review back to session
role: "assistant",
content: codexResult.review,
});
}
Summary
- The review gate Stop hook registers in
plugins/codex/scripts/stop-review-gate-hook.mjsand triggers on thestoplifecycle event immediately after Claude completes generation - Claude's final output is extracted from session state via
state.lastClaudeMessageinplugins/codex/scripts/lib/state.mjs - The hook utilizes the prompt template at
plugins/codex/prompts/stop-review-gate.mdto frame the targeted Codex review request - Codex API calls are abstracted through
plugins/codex/scripts/lib/codex.mjswith structured output validation againstplugins/codex/schemas/review-output.schema.json - Validated reviews are re-injected into the conversation using
addMessage(), making them visible as assistant messages
Frequently Asked Questions
What triggers the review gate Stop hook in codex-plugin-cc?
The hook activates immediately after Claude completes response generation, listening for the stop lifecycle event defined in plugins/codex/scripts/stop-review-gate-hook.mjs. This event fires automatically at the end of every Claude response, creating a consistent review checkpoint.
How does the Stop hook isolate Claude's specific response for review?
The hook accesses the current session through getState() in plugins/codex/scripts/lib/state.mjs and references state.lastClaudeMessage to extract only the most recent assistant output. This ensures the review targets the correct content without processing the entire conversation history, making the evaluation both targeted and efficient.
What validates the Codex review output format?
The review must conform to plugins/codex/schemas/review-output.schema.json, which defines the expected JSON structure including review categories, severity levels, and descriptive feedback fields. The hook validates Codex's response against this schema before accepting it, ensuring downstream components receive properly structured data.
Can the review criteria be customized without modifying the hook implementation?
Yes. By editing plugins/codex/prompts/stop-review-gate.md to include different evaluation instructions or updating the JSON schema to require additional fields, you can adjust review criteria. The modular architecture separates prompt engineering from execution logic, allowing targeted adjustments to the review process without changing the core hook code in stop-review-gate-hook.mjs.
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 →