Skip to content

bug: auto-merge never triggers for bot-authored PRs — selfApprovalFallback downgrades APPROVE→COMMENT but publishCriteriaApprovedReview requires APPROVE #602

Description

@baderdean

Summary

When looper runs as a bot account (e.g. ankaboot-bot) and the worker opens PRs as that bot, the reviewer cannot APPROVE its own PRs (GitHub blocks self-approval). Looper correctly downgrades APPROVECOMMENT via selfApprovalFallback, but the auto-merge path requires marker.Event == ReviewEventApprove and returns early on COMMENT — so EnableAutoMerge is never called.

Evidence

PR: ankaboot-source/m3llm#180 (bot-authored, reviewer-clean)

  • Reviewer loop Add a Looper inbox for completed runs and needs-human items #49 completed with outcome=clean (all fixer corrections verified).
  • Config: [roles.reviewer.autoMerge] enabled = true, requireBranchProtection = false, scope = "looper-only", strategy = "squash".
  • reviewEvents.clean = "APPROVE".
  • GitHub autoMergeRequest: null on the PR — auto-merge was never enabled.

Root cause

internal/reviewer/runner.go:

  • Line 3791-3801 (submitOrReuseReview): selfApprovalFallback := event == ReviewEventApprove && sameReviewAuthorLogin(detail.Author, currentLogin) — when PR author == current user (bot), downgrades APPROVECOMMENT. This is correct (GitHub forbids self-approval).

  • Line 3672 (publishCriteriaApprovedReview): if marker.Event != ReviewEventApprove { return ... } — since marker.Event is COMMENT (downgraded), returns early and never calls decideAutoMerge or EnableAutoMerge.

The selfApprovalFallback correctly handles the review event, but the auto-merge path does not account for it.

Relationship to #352

#352 (auto-merge PRD) assumes Reviewer's APPROVE as the trigger. It does not address the case where the reviewer and PR author share the same GitHub identity (single-bot-account mode), where APPROVE is downgraded to COMMENT by selfApprovalFallback.

Relationship to #598

Same root cause as #598 (single-identity mode): the bot can review (COMMENT) but cannot approve or auto-merge its own PRs.

Expected behavior

When autoMerge.enabled = true and the reviewer marks the PR outcome=clean, auto-merge should be enabled via GitHub's native auto-merge API (gh pr merge --auto), even if the review event was downgraded to COMMENT by selfApprovalFallback. GitHub's branch protection (not the review event type) is the authority for "safe to merge" per #352.

Proposed fix

In publishCriteriaApprovedReview (runner.go:3672), relax the gate:

// Before
if marker.Event != ReviewEventApprove { return ... }

// After
if marker.Event != ReviewEventApprove && !selfApprovalFallback { return ... }

Or, more robustly: gate on outcome=clean (the reviewer's verdict) rather than marker.Event (the GitHub review event type), since selfApprovalFallback already correctly downgrades the event type for GitHub API compliance.

Environment

Reproduction

  1. Run looperd as a bot account (GH_TOKEN=bot_pat in daemon env)
  2. Worker opens a PR as the bot
  3. Reviewer reviews and marks outcome=clean
  4. Review event is downgraded to COMMENT (selfApprovalFallback)
  5. publishCriteriaApprovedReview returns early (marker.Event != APPROVE)
  6. EnableAutoMerge never called → PR sits at human gate indefinitely

Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions