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.
File:
scripts/stop-review-gate-hook.mjs(v1.0.6)Problem
When
stopReviewGateis enabled,main()runs the review and emits{"decision":"block"}whenever the review is notok— including the non-okcases 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: truein 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: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_activebefore running the blocking review:This lets the gate review once; on the harness's forced retry it returns success instead of blocking again.
codex-companion.mjshas the sameconfig.stopReviewGatebranch — worth auditing it for the same issue.