# Stop Review Gate Mechanism in the OpenAI Codex Plugin: Integration with Claude's Lifecycle

> Understand the stop review gate mechanism in OpenAI Codex plugin. Learn how it automatically reviews code changes and integrates with Claude's lifecycle to control session termination.

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

---

**The stop review gate is a safety hook that automatically reviews code changes at the end of each Claude turn and emits an `ALLOW` or `BLOCK` decision to determine whether the session may terminate.**

The **stop review gate mechanism** in the `openai/codex-plugin-cc` repository provides an automated code review checkpoint that intercepts Claude's session termination. This safety feature ensures that any code modifications produced during a Claude turn are vetted by Codex before the session officially closes. Understanding how this mechanism integrates with Claude's lifecycle is essential for developers configuring automated review pipelines.

## What Is the Stop Review Gate?

The stop review gate is a deterministic checkpoint implemented in `stop-review-gate-hook.mjs` that runs as part of Claude's "stop-gate" step. Its purpose is to automatically perform a brief Codex-driven review of the code changes produced by the just-finished Claude turn. The gate decides whether the session may be terminated (`ALLOW`) or must be paused (`BLOCK`) based on the review outcome.

When active, the hook receives a JSON payload on **STDIN** containing the previous Claude message (`last_assistant_message`) and the current working directory (`cwd`). It then orchestrates a review task that must complete within **15 minutes** (`STOP_REVIEW_TIMEOUT_MS`) before allowing the session to proceed toward termination.

## How the Stop Review Gate Processes Code Changes

The mechanism follows a six-step pipeline to evaluate code changes before session termination.

### Triggering the Hook via STDIN

Claude invokes the `stop-review-gate-hook.mjs` script as part of the stop-gate step that occurs just before a session would finish. The hook receives input data through standard input in the following format:

```json
{
  "session_id": "abc123",
  "cwd": "/path/to/repo",
  "last_assistant_message": "Implemented foo() and added tests."
}

```

This payload provides the context necessary to associate the review with the correct session and working directory.

### Configuration Validation with getConfig

Before executing the review, the hook loads the repository-wide configuration via `getConfig` from `state.mjs`. If `config.stopReviewGate` is disabled, the hook simply logs any running Codex task and returns immediately, allowing the session to end without a review.

This configuration check ensures that the gate respects user preferences and can be bypassed in environments where automated review is not required.

### Building the Review Prompt

