# Understanding the Stop-Time Review Gate in the OpenAI Codex Plugin

> Learn about the stop time review gate, an optional safety checkpoint in the OpenAI Codex Plugin, that reviews Claude turns before session completion.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: deep-dive
- Published: 2026-07-08

---

**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:

1. **Collects the last Claude assistant message** from the session context, capturing any code changes performed in that turn.
2. **Builds a review prompt** using the template stored in [`plugins/codex/prompts/stop-review-gate.md`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/prompts/stop-review-gate.md), which instructs Codex to "Run a stop-gate review of the previous Claude turn."
3. **Spawns the Codex companion** (`codex-companion.mjs`) as a child process with a 15-minute timeout, passing the constructed prompt via `spawnSync()`.
4. **Parses the compact response** from Codex. If the first line begins with `ALLOW:`, the session proceeds to close. If it begins with `BLOCK:`, the hook emits a decision object that prevents session termination and provides a reason.
5. **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.

```bash

# 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:

```json
{
  "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:

```json
{
  "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:

```javascript
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`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/prompts/stop-review-gate.md) establishes a strict output contract for Codex:

```text
<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-cc` that reviews the last Claude turn before session termination.
- Configuration is managed through `state.mjs` with `stopReviewGate` defaulting to `false` and controllable via `setConfig` or CLI commands.
- The main hook at `plugins/codex/scripts/stop-review-gate-hook.mjs` orchestrates the review by spawning `codex-companion.mjs` with a 15-minute timeout.
- Codex returns either `ALLOW:` or `BLOCK:` as the first line of its response, determining whether the session can close.
- The feature requires the [`stop-review-gate.md`](https://github.com/openai/codex-plugin-cc/blob/main/stop-review-gate.md) prompt 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.