Skip to content

docs: ADR 0062 — Auto-merge#2791

Draft
ralphbean wants to merge 1 commit into
mainfrom
adr-0062-auto-merge
Draft

docs: ADR 0062 — Auto-merge#2791
ralphbean wants to merge 1 commit into
mainfrom
adr-0062-auto-merge

Conversation

@ralphbean

Copy link
Copy Markdown
Member

Summary

  • Adds ADR 0062 proposing a separate fullsend-ai-merge GitHub App for auto-merge
  • Key finding: GitHub only counts approvals toward branch protection when the reviewer has contents: write — our review bot has contents: read, so its approvals are currently informational only
  • Proposes combining a new merge app (opt-in per repo) with blank-owner CODEOWNERS entries for dependency files

Looking for team feedback on the approach before implementation.

Test plan

  • Review the ADR for correctness and completeness
  • Discuss whether the two-app model is the right tradeoff vs. adding contents: write to the review app

Proposes a separate fullsend-ai-merge app with contents:write so bot
approvals count toward branch protection, combined with blank-owner
CODEOWNERS entries for dependency files.

Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com>
Signed-off-by: Ralph Bean <rbean@redhat.com>
@ralphbean ralphbean requested a review from a team as a code owner June 30, 2026 17:39
@ralphbean ralphbean marked this pull request as draft June 30, 2026 17:39
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

ADR 0062: Propose separate GitHub App for auto-merge approvals

📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Document why bot approvals don’t satisfy branch protection without write access.
• Propose separate opt-in merge app to preserve least-privilege boundaries.
• Recommend blank-owner CODEOWNERS entries for dependency file paths.
Diagram

graph TD
  PR["Pull request"] --> REV["fullsend-ai-review app"] --> INFO["Approval (informational)"] --> BP{"Branch protection met?"} --> MERGED["Auto-merge enabled"]
  PR --> MERGE["fullsend-ai-merge app"] --> COUNT["Approval counts"] --> BP
  CODE["Blank-owner CODEOWNERS"] --> BP
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Grant `contents: write` to the existing review app
  • ➕ Simpler operationally: one app to install and manage
  • ➕ No new deployment/enrollment surface area
  • ➖ Violates the least-privilege boundary between review and merge roles
  • ➖ All repos installing the review app inherit elevated write permissions
2. Use GitHub-native merge automation (merge queue / Actions) instead of a new app
  • ➕ Avoids managing an additional GitHub App and its credentials
  • ➕ Keeps permissions within GitHub’s existing automation model (e.g., rulesets + Actions tokens)
  • ➖ May not satisfy the specific requirement of a review approval “counting” toward required reviews
  • ➖ Can be harder to make security posture and trust escalation explicit to repo owners
3. Remove required reviews for dependency paths and rely on CI/status checks only
  • ➕ No additional write-capable automation identity required
  • ➕ Directly addresses dependency-file friction (go.mod/go.sum) with minimal moving parts
  • ➖ Reduces human/ownership guardrails beyond just bot enablement, depending on how broadly applied
  • ➖ Does not address the branch-protection approval-counting limitation for other paths

Recommendation: The ADR’s two-part approach (separate opt-in fullsend-ai-merge app + blank-owner CODEOWNERS for narrowly scoped dependency files) is a good balance: it preserves least-privilege for the review bot while making write access an explicit, repo-level decision. If adopted, keep the blank-owner scope minimal (only the dependency files intended) and document operational controls around the merge app (installation policy, key handling, audit/logging expectations) since it becomes the higher-value target.

Files changed (1) +73 / -0

Documentation (1) +73 / -0
0062-auto-merge.mdAdd ADR 0062 outlining auto-merge permission model +73/-0

Add ADR 0062 outlining auto-merge permission model

• Introduces an accepted ADR describing why bot approvals don’t satisfy branch protection without write access. Proposes a separate opt-in merge GitHub App with 'contents: write'/'pull_requests: write' and recommends blank-owner CODEOWNERS entries for dependency files (e.g., go.mod/go.sum).

docs/ADRs/0062-auto-merge.md

@github-actions

Copy link
Copy Markdown

Site preview

Preview: https://70538298-site.fullsend-ai.workers.dev

Commit: 996296dfd975f8cd393b6675722f2b546193eaa3

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 5:42 PM UTC · Ended 5:49 PM UTC
Commit: 104508d · View workflow run →