The hook constructs the review prompt by loading the [`stop-review-gate.md`](https://github.com/openai/codex-plugin-cc/blob/main/stop-review-gate.md) template and interpolating the previous Claude response into the `{{CLAUDE_RESPONSE_BLOCK}}` placeholder. The template instructs Codex to focus exclusively on code-changing statements from the prior turn and to emit a compact decision line using the `ALLOW:` or `BLOCK:` format.

This targeted approach ensures that the review concentrates on actual code modifications rather than conversational text.

### Executing the Codex Review Task

The script launches `codex-companion.mjs` as a child process using `spawnSync` with the prepared prompt. The operation waits up to **15 minutes** for completion, after which the child returns a JSON payload. The `rawOutput` field contains the textual answer from Codex.

During this phase, the gate leverages the Codex broker managed by `broker-lifecycle.mjs` to execute the review task asynchronously while blocking the session termination thread.

### Parsing ALLOW and BLOCK Decisions

The `parseStopReviewOutput` function examines the first line of Codex's answer to determine the gate decision:

- **`ALLOW:`** → The gate passes, permitting the session to finish normally.
- **`BLOCK:`** → The gate blocks the session and returns the supplied reason.

Any missing, malformed, or timed-out output is treated as a failure, causing the gate to emit a `block` decision with a helpful error message.

### Emitting the Decision to STDOUT

On a block decision, the script writes a JSON object to **STDOUT** in the following format:

```json
{
  "decision": "block",
  "reason": "Codex stop-time review found issues that still need fixes before ending the session: Missing error handling in foo()."
}

```

On success, the script only logs any still-running Codex jobs and allows the normal Claude shutdown to proceed without emitting additional output.

## Integration with Claude's Session Lifecycle

The stop review gate integrates deeply with Claude's lifecycle through the `session-lifecycle-hook.mjs` handler, which manages two critical events.

### Session Lifecycle Hook Events

The session lifecycle hook handles `SessionStart` and `SessionEnd` events:

- **SessionStart**: Records the session ID and transcript path in the environment so that subsequent hooks, including the stop-review gate, can associate jobs with the correct session.
- **SessionEnd**: Shuts down the Codex broker, terminates any still-running Codex jobs, and clears session-specific state.

### The Final Checkpoint Before Termination

Before the session is finally torn down, the **stop-review-gate-hook** is invoked via the Codex runtime to decide whether the session may close. If the gate returns `BLOCK`, the session end is aborted, giving the user a chance to address the highlighted issues.

Thus, the stop review gate serves as the **final checkpoint** in Claude's lifecycle: it runs after Claude has produced its last turn but before the session is officially terminated, ensuring that any code modifications are vetted by Codex before the session concludes.

## Key Implementation Files

The stop review gate mechanism relies on the following components in the `openai/codex-plugin-cc` repository:

- **`stop-review-gate-hook.mjs`**: Core implementation that reads input, builds prompts, runs the Codex task, and parses results.
- **`session-lifecycle-hook.mjs`**: Manages Claude session start and end events; invokes the stop review gate as the final step before session termination.
- **[`stop-review-gate.md`](https://github.com/openai/codex-plugin-cc/blob/main/stop-review-gate.md)**: Prompt template instructing Codex how to perform the review and format its compact decision.
- **`state.mjs`**: Provides `getConfig` and job-listing utilities used to respect the `stopReviewGate` configuration flag.
- **`codex-companion.mjs`**: Runs the actual Codex review task; invoked by the gate via `spawnSync`.
- **`broker-lifecycle.mjs`**: Handles starting and stopping the Codex broker; cleanup is performed during `SessionEnd`.

## Summary

The stop review gate mechanism provides a critical safety layer for Claude sessions by enforcing automated code reviews before termination:

- It acts as a **final checkpoint** that intercepts session termination via `stop-review-gate-hook.mjs`.
- The gate evaluates code changes using the **[`stop-review-gate.md`](https://github.com/openai/codex-plugin-cc/blob/main/stop-review-gate.md)** template and Codex review tasks.
- It supports **`ALLOW`** and **`BLOCK`** decisions, with the latter preventing session closure when issues are detected.
- Configuration via **`getConfig`** allows users to enable or disable the gate per repository.
- Integration with **`session-lifecycle-hook.mjs`** ensures the gate runs atomically between Claude's final turn and session cleanup.

## Frequently Asked Questions

### What happens if the stop review gate times out?

If the Codex review task exceeds the **15-minute** timeout (`STOP_REVIEW_TIMEOUT_MS`), the gate treats the failure as a blocking condition. The `parseStopReviewOutput` function emits a `block` decision with a descriptive message explaining that the review timed out, preventing the session from closing until the issue is resolved or the configuration is adjusted.

### How do I disable the stop review gate?

You can disable the gate by setting `stopReviewGate` to `false` in your repository configuration. When `getConfig` detects this flag, the hook in `stop-review-gate-hook.mjs` logs any running Codex tasks and returns immediately without invoking the review process, allowing sessions to terminate without automated review.

### What is the difference between ALLOW and BLOCK decisions?

An **`ALLOW`** decision permits the Claude session to terminate normally, indicating that Codex found no blocking issues with the code changes. A **`BLOCK`** decision aborts the session termination, returning a JSON object with a specific reason (such as missing error handling or syntax issues) that must be addressed before the session can close.

### Where does the stop review gate fit in Claude's lifecycle?

The stop review gate operates as the **final checkpoint** in the lifecycle managed by `session-lifecycle-hook.mjs`. It executes after Claude produces its last assistant message but before the `SessionEnd` event completes and the Codex broker shuts down. This positioning ensures that code is reviewed while the session context is still active and can be modified if the gate blocks termination.