Understanding the Stop-Time Review Gate in the OpenAI Codex Plugin
The stop-time review gate is an optional safety checkpoint that runs a Codex-driven review of the immediately preceding Claude turn before allowing a session to finish.
The stop-time review gate feature in the openai/codex-plugin-cc repository provides an automated quality assurance mechanism that vets code changes before a session closes. This configurable safety layer intercepts the session termination process to ensure the last assistant turn doesn't introduce regressions or incomplete implementations.
How the Stop-Time Review Gate Works
When enabled, the stop-time review gate operates as a final checkpoint in the session lifecycle. The system captures the last assistant message, evaluates it through a Codex-powered review process, and either permits the session to end or blocks it based on the review outcome.
Configuration and State Management
The gate's configuration lives in the plugin's state system, specifically in plugins/codex/scripts/lib/state.mjs. By default, the stopReviewGate setting is initialized to false, meaning the feature is opt-in.
Users can toggle this setting through the /codex:setup command or by directly invoking setConfig to update the JSON configuration. When config.stopReviewGate is set to true, the hook becomes active and will execute during session termination.
The Review Execution Flow
The main orchestration logic resides in plugins/codex/scripts/stop-review-gate-hook.mjs. When a session attempts to close, the hook executes the following sequence:
- Collects the last Claude assistant message from the session context, capturing any code changes performed in that turn.
- Builds a review prompt using the template stored in
plugins/codex/prompts/stop-review-gate.md, which instructs Codex to "Run a stop-gate review of the previous Claude turn." - Spawns the Codex companion (
codex-companion.mjs) as a child process with a 15-minute timeout, passing the constructed prompt viaspawnSync(). - Parses the compact response from Codex. If the first line begins with
ALLOW:, the session proceeds to close. If it begins withBLOCK:, the hook emits a decision object that prevents session termination and provides a reason. - Handles disabled states by logging a note and allowing the session to end when the gate is disabled or Codex isn't configured for the workspace.
The prompt template is loaded through plugins/codex/scripts/lib/prompts.mjs, which handles interpolation of the {{CLAUDE_RESPONSE_BLOCK}} variable containing the assistant's output to be reviewed.
Enabling and Configuring the Gate
You can activate the stop-time review gate using the CLI configuration system provided by the plugin.
# Inside a Codex-enabled workspace
codex config set stopReviewGate true
This command updates the persistent configuration stored in state.mjs. When enabled, every session termination will trigger the review process unless Codex is not configured for the current workspace.
Implementation Details and Code Examples
Hook Input Format
The stop-review-gate-hook.mjs script expects a JSON payload via stdin containing the session context:
{
"cwd": "/path/to/project",
"last_assistant_message": "Added new API endpoint …",
"session_id": "abc123"
}
Decision Output Format
When the gate blocks a session, it outputs a JSON decision object to stdout:
{
"decision": "block",
"reason": "Codex stop-time review found issues ... "
}
If the review passes, the hook exits silently without writing to stdout.
Programmatic Usage
You can invoke the gate programmatically using Node.js child processes:
import { spawnSync } from "child_process";
import path from "path";
const hookPath = path.join(__dirname, "plugins/codex/scripts/stop-review-gate-hook.mjs");
const payload = JSON.stringify({
last_assistant_message: "...",
cwd: process.cwd()
});
const result = spawnSync("node", [hookPath], {
input: payload,
encoding: "utf8"
});
if (result.stdout) {
const decision = JSON.parse(result.stdout);
console.log(`Gate decision: ${decision.decision}`);
}
Review Prompt Structure
The prompt template in plugins/codex/prompts/stop-review-gate.md establishes a strict output contract for Codex:
<task>
Run a stop-gate review of the previous Claude turn.
Only review the work from the previous Claude turn.
Only review it if Claude actually did code changes in that turn.
...
{{CLAUDE_RESPONSE_BLOCK}}
</task>
<compact_output_contract>
Return a compact final answer.
Your first line must be exactly one of:
- ALLOW: <short reason>
- BLOCK: <short reason>
...
</compact_output_contract>
This structure ensures Codex returns machine-parseable responses that the hook can evaluate without complex parsing logic.
Summary
- The stop-time review gate is an optional safety feature in
openai/codex-plugin-ccthat reviews the last Claude turn before session termination. - Configuration is managed through
state.mjswithstopReviewGatedefaulting tofalseand controllable viasetConfigor CLI commands. - The main hook at
plugins/codex/scripts/stop-review-gate-hook.mjsorchestrates the review by spawningcodex-companion.mjswith a 15-minute timeout. - Codex returns either
ALLOW:orBLOCK:as the first line of its response, determining whether the session can close. - The feature requires the
stop-review-gate.mdprompt template and the companion script to be properly configured in the workspace.
Frequently Asked Questions
What triggers the stop-time review gate to execute?
The gate triggers when a session attempts to terminate and config.stopReviewGate is set to true in the plugin state. The hook reads the session context via readHookInput() from stdin, retrieves the last assistant message, and initiates the review process only if Codex is configured for the workspace.
How does the gate determine whether to allow or block a session?
The gate parses the first line of Codex's response in parseStopReviewOutput(). If the line starts with ALLOW:, the session proceeds. If it starts with BLOCK:, the hook emits a decision object with "decision": "block" and a reason string. Any other response format would likely cause the hook to fail or default to blocking, though the code specifically checks for these two prefixes.
Where is the stop-time review gate configuration stored?
Configuration persists in the plugin's state management system implemented in plugins/codex/scripts/lib/state.mjs. The stopReviewGate boolean is part of the default configuration object, and users modify it through the setConfig method or the /codex:setup interface, which writes to the workspace's stored JSON state.
Can the stop-time review gate run without Codex being configured for the workspace?
No. If Codex isn't set up for the workspace, the hook detects this condition and logs a note before allowing the session to end normally. The gate requires the codex-companion.mjs script to be available and executable, as it spawns this process to perform the actual review using the OpenAI Codex API.
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 →