You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A Merge run reports "review required" without trying a merge it knows will be refused #707
When the Base branch requires an approving review, a Merge run spends a whole Run before it finds out it can't merge. Then it takes a Repair round that can't help, and it ends with a generic failed.
Example: Educational-Travel-Adventures/tourbot#1438 (from issue 1437). CI passed on 79f6bfe, then gh pr merge was refused with "the base branch policy prohibits the merge". thirdshift went round the Repair loop once more: it merged an unchanged Base branch, pushed the same head and waited for CI that was already green. Then it reported:
Result: failed
Cause: the merge was refused with nothing left to fix, so the PR stays ready for review: ...
ADR-0004 already says this is a policy refusal and that "a repository that requires reviews can't be used with a Merge run". This issue keeps that decision and makes the outcome faster and clearer.
Idea
Before the Self-merge, read the pull request's reviewDecision. If it says a review still blocks the merge, skip the merge attempt and the no-op Repair round, and end the run as a named Review required outcome. It stays a policy refusal: exit 1, the PR left ready for review. This reads a structured field, not GitHub's error text, so it fits ADR-0004.
GitHub auto-merge (--auto) stays out of scope. ADR-0004 rejected it.
changed the title [-]Report a review-required PR as awaiting review, not a Failed run, and optionally enable auto-merge[/-][+]A Merge run reports "review required" without trying a merge it knows will be refused[/+]on Oct 16, 2026
Category: enhancement Summary: Before the Self-merge, a Merge run checks the pull request's reviewDecision. When a review blocks the merge, the run skips the merge attempt and the Repair round and ends as a named "review required" policy refusal.
Current behavior:
Once the pull request is open, ready, mergeable and green, a Merge run runs gh pr merge --merge --match-head-commit <sha>. If the Base branch requires an approving review that the PR lacks, GitHub refuses the merge. The run then goes back round the Repair loop: it merges the Base branch, pushes and waits for CI. That round finds nothing to fix, so the run ends as a policy refusal: exit 1, PR URL on stdout, GitHub's error on stderr, PR left ready for review, Claim kept. The summary says only failed with GitHub's raw error, so a user can't see at a glance that nothing is wrong except a missing review.
Desired behavior:
Just before each Self-merge attempt (the first one and any after a Repair round), read the PR's reviewDecision (gh pr view --json reviewDecision). If it is REVIEW_REQUIRED or CHANGES_REQUESTED, do not call gh pr merge and do not take a Repair round for it. End the run at once as a policy refusal.
This refusal has its own wording on stderr and in the Run notification/summary. It names the reason, for example PR <url> needs an approving review before it can merge; it is ready for review, not just failed with GitHub's raw error.
Everything else about a policy refusal stays the same: exit 1, PR URL on stdout, PR left open and ready (not converted to draft, no failure commit pushed), Claim kept, cleanup as usual.
An empty or APPROVEDreviewDecision (repositories with no review rule, or an approved PR) changes nothing: the Self-merge goes ahead as it does today, including the existing refusal handling for other policies.
If reading reviewDecision fails, it counts as "unknown" and the existing behavior applies. The read must never turn a run that could merge into a failure.
The Spec PR's Self-merge in a Spec run behaves the same way.
Key interfaces:
The Self-merge step of the Delivery / Repair loop, where it decides between "merge", "repair" and "policy refusal": it gains a review-required branch, decided from the structured reviewDecision field, never by parsing GitHub's error text (ADR-0004).
The fake gh used in tests: it must be able to return a given reviewDecision from gh pr view --json.
The Run outcome / summary rendering and the Run notification: they gain a "review required" wording for this case.
Acceptance criteria:
With the fake gh returning reviewDecision: REVIEW_REQUIRED on a green, mergeable PR, a Merge run never calls gh pr merge, takes no Repair round, exits 1, prints the PR URL on stdout and leaves the PR ready for review.
The same holds for CHANGES_REQUESTED.
stderr and the Run notification name the review requirement, not just a generic failure.
With reviewDecision empty or APPROVED, the Self-merge runs exactly as before (existing tests stay green).
If the reviewDecision read fails, the run falls back to today's behavior.
A Spec run's Spec PR Self-merge follows the same rules.
README's Merge run outcomes list and Failed runs section describe the review-required refusal. ADR-0004's Consequences gets a line saying the review requirement is now detected up front from reviewDecision.
Detecting the review requirement at launch, before any work, by reading branch protection or rulesets. This needs extra permissions and no PR exists yet; it could be a follow-up.
Requesting reviewers, or waiting/polling for a review to arrive.
Activity
[-]Report a review-required PR as awaiting review, not a Failed run, and optionally enable auto-merge[/-][+]A Merge run reports "review required" without trying a merge it knows will be refused[/+]JacobStephens2 commentedon Oct 16, 2026
Agent Brief
Category: enhancement
Summary: Before the Self-merge, a Merge run checks the pull request's
reviewDecision. When a review blocks the merge, the run skips the merge attempt and the Repair round and ends as a named "review required" policy refusal.Current behavior:
Once the pull request is open, ready, mergeable and green, a Merge run runs
gh pr merge --merge --match-head-commit <sha>. If the Base branch requires an approving review that the PR lacks, GitHub refuses the merge. The run then goes back round the Repair loop: it merges the Base branch, pushes and waits for CI. That round finds nothing to fix, so the run ends as a policy refusal: exit1, PR URL on stdout, GitHub's error on stderr, PR left ready for review, Claim kept. The summary says onlyfailedwith GitHub's raw error, so a user can't see at a glance that nothing is wrong except a missing review.Desired behavior:
reviewDecision(gh pr view --json reviewDecision). If it isREVIEW_REQUIREDorCHANGES_REQUESTED, do not callgh pr mergeand do not take a Repair round for it. End the run at once as a policy refusal.PR <url> needs an approving review before it can merge; it is ready for review, not justfailedwith GitHub's raw error.1, PR URL on stdout, PR left open and ready (not converted to draft, no failure commit pushed), Claim kept, cleanup as usual.APPROVEDreviewDecision(repositories with no review rule, or an approved PR) changes nothing: the Self-merge goes ahead as it does today, including the existing refusal handling for other policies.reviewDecisionfails, it counts as "unknown" and the existing behavior applies. The read must never turn a run that could merge into a failure.Key interfaces:
reviewDecisionfield, never by parsing GitHub's error text (ADR-0004).ghused in tests: it must be able to return a givenreviewDecisionfromgh pr view --json.Acceptance criteria:
ghreturningreviewDecision: REVIEW_REQUIREDon a green, mergeable PR, a Merge run never callsgh pr merge, takes no Repair round, exits1, prints the PR URL on stdout and leaves the PR ready for review.CHANGES_REQUESTED.reviewDecisionempty orAPPROVED, the Self-merge runs exactly as before (existing tests stay green).reviewDecisionread fails, the run falls back to today's behavior.reviewDecision.Out of scope:
gh pr merge --auto). ADR-0004 rejected it; this issue doesn't reopen that.--adminto bypass the review.Report review-required policy refusals before Self-merge (#707)