@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (3)

Context used
✅ Compliance rules (platform): 51 rules

Grey Divider


Action required

1. docs/architecture.md not updated 📜 Skill insight ⚙ Maintainability
Description
This PR adds a new ADR marked Accepted, but there is no corresponding update to
docs/architecture.md to reflect the newly decided behavior and annotate any resolved open
questions. This can leave the architecture overview inconsistent with the accepted decision and
makes it harder to discover the current state of the system.
Code

docs/ADRs/0062-auto-merge.md[R2-3]

+title: "62. Auto-merge"
+status: Accepted
Relevance

⭐⭐⭐ High

Accepted ADRs must update living docs/architecture.md; explicitly practiced in PR #1578 and policy
in PR #161.

PR-#1578
PR-#161

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The ADR is explicitly marked Accepted, which triggers the requirement to update
docs/architecture.md and to annotate resolved open questions. docs/architecture.md currently
contains relevant sections about GitHub Apps and an explicit open question about the auto-merge vs.
escalate policy, but there is no recorded 'Decided' update referencing ADR 0062 in this PR.

Rule 1062062: Update architecture overview and problem docs when ADR is accepted
docs/ADRs/0062-auto-merge.md[2-3]
docs/architecture.md[138-149]
docs/architecture.md[190-195]
Skill: writing-adrs

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new ADR (`0062-auto-merge`) is introduced as `Accepted`, but the architecture overview is not updated to reflect/record the decision and to annotate any relevant resolved open questions.

## Issue Context
The compliance rules require that when an ADR is accepted, `docs/architecture.md` is updated in the same PR (and resolved open questions are annotated as resolved rather than left dangling).

## Fix Focus Areas
- docs/ADRs/0062-auto-merge.md[2-3]
- docs/architecture.md[138-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. ADR makes two decisions 📜 Skill insight ⚙ Maintainability
Description
The ## Decision section makes two distinct decisions (create a separate merge app, and adopt
blank-owner CODEOWNERS entries), which violates the requirement that each ADR records exactly one
decision. This reduces clarity and makes it harder to supersede or revisit each decision
independently.
Code

docs/ADRs/0062-auto-merge.md[R54-65]

+## Decision
+
+Use options B and C together:
+
+1. **Create a `fullsend-ai-merge` app** with `contents: write` and
+   `pull_requests: write`. Its approvals count toward branch protection. Repos
+   that want bot-driven auto-merge install this app; repos that only want
+   informational reviews keep `fullsend-ai-review`.
+
+2. **Use blank-owner CODEOWNERS entries** for files that bots should be able to
+   approve (starting with `go.mod` and `go.sum`). This removes the CODEOWNERS
+   gate for those files without affecting other paths.
Relevance

⭐⭐ Medium

