diff --git a/codex/sections/review-mode.md b/codex/sections/review-mode.md index 84dc1f617..b2599c784 100644 --- a/codex/sections/review-mode.md +++ b/codex/sections/review-mode.md @@ -119,8 +119,9 @@ instead of the harness killing the call silently. grep "tokens used" "$TMPERR" 2>/dev/null || echo "tokens: unknown" ``` -4. Determine the gate verdict. **The gate FAILS CLOSED** — a run that cannot be -verified is a FAIL, never a PASS. Work through these checks IN ORDER; the first +4. Determine the gate verdict: **PASS**, **FAIL**, or **UNVERIFIED**. +**The gate FAILS CLOSED**: a run that did not complete is a FAIL, and output the +gate cannot check is UNVERIFIED, never a PASS. Work through these checks IN ORDER; the first match wins: 1. `_CODEX_EXIT` is non-zero (including 124) → **GATE: FAIL** (fail-closed: @@ -132,18 +133,20 @@ match wins: 3. The output contains `[P0]` or `[P1]` (or codex's native unbracketed `P0:` / `P1:` severity labels) → **GATE: FAIL** (N critical findings). Codex's own review rubric treats P0 as blocking; this gate does too. - 4. The output contains NO `[P0]`, `[P1]`, or `[P2]` tag (nor native `P0:`/`P1:`/ - `P2:` labels) anywhere → **GATE: FAIL** (fail-closed: untagged output — the - severity markers this gate greps for are absent, so "no critical findings" - cannot be verified mechanically; a human must read the verbatim output above - and judge). "No `[P1]` substring" and "no critical findings" are different - claims — never infer PASS from an untagged body. - 5. Severity tags are present and none is P0/P1 (only P2/advisory) → + 4. The output contains NO `[P0]`–`[P3]` tag (nor native `P0:`–`P3:` labels) + anywhere → **GATE: UNVERIFIED** (Codex completed and tagged nothing; read + the output above). `codex review` puts severity tags only in finding titles + and prints its structured clean verdict nowhere (verified on 0.160.0), so a + clean review is untagged prose. "No `[P1]` substring" and "no critical + findings" are different claims: never infer PASS from an untagged body, and + never report it as a FAIL or a finding count either. + 5. Severity tags are present and none is P0/P1 (only P2/P3 advisory) → **GATE: PASS**. - There is no default branch: PASS is only reachable through check 5. When the - gate fails closed (checks 1, 2, 4), say explicitly that this is a - verification failure requiring human attention, not a finding count. + There is no default branch: PASS is only reachable through check 5. For FAIL + via checks 1 or 2, say explicitly that the review did not complete. For + UNVERIFIED, tell the user to read Codex's verdict above and decide; it is + not a blocker by itself and not a pass. 5. Present the output: @@ -161,10 +164,16 @@ or GATE: FAIL (N critical findings) ``` -or, when the run itself could not be verified: +or, when the run itself did not complete: ``` -GATE: FAIL (fail-closed: — needs human attention) +GATE: FAIL (fail-closed: — needs human attention) +``` + +or, when Codex completed without severity tags: + +``` +GATE: UNVERIFIED (Codex completed and tagged nothing; read the output above) ``` 5a. **Synthesis recommendation (REQUIRED).** After presenting Codex's verbatim @@ -198,9 +207,10 @@ CROSS-MODEL ANALYSIS: ~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N,"commit":"'"$(git rev-parse --short HEAD)"'","completed":COMPLETED,"converged":CONVERGED}' --finish CODEX_REVIEW_START ``` -Substitute: TIMESTAMP (ISO 8601), STATUS ("clean" if PASS, "issues_found" if FAIL), -GATE ("pass" or "fail" — fail-closed verdicts log as "fail"), findings (count of -[P0] + [P1] + [P2] markers; 0 for fail-closed runs, which reviewed nothing), +Substitute: TIMESTAMP (ISO 8601), STATUS ("clean" if PASS, "issues_found" if FAIL, +"unverified" if UNVERIFIED), GATE ("pass", "fail" or "unverified" — fail-closed +verdicts log as "fail"), findings (count of [P0]–[P3] markers; 0 for fail-closed +and UNVERIFIED runs), findings_fixed (count of findings that were addressed/fixed before shipping). CODEX_REVIEW_START is the original token from the command path that ran. COMPLETED is true only when the review completed with coverage of the branch diff and current working-tree changes; timeout, failure, refusal, or missing coverage is false. A limited `--commit`/`--uncommitted` review, or a committed-only custom prompt that omitted dirty/untracked source, does not establish whole-branch coverage: log completed false and explain the limitation. CONVERGED is true only for a completed pass with zero edits. Fixes stay stale until a genuine rerun reads the updated diff with a new start token. These evidence fields do not change the gate verdict above.