How the Codex Review Gate Works and How to Enable or Disable It
The Codex review gate is a safety mechanism that forces a mandatory review of the previous Claude turn before a session can be closed, controlled by the Boolean stopReviewGate flag in the plugin's persistent state.
The Codex review gate is implemented in the openai/codex-plugin-cc repository as an optional safeguard. When enabled, it intercepts /codex:stop commands, runs a programmatic review of the session's changes, and can block termination if issues are detected. This article explains the gate's architecture and provides the exact commands to toggle it.
How the Codex Review Gate Works
Core Architecture
The review gate consists of four interconnected components:
-
Persisted configuration — The
stopReviewGateflag is stored instate.jsonand defaults tofalseon first use. Inplugins/codex/scripts/lib/state.mjs, lines 19-26 initialize this value when the plugin state is created. -
Setup command — The
/codex:setupsub-command provides CLI access to toggle the flag, implemented inplugins/codex/scripts/codex-companion.mjs(lines 29-34). -
Stop-gate hook — The
stop-review-gate-hook.mjsscript enforces the gate logic when sessions terminate. -
Status reporting — The global status view displays the gate state through the
needsReviewfield.
The Stop-Gate Hook Execution Flow
When a user runs /codex:stop or the companion process exits, plugins/codex/scripts/stop-review-gate-hook.mjs executes:
// From stop-review-gate-hook.mjs, lines 46-48
const config = await getConfig(workspaceRoot);
If config.stopReviewGate is false, the hook logs any running task and allows the stop to proceed (lines 54-57).
If config.stopReviewGate is true, the hook performs three operations (lines 66-74):
- Verifies Codex is correctly set up
- Runs the
runStopReviewtask to analyze the previous turn - Blocks the stop unless the review returns an
ALLOW:line, emitting{"decision": "block"}with a reason
How to Enable or Disable the Codex Review Gate
Using CLI Commands
| Action | Command | Effect |
|---|---|---|
| Enable | !codex setup --enable-review-gate |
Sets config.stopReviewGate to true; stops now require review approval |
| Disable | !codex setup --disable-review-gate |
Sets config.stopReviewGate to false; stops proceed immediately |
| Check state | !codex status |
Shows "Review gate: enabled" or "Review gate: disabled" in output |
The --enable-review-gate and --disable-review-gate flags call setConfig(workspaceRoot, "stopReviewGate", value) as shown in codex-companion.mjs lines 29-34. The setup report (lines 98-110) confirms the new state.
Verifying the Current State
The status system exposes the gate state through two mechanisms:
- Programmatic access:
plugins/codex/scripts/lib/job-control.mjslines 38-39 setneedsReviewfromconfig.stopReviewGate - Human-readable output:
plugins/codex/scripts/lib/render.mjslines 330-331 print the formatted status line
# Example status output showing enabled gate
!codex status
# → Review gate: enabled
# → needsReview: true
Programmatic Control
To toggle the gate from custom scripts, use the same internal helpers:
import { setConfig, getConfig } from "./plugins/codex/scripts/lib/state.mjs";
import { resolveWorkspaceRoot } from "./plugins/codex/scripts/lib/workspace.mjs";
const workspaceRoot = resolveWorkspaceRoot(process.cwd());
// Check current state
const current = await getConfig(workspaceRoot);
console.log("Gate enabled:", current.stopReviewGate);
// Toggle
await setConfig(workspaceRoot, "stopReviewGate", !current.stopReviewGate);
The setConfig helper is defined in plugins/codex/scripts/lib/state.mjs lines 53-60 and atomically writes to state.json.
Complete Example Workflow
# 1. Enable the review gate
!codex setup --enable-review-gate
# → Enabled the stop‑time review gate for /path/to/workspace.
# 2. Start a coding session
!codex start
# 3. Make changes...
# 4. Attempt to stop — this triggers the review
!codex stop
# → [review runs automatically]
# → If review finds issues: {"decision":"block","reason":"Codex stop‑time review found issues …"}
# → If review passes: session closes normally
# 5. Disable when no longer needed
!codex setup --disable-review-gate
Key Implementation Files
| File | Purpose |
|---|---|
plugins/codex/scripts/stop-review-gate-hook.mjs |
Core enforcement logic; checks flag and runs blocking review |
plugins/codex/scripts/codex-companion.mjs |
CLI toggle commands (--enable-review-gate, --disable-review-gate) |
plugins/codex/scripts/lib/state.mjs |
Persistence layer; provides setConfig() and getConfig() |
plugins/codex/scripts/lib/job-control.mjs |
Status snapshot including needsReview field |
plugins/codex/scripts/lib/render.mjs |
Formatted "Review gate: enabled/disabled" output |
Summary
- The Codex review gate is controlled by
config.stopReviewGate, defaulting tofalse - Enable with
!codex setup --enable-review-gate; disable with--disable-review-gate - When enabled, the
stop-review-gate-hook.mjsscript blocks/codex:stopuntil review returnsALLOW: - Configuration persists in
state.jsonviaplugins/codex/scripts/lib/state.mjs - Check current state through
!codex statusor theneedsReviewfield in status snapshots
Frequently Asked Questions
What happens if the review gate blocks a stop?
The hook emits a JSON payload with "decision": "block" and a reason string, as implemented in stop-review-gate-hook.mjs lines 66-74. The session remains active and the user must address the identified issues or disable the gate to proceed.
Can the review gate be enabled per-workspace?
Yes. The state.json file and stopReviewGate flag are scoped to the workspace root resolved via resolveWorkspaceRoot(). Each workspace maintains independent configuration, so enabling the gate in one project does not affect others.
Does enabling the gate affect existing running sessions?
No. The gate is evaluated only at stop-time. Enabling the flag via !codex setup --enable-review-gate takes effect immediately for future stop commands but does not interrupt or modify active Codex processes.
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 →