Some precedent to create new ADR for new decision (PR #2525), but no evidence of strict
one-decision-per-ADR rule.

PR-#2525

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance rule requires exactly one decision per ADR. The Decision section explicitly
enumerates two separate decisions as items 1 and 2.

docs/ADRs/0062-auto-merge.md[54-65]
Skill: writing-adrs

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ADR's Decision section currently records two distinct decisions.

## Issue Context
Compliance requires each ADR to record exactly one decision; multiple decisions should be split so each can be reviewed, accepted, and superseded independently.

## Fix Focus Areas
- docs/ADRs/0062-auto-merge.md[54-65]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Context lacks problem doc links 📜 Skill insight ⚙ Maintainability
Description
The ADR Context describes motivations but does not link to the related problem documents, despite
listing them in relates_to. This makes it harder to trace the decision back to the canonical
problem statements and risks duplicating/fragmenting context over time.
Code

docs/ADRs/0062-auto-merge.md[R21-32]

+## Context
+
+Our review bot (`fullsend-ai-review`) can approve PRs, but GitHub only counts
+an approval toward branch protection when the reviewer has write access
+(`contents: write`) to the repository. The review app intentionally has
+`contents: read` — giving it write access would violate the least-privilege
+boundary established in [ADR 7](0007-per-role-github-apps.md).
+
+We also need the bot's approval to satisfy CODEOWNERS for dependency files
+(`go.mod`, `go.sum`). GitHub App bots cannot be listed as CODEOWNERS entries —
+they are not "users" in GitHub's model.
+
Relevance

⭐⭐ Medium

No clear historical enforcement that Context must link problem docs; only general link tidy-ups like
PR #2663.

PR-#2663

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The rule requires the Context to link to problem docs instead of restating/isolating context. The
frontmatter indicates related problem docs, but the Context section does not link to those problem
doc files.

docs/ADRs/0062-auto-merge.md[4-6]
docs/ADRs/0062-auto-merge.md[21-32]
Skill: writing-adrs

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ADR Context should link to the relevant problem docs rather than standing alone.

## Issue Context
The ADR declares `relates_to` entries for `agent-architecture` and `security-threat-model`, but the Context section does not include links to those problem documents.

## Fix Focus Areas
- docs/ADRs/0062-auto-merge.md[4-6]
- docs/ADRs/0062-auto-merge.md[21-32]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +2 to +3
title: "62. Auto-merge"
status: Accepted

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. docs/architecture.md not updated 📜 Skill insight ⚙ Maintainability

This PR adds a new ADR marked Accepted, but there is no corresponding update to
docs/architecture.md to reflect the newly decided behavior and annotate any resolved open
questions. This can leave the architecture overview inconsistent with the accepted decision and
makes it harder to discover the current state of the system.
Agent Prompt
## Issue description
A new ADR (`0062-auto-merge`) is introduced as `Accepted`, but the architecture overview is not updated to reflect/record the decision and to annotate any relevant resolved open questions.

## Issue Context
The compliance rules require that when an ADR is accepted, `docs/architecture.md` is updated in the same PR (and resolved open questions are annotated as resolved rather than left dangling).

## Fix Focus Areas
- docs/ADRs/0062-auto-merge.md[2-3]
- docs/architecture.md[138-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +54 to +65
## Decision

Use options B and C together:

1. **Create a `fullsend-ai-merge` app** with `contents: write` and
`pull_requests: write`. Its approvals count toward branch protection. Repos
that want bot-driven auto-merge install this app; repos that only want
informational reviews keep `fullsend-ai-review`.

2. **Use blank-owner CODEOWNERS entries** for files that bots should be able to
approve (starting with `go.mod` and `go.sum`). This removes the CODEOWNERS
gate for those files without affecting other paths.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Adr makes two decisions 📜 Skill insight ⚙ Maintainability

The ## Decision section makes two distinct decisions (create a separate merge app, and adopt
blank-owner CODEOWNERS entries), which violates the requirement that each ADR records exactly one
decision. This reduces clarity and makes it harder to supersede or revisit each decision
independently.
Agent Prompt
## Issue description
The ADR's Decision section currently records two distinct decisions.

## Issue Context
Compliance requires each ADR to record exactly one decision; multiple decisions should be split so each can be reviewed, accepted, and superseded independently.

## Fix Focus Areas
- docs/ADRs/0062-auto-merge.md[54-65]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +21 to +32
## Context

Our review bot (`fullsend-ai-review`) can approve PRs, but GitHub only counts
an approval toward branch protection when the reviewer has write access
(`contents: write`) to the repository. The review app intentionally has
`contents: read` — giving it write access would violate the least-privilege
boundary established in [ADR 7](0007-per-role-github-apps.md).

We also need the bot's approval to satisfy CODEOWNERS for dependency files
(`go.mod`, `go.sum`). GitHub App bots cannot be listed as CODEOWNERS entries —
they are not "users" in GitHub's model.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Context lacks problem doc links 📜 Skill insight ⚙ Maintainability

The ADR Context describes motivations but does not link to the related problem documents, despite
listing them in relates_to. This makes it harder to trace the decision back to the canonical
problem statements and risks duplicating/fragmenting context over time.
Agent Prompt
## Issue description
The ADR Context should link to the relevant problem docs rather than standing alone.

## Issue Context
The ADR declares `relates_to` entries for `agent-architecture` and `security-threat-model`, but the Context section does not include links to those problem documents.

## Fix Focus Areas
- docs/ADRs/0062-auto-merge.md[4-6]
- docs/ADRs/0062-auto-merge.md[21-32]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 5:42 PM UTC · Completed 5:49 PM UTC
Commit: 996296d · View workflow run →

@ralphbean

Copy link
Copy Markdown
Member Author

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 6:30 PM UTC · Completed 6:46 PM UTC
Commit: b95b879 · View workflow run →

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