Stop-review gate hook loops until CLAUDE_CODE_STOP_HOOK_BLOCK_CAP (missing `stop_hook_active` guard)
File: scripts/stop-review-gate-hook.mjs (v1.0.6)
Problem
When stopReviewGate is enabled, main() runs the review and emits {"decision":"block"} whenever the review is not ok — including the non-ok cases where the review task returns no output, times out (15 min), fails, or returns invalid JSON.
After a Stop hook blocks, Claude Code re-runs the turn with stop_hook_active: true in the hook input. This hook never checks that flag, so it re-runs the review and blocks again on every retry. The result is the harness message:
A hook blocked the turn from ending 9 consecutive times — overriding and ending turn. For Stop/SubagentStop hooks, check stop_hook_active in the input and return success while it's true.
The failure is worst in exactly the cases the gate is least useful — a Codex review that errors or times out blocks the session 9× before the cap force-ends it.
Fix
Honor stop_hook_active before running the blocking review:
if (input.stop_hook_active) {
logNote(runningTaskNote);
return;
}
const review = runStopReview(cwd, input);
This lets the gate review once; on the harness's forced retry it returns success instead of blocking again.
codex-companion.mjs has the same config.stopReviewGate branch — worth auditing it for the same issue.
Source: openai/codex-plugin-cc