Skip to content

stop-review-gate-hook.mjs: fail-closed reason strings do not mention the /codex:setup --disable-review-gate escape valve #483

Description

@nomad4444

Summary

When stopReviewGate: true, scripts/stop-review-gate-hook.mjs emits {"decision":"block","reason":"..."} on any of 5 fail-closed branches (timeout, task failure, invalid JSON, empty rawOutput, unexpected first-line). The reason string is the ONLY message operators see — Claude Code's Stop-hook does not offer a UI for hook decisions beyond the reason text.

The reason strings currently include "Run /codex:review --wait manually or bypass the gate." — but the concrete "bypass the gate" command is not spelled out. Operators in a fail-closed loop (e.g., 3 consecutive infra failures with empty rawOutput) cannot discover the escape valve /codex:setup --disable-review-gate from the message they see.

Failure scenario (observed)

A derivative Claude Code session on 2026-07-09 hit 3 consecutive status: 1 / rawOutput: "" failures from the underlying Codex CLI. Each time, the Stop hook fired at 15-min timeout limits and re-blocked. The session became terminaion-incapable — CC's built-in ~9-iteration recursive-stop limit was the only path out.

The operator recovered manually by finding the escape valve in tritool-side docs (.claude/rules/safety-gate.md §14). Without those tritool-side docs, the escape valve is not discoverable.

Proposed fix (3 options, any one closes the loop)

(a) Reason-string literal command (smallest change)

Append the literal command to all 5 fail-closed branches:

"Run /codex:review --wait manually or bypass the gate by running /codex:setup --disable-review-gate."

(b) Distinguish infra failure vs rule violation via reasonCategory field

CC's Stop-hook decision schema accepts extra fields. Adding:

{
  "decision": "block",
  "reason": "...",
  "reasonCategory": "infra_failure" | "rule_violation"
}

lets downstream (e.g., tritool-side wrapper Stop hook) handle infra failures differently — e.g., downgrade to advisory after N consecutive infra failures.

(c) Consecutive-N counter + downgrade

Persist a counter in the plugin's state file (stateModule.setConfig). After N consecutive infra failures (recommended default N=3), downgrade decision: block → advisory ({"continue":true, "systemMessage":"..."}) so the session can terminate. Reset the counter on any allow / successful review / rule-violation block.

Reproduction

  1. stopReviewGate: true (/codex:setup --enable-review-gate)
  2. Make the underlying Codex CLI fail 3 times consecutively (e.g., simulate by unavailable auth or config drift)
  3. Observe Stop hook blocks each iteration with the same reason string
  4. Confirm the operator cannot discover the escape valve from the reason string alone

Environment

  • codex-plugin-cc: v1.0.4 (sha 807e03a at time of investigation)
  • Claude Code: v2.1.198
  • OS: Linux (verified 2026-07-09), likely applies to all platforms

Cross-reference

Tritool-template documented the discovery gap in docs/runbook-cc-codex-outage.md §8 (see linked repo URL) and .claude/rules/safety-gate.md §14 (Plugin hooks Stop row) as short-term workaround for their derivative projects. Filing here so the fix can land upstream and eliminate the need for the downstream doc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions