Skip to content

feat(web): offer an admin merge when auto-merge cannot get past branch protections - #17281

Open
pzep1 wants to merge 1 commit into
pingdotgg:mainfrom
pzep1:feat/auto-merge-admin-bypass
Open

pzep1 wants to merge 1 commit into
pingdotgg:mainfrom
pzep1:feat/auto-merge-admin-bypass

Conversation

@pzep1

@pzep1 pzep1 commented Oct 8, 2026 •

Copy link
Copy Markdown

Problem

On a GitHub branch that needs a review the viewer can't give, such as a code owner's approval on their own PR, auto-merge never has anything it can finish waiting on. GitHub can also refuse to arm it at all, which shows up as "Could not turn on auto-merge: The host refused it…". The only way through is gh pr merge --admin in a terminal, even when GitHub would let the viewer bypass the protections.

Change

  • Server (GitHub): read viewerCanMergeAsAdmin with the core detail and with the viewer-permissions check. Expose it as a new mergeAsAdmin viewer permission. It is only set when GitHub says true and the viewer can write; absent means no.
  • Contracts: add bypassRequirements to PullRequestActionInput. For merge and enable-auto-merge it sends the direct mergePullRequest mutation rather than enablePullRequestAutoMerge, and skips the merge queue. That matches gh pr merge --admin. PullRequestService.runAction refuses the flag for stack merges, for any other action, and for viewers without mergeAsAdmin.
  • Web: the merge and auto-merge confirm dialogs show a Merge now as an administrator checkbox to viewers GitHub allows. When it's ticked, the dialog's title, description and destructive button change to say it merges now without waiting for reviews, checks or the queue. The checkbox resets every time the dialog closes. If auto-merge fails, viewers who can admin-merge get a hint pointing them to the checkbox.
  • Docs: one paragraph in docs/user/source-control.md.

Mobile has no PR merge UI, so nothing changes there. Other hosts never set mergeAsAdmin, so they never see the checkbox.

Scope and approval

There is no prior issue or discussion for this. It reuses the existing merge and auto-merge actions and adds one GitHub-only option to them.

Screenshots

Before: turning on auto-merge on a branch that needs a code owner's review fails, and there's no way through from the app.

Could not turn on auto-merge toast

After: viewers GitHub lets bypass protections get a checkbox in the dialog. Ticking it turns the action into a direct admin merge. Captured on a real BLOCKED pull request; the dialog was cancelled each time.

Unticked Ticked
Enable auto-merge dialog with admin checkbox Merge as administrator dialog

Verification

  • vp test run passes on GitHubPullRequestApi.test.ts, GitHubPullRequestProvider.test.ts, gitHubPullRequestJson.test.ts, PullRequestService.test.ts (450 tests) and packages/contracts/src/pullRequest.test.ts. New tests cover:
    • An admin merge sends mergePullRequest, not enablePullRequestAutoMerge, for a BLOCKED branch and for a merge-queue branch.
    • viewerCanMergeAsAdmin decodes only when true, and an unknown or missing value grants nothing.
    • The permission needs both write access and GitHub's yes.
    • The service refuses the flag without the permission or on a non-merge action, and passes it through when allowed.
  • tsc --noEmit is clean for contracts, server and web. Lint on the changed files shows only warnings that already exist on main.
  • Ran the web client on a dev server against a real BLOCKED pull request where GitHub reports viewerCanMergeAsAdmin: true. The checkbox appears and the dialog switches to the admin merge, as in the screenshots above.
  • Not checked: actually confirming an admin merge. Every dialog was cancelled.

Opus 5.5 (1M context) via Claude Code in T3 Code.

🤖 Generated with Claude Code

…h protections

When a GitHub branch needs a review the viewer cannot give (a code owner's, say), auto-merge has
nothing it can ever finish waiting on, and the host may refuse to arm it at all. GitHub already
lets administrators merge past those protections, which is what `gh pr merge --admin` does.

Read GitHub's `viewerCanMergeAsAdmin` into a new `mergeAsAdmin` viewer permission, accept a
`bypassRequirements` flag on merge actions that sends the direct `mergePullRequest` mutation
instead of arming auto-merge or joining the merge queue, and offer it as a checkbox in the merge
and auto-merge confirm dialogs for viewers GitHub says may use it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Oct 8, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a cross-layer GitHub administrator-merge workflow that can bypass required reviews, checks, and merge queues through a new destructive confirmation path. Although it is explicitly opt-in and permission-gated, the privileged and consequential production behavior requires human review.

You can add or adjust custom eligibility rules. Learn more.

@pzep1

pzep1 commented Oct 8, 2026

Copy link
Copy Markdown
Author

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a cross-layer GitHub administrator-merge workflow that can bypass required reviews, checks, and merge queues through a new destructive confirmation path. Although it is explicitly opt-in and permission-gated, the privileged and consequential production behavior requires human review.

You can add or adjust custom eligibility rules. Learn more.

relax

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c86e1697-d7ff-426e-8155-471e6e2e1fa5
📥 Commits

Reviewing files that changed from the base of the PR and between fd25c42 and 30f556e.

📒 Files selected for processing (12)
  • apps/server/src/pullRequest/GitHubPullRequestApi.test.ts
  • apps/server/src/pullRequest/GitHubPullRequestApi.ts
  • apps/server/src/pullRequest/GitHubPullRequestProvider.test.ts
  • apps/server/src/pullRequest/GitHubPullRequestProvider.ts
  • apps/server/src/pullRequest/PullRequestProvider.ts
  • apps/server/src/pullRequest/PullRequestService.test.ts
  • apps/server/src/pullRequest/PullRequestService.ts
  • apps/server/src/pullRequest/gitHubPullRequestJson.test.ts
  • apps/server/src/pullRequest/gitHubPullRequestJson.ts
  • apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx
  • docs/user/source-control.md
  • packages/contracts/src/pullRequest.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The pull request adds GitHub administrator-merge permission data and a bypass option for merge actions. The server validates bypass requests and sends permitted requests as direct merges. The pull request dialog exposes the option when permission is available.

Changes

Administrator Merge Bypass

Layer / File(s) Summary
Read and expose administrator-merge permission
packages/contracts/src/pullRequest.ts, apps/server/src/pullRequest/gitHubPullRequestJson.ts, apps/server/src/pullRequest/gitHubPullRequestJson.test.ts, apps/server/src/pullRequest/GitHubPullRequestProvider.ts, apps/server/src/pullRequest/GitHubPullRequestProvider.test.ts
The contracts and GitHub permission decoders expose administrator-merge permission only when GitHub explicitly reports it. The provider requires write access before exposing the permission.
Validate and execute bypassed merge actions
apps/server/src/pullRequest/PullRequestProvider.ts, apps/server/src/pullRequest/PullRequestService.ts, apps/server/src/pullRequest/PullRequestService.test.ts, apps/server/src/pullRequest/GitHubPullRequestProvider.ts, apps/server/src/pullRequest/GitHubPullRequestApi.ts, apps/server/src/pullRequest/GitHubPullRequestApi.test.ts
The service restricts bypass requests to permitted, non-stack merge actions. The provider and GitHub API forward the flag and select a direct merge instead of auto-merge when it is true.
Offer administrator merge in the confirmation dialog
apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx, docs/user/source-control.md
The dialog conditionally offers a bypass checkbox and clears its selection when closed. A selected bypass submits a direct merge. The documentation describes the option.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant PullRequestDetailPanel
  participant PullRequestService
  participant GitHubPullRequestProvider
  participant GitHubPullRequestApi
  participant GitHub
  PullRequestDetailPanel->>PullRequestService: runAction with bypassRequirements
  PullRequestService->>GitHubPullRequestProvider: forward validated bypass request
  GitHubPullRequestProvider->>GitHubPullRequestApi: runPullRequestAction with bypassRequirements
  GitHubPullRequestApi->>GitHub: mergePullRequest mutation
Loading

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 30f55

This adds an opt-in administrator merge that is permission-gated on the server and shown in the dialog only to eligible viewers. No merge-blocking issue was found. A live admin merge against a protected repository has not been exercised.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 30f55

The new operation can merge code without required reviews, checks or the merge queue. It requires an explicit choice and freshly checked administrator-merge permission. No unauthorized bypass was established, but concurrent branch changes and uncertain remote outcomes remain important limitations.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The immediate security-sensitive outcome is merging the selected PR into its repository branch without the protections it would otherwise wait for. Application authorization restricts this to a single PR action for a viewer with GitHub-derived write and administrator-merge capability; it does not grant a new token or change repository policy.

Trust Boundaries and Controls

  • observed — The client-controlled bypass flag is not itself authority. Fresh server-side permission checks require mergeAsAdmin exactly true and reject stacks or unrelated actions. The GitHub permission mapper grants that capability only with write access and an exact true host answer; missing capability or an unavailable PR does not grant it.
  • observed — Permission reads and mutations share a host-scoped credential resolver and bearer-token transport. Credentials are resolved separately per request, so the source establishes a common credential policy rather than immutable viewer identity across the authorization and mutation sequence.

Resilience and Maintainability Implications

  • observed — Direct merges generally do not bind expectedHeadOid unless merge-message rewriting supplies it. This predates the PR, whose source describes merging the head as it stands now. The bypass newly exposes those latest-head semantics to queue and deferred-auto-merge cases; a freshly resolved PR identity is not a guarantee that the confirmed code revision is unchanged.

Hardening Proposals

  • proposed — If administrator confirmation is intended to authorize a particular reviewed revision, carry that revision through the action contract and enforce it with expectedHeadOid. This would strengthen the current latest-head contract rather than fix an established unauthorized bypass.
  • proposed — For an uncertain merge result, reconcile current host state before encouraging repetition and distinguish a transport failure from a confirmed merge refusal. Remote timeout and repetition semantics still require verification.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the problem, implementation, scope, screenshots, and focused verification. However, the change introduces broader merge workflow behavior without linking a triaged issue or expl… Add a link to the triaged issue or discussion with explicit maintainer approval of the direction and scope. If approval already exists, include the approval comment in this section.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: adding an administrator merge option when auto-merge cannot satisfy branch protections.
Full details: Description check

Explanation

The description covers the problem, implementation, scope, screenshots, and focused verification. However, the change introduces broader merge workflow behavior without linking a triaged issue or explicit maintainer approval, as required by the template.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant