Repository navigation
fix(source-control): bind a review re-run after an unposted timeout - #12863
Conversation
A review run whose first attempt failed with failure-class=timeout (every review while the reviews credential was rejected at its usage limit, run 41626484307) left its successful second attempt unbound, so the merge gate refused six lanes App PRs with rerun-not-allowed. A timeout now binds the second attempt under the same unposted proof no-outcome uses; a lane that posted on the head still refuses, and the gate never starts the re-run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed Security review: PR #12863No security issues found. This PR changes how the merge gate reads review evidence. When an AI review's first attempt fails with Merge-hold check. This loosens the gate's evidence binding, so I judged it under the merge-hold bullet:
No token, secret, trusted actor, untrusted-text path or billing surface changes, so none of the three severity-bar impacts (leak, compromise, charge) applies. Other files:
Spend: none. The change only reclassifies annotations the gate already fetches. critical-findings: 0 |
|
claude-review reviewed Code review: PR #12863, bind a review re-run after an unposted timeoutNo findings. I read all 4 changed files in the diff: the changelog fragment, What the change does.
Tests.
Docs. Optional, not counted. Two untouched comments still name only Other checks.
|
No related issue: a merge-gate defect found while measuring the pr-merge wakes for #12445; open-issue intake is closed while issues are driven to zero.
Summary
Six lanes App PRs (#12814, #12812, #12795, #12665, #12636, #12604) can't be armed. The merge gate refuses each with
evidence-unbound:claude-review: not bound: rerun-not-allowed(and the same for the security lane). That refusal is 7 of the 25 pr-merge wakes since #12771. In each review run, attempt 1 failed while the reviews credential was rejected at its usage limit. For example, run 41626484307 attempt 1 failed at 11:31Z withclaude-review: failure-class=timeout: the review leg reached its time limitand the warningREVIEWS_CLAUDE_CODE_OAUTH_TOKEN ... status=rejected. Attempt 2 then passed.timeoutwas not a class after which attempt 2 binds (babysit_review_evidence.pyRERUN_CLASSES, and theno-outcomebranch ofrerun_binds), so the passing review never counted.Fix
NO_OUTCOME_REnow also matches this lane'sfailure-class=timeout:line. A timed-out attempt 1 binds attempt 2 only under the proofno-outcomealready uses: no completion record, and the lane posted nothing on the head between the two attempts (_unposted). Attempt 1 then left no verdict, so attempt 2 is the only review and binding it trades nothing away.TIMEOUTis not inGATE_RERUN_CLASSES). A spent credential would fail the one allowed attempt.reference/safety.mdnames the new class.Decision: GitHub Support (hub ledger L108), relayed in session: "go with (a); you own it ... Keep the same unposted proof NO_OUTCOME uses: an unposted attempt 1 leaves attempt 2 as the only review, so binding it adds no risk."
Verification
test_babysit_review_evidence.py: 268 passed. The newTimeoutRerunTestsuse run 41626484307's annotation shape (the timeout line plus thestatus=rejectedusage warning). They cover: binds for both lanes when nothing was posted; refuses withrerun-not-allowedwhen the lane posted its marker; and the gate does not start the re-run.ev.TIMEOUTcheck).claude-security-review: failure-class=timeout: the review leg reached its time limit(check run 125891481218, attempt 1 of run 41626483992).scripts/run-ruff.sh checkon both files: all checks passed.Related
no-outcomebinding this extends)🤖 Generated with Claude Code