{"slug": "copilot-can-now-approve-pull-requests-should-it-count-toward-your-branch", "title": "Copilot Can Now Approve Pull Requests. Should It Count Toward Your Branch Protection?", "summary": "GitHub enabled Copilot code review to submit approving reviews that count toward a repository's required-approvals rule on 1 September 2026, moving AI review from an advisory comment layer into the branch protection control plane. A follow-up release on 11 September added auto-resolution of Copilot's own comments, shell-tool execution during reviews, and an ensemble of agents at the Lite effort level that GitHub says raised addressed high-severity comments by 47% while cutting review cost about 8%. The capability is in public preview and governed by a chain of enterprise, organisation, and repository settings that administrators must configure deliberately.", "body_md": "Until this month, a Copilot code review was advice. It left a **Comment** review, never an **Approve** or **Request changes**, and GitHub's own documentation was explicit that Copilot reviews did not count toward required approvals. You could ignore it, act on it, or argue with it, but it never moved the merge button.\n\nOn 1 September 2026 that changed. Copilot code review now includes an **approval assessment** in every review, and administrators can authorise Copilot to submit an approving review that **counts toward the repository's required-approvals rule**. Ten days later GitHub followed up with auto-resolution of Copilot's own comments, shell-tool execution during reviews, and an ensemble of agents at the Lite effort level.\n\nThis is the moment where AI code review stops being a suggestion layer and becomes part of the control plane. That deserves more scrutiny than \"turn it on and see\". This article covers what changed, exactly how the controls compose across enterprise, organisation, and repository, what GitHub has not documented yet, and a rollout pattern that lets you benefit without quietly weakening branch protection.\n\nIf you want the wider landscape of Copilot review surfaces, my earlier [definitive guide to code reviews with Copilot](https://dev.to/pwd9000/mastering-code-reviews-with-github-copilot-the-definitive-guide-3nfp) still applies. This post is narrowly about the approval capability and the governance around it.\n\n**Evidence boundary:** Copilot approvals are a public preview and GitHub's docs say they are \"subject to change\". Everything below about product behaviour is grounded in the 1 and 11 September 2026 changelog entries and GitHub Docs as of 13 September 2026.\n\nThree changelog entries in two weeks matter here.\n\n**[27 August 2026.](https://github.blog/changelog/2026-08-27-copilot-code-review-resolution-reasons-and-expanded-capabilities/)** The 300 file / 20,000 line limit on Copilot code review no longer applies, and reviewers gained resolution reasons (**Addressed**, **Won't fix**, **Incorrect**) on Copilot comments. \n\n**[1 September 2026.](https://github.blog/changelog/2026-09-01-copilot-code-review-can-now-approve-pull-requests/)** Two related things shipped in public preview for Copilot Pro, Pro+, Max, Business, and Enterprise:\n\n**[11 September 2026.](https://github.blog/changelog/2026-09-11-auto-resolution-and-analysis-updates-in-copilot-code-review/)** Copilot now resolves its own review comments during a re-review when a later commit addresses them, writes a generated commit message when you apply a Copilot suggestion, runs \"the full set of shell tools from the Copilot SDK\" behind the Copilot agent firewall to validate what it reviews, and uses an ensemble of agents at the Lite effort level. GitHub reports the ensemble increased addressed comments per review by 47% for high severity findings, 31% for medium, and 11% for low, while reducing review cost by about 8%.\n\nRead together, the story is clear. The reviewer got more capable (it can build and run tests), more efficient (ensemble at Lite), and, optionally, authoritative (it can approve). The first two are uncontroversial. The third changes what your branch protection means.\n\nThis is where most of the value of this article lives, because the changelog summarises the controls and the docs spread them across three pages. Here is the full chain as documented in [Configuring code review by GitHub Copilot](https://docs.github.com/en/copilot/how-tos/copilot-on-github/set-up-copilot/configure-code-review).\n\nPath: enterprise **AI controls** > **Available Agents** > **Copilot code review**, then **Allow Copilot to approve pull requests**.\n\n| Option | Effect | \n|---|---|\n| Disabled everywhere | Default. No organisation can enable approvals. | \n| Let organizations decide | Delegates to organisation settings. | \n| Enable for selected organizations | Allow-list specific organisations. | \n\nPath: organisation **Settings** > **Copilot** > **Code review** > **Approvals** > **Count Copilot approvals toward merge requirements**.\n\n| Option | Effect | \n|---|---|\n| Enabled everywhere | Every repository counts Copilot approvals. | \n| Let repositories decide | Delegates to repository settings. | \n| Enable for selected repositories | Allow-list specific repositories. | \n| Disabled everywhere | No repository counts Copilot approvals. | \n\nPath: repository **Settings** > **Copilot** > **Code review** > **Auto-approval**.\n\n| Setting | What it does | \n|---|---|\n| Allow Copilot to approve pull requests | Lets Copilot submit an **Approve** review at all. | \n| Allow Copilot approvals to count toward merge requirements | Lets that approval satisfy the ruleset's required-approvals count. | \n| File paths | Optional. One glob per line, up to 15. The approval counts only when **every changed file** in the pull request matches at least one glob. Blank means all files. | \n\nThe **two-toggle design** at repository level is the detail to internalise. You can allow Copilot to post an Approve review (useful signal in the timeline) without letting that review satisfy branch protection. The second toggle is the one that changes merge semantics.\n\nApprovals are not configured in rulesets. Automatic review is. The ruleset rule is **Automatically request Copilot code review**, with sub-options **Review new pushes** and **Review draft pull requests**. In the REST rulesets API this is rule type `copilot_code_review` with parameters `review_on_push` and `review_draft_pull_requests` ([REST API: repository rules](https://docs.github.com/en/rest/repos/rules)).\n\nThat separation has a practical consequence for the 11 September auto-resolution feature: Copilot resolves its comments **during a re-review**. If your ruleset does not enable **Review new pushes**, a re-review only happens when someone requests it, so comments will not auto-resolve on their own.\n\nPutting the chain together, a Copilot approval satisfies your required-approvals rule only when **all** of these are true:\n\n```\nenterprise policy allows the org\n  AND org policy allows the repo\n  AND repo: \"Allow Copilot to approve pull requests\" = on\n  AND repo: \"Allow Copilot approvals to count toward merge requirements\" = on\n  AND (file paths blank OR every changed file matches a configured glob)\n  AND Copilot's assessment is \"ready to approve\"\n  AND no commit was pushed after the approval\n```\n\nAny false in that chain and you are back to the pre-September behaviour: a review with an assessment that a human reads and acts on.\n\n| Aspect | Before 1 Sep 2026 | Now (public preview) | \n|---|---|---|\n| Review type Copilot can leave | Comment only | Comment, or Approve when enabled | \n| Effect on required approvals | None | Counts when enabled at every level | \n| Readiness signal | Implicit in comment tone | Explicit approval assessment in every overview comment | \n| Scope control | Repository on/off for reviews | Repository-level path globs for counting approvals | \n| Comment lifecycle | Humans resolve threads | Copilot resolves its own threads on re-review when addressed | \n| Validation during review | Static read of the diff | Shell tools inside the agent firewall (build, test, scripts) | \n| Size limits | 300 files / 20k lines | Removed | \n| Lite effort | Single pass | Ensemble of agents | \n| Default effort (from 28 Sep 2026) | Lite | Balanced | \n\nThat last row is a cost item you should not miss. GitHub's [28 August billing changelog](https://github.blog/changelog/2026-08-28-upcoming-changes-to-github-copilot-policies-and-billing/) states that a review effort value of **Default** will use **Balanced** from 28 September 2026. According to the [Copilot code review concept page](https://docs.github.com/en/copilot/concepts/agents/code-review), a Lite review typically consumes an estimated $0.05 to $1 of AI credits and a Balanced review $0.25 to $5, excluding GitHub Actions minutes. If you never explicitly chose Lite, your per-review cost ceiling rises fivefold in two weeks. Select **Lite** explicitly if that is what you want.\n\nRequired approvals are not a productivity feature. They are a control that auditors, security teams, and incident reviewers rely on. Letting a model satisfy that control is a policy decision, not a settings tweak. Three angles matter.\n\n**Separation of duties.** Copilot can now be on both sides of a pull request: author (via Copilot cloud agent) and reviewer (via Copilot code review). GitHub already has a ruleset rule, **Require an additional approval for unattributed Copilot pull requests** (public preview, enabled by default), that adds one approval when Copilot opens a PR with no human attribution. The documentation for that rule and the documentation for Copilot approvals do not reference each other, so whether a Copilot approval can satisfy the *extra* approval on a Copilot-authored PR is not stated. Assume nothing; test it in your sandbox before relying on it.\n\n**Prompt injection becomes merge-relevant.** A reviewer that only comments is a low-value target for content injected into a diff, a commit message, or a linked issue. A reviewer whose approval unblocks merge is a higher-value target. GitHub's agent firewall and read-only review contexts reduce that surface, but the correct mitigation is structural: keep a human approval on paths where a bad merge is expensive.\n\n**Metrics drift.** Auto-resolution changes what \"open review comments\" means in your dashboards. A thread resolved by Copilot after a fix commit is a good outcome, but it is now indistinguishable in a naive count from a thread a human resolved. If you report on review health, tag the resolver.\n\nThe file paths control is the feature that turns \"should an AI approve?\" from a yes/no argument into an engineering decision. Here is a starting configuration for a repository where Copilot's approval is allowed to count only for low-blast-radius change classes.\n\nImport this via **Settings** > **Rules** > **Rulesets** > **Import a ruleset**, or with the REST API. A copy lives in the article's [code folder](https://github.com/Pwd9000-ML/blog-devto/blob/main/posts/2026/copilot-code-review-pr-approvals/code/main-branch-ruleset.json).\n\n```\n{\n  \"name\": \"main: reviewed merges\",\n  \"target\": \"branch\",\n  \"enforcement\": \"active\",\n  \"conditions\": {\n    \"ref_name\": {\n      \"include\": [\"~DEFAULT_BRANCH\"],\n      \"exclude\": []\n    }\n  },\n  \"rules\": [\n    { \"type\": \"deletion\" },\n    { \"type\": \"non_fast_forward\" },\n    {\n      \"type\": \"pull_request\",\n      \"parameters\": {\n        \"required_approving_review_count\": 1,\n        \"dismiss_stale_reviews_on_push\": true,\n        \"require_code_owner_review\": true,\n        \"require_last_push_approval\": true,\n        \"required_review_thread_resolution\": true,\n        \"allowed_merge_methods\": [\"squash\"]\n      }\n    },\n    {\n      \"type\": \"copilot_code_review\",\n      \"parameters\": {\n        \"review_on_push\": true,\n        \"review_draft_pull_requests\": false\n      }\n    }\n  ]\n}\n```\n\nTo create it from the terminal:\n\n```\ngh api \"repos/$env:OWNER/$env:REPO/rulesets\" --method POST --input ./code/main-branch-ruleset.json\n```\n\n`gh api` uses your existing `gh auth login` token. Creating repository rulesets requires repository admin permissions. Do not put a personal access token in the command or in the file.\n\n```\n# .github/CODEOWNERS\n*                       @acme/platform-reviewers\n/infra/**               @acme/platform-security\n/src/auth/**            @acme/identity-team\n/.github/workflows/**   @acme/platform-security\n```\n\nBecause the ruleset requires code owner review, any PR touching these paths needs a designated human owner regardless of what Copilot does. The interaction between Copilot approvals and code owner reviews is not documented, and the safe assumption is that Copilot is not a code owner.\n\nIn **Settings** > **Copilot** > **Code review**:\n\n```\ndocs/**\n*.md\nCHANGELOG.md\n```\n\nWith this configuration, a documentation-only PR can be merged with Copilot's approval plus a passing CODEOWNERS check from `@acme/platform-reviewers` if that team is also required for `*`. If you want docs PRs to merge on Copilot's approval alone, narrow the `*` CODEOWNERS entry so it does not cover `docs/**` and Markdown files. That is a deliberate choice; make it in a PR that the security team reviews.\n\nSet the enterprise policy to **Enable for selected organizations** and the organisation policy to **Enable for selected repositories**. Add only the pilot repository. Allow-lists at both levels mean a repository admin cannot opt in without a platform-level decision, which is exactly the property you want for a control that affects merge gating.\n\nDo not trust a settings page. Prove the behaviour with two pull requests in a non-production repository that has the configuration above.\n\n**PR A: in scope.** Change only `docs/getting-started.md`. Let the automatic review run. Expect an overview comment containing an approval assessment. If Copilot judges it ready, expect an **Approve** review from `copilot-pull-request-reviewer[bot]` and the required-approvals check to turn green.\n\n**PR B: mixed scope.** Change `docs/getting-started.md` and `src/auth/session.ts`. Expect the review, expect the assessment, and expect the approval **not** to count, because not every changed file matches a glob. Expect the code owner requirement for `/src/auth/**` to remain unsatisfied.\n\n**PR A, second push.** Push a trivial follow-up commit to PR A. Expect Copilot's approval to be dismissed. With **Review new pushes** on, expect a re-review and, if the diff still passes, a fresh approval.\n\nInspect the review state from the terminal:\n\n```\ngh pr view 42 --json reviews --jq '.reviews[] | {author: .author.login, state: .state, submittedAt: .submittedAt}'\n```\n\nExpected shape of the output for PR A after the automatic review:\n\n```\n{\n  \"author\": \"copilot-pull-request-reviewer[bot]\",\n  \"state\": \"APPROVED\",\n  \"submittedAt\": \"2026-09-14T09:12:41Z\"\n}\n```\n\nThen confirm merge-readiness from the same data source your automation would use:\n\n```\ngh pr view 42 --json mergeStateStatus,reviewDecision --jq '{mergeStateStatus, reviewDecision}'\n```\n\n`reviewDecision` should remain `REVIEW_REQUIRED` for both PRs until `@acme/platform-reviewers` approves PR A; after that, PR A can become `APPROVED` if Copilot satisfies the required-approval and last-push rules, while PR B remains `REVIEW_REQUIRED`. Record the undocumented interactions rather than assuming them.\n\nA small PowerShell helper that runs these checks for a list of PR numbers is included in the [code folder](https://github.com/Pwd9000-ML/blog-devto/blob/main/posts/2026/copilot-code-review-pr-approvals/code/check-copilot-approvals.ps1).\n\nBeing precise about the gaps is more useful than pretending they do not exist. As of 13 September 2026:\n\n| Question | Status | \n|---|---|\n| Does a Copilot approval satisfy **Require approval of the most recent reviewable push** ? | Not documented. The rule requires approval \"by someone other than the person who pushed it\". A fresh Copilot approval after the last push plausibly qualifies, but no docs page says so. | \n| Does a Copilot approval satisfy **Require review from Code Owners** ? | Not documented. Copilot is not a CODEOWNERS entity. Assume no. | \n| Does a Copilot approval trigger **auto-merge** ? | Not documented. If the approval satisfies all required rules, standard auto-merge logic would presumably proceed. Test it. | \n| Can a Copilot approval satisfy the extra approval from **Require an additional approval for unattributed Copilot pull requests** ? | Not documented. | \n| Exact wording of approval assessment outcomes | Not documented beyond \"whether Copilot considers the pull request ready to approve\". | \n| REST or GraphQL surface for the approval settings | None found in the rulesets API or the Copilot REST API. Configuration is UI-only for now. | \n| Audit log | Settings changes surface as `copilot.code_review_repository_settings_updated` and`copilot.code_review_organization_settings_updated` . No approval-specific event is documented. | \n| GitHub Enterprise Server | The docs are versioned for GitHub.com and Enterprise Cloud only. No GHES availability is stated. | \n\n`package.json` or `Gemfile.lock`, log files, or SVGs. Be cautious about letting an approval count on lockfile-only PRs when the reviewer did not read the lockfile.`docs/**` and Markdown, keep a human code owner on anything else. Approvals count, humans are freed from reviewing typo fixes.`required_approving_review_count` at 2 and let Copilot count as one. A human still signs every merge, and the human reviewer starts from Copilot's findings.`/infra/**` under a security code owner so anything material still needs a person.\nThis is opinion, clearly labelled.\n\nLetting Copilot's approval **count** is defensible only when three things hold: the change class is genuinely low blast radius, the path allow-list is narrow enough that generated files and incidental edits do not defeat it, and a human still owns the merge decision on anything security-relevant through CODEOWNERS. Under those conditions the feature removes real toil. Outside them, it is a way to make branch protection look intact while removing the person who was providing the protection.\n\nThe approval **assessment**, on the other hand, should be on everywhere. It costs nothing extra, it is a better signal than scanning fifteen comments to infer whether the reviewer was broadly happy, and it trains teams to read Copilot's judgement critically before anyone proposes letting it count.\n\nThe 11 September changes are the more important technical shift. A reviewer that can run the build and the tests inside a firewalled environment is a different class of tool from one that reads a diff. That is what will eventually make the approval question less fraught. Until GitHub documents the CODEOWNERS and last-push interactions, and exposes the settings through an API you can enforce with policy-as-code, treat counting approvals as a pilot, not a platform default.\n\nCopilot earning the right to approve is a reasonable direction. Whether it has earned it in your repository is a question only your evidence can answer.\n\nLike, share, follow me on: 🐙 [GitHub](https://github.com/Pwd9000-ML) | 🐧 [X](https://x.com/pwd9000) | 👾 [LinkedIn](https://www.linkedin.com/in/marcel-pwd9000/)\n\nDate: 13-09-2026", "url": "https://wpnews.pro/news/copilot-can-now-approve-pull-requests-should-it-count-toward-your-branch", "canonical_source": "https://dev.to/pwd9000/copilot-can-now-approve-pull-requests-should-it-count-toward-your-branch-protection-2b78", "published_at": "2026-09-13 16:07:51+00:00", "updated_at": "2026-09-13 16:14:28.199941+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-products", "ai-tools", "ai-policy"], "entities": ["GitHub", "Copilot", "Copilot SDK"], "alternates": {"html": "https://wpnews.pro/news/copilot-can-now-approve-pull-requests-should-it-count-toward-your-branch", "markdown": "https://wpnews.pro/news/copilot-can-now-approve-pull-requests-should-it-count-toward-your-branch.md", "text": "https://wpnews.pro/news/copilot-can-now-approve-pull-requests-should-it-count-toward-your-branch.txt", "jsonld": "https://wpnews.pro/news/copilot-can-now-approve-pull-requests-should-it-count-toward-your-branch.jsonld"}}