Skip to content

Gate merges on a review-fix-loop commit status - #168

Merged
sreejithraman merged 7 commits into
mainfrom
agent/review-merge-gate
Nov 9, 2026
Merged

sreejithraman merged 7 commits into
mainfrom
agent/review-merge-gate

Conversation

@sreejithraman

@sreejithraman sreejithraman commented Nov 9, 2026 •

Copy link
Copy Markdown
Owner

Agents can no longer land a PR through merge until review-fix-loop has finished on that exact head.

What changed

  • The record: when the loop finishes on a commit headed for a PR, it posts a review-fix-loop commit status on the exact SHA its final pass assessed. It posts once that SHA is on the remote, and a PR doesn't have to exist yet. GitHub ties the status to the commit, so any later push has none.
  • The gate: pr_state.py treats only a commit status with that context as the review record, and reports it as review_status, apart from CI checks. A CI job with the same name stays a normal check. Anything but a passing status blocks.
  • Only the loop posts:
    • Any head without a passing status, including after a base update or restack, goes back through PR's Prepare and Review steps.
    • A new head of already-reviewed work is a small repair pass, not a fresh two-wave review.
    • There is no carry-over.
  • What the status covers:
    • For PR work, every pass reviews a clean, committed HEAD, with Show, Don't Tell's edits and repairs committed first.
    • The loop records completion only once Show, Don't Tell covers the change, so the status covers both.
    • A local-diff review with no PR planned finishes without a status.
  • Failure: a failed status post, such as a permission error or a fork, is reported to the user instead of rerunning the loop.

No GitHub settings change. The status isn't a required check, so the user's own merges are unaffected, and nothing is added to any repo's code.

Why

On #166, reviews were run by hand outside the loop, so its pause and fix routing never ran. #167 showed that wording can't route an improvising agent to the loop. Enforcing it in code at landing turns skipping the loop into an obvious block.

How the review went

Seven passes through review-fix-loop, including the #167 pause, which fired twice:

  • Passes 1–2: found name-only matching, posting that needed a PR, and a pending status that never cleared. Repairs then kept surfacing new ways to put the status on the wrong commit.
  • First pause: one posting rule, and the status bound to the reviewed commit.
  • Pass 3: found that carry-over's "identical change" check wasn't exact. patch-id --stable ignores whitespace, which was reproduced, and range-diff skips merge commits.
  • Second pause: the user chose to drop carry-over entirely.
  • Passes 4–7: closed the remaining entry points (Show, Don't Tell, local-only reviews, reuse, untracked files) with wording only. The final pass found nothing.

The full decision record is kept with the review archive.

Verification

  • python3 scripts/check.py passes. test_pr_state.py has 54 tests, each new behavior seen failing first:
    • missing, pending and failed statuses;
    • a same-named CI job, in both orders across pages;
    • the review status not counted as CI;
    • UNSTABLE;
    • closed and merged PRs;
    • the exact blocker message.
  • Dry-run trials on frozen copies, with outcomes written first. All matched:
    • publish with uncommitted edits;
    • an unreviewed fix followed by a base update, which was refused;
    • a clean base update;
    • a restacked layer;
    • a local-only review that is published later.
  • Live: this PR's own status was the first one posted. pr_state reported review_status: pass and ready before merge.
  • The OpenCode extra review was skipped because its usage limit was reached. Gemini 3.8 Flash reviewed pass 1.

🤖 Generated with Claude Code

sreejithraman and others added 7 commits November 8, 2026 22:22
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sreejithraman
sreejithraman merged commit acb6280 into main Nov 9, 2026
3 checks passed
@sreejithraman
sreejithraman deleted the agent/review-merge-gate branch November 9, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant