<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emil Reiter</title>
    <description>The latest articles on DEV Community by Emil Reiter (@emilreiter).</description>
    <link>https://dev.to/emilreiter</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4122532%2Fc1774fd9-c2b7-45bf-bbe5-7e04fc444e8a.png</url>
      <title>DEV Community: Emil Reiter</title>
      <link>https://dev.to/emilreiter</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emilreiter"/>
    <language>en</language>
    <item>
      <title>Measuring review time on GitLab, Azure Repos and Bitbucket DC</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Wed, 11 Nov 2026 14:45:01 +0000</pubDate>
      <link>https://dev.to/emilreiter/measuring-review-time-on-gitlab-azure-repos-and-bitbucket-dc-n45</link>
      <guid>https://dev.to/emilreiter/measuring-review-time-on-gitlab-azure-repos-and-bitbucket-dc-n45</guid>
      <description>&lt;p&gt;GitLab, Azure Repos and Bitbucket Data Center each answer the question of how long code review takes, and only one of them computes the number for you. GitLab ships two analytics pages that define review time differently from each other. Azure Repos has no Repos data in Analytics at all. Bitbucket Data Center gives you a channel for the number and leaves the arithmetic to your CI. If the reason you turned on an AI reviewer was to show that review got faster, the definition you pick decides the answer, and one of those definitions moves the moment the bot posts its first comment.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitLab: two analytics pages, two definitions
&lt;/h2&gt;

&lt;p&gt;GitLab is the only one of the three with a review-time number you can open in a browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.gitlab.com/user/analytics/code_review_analytics/" rel="noopener noreferrer"&gt;Code review analytics&lt;/a&gt; shows a table of open merge requests that have at least one non-author comment, and defines review time as the time since the first comment by a non-author. The table holds up to 20 merge requests per page with review time, author, approvers, comments, commits and line changes, and you can filter by milestone and label. It is Premium and Ultimate, on GitLab.com, Self-Managed and Dedicated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.gitlab.com/user/analytics/merge_request_analytics/" rel="noopener noreferrer"&gt;Merge request analytics&lt;/a&gt; answers a different question. It reports throughput per month and mean time to merge, defined as the average time between merge request creation and the merge event, excluding closed and not-yet-merged merge requests. Same tiers, same offerings.&lt;/p&gt;

&lt;p&gt;Those two numbers will not agree. One is a live counter over open work that starts when someone other than the author comments. The other is an average over completed work measured from creation. Neither one is how long a human waited for a first look, which is usually the thing people mean by review time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure Repos: Analytics has no Repos data
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/devops/report/powerbi/data-available-in-analytics" rel="noopener noreferrer"&gt;Data available from Analytics&lt;/a&gt; lists Repos as None for Azure DevOps Services, Server 2020 and Server 2022, with future availability marked "Under investigation". The OData versions, from v2.0 through v4.0-preview, cover Boards, Test Plans and Pipelines. The &lt;a href="https://learn.microsoft.com/en-us/azure/devops/report/dashboards/widget-catalog" rel="noopener noreferrer"&gt;dashboard widget catalog&lt;/a&gt; lists exactly two Repos widgets, Code Tile and Pull Request, and the Pull Request widget shows pull requests for a team rather than computing any duration.&lt;/p&gt;

&lt;p&gt;That page also carries its own caveat that the platform table was last updated in August 2022, so "Under investigation" is a long-standing state rather than a roadmap item.&lt;/p&gt;

&lt;p&gt;If you want a review-time number on Azure Repos, you build it. The pull request REST object carries creation and closed timestamps and a vote per reviewer, which is enough for time to first vote, time to first approval and time to completion. There is no historical series waiting for you, so you either snapshot on a schedule or reconstruct from the API later. And because that API is versioned per collection, the field you read today is the field you have to keep reading if you want the series to stay comparable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bitbucket Data Center: Code Insights is the channel, not the metric
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://confluence.atlassian.com/spaces/BITBUCKETSERVER104/pages/1822591226/Code+Insights" rel="noopener noreferrer"&gt;Code Insights&lt;/a&gt; is how data reaches a pull request on Bitbucket Data Center. An integration posts a report with a description, a link back to the reporter's URL and up to 6 fields, plus annotations attached to that report. Annotations render on changed lines and only in the unified diff view, not on side-by-side, commit or iterative diffs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://confluence.atlassian.com/spaces/BITBUCKETSERVER104/pages/1822591164/Checks+for+merging+pull+requests" rel="noopener noreferrer"&gt;Checks for merging pull requests&lt;/a&gt; can then require a report to be present, to pass or fail, or to carry annotations of a given severity, and an annotation only blocks a merge when it sits on a changed line in the diff. Nothing in the product computes review time. Whatever number you want on the pull request, your CI has to calculate and post it as a report field, and the history lives wherever your CI keeps it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the GitLab number moves when you add an AI reviewer
&lt;/h2&gt;

&lt;p&gt;GitLab defines review time as the time since the first comment by a non-author, and includes merge requests that have at least one non-author comment. A review bot posting a summary comment is a non-author, and the docs do not carve bot or service-account comments out of either the inclusion rule or the definition.&lt;/p&gt;

&lt;p&gt;The consequence is that enabling an AI reviewer tends to push that number up. Before the bot, the counter started when the first human reviewer commented. With the bot, it starts seconds after the merge request opens, so review time drifts toward the age of the merge request itself. Human latency did not change; the dashboard now reports something worse, because the clock starts earlier.&lt;/p&gt;

&lt;p&gt;Mean time to merge is not affected, since it only looks at creation and the merge event. That makes it the more stable headline if your reporting has to survive a change in tooling, at the cost of hiding the difference between waiting for a first look and waiting for a final approval.&lt;/p&gt;

&lt;p&gt;The docs do not state whether service accounts are excluded from code review analytics, so check on your own instance before quoting the number anywhere. On a self-managed instance you can inspect the data directly, which is the only way to know whether your reviewer's comments are in the sample.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to compute if you need a number that holds up
&lt;/h2&gt;

&lt;p&gt;Fix the definition before you turn anything on, and keep it fixed. Pick either time to first human comment or time to merge, and be explicit that they measure different things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exclude bot accounts from the first-comment calculation yourself. On GitLab that means filtering by author, because the analytics page will not do it for you.&lt;/li&gt;
&lt;li&gt;Use a percentile rather than a mean when a handful of long-running merge requests skew the distribution. &lt;a href="https://docs.kodus.io/en/how_to_use/cockpit/metrics/lead_time_breakdown" rel="noopener noreferrer"&gt;Kodus&lt;/a&gt; computes its review phase with P75 for that reason, and defines review time as PR opened to PR closed with abandoned pull requests excluded, which sits closer to cycle time than to first-response time.&lt;/li&gt;
&lt;li&gt;Snapshot the raw data. Azure Repos Analytics will not keep a review-time series and Bitbucket Data Center will not either, so a query you run in three months will not be able to look back.&lt;/li&gt;
&lt;li&gt;Annotate your own chart when the tooling changes. If the number moved because the clock definition changed, that is worth knowing before someone presents it as an improvement.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Review-time metric&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;th&gt;Where it lives&lt;/th&gt;
&lt;th&gt;What you still build&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitLab&lt;/td&gt;
&lt;td&gt;Review time per open merge request, plus mean time to merge&lt;/td&gt;
&lt;td&gt;Time since first non-author comment; creation to merge&lt;/td&gt;
&lt;td&gt;Code review analytics and merge request analytics, Premium and Ultimate, cloud and self-managed&lt;/td&gt;
&lt;td&gt;Bot filtering for the first-comment metric&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure Repos&lt;/td&gt;
&lt;td&gt;None for Repos&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;Analytics covers Boards, Test Plans and Pipelines only&lt;/td&gt;
&lt;td&gt;REST API snapshots of creation, closed and votes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Data Center&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;Code Insights reports, up to 6 fields&lt;/td&gt;
&lt;td&gt;CI computes the duration and posts the report field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kodus&lt;/td&gt;
&lt;td&gt;Lead Time Breakdown with coding, pickup and review phases&lt;/td&gt;
&lt;td&gt;PR opened to PR closed, P75, abandoned pull requests excluded&lt;/td&gt;
&lt;td&gt;Cockpit, paid tier; self-hosted Enterprise also needs the Analytics Worker&lt;/td&gt;
&lt;td&gt;Nothing for the metric itself&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Kodus row is the only one of the four where the review phase is a first-class metric rather than something you assemble. The trade-off is scope: Cockpit needs a paid tier, and a licensed self-hosted Enterprise deployment needs the &lt;a href="https://docs.kodus.io/en/how_to_deploy/deploy_kodus/analytics_worker" rel="noopener noreferrer"&gt;Analytics Worker&lt;/a&gt; running alongside the code review worker, so an air-gapped instance that only runs the reviewer will not produce the chart. Data refreshes every 30 minutes by default, which is fine for a trend line and not fine if you want to watch a review land.&lt;/p&gt;

&lt;h2&gt;
  
  
  First-look versus completion: pick one before you measure
&lt;/h2&gt;

&lt;p&gt;The useful split is between a first-look metric and a completion metric. A first-look number tells you whether work is sitting in a queue, which is what most teams mean by review time. A completion number tells you whether work is leaving the system. AI review can plausibly move the second and mostly does not move the first, since a human still has to read the diff. Claiming a drop in review time without saying which of the two you measured is the quickest way to have the number ignored, or to have someone reconstruct it and find the opposite.&lt;/p&gt;

&lt;p&gt;There is also a version of this where the metric is the wrong target entirely. If review time is long because a 4,000-line pull request arrives on Friday, the AI reviewer posting faster comments changes nothing about the human read. Measure first, then decide whether the reviewer is the thing to change.&lt;/p&gt;

&lt;p&gt;For the settings that change those numbers rather than the measurement itself, the trigger, scope, draft behavior, blocking and re-review levers are in &lt;a href="https://mergerequests.dev/blog/cutting-pull-request-review-time-with-ai-gitlab-azure-repos-bitbucket/" rel="noopener noreferrer"&gt;cutting pull request review time with AI on GitLab, Azure Repos and Bitbucket&lt;/a&gt;. For the case where the number looks fine and reviewers still complain, the caps that hide parts of a large diff are in &lt;a href="https://mergerequests.dev/blog/what-gitlab-azure-devops-and-bitbucket-hide-in-large-prs/" rel="noopener noreferrer"&gt;what GitLab, Azure DevOps and Bitbucket hide in large PRs&lt;/a&gt;. On Azure DevOps Server rather than Services, the &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-azure-devops-services-vs-server-per-tool/" rel="noopener noreferrer"&gt;per-tool edition split&lt;/a&gt; decides whether a given reviewer exists for you at all, which matters before you invest in building the metric around it.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Reviewing AI-generated code at volume: the ceilings per forge</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Mon, 09 Nov 2026 01:45:01 +0000</pubDate>
      <link>https://dev.to/emilreiter/reviewing-ai-generated-code-at-volume-the-ceilings-per-forge-25gl</link>
      <guid>https://dev.to/emilreiter/reviewing-ai-generated-code-at-volume-the-ceilings-per-forge-25gl</guid>
      <description>&lt;p&gt;AI code review usually gets evaluated on quality and then deployed into a volume problem. The reviewer that looked sharp on a five-file pull request meets a backlog where an agent opens twelve a day, each one large, each one pushed to three times before it is ready. What breaks first is not the model. It is one of three ceilings that nobody configured deliberately: the forge's API quota, the vendor's review quota, and the reviewer's own trigger cadence.&lt;/p&gt;

&lt;p&gt;Those three live in different products, are owned by different people, and fail in ways that look like something else. The forge ceiling looks like an outage. The vendor ceiling looks like the reviewer going quiet. The cadence ceiling looks like a reviewer that stopped noticing new commits. Each one has documented numbers, and for the two self-managed forges the numbers are yours to set.&lt;/p&gt;

&lt;h2&gt;
  
  
  The forge ceiling comes first, because everything shares it
&lt;/h2&gt;

&lt;p&gt;An AI reviewer is an API client. It reads diffs, posts comments, updates statuses, and every one of those calls draws from the same quota as your pipelines, your scripts, and your dashboards. Volume is what makes that quota visible.&lt;/p&gt;

&lt;p&gt;Azure DevOps publishes the clearest numbers, and the behavior is the part worth internalizing. Consumption is measured in Azure DevOps throughput units, an abstract blend of database, compute and storage load. One TSTU is the average load of a typical user over five minutes; &lt;a href="https://learn.microsoft.com/en-us/azure/devops/integrate/concepts/rate-limits?view=azure-devops" rel="noopener noreferrer"&gt;the rate limits page&lt;/a&gt; puts normal activity at spikes of 10 TSTU or less, larger but less frequent spikes up to 100, and the global limit at 200 TSTU within any sliding five-minute window. A user is delayed when their personal usage exceeds 200 times a typical user in that window, with delays from a few milliseconds up to 30 seconds.&lt;/p&gt;

&lt;p&gt;The trap is the response code. A delayed request still returns HTTP 200, with &lt;code&gt;Retry-After&lt;/code&gt; and the &lt;code&gt;X-RateLimit-Delay&lt;/code&gt; header carrying the delay. A client that treats any 2xx as success records requests that never ran, and a review that silently did not happen looks identical to a review that found nothing. Only sustained overuse produces the unambiguous HTTP 429 with &lt;code&gt;TF400733&lt;/code&gt;. If you are building or configuring a bot against Azure Repos, reading &lt;code&gt;X-RateLimit-Remaining&lt;/code&gt; and treating a non-zero delay as a failure is the difference between a working integration and a mystery. Note also that the documented remedy for a higher ceiling is an access level, not a setting: the identity your integration uses needs Basic + Test Plans.&lt;/p&gt;

&lt;p&gt;Bitbucket Data Center gives you a real lever here. &lt;a href="https://confluence.atlassian.com/spaces/BitbucketServer/pages/976171954/Improving+instance+stability+with+rate+limiting" rel="noopener noreferrer"&gt;Rate limiting&lt;/a&gt; is a token bucket per user, off by default, with defaults of 60 tokens and a refill rate of 5 per second. It applies to HTTP requests using basic or bearer authentication, so REST API calls and Git over HTTP, while Git SSH operations are a separate mechanism. Exhaustion returns 429, records a &lt;code&gt;rate-limited&lt;/code&gt; event in the access log, and surfaces in JMX metrics. Two details matter when a bot misbehaves. First, you can give a specific user an exemption, either custom bucket settings or unlimited requests, which is the clean way to stop your reviewer competing with your pipelines for the same bucket. Second, in a cluster every user gets a separate bucket on every node, so a three-node instance gives each user three buckets and the global settings apply to each.&lt;/p&gt;

&lt;p&gt;GitLab's forge-side limits are documented per endpoint rather than as a single quota page, and the relevant ones for a review bot are the write endpoints it hammers: notes and comments. Those are the limits to check before blaming the reviewer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vendor ceiling: reviews per hour, or credits per month
&lt;/h2&gt;

&lt;p&gt;The second ceiling belongs to whatever reviews your code, and the pricing models are not comparable at face value.&lt;/p&gt;

&lt;p&gt;CodeRabbit meters reviews. &lt;a href="https://docs.coderabbit.ai/management/plans" rel="noopener noreferrer"&gt;Its plans page&lt;/a&gt; lists per-developer, per-hour rolling allowances: 1 review per hour on Free and that is summarization only, 5 on Essentials, 8 on Team, 10 on Advanced, 12 on Enterprise. Files per review are a separate cap, 5 on Essentials up to 12 on Enterprise, counted after path filters are applied. A team that runs one pull request per developer per day never touches this. A team where an agent opens several pull requests per developer per hour hits it during a normal working morning, and the failure is a review that never starts. Essentials and above can enable usage-based reviews to keep processing past the allowance, with the caveat that pull requests above 300 files are not supported through usage pricing at all, and that the Fair Usage Limits Policy lets availability adjust under sustained high volume.&lt;/p&gt;

&lt;p&gt;GitLab meters credits instead. &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/raw/master/doc/subscriptions/gitlab_credits.md" rel="noopener noreferrer"&gt;GitLab Credits&lt;/a&gt; are the consumption currency, with included credits allocated per user per month and no rollover, a shared monthly commitment pool, and on-demand usage at $1 per credit once everything else is spent. The detail that decides how a volume spike lands: a flow that runs as a service account with composite identity is billed to the namespace, not to the user who started it. Code Review Flow is one of those. So a busy team draws from the namespace pool rather than from individual allowances, which is a simpler model to reason about and a worse one to attribute, since you cannot reserve part of the pool for a subset of users. Usage caps on the dashboard are the available control. On the Free tier, on-demand usage is capped at $25,000 per calendar month and switches off automatically when it is reached.&lt;/p&gt;

&lt;p&gt;The self-managed split is the one that catches teams mid-deployment. &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/raw/master/doc/subscriptions/subscription-add-ons.md" rel="noopener noreferrer"&gt;GitLab Duo Core&lt;/a&gt; arrives automatically with Premium or Ultimate on 18.0 and later, but it is not available on GitLab Duo Self-Hosted under an offline license, because Core needs a connection to the GitLab AI Gateway. If you want self-hosted models on an air-gapped instance, the Agent Platform Self-Hosted add-on is the path, and it is billed as a flat fee under an Enterprise License Agreement rather than by usage, which makes the cost predictable and the capacity commitment real.&lt;/p&gt;

&lt;p&gt;Azure Repos Copilot code review meters nothing in the same way. Billing runs through &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews?view=azure-devops" rel="noopener noreferrer"&gt;Azure Cost Management&lt;/a&gt; on an Azure subscription linked to the organization, and the volume lever is the review effort level, set per project with optional per-repository override, where higher effort consumes more tokens and increases cost. Users can pick a different effort for a single review. That makes cost a per-review decision rather than a plan limit, which suits teams that want to spend effort where it matters and not on every agent-generated pull request.&lt;/p&gt;

&lt;p&gt;Kodus sits at the other end of that spectrum: reviews are unlimited on every plan because it runs on your own model key. The free Community tier is self-hosted or cloud with up to 10 Kody Rules and 3 plugins, Teams is $10 per active developer per month on cloud, and Enterprise is custom with self-hosting. The ceiling is technical rather than commercial, at 2,000 changed files, past which the pull request is not reviewed.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What is metered&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Where the volume bites&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Azure DevOps forge API&lt;/td&gt;
&lt;td&gt;TSTU, 200 per sliding 5-minute window, delays up to 30s&lt;/td&gt;
&lt;td&gt;Bot API calls share the quota with pipelines; delays return HTTP 200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket DC forge API&lt;/td&gt;
&lt;td&gt;Token bucket per user, 60 size / 5 per second, off by default&lt;/td&gt;
&lt;td&gt;Cluster gives each user a separate bucket per node; exemptions are per user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;5-12 reviews per developer per hour, 5-12 files per review&lt;/td&gt;
&lt;td&gt;Sustained bursts exhaust a rolling hourly allowance; no usage pricing above 300 files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitLab&lt;/td&gt;
&lt;td&gt;Credits: included per user, then shared pool, then $1 per credit&lt;/td&gt;
&lt;td&gt;Code Review Flow bills the namespace, so a team spike drains a shared pool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure Repos Copilot&lt;/td&gt;
&lt;td&gt;Azure subscription via Cost Management, effort level per review&lt;/td&gt;
&lt;td&gt;Cost scales with effort and frequency, not with a plan limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kodus&lt;/td&gt;
&lt;td&gt;Nothing per review; BYOK token cost to your provider&lt;/td&gt;
&lt;td&gt;Hard stop at 2,000 changed files per pull request&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The cadence ceiling: how many times one pull request gets reviewed
&lt;/h2&gt;

&lt;p&gt;The third ceiling is internal to the reviewer, and it is the one teams most often discover by accident.&lt;/p&gt;

&lt;p&gt;Kodus documents its trigger model explicitly. &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/flow" rel="noopener noreferrer"&gt;The review flow&lt;/a&gt; runs on pull request open, on new commits, or on a &lt;code&gt;@kody start-review&lt;/code&gt; comment, and it skips when there are no new commits since the last run, when the changes are merge-only, when every changed file matches an ignore pattern, when the file limit is exceeded, or when the pull request is in draft mode and configured to skip drafts. The cadence setting is the volume control: automatic reviews every push, auto-pause during rapid consecutive pushes with a default of 3 pushes in 15 minutes, or manual only. A force re-run is available with &lt;code&gt;@kody review --force&lt;/code&gt;, which matters because a plain &lt;code&gt;start-review&lt;/code&gt; will skip again if there is nothing new.&lt;/p&gt;

&lt;p&gt;CodeRabbit has an equivalent default that behaves the same way without being set. &lt;code&gt;auto_pause_after_reviewed_commits&lt;/code&gt; defaults to 5, so incremental reviews pause after five reviewed commits. On a pull request that an agent pushes to eight times, the last three pushes get no review, and nothing on the pull request says so. Combined with the per-developer hourly allowance, that is two independent limits that both express themselves as silence.&lt;/p&gt;

&lt;p&gt;The consequence is that the useful question about a review setup is not how good the findings are. It is how many reviews per pull request you are actually buying, and whether the answer is the one you assumed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to set before volume arrives
&lt;/h2&gt;

&lt;p&gt;The ordering matters, because the ceilings interact.&lt;/p&gt;

&lt;p&gt;Raise the forge ceiling first, since it is the only one that takes down things other than your reviewer. On Bitbucket Data Center that means turning rate limiting on deliberately and giving the review bot an exemption, rather than leaving it off and discovering the problem when someone enables it. On Azure Repos it means reading the delay headers in whatever integrates, because the 200 response will not tell you.&lt;/p&gt;

&lt;p&gt;Then decide whether your reviewer is metered by reviews or by credits, because the failure looks different. A metered-by-review allowance runs out mid-morning and comes back on a rolling window; a credit pool drains and needs a purchase or an on-demand acceptance. Both are visible in advance if you look at the numbers rather than at the pull request.&lt;/p&gt;

&lt;p&gt;Then set the cadence to match how your team actually pushes. Auto-pause defaults exist because reviewers that comment on every push generate noise, and a reviewer nobody reads is the same as no reviewer. For teams running agents that push frequently, reviewing once on open and once when the pull request is marked ready is usually a better use of the same budget than reviewing every intermediate push, and it sidesteps the cadence pause entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why does AI code review stop working when pull request volume goes up?
&lt;/h3&gt;

&lt;p&gt;Because three separate ceilings exist, and each fails differently. The forge throttles API calls, the vendor caps how many reviews you get, and the reviewer's own trigger cadence decides how many times it runs on a single pull request. Adding a reviewer multiplies load against the forge ceiling it already shares with your pipelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who pays for a GitLab Code Review Flow run?
&lt;/h3&gt;

&lt;p&gt;The namespace, not the person who started it. Foundational flows like Code Review Flow run as a service account with composite identity, so the usage is billed to the namespace and draws from the monthly commitment pool and then on-demand credits, at $1 per credit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Azure DevOps return an error when it delays a request?
&lt;/h3&gt;

&lt;p&gt;No. A delayed request still returns HTTP 200 with Retry-After and the X-RateLimit headers set. A client that logs success on any 2xx records requests that never ran, and the delay ranges from a few milliseconds up to 30 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a TSTU on Azure DevOps?
&lt;/h3&gt;

&lt;p&gt;An Azure DevOps throughput unit, an abstract measure of load blending database, compute and storage consumption. One TSTU is the average load of a typical user over five minutes, normal activity produces spikes of 10 TSTU or less, and the global limit is 200 TSTU in any sliding five-minute window.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Bitbucket Data Center's rate limiting per instance or per user?
&lt;/h3&gt;

&lt;p&gt;Per user, using a token bucket. Defaults are a bucket size of 60 requests and a refill rate of 5 per second, applied to HTTP requests with basic or bearer authentication such as REST API calls. In a cluster, each user gets a separate bucket on each node.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
      <category>codereview</category>
    </item>
    <item>
      <title>AI code review on Azure DevOps: Services vs Server, per tool</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Wed, 04 Nov 2026 14:45:01 +0000</pubDate>
      <link>https://dev.to/emilreiter/ai-code-review-on-azure-devops-services-vs-server-per-tool-91a</link>
      <guid>https://dev.to/emilreiter/ai-code-review-on-azure-devops-services-vs-server-per-tool-91a</guid>
      <description>&lt;p&gt;Azure Repos ships in two editions, and the AI review options are not the same in both. Microsoft's Copilot code review is documented for Azure DevOps Services and carries a limited preview label. Azure DevOps Server has no Microsoft-native reviewer at all, so a Server team runs PR-Agent from a pipeline, points a vendor webhook at Service Hooks, or self-hosts something. Which edition you are on decides the setup work, the permissions you need, and where the reviewer reads your coding standards from.&lt;/p&gt;

&lt;p&gt;That last part is where most rollouts go sideways, so it is worth walking through the routes one at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copilot code review is Azure DevOps Services only
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews" rel="noopener noreferrer"&gt;get started page&lt;/a&gt; is headed Azure DevOps Services, and the feature is in limited preview: no service level agreement, and functionality can change or be removed. Prerequisites are an Azure DevOps organization, a Git repository in Azure Repos (TFVC is not supported), and an Azure subscription linked to the organization, because usage bills through Azure Cost Management instead of through seats.&lt;/p&gt;

&lt;p&gt;Enablement cascades across scopes. A Project Collection Administrator turns the feature on at the organization level and can enable it for every project at once. A Project Administrator scopes it to specific projects, and a repository owner enables it per repository when project settings allow overrides. Individual users opt in through Preview features unless an administrator has already enabled the preview for everyone.&lt;/p&gt;

&lt;p&gt;Automatic reviews are a separate switch from enablement. Copilot reviews pull requests on its own only where you add a branch policy on the target branch. Without that policy, someone has to add Copilot as a reviewer by hand on each pull request, which is fine for a pilot and not fine for a team. The default review effort is set at project or repository level, and higher effort consumes more tokens, so the effort setting is also a cost setting.&lt;/p&gt;

&lt;p&gt;For a Server install, none of this exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Copilot reads your team's rules, and the target-branch catch
&lt;/h2&gt;

&lt;p&gt;Copilot takes instructions at the organization and project level through Azure DevOps settings, and at the repository level through a file. The &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/configure-copilot-code-review-instructions" rel="noopener noreferrer"&gt;instructions page&lt;/a&gt; accepts two paths for that file: &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; or &lt;code&gt;.azuredevops/copilot-instructions.md&lt;/code&gt;, both at the repository root. Path-scoped files go in &lt;code&gt;.github/instructions/&lt;/code&gt; or &lt;code&gt;.azuredevops/instructions/&lt;/code&gt; as &lt;code&gt;*.instructions.md&lt;/code&gt;, with YAML front matter carrying an &lt;code&gt;applyTo&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;A path-scoped file without &lt;code&gt;applyTo&lt;/code&gt; is skipped. Nothing errors, the file is committed, and reviews keep running without it. If you have a rules file that seems to have no effect, that front matter value is the first thing to check.&lt;/p&gt;

&lt;p&gt;The catch that changes how you roll standards out is which branch the instructions come from. Repository-level and path-scoped files are read from the pull request's target branch only. A pull request that adds or edits the instructions file is not reviewed against the new text. Those rules apply after the change merges into the target branch. If you are introducing a standard, land the file on the default branch first, then let the later pull requests pick it up.&lt;/p&gt;

&lt;p&gt;When instructions exist at several scopes, Copilot uses all applicable ones during a review. The docs do not promise a precedence order for an organization rule that contradicts a repository rule, so that is a conflict to avoid rather than resolve.&lt;/p&gt;

&lt;h2&gt;
  
  
  What runs on Azure DevOps Server instead
&lt;/h2&gt;

&lt;p&gt;On the server edition the choice is between self-hosted tools and hosted vendors that reach into your instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.pr-agent.ai/overview/supported_platforms/" rel="noopener noreferrer"&gt;PR-Agent&lt;/a&gt; lists Azure DevOps as a supported git provider, and the support matrix lists an Azure DevOps pipeline as supported usage. A Server team can run it as a pipeline job or behind a webhook. It is community-owned and MIT licensed, review categories and prompts live in configuration files you own, and the matrix lists repo context files such as &lt;code&gt;AGENTS.md&lt;/code&gt;. One caveat to note before you plan around its help tooling: &lt;code&gt;/help_docs&lt;/code&gt; has been disabled since v0.36.1 pending a fix for a credential-exposure issue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/alibaba/open-code-review" rel="noopener noreferrer"&gt;Open Code Review&lt;/a&gt; from Alibaba is a different shape. It installs from npm as &lt;code&gt;ocr&lt;/code&gt;, works on a git diff, a commit range, or a whole-file scan, and needs an LLM endpoint rather than a forge integration. On a firewalled Server install that is convenient, and it also means the tool does not post comments to a pull request by itself unless you wire that up. Its published benchmark is the project's own, built from 50 repositories and 200 pull requests with engineer-annotated issues, and it reports higher precision than a general-purpose agent on the same model at roughly a ninth of the tokens, with lower recall as a stated trade-off. Treat it as the project's number, not a third-party measurement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.kodus.io/en/how_to_use/code_review/general_config/azure_devops_pat" rel="noopener noreferrer"&gt;Kodus&lt;/a&gt; connects to Azure DevOps with a Personal Access Token and documents no OAuth path for that provider, unlike GitHub and GitLab. The PAT scopes the docs list are Analytics Read, Code Read &amp;amp; Write, Graph Read, Identities and Groups Read, Project and Team Read, and User Profile Read, with Code write access being the one that lets it post comments. If the connection succeeds but nothing appears on new pull requests, the PAT scopes are the first thing the troubleshooting page points at.&lt;/p&gt;

&lt;p&gt;One Azure-specific detail matters if you self-host it: the Azure Repos webhook URL has to carry an encrypted &lt;code&gt;token&lt;/code&gt; query parameter, derived by encrypting &lt;code&gt;CODE_MANAGEMENT_WEBHOOK_TOKEN&lt;/code&gt; with &lt;code&gt;CODE_MANAGEMENT_SECRET&lt;/code&gt; using AES-256-CBC. Requests without it get a 403. The &lt;a href="https://docs.kodus.io/en/how_to_deploy/platforms/azure_devops/azdevops_webhook" rel="noopener noreferrer"&gt;webhook page&lt;/a&gt; also notes the URL has to reach the webhooks service on port 3332, or your reverse proxy has to route the webhook path there. And on rules, Kody reads coding-agent instruction files including &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; and &lt;code&gt;.github/instructions/**/*.instructions.md&lt;/code&gt;; the &lt;code&gt;.azuredevops/&lt;/code&gt; paths are not in that list, so a team standardizing on the Azure-native path should know which tools will read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do the hosted vendors document Azure DevOps Server?
&lt;/h2&gt;

&lt;p&gt;Less clearly than you would want, and the difference matters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.coderabbit.ai/platforms/azure-devops" rel="noopener noreferrer"&gt;CodeRabbit's Azure DevOps page&lt;/a&gt; covers a PAT or a Microsoft Entra service principal, Project Administrator or Project Collection Administrator rights, and the Edit Subscriptions permission on Service Hooks so the webhook can be installed. It notes that permission cannot currently be granted through the UI and that it is granted per project, which becomes real work across a large organization. The page does not split Azure DevOps Services from Azure DevOps Server, so it does not establish Server support on its own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.qodo.ai/on-prem/git-integration/install/azure-devops" rel="noopener noreferrer"&gt;Qodo's on-premises Azure DevOps guide&lt;/a&gt; walks through a Microsoft Entra app registration, a service account added to the organization with Basic access and Project Administrators, and a Service Hooks webhook subscribed to PR Created, PR Updated, PR Commented and PR Merged. Those steps assume &lt;code&gt;dev.azure.com&lt;/code&gt; and Entra ID, which are Azure DevOps Services constructs. The &lt;a href="https://docs.qodo.ai/install-qodo/deployment-model-support" rel="noopener noreferrer"&gt;deployment matrix&lt;/a&gt; separately marks on-prem as unsupported for Azure DevOps Cloud. Read together, the guide covers running Qodo on-premises against Azure DevOps Services. It does not document an Azure DevOps Server install.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;Azure DevOps Services&lt;/th&gt;
&lt;th&gt;Azure DevOps Server&lt;/th&gt;
&lt;th&gt;Where rules come from&lt;/th&gt;
&lt;th&gt;Where the review runs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Copilot code review&lt;/td&gt;
&lt;td&gt;Yes, limited preview&lt;/td&gt;
&lt;td&gt;Not documented&lt;/td&gt;
&lt;td&gt;Org and project settings, &lt;code&gt;.github/&lt;/code&gt; or &lt;code&gt;.azuredevops/&lt;/code&gt; instruction files&lt;/td&gt;
&lt;td&gt;Azure Pipelines agent pool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;Documented (Entra service principal or PAT)&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;Web UI and repository config files&lt;/td&gt;
&lt;td&gt;CodeRabbit cloud, via Service Hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo on-premises&lt;/td&gt;
&lt;td&gt;Documented through Entra ID and Service Hooks&lt;/td&gt;
&lt;td&gt;Not documented&lt;/td&gt;
&lt;td&gt;Repository config and PR commands&lt;/td&gt;
&lt;td&gt;Your Qodo environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR-Agent&lt;/td&gt;
&lt;td&gt;Supported provider, pipeline or webhook&lt;/td&gt;
&lt;td&gt;Supported provider, pipeline or webhook&lt;/td&gt;
&lt;td&gt;JSON config, prompt files, &lt;code&gt;AGENTS.md&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Your pipeline, CLI, or webhook server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Code Review&lt;/td&gt;
&lt;td&gt;CLI on a git checkout&lt;/td&gt;
&lt;td&gt;CLI on a git checkout&lt;/td&gt;
&lt;td&gt;Path-scoped review rules&lt;/td&gt;
&lt;td&gt;Wherever you run the CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kodus&lt;/td&gt;
&lt;td&gt;Documented, token auth&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;Kody Rules plus detected repository rule files&lt;/td&gt;
&lt;td&gt;Kodus self-hosted or cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every cell reflects the vendor or project page linked above. Where a cell says not documented or not stated, the page I read does not cover that edition, and that gap is the thing to verify before you commit. The wider &lt;a href="https://mergerequests.dev/blog/ai-code-review-tools-on-self-managed-gitlab-azure-repos-and-bitbucket/" rel="noopener noreferrer"&gt;edition coverage comparison across all three forges&lt;/a&gt; covers the same question for GitLab Self-Managed and Bitbucket Data Center.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which route fits which team
&lt;/h2&gt;

&lt;p&gt;On Azure DevOps Services, Copilot code review is the shortest path to a first automated review. An administrator turns it on at the organization level, billing runs through a subscription you already have, and reviewers appear on pull requests without a webhook to maintain. What you accept in return is the preview status, the missing precedence order when instructions conflict, and the target-branch rule for instruction files. If your standard is that a reviewer must apply a rules file changed inside the same pull request, Copilot will not do that, and you want a tool that reads the rule at review time.&lt;/p&gt;

&lt;p&gt;On Azure DevOps Server the choice is between PR-Agent and a self-hosted product. PR-Agent is the lower-commitment option: MIT, no vendor account, configuration stored in files in your repository, and a documented pipeline trigger. What you pay for it is operational work, since you own the pipeline, the model key and the webhook endpoint. A UI for managing rules, or metrics on what the reviewer found over time, is where a product like Kodus starts to make sense, and the price of that is running the service yourself, including the webhook token and the port exposure above.&lt;/p&gt;

&lt;p&gt;The cheapest test before committing to any of them is one pull request. Put a single rule in the file that route reads, open a pull request that breaks the rule, and see which reviewers flag it. On Azure Repos, the file that reaches the most reviewers is &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;, because Copilot reads it and Kody detects it among its supported patterns. If your repository already speaks &lt;code&gt;.azuredevops/&lt;/code&gt;, keep both paths in sync or the tools will end up reviewing against different standards.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Copilot code review available on Azure DevOps Server?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Microsoft documents it for Azure DevOps Services, and the documentation is headed for that edition. Server teams run a self-hosted reviewer such as PR-Agent, or wire a vendor integration into Service Hooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does Copilot code review read custom instructions from?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Organization and project settings, repository files at &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; or &lt;code&gt;.azuredevops/copilot-instructions.md&lt;/code&gt;, and path-scoped &lt;code&gt;*.instructions.md&lt;/code&gt; files carrying an &lt;code&gt;applyTo&lt;/code&gt; value. Repository-level and path-scoped files are read from the pull request's target branch, so a change to them applies after it merges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can CodeRabbit or Qodo review Azure DevOps Server pull requests?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neither vendor page establishes Server support. CodeRabbit documents an Azure DevOps integration through a PAT or an Entra service principal, and Qodo's on-premises guide uses &lt;code&gt;dev.azure.com&lt;/code&gt; and Entra ID, which are Azure DevOps Services constructs.&lt;/p&gt;

</description>
      <category>azuredevops</category>
      <category>codereview</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Open source AI code review on GitLab, Azure Repos, Bitbucket DC</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Mon, 02 Nov 2026 01:30:04 +0000</pubDate>
      <link>https://dev.to/emilreiter/open-source-ai-code-review-on-gitlab-azure-repos-bitbucket-dc-2ch4</link>
      <guid>https://dev.to/emilreiter/open-source-ai-code-review-on-gitlab-azure-repos-bitbucket-dc-2ch4</guid>
      <description>&lt;p&gt;If your forge is GitLab Self-Managed, Azure Repos, or Bitbucket Data Center, there are two open source AI code review projects that will run inside infrastructure you control: PR-Agent and Kodus. Everything else with a self-hosted option is a commercial product attached to a contract and a seat floor, which is a different kind of purchase.&lt;/p&gt;

&lt;p&gt;Both of them review pull requests on all three forges, both let you point the model layer at a provider you already pay, and both can run with no outbound internet if you host the model too. What separates them is the license and which features survive on each provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  License and provider coverage are separate questions
&lt;/h2&gt;

&lt;p&gt;A tool can be free to self-host without being open source. CodeRabbit's self-hosted deployment ships as a container image you run in your own environment, and it is scoped to the Enterprise plan, with the docs putting the entry point at 500 or more user seats. That is a reasonable product to sell, and it is a procurement conversation rather than a git clone. The reverse also happens, where a permissively licensed project cannot do a specific thing on your forge because the provider API does not expose the hook that feature needs.&lt;/p&gt;

&lt;p&gt;So the questions that matter for a self-managed team are what the license permits and what the tool can actually do on your forge.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR-Agent is MIT, and the license is held by the project
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/The-PR-Agent/pr-agent" rel="noopener noreferrer"&gt;PR-Agent repository&lt;/a&gt; carries an MIT license held by the project itself, not by a vendor, and the README states plainly that this is a community-owned project Qodo donated and that it is separate from Qodo's commercial product. That distinction matters when you are choosing something to run for the next three years: the license cannot be re-scoped by a company that later changes direction.&lt;/p&gt;

&lt;p&gt;The most useful document in this whole space is the &lt;a href="https://docs.pr-agent.ai/overview/supported_platforms/" rel="noopener noreferrer"&gt;supported platforms matrix&lt;/a&gt;, because it lists where features differ per provider instead of claiming uniform support. Describe, Review, Improve, Ask, Add Docs, and Help work on GitHub, GitLab, Bitbucket, Azure DevOps, and Gitea. Ask on code lines works on GitHub, GitLab, and Bitbucket only. Similar Issues is GitHub only. Update CHANGELOG runs everywhere but posts as a pull request comment on Bitbucket, Azure DevOps, and Gitea, because those providers cannot push files through the API path the tool uses. Generate Labels on Gitea is marked as not yet verified.&lt;/p&gt;

&lt;p&gt;That matrix is the reason to check before you assume. A team on Azure Repos that wants comment-anchored questions is asking for something the project does not list as supported there. The deployment paths for the non-GitHub forges are covered in &lt;a href="https://mergerequests.dev/blog/pr-agent-on-gitlab-azure-devops-bitbucket-the-self-hosted-code-review-option/" rel="noopener noreferrer"&gt;PR-Agent on GitLab, Azure DevOps and Bitbucket&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One upgrade detail catches people out: Docker images from 0.34.2 onward are published under the &lt;code&gt;pragent/pr-agent&lt;/code&gt; namespace, and the older &lt;code&gt;codiumai/pr-agent&lt;/code&gt; namespace is a frozen archive with no new pushes. Any pinned image reference needs updating before you move versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kodus splits its license between AGPL-3.0 and an enterprise file license
&lt;/h2&gt;

&lt;p&gt;Kodus is open source in a way that needs one clarification, because the license is split by file rather than applied to the whole repository. Filenames containing &lt;code&gt;.ee.&lt;/code&gt; and everything under an &lt;code&gt;ee/&lt;/code&gt; directory fall under the &lt;a href="https://github.com/kodustech/kodus-ai/blob/main/license_ee.md" rel="noopener noreferrer"&gt;Kodus Enterprise Code License&lt;/a&gt;; the rest of the source is AGPL-3.0.&lt;/p&gt;

&lt;p&gt;That enterprise license grants Community users the right to run the unmodified enterprise code as needed to operate Community features, including code review and BYOK model providers, in a self-hosted deployment for internal purposes, production included, within the limits the software enforces. It does not grant the right to modify that code, to bypass the Community limits, or to use Enterprise-only features. Offering Kodus as a hosted or managed service to third parties is not internal use, so a team planning to resell it is outside the grant.&lt;/p&gt;

&lt;p&gt;The Community limits are specific rather than vague. The &lt;a href="https://docs.kodus.io/en/how_to_use/pricing.md" rel="noopener noreferrer"&gt;pricing documentation&lt;/a&gt; puts Community at up to 10 Kody Rules and up to 3 active plugins, with reviews unlimited on every plan because the model calls run on your own key and Kodus does not mark up tokens. Teams is 10 dollars per active developer per month, cloud only, and Enterprise is contract-priced. The published hard cap is that pull requests with more than 2,000 changed files are not reviewed, which is the kind of limit that only shows up on generated-code branches.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/kodustech/kodus-ai" rel="noopener noreferrer"&gt;repository README&lt;/a&gt; gives the self-hosting floor as Docker on a VM you control, with at least 2 CPU cores, 8 GB of RAM, and 60 GB of free disk. It names self-managed GitLab and Forgejo as the on-premises forges it connects to, and lists GitHub, GitLab, Bitbucket, Azure DevOps, and Forgejo for pull request reviews. Self-hosted instances send one anonymous heartbeat per day carrying aggregated counters with no code, names, or identifiers, and &lt;code&gt;KODUS_TELEMETRY_DISABLED=true&lt;/code&gt; turns it off.&lt;/p&gt;

&lt;h2&gt;
  
  
  The commercial self-hosted tier, and where the seat floor bites
&lt;/h2&gt;

&lt;p&gt;CodeRabbit's &lt;a href="https://docs.coderabbit.ai/self-hosted/overview.md" rel="noopener noreferrer"&gt;self-hosted option&lt;/a&gt; runs the review agent in your infrastructure, with the platform integration connecting through a service account or app, and a reverse tunnel for platforms that cannot accept inbound connections. The supported platform list covers GitHub Enterprise Server, GitLab self-managed, Azure DevOps, and Bitbucket Data Center. The docs scope the whole thing to Enterprise customers with 500 or more user seats, which is the number to bring to a budget conversation before you evaluate the product at all.&lt;/p&gt;

&lt;p&gt;Qodo's &lt;a href="https://docs.qodo.ai/install-qodo/deployment-model-support" rel="noopener noreferrer"&gt;deployment model table&lt;/a&gt; is the page to read if air-gapping is on your requirements list. On-premises and air-gapped deployments are documented for GitHub Enterprise, GitLab Self-Managed, Bitbucket Data Center, and Gerrit. Bitbucket Cloud and Azure DevOps Cloud are listed as multi-tenant and single-tenant only, with on-premises marked unavailable, and Azure DevOps has no on-premises entry in that table at all.&lt;/p&gt;

&lt;p&gt;For a team on Azure DevOps Server that is the deciding line, since there is no documented Qodo on-premises path for Azure DevOps. The wider per-tool picture across Services and Server is worth reading in full, and it is laid out in &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-azure-devops-services-vs-server-per-tool/" rel="noopener noreferrer"&gt;AI code review on Azure DevOps Services vs Server, per tool&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature coverage across the options
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;PR-Agent&lt;/th&gt;
&lt;th&gt;Kodus&lt;/th&gt;
&lt;th&gt;CodeRabbit self-hosted&lt;/th&gt;
&lt;th&gt;Qodo on-prem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;MIT, held by the project&lt;/td&gt;
&lt;td&gt;AGPL-3.0 core, enterprise-licensed &lt;code&gt;.ee.&lt;/code&gt; files&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted path&lt;/td&gt;
&lt;td&gt;CLI, Docker, webhook, CI pipeline&lt;/td&gt;
&lt;td&gt;Docker on a VM you control&lt;/td&gt;
&lt;td&gt;Container image, Enterprise plan only&lt;/td&gt;
&lt;td&gt;Contract, per provider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitLab Self-Managed&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, air-gapped documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure Repos&lt;/td&gt;
&lt;td&gt;Yes per the provider matrix (Services and Server not split)&lt;/td&gt;
&lt;td&gt;Yes, provider list does not split editions&lt;/td&gt;
&lt;td&gt;Listed as Azure DevOps, edition not qualified&lt;/td&gt;
&lt;td&gt;Cloud only, no on-premises entry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Data Center&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, air-gapped documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Air-gapped&lt;/td&gt;
&lt;td&gt;Yes, with a self-hosted model&lt;/td&gt;
&lt;td&gt;Yes, with a self-hosted model&lt;/td&gt;
&lt;td&gt;Private-network option via reverse tunnel&lt;/td&gt;
&lt;td&gt;Documented for GitHub Enterprise, GitLab SM, Bitbucket DC, Gerrit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Community free, Teams 10 dollars per active dev per month&lt;/td&gt;
&lt;td&gt;Enterprise contract&lt;/td&gt;
&lt;td&gt;Contract&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documented limits&lt;/td&gt;
&lt;td&gt;Per-provider feature gaps in the matrix&lt;/td&gt;
&lt;td&gt;10 Kody Rules and 3 plugins on Community, 2,000 changed files&lt;/td&gt;
&lt;td&gt;500+ user seats&lt;/td&gt;
&lt;td&gt;Not stated in the deployment table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neither PR-Agent nor Kodus splits Azure DevOps Services from Azure DevOps Server in its provider list, so if you run Server, treat the Azure DevOps row as needing a direct test rather than a documentation check.&lt;/p&gt;

&lt;h2&gt;
  
  
  What GitLab ships itself, and what running it offline takes
&lt;/h2&gt;

&lt;p&gt;GitLab's own AI review is Duo, and which feature runs depends on the seat. A user holding a GitLab Duo Enterprise seat gets GitLab Duo Code Review, which is single-pass and scoped to the merge request and its file diffs. Everyone else gets Code Review Flow, which needs no add-on but consumes GitLab Credits, and a group Owner can configure all reviews to use Code Review Flow regardless of seat type. The routing table is in the &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/raw/master/doc/user/project/merge_requests/duo_in_merge_requests.md" rel="noopener noreferrer"&gt;GitLab Duo in merge requests documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Running that offline is a separate project with its own prerequisites. Offline flow execution needs GitLab 18.9 or later, and the setup requires an opt-out exemption of cloud licensing arranged before purchase, which means it is a sales conversation and not a config flag. You then move the AI Gateway image, the Agent Platform Flows executor image, the vLLM inference server image, and the model weights to the internal registry and filesystem by hand, roughly 0.6 GiB, 0.5 GiB, and 9 GiB compressed before the weights, per the &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/raw/master/doc/administration/gitlab_duo_self_hosted/offline_deployment.md" rel="noopener noreferrer"&gt;offline deployment documentation&lt;/a&gt;. The self-managed angle where review policy comes from your team instead of a vendor default is covered in &lt;a href="https://mergerequests.dev/blog/gitlab-self-managed-ai-review-that-follows-your-own-rules/" rel="noopener noreferrer"&gt;GitLab Self-Managed AI review that follows your own rules&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which of these fits your team
&lt;/h2&gt;

&lt;p&gt;If forking and modifying the reviewer matters to you, PR-Agent is the only option in this set that grants it, and you accept the per-provider gaps its matrix documents instead of discovering them during rollout. The cost is operational: you run it, you own the model routing, and you own the upgrades.&lt;/p&gt;

&lt;p&gt;If the part you care about is review policy your team writes in plain language, plus delivery metrics and a dashboard, Kodus covers the same forges with a self-hosting floor you can size from the README, and the trade-off moves from licensing to the Community limits on rules and plugins. A team that wants more than 10 rules is looking at a per-developer fee rather than a fork.&lt;/p&gt;

&lt;p&gt;If the constraint is that nothing leaves the network, the open source pair is the practical field for Bitbucket Data Center and GitLab Self-Managed, and it is the only field for Azure DevOps Server. Commercial self-hosting starts with an Enterprise contract and a seat threshold, and Qodo's own table does not list Azure DevOps on-premises. That is a narrow field, but it is a real one, and the difference between the two options comes down to whether you want to operate a CLI-and-webhook tool you can modify or a self-hosted service with a rule layer and a UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Are there open source AI code review tools that work on GitLab Self-Managed and Azure Repos?
&lt;/h3&gt;

&lt;p&gt;Yes. PR-Agent (MIT) and Kodus (AGPL-3.0 core) both review pull requests on GitLab, Bitbucket, and Azure DevOps, and both can be self-hosted. PR-Agent documents which features differ per provider in its supported platforms matrix; Kodus publishes its Community limits and self-hosting requirements in its docs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Kodus fully open source?
&lt;/h3&gt;

&lt;p&gt;The license is split by file. Files containing .ee. in the name and everything under an ee/ directory fall under the Kodus Enterprise Code License; the rest of the source is AGPL-3.0. Community users may run the unmodified enterprise code for internal use, including production, within the limits the software enforces, but may not modify it or use Enterprise-only features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can CodeRabbit be self-hosted without an Enterprise contract?
&lt;/h3&gt;

&lt;p&gt;No. CodeRabbit's self-hosted deployment is documented as an Enterprise plan feature, and the docs state it is available to customers with 500 or more user seats.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is there an on-premises Qodo deployment for Azure DevOps?
&lt;/h3&gt;

&lt;p&gt;Qodo's deployment model table lists on-premises and air-gapped support for GitHub Enterprise, GitLab Self-Managed, Bitbucket Data Center, and Gerrit. Bitbucket Cloud and Azure DevOps Cloud are listed as multi-tenant and single-tenant only, and the table has no on-premises entry for Azure DevOps.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Cutting pull request review time with AI: GitLab, Azure Repos, Bitbucket</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Wed, 28 Oct 2026 11:15:01 +0000</pubDate>
      <link>https://dev.to/emilreiter/cutting-pull-request-review-time-with-ai-gitlab-azure-repos-bitbucket-5b0b</link>
      <guid>https://dev.to/emilreiter/cutting-pull-request-review-time-with-ai-gitlab-azure-repos-bitbucket-5b0b</guid>
      <description>&lt;p&gt;Reducing review time with an AI reviewer is mostly not about the model. It is about six configuration decisions, and each of the three forges on this beat implements them differently. On GitLab both code review features run on GitLab.com, Self-Managed and Dedicated, but they are gated by different add-ons. On Azure Repos Copilot code review runs on Services only, in limited preview, and requires Azure Pipelines. Bitbucket Data Center has no native AI reviewer at all, so review time is set by merge checks and whatever bot you wire in through the REST API.&lt;/p&gt;

&lt;p&gt;The levers are the same everywhere. When the review starts, which files it reads, whether it runs on a draft, whether a finding actually blocks the merge, whether a new push triggers a new review, and how much effort each review is allowed to spend. Below is what each forge documents for those six, and where the defaults work against you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The six levers that set review latency
&lt;/h2&gt;

&lt;p&gt;An AI reviewer adds a step to a workflow that already has a human bottleneck, so the useful question is whether it removes more waiting than it adds. That depends on these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trigger&lt;/strong&gt;: on every push, on PR creation, or only when someone asks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope&lt;/strong&gt;: which files get reviewed and which are skipped, including how large diffs are handled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Draft behavior&lt;/strong&gt;: whether a review runs, or a gate silently disappears, before the PR is marked ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocking&lt;/strong&gt;: whether a finding stops the merge or is only a comment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-review&lt;/strong&gt;: whether new commits get a fresh review and whether the bot remembers what it already said.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effort and cost&lt;/strong&gt;: how much the reviewer is allowed to think, and who pays for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those six are also where most "we turned on AI review and nothing got faster" reports come from. A review that runs but does not block anything is a comment feed. A gate that disappears on drafts is not a gate. A reviewer with no scoping reviews lock files and generated code forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitLab: two review features, two add-on paths
&lt;/h2&gt;

&lt;p&gt;GitLab runs one of two code review features depending on your add-on and group settings. The non-agentic one is &lt;a href="https://docs.gitlab.com/user/gitlab_duo/code_review/" rel="noopener noreferrer"&gt;GitLab Duo Code Review&lt;/a&gt;, which requires the GitLab Duo Enterprise add-on and is Premium/Ultimate. The agentic one is &lt;a href="https://docs.gitlab.com/user/duo_agent_platform/flows/foundational_flows/code_review/" rel="noopener noreferrer"&gt;Code Review Flow&lt;/a&gt;, part of the GitLab Duo Agent Platform, available on Free, Premium and Ultimate and paid for with GitLab Credits.&lt;/p&gt;

&lt;p&gt;Which one runs is decided by the seat of the user who initiates the review. If that user holds a Duo Enterprise seat, GitLab runs the non-agentic feature by default, because it does not consume GitLab Credits. A group Owner can override that and route all reviews through Code Review Flow. Both features can run in the same project, which is worth knowing before you assume everyone on the team gets the same reviewer.&lt;/p&gt;

&lt;p&gt;The self-managed detail that decides whether any of this is usable: Code Review Flow runs as a CI/CD job and needs a runner with the &lt;code&gt;gitlab--duo&lt;/code&gt; tag and an executor that supports Docker images, or GitLab hosted runners enabled for the project. On an air-gapped instance with no such runner, the flow has nowhere to execute. The non-agentic feature does not have that requirement, but it does depend on the AI Gateway request timeout, and reviews that do not finish in that window surface as a generic error.&lt;/p&gt;

&lt;p&gt;For triggering, automatic reviews are a project setting since 18.0. Group and instance level automatic reviews arrived in 18.4 behind the &lt;code&gt;cascading_auto_duo_code_review_settings&lt;/code&gt; flag, which was removed in 18.7. GitLab skips draft merge requests, merge requests with no changes, and anything matching your exclusion rules. Code Review Flow also has a &lt;strong&gt;Start a new review on push&lt;/strong&gt; option, and its follow-up reviews use earlier Duo threads and replies to judge the new changes.&lt;/p&gt;

&lt;p&gt;The blocking lever on GitLab is the weakest of the three. A user's request for changes blocks a merge on Premium and Ultimate, and a bot can bypass it. GitLab Duo approving or requesting changes is beta in 19.5 behind &lt;code&gt;duo_code_review_decisions&lt;/code&gt;, disabled by default, and a Duo approval does not count toward required approvals. If you want an AI reviewer to hold a merge, the reliable path is a required external status check with &lt;strong&gt;Status checks must succeed&lt;/strong&gt; turned on, which is a separate setting from the check itself.&lt;/p&gt;

&lt;p&gt;For teams on self-managed GitLab with their own rules, that combination is the one worth testing: a required status check for the gate, plus review instructions scoped to the project so the reviewer follows your standards instead of generic advice. I wrote about the add-on paths and rule scoping separately in &lt;a href="https://mergerequests.dev/blog/gitlab-self-managed-ai-review-that-follows-your-own-rules/" rel="noopener noreferrer"&gt;AI review on self-managed GitLab that follows your own rules&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On large merge requests, GitLab Duo Code Review sends the diffs plus the original contents of changed files, and if that request fails it retries without the file contents. The retry shrinks the prompt and also shrinks the context, so comments can be less specific. If the retry fails too, you get a generic error message. Splitting large merge requests and excluding irrelevant files is the documented mitigation. I covered the general problem in &lt;a href="https://mergerequests.dev/blog/what-gitlab-azure-devops-and-bitbucket-hide-in-large-prs/" rel="noopener noreferrer"&gt;what GitLab, Azure DevOps and Bitbucket hide in large PRs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure Repos: Copilot code review is Services-only and preview-gated
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews" rel="noopener noreferrer"&gt;GitHub Copilot code review for Azure Repos&lt;/a&gt; is in limited preview and applies to Azure DevOps Services. A Project Collection Administrator enables it for the organization, a Project Administrator manages project defaults, and a repository owner turns it on per repository. Individual users also opt in through Preview features unless an administrator enables it for everyone.&lt;/p&gt;

&lt;p&gt;Two constraints change the plan more than anything else in that page. Copilot code review requires Azure Pipelines, and self-hosted agent pools and Managed DevOps Pools are not supported. For a team whose pipelines run entirely on self-hosted agents, the feature is not a smaller version of itself, it is unavailable. The second is that automatic review is not part of enablement. It is a separate branch policy, &lt;strong&gt;Automatically request Copilot code review&lt;/strong&gt;, that you set per target branch. Enabling the feature makes it available; the policy is what makes it run without a manual request.&lt;/p&gt;

&lt;p&gt;Effort is a per-project default that repository admins can override when the project allows it, and higher effort consumes more tokens and costs more. That is a reasonable place to start a review-time experiment: leave the default low on most repositories, raise it where the diffs are riskier, and compare against what the pipeline costs you in wall-clock time.&lt;/p&gt;

&lt;p&gt;The draft-PR behavior on Azure Repos deserves its own look because it affects every gate, not just the AI one. A draft pull request suppresses build validation policies so they do not run automatically, disables voting, and does not auto-add required reviewers. Publishing the PR assigns reviewers and evaluates policies. Marking a published PR as a draft removes all existing votes. So a PR that sits in draft while someone iterates looks unblocked, and any gate you wired to build validation or a required reviewer is simply absent until the PR is published.&lt;/p&gt;

&lt;p&gt;Once a PR is published, Azure Repos gives you a policy model with a real blocking lever: a status check policy that a bot can post to, plus the minimum reviewer and build validation policies. If you are wiring an AI reviewer into that model, &lt;a href="https://mergerequests.dev/blog/azure-repos-merge-gating-for-ai-reviewers-the-status-check-policy/" rel="noopener noreferrer"&gt;the status check policy is the piece that actually gates the merge&lt;/a&gt;, and the build expiration setting (Immediately, After n hours, or Never) decides how stale a passing build is allowed to get before it stops counting.&lt;/p&gt;

&lt;p&gt;For Azure DevOps Server, none of the above applies. Copilot code review is a Services feature, so a Server team looking to cut review time is choosing between third-party tools and their own pipeline job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bitbucket Data Center: the gate and the finding are the same object
&lt;/h2&gt;

&lt;p&gt;Bitbucket Data Center has no native AI reviewer, so the review-time question becomes which merge checks you enforce and what you post into Code Insights. &lt;a href="https://confluence.atlassian.com/bitbucketserver096/checks-for-merging-pull-requests-1627097061.html" rel="noopener noreferrer"&gt;Merge checks&lt;/a&gt; are set at Project settings &amp;gt; Merge checks and inherited by repositories, with repository admins able to override unless a project admin has restricted repository-level customization (available from Bitbucket 8.10, and restricting it deletes any saved repository-level settings for that check). Minimum approvals and default reviewers are separate checks and both must be met.&lt;/p&gt;

&lt;p&gt;The Code Insights merge check is where an AI reviewer gets to block a merge, and its scope is narrow in a way that matters. Annotations only block merging if they are on the diff. An annotation placed on a changed file outside the changed lines, or on a file that did not change, will not block anything. So the same finding can gate the merge or be invisible to the gate depending on where the line anchor lands. This is the opposite of Azure Repos and GitLab, where the finding surface and the gate are two different objects that you connect.&lt;/p&gt;

&lt;p&gt;The other Code Insights constraints are operational. Annotations display only on lines changed in the unified diff, so they are absent in side-by-side, commit, and iterative diff views. A rerun must delete the previous annotations first, because there is no de-duplication, and posting more than 1,000 annotations rejects the whole request. A reviewer that re-posts the same findings on every push will eventually hit one of those limits rather than a merge check.&lt;/p&gt;

&lt;p&gt;Bitbucket Data Center is also the one forge of the three that lets you ask for the delta. Its changes resource accepts &lt;code&gt;changeScope=UNREVIEWED&lt;/code&gt;, which uses a per-user last reviewed commit, so a reviewer can fetch only what changed since that user last looked. Azure Repos tracks something similar through &lt;code&gt;changeTrackingId&lt;/code&gt; and &lt;code&gt;firstComparingIteration&lt;/code&gt;, and GitLab does not have a cross-version diff API, so the delta there comes from the repository compare endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  What third-party reviewers document for these forges
&lt;/h2&gt;

&lt;p&gt;If you want a native reviewer on Bitbucket Data Center, or a self-hosted one on Azure DevOps Server, the options are third-party tools, and their docs are the only honest source for what they support.&lt;/p&gt;

&lt;p&gt;CodeRabbit documents &lt;a href="https://docs.coderabbit.ai/self-hosted/overview" rel="noopener noreferrer"&gt;self-hosted deployment&lt;/a&gt; as Enterprise-only, for customers with 500 or more user seats, running the review agent as a container inside your infrastructure with a bring-your-own-model setup. The supported platforms listed are GitHub Enterprise Server, GitLab self-managed, Azure DevOps and Bitbucket Data Center. Deployment and configuration instructions are provided during onboarding rather than published. For scope, it uses &lt;a href="https://docs.coderabbit.ai/guides/review-instructions" rel="noopener noreferrer"&gt;path filters and path instructions&lt;/a&gt;, where exclusions win over includes regardless of order, and there is an Azure DevOps-specific caveat: repository inventory and diff hydration apply the default ignored paths directly rather than through your configured filters, so an override does not take effect on those two paths.&lt;/p&gt;

&lt;p&gt;Qodo documents an &lt;a href="https://docs.qodo.ai/on-prem" rel="noopener noreferrer"&gt;on-premises deployment&lt;/a&gt; on Kubernetes, with integrations for GitLab Server, Bitbucket Data Center, Azure DevOps and Gerrit. Cloud-hosted Git instances use a separate install path.&lt;/p&gt;

&lt;p&gt;Kodus is open source and &lt;a href="https://github.com/kodustech/kodus-ai" rel="noopener noreferrer"&gt;self-hostable&lt;/a&gt; with your own model keys, running on Docker on a VM you control (2 CPU cores, 8 GB RAM, 60 GB disk minimum) or as a hosted service. It reviews pull requests on GitLab, Bitbucket, Azure DevOps and GitHub, including self-managed GitLab, and its Kody Rules are written in plain language and scoped to an organization, repository, path or review scope, which is the lever that maps to the scope row in the table below. The CLI can review a working tree, staged diff, branch or commit, so a pre-push review does not need a pull request to exist. The trade-off sits in the plan split: the Community tier caps Kody Rules at 10 and active plugins at 3, so teams that want many scoped rule sets or integrations are choosing between paying and trimming the ruleset.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;GitLab&lt;/th&gt;
&lt;th&gt;Azure Repos&lt;/th&gt;
&lt;th&gt;Bitbucket Data Center&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Native AI reviewer&lt;/td&gt;
&lt;td&gt;Duo Code Review (Duo Enterprise add-on) or Code Review Flow (GitLab Credits)&lt;/td&gt;
&lt;td&gt;Copilot code review, limited preview&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edition scope&lt;/td&gt;
&lt;td&gt;GitLab.com, Self-Managed, Dedicated&lt;/td&gt;
&lt;td&gt;Services only&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic review&lt;/td&gt;
&lt;td&gt;Project setting since 18.0; group/instance 18.4+&lt;/td&gt;
&lt;td&gt;Separate branch policy per target branch&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted execution&lt;/td&gt;
&lt;td&gt;Code Review Flow needs a runner with the &lt;code&gt;gitlab--duo&lt;/code&gt; tag&lt;/td&gt;
&lt;td&gt;Requires Azure Pipelines; self-hosted agent pools not supported&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Draft PR behavior&lt;/td&gt;
&lt;td&gt;Skipped by automatic reviews&lt;/td&gt;
&lt;td&gt;Suppresses build validation, disables voting, no auto reviewers&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blocking a merge&lt;/td&gt;
&lt;td&gt;Request changes (Premium/Ultimate, bypassable); Duo decisions beta in 19.5&lt;/td&gt;
&lt;td&gt;Status check policy, build validation, minimum reviewers&lt;/td&gt;
&lt;td&gt;Merge checks; Code Insights blocks only on-diff annotations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Re-review on push&lt;/td&gt;
&lt;td&gt;"Start a new review on push"; follow-up reviews reuse earlier threads&lt;/td&gt;
&lt;td&gt;New policy evaluation per push&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;changeScope=UNREVIEWED&lt;/code&gt; via last reviewed commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Effort or cost control&lt;/td&gt;
&lt;td&gt;Model selection per feature; GitLab Credits&lt;/td&gt;
&lt;td&gt;Default effort level per project/repo&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What this means when you are picking levers
&lt;/h2&gt;

&lt;p&gt;Two of these three forges let you build a real gate for an AI reviewer, and one makes it awkward. On Azure Repos the status check policy is a first-class blocking object and the draft-PR behavior is the thing most likely to surprise you, because a gate you configured can be absent without any error. On GitLab the gate exists but the AI reviewer's own approval does not count toward required approvals, so the check that holds the merge is the status check, not the bot's verdict. On Bitbucket Data Center the finding and the gate are the same object, which is simpler to reason about and much more sensitive to where a line anchor lands.&lt;/p&gt;

&lt;p&gt;If you are on Bitbucket Data Center or Azure DevOps Server, no native option is on the table, and the honest comparison is between CodeRabbit's Enterprise-only self-hosted path, Qodo's Kubernetes deployment, and Kodus's open-source self-hosting with your own keys. Those are different shapes of commitment: a seat threshold, a Kubernetes platform, or a VM and a ruleset budget. Which one fits depends less on review quality than on what your team already runs and how much of the configuration you are willing to own.&lt;/p&gt;

&lt;p&gt;For the effort lever, the default should be the cheap end. Raise review effort on the repositories where diffs are riskier, and measure the change in review latency and cost rather than assuming a heavier review is a better one. A reviewer that runs on every push at the highest effort level and posts findings nobody can merge-block with is just a slower comment feed.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Azure Repos merge gating for AI reviewers: the status check policy</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Wed, 21 Oct 2026 00:30:05 +0000</pubDate>
      <link>https://dev.to/emilreiter/azure-repos-merge-gating-for-ai-reviewers-the-status-check-policy-1adj</link>
      <guid>https://dev.to/emilreiter/azure-repos-merge-gating-for-ai-reviewers-the-status-check-policy-1adj</guid>
      <description>&lt;p&gt;On Azure Repos, an AI reviewer can only stop a merge if a branch policy requires a status check whose genre and name match a status that reviewer posts. Review comments and votes leave the Complete button where it was. The mechanism is the PR Status API plus a required status check policy, and it lives on the branch rather than in the reviewer's own settings. That distinction decides whether a tool is a merge gate or an advisory commenter on your pull requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually blocks completion in Azure Repos
&lt;/h2&gt;

&lt;p&gt;Azure Repos gates merges through branch policies, and for an external service the relevant one is the status check policy. The &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/available-pr-status-checks" rel="noopener noreferrer"&gt;reference of available status checks&lt;/a&gt; spells out how a posted status maps to merge behavior:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;With a required policy&lt;/th&gt;
&lt;th&gt;With an optional policy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;succeeded&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unblocks the policy&lt;/td&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;failed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocks merge&lt;/td&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;error&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocks merge&lt;/td&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pending&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocks merge, awaiting result&lt;/td&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;notApplicable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bypasses the policy requirement&lt;/td&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;notSet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Treated as pending&lt;/td&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two entries matter when you wire up a reviewer. &lt;code&gt;notApplicable&lt;/code&gt; is the documented way to exempt a specific pull request from a required policy without editing the policy, which is useful when a check genuinely doesn't apply to a change such as a docs-only edit. &lt;code&gt;notSet&lt;/code&gt; behaving as pending means a service that creates the policy but never posts a status leaves the pull request permanently blocked. That's the failure mode to watch for during a first rollout, and it's a quiet one because nothing errors.&lt;/p&gt;

&lt;p&gt;The same page lists what Azure DevOps posts on its own: &lt;code&gt;AdvancedSecurity/AllHighAndCritical&lt;/code&gt; and &lt;code&gt;AdvancedSecurity/NewHighAndCritical&lt;/code&gt; from GitHub Advanced Security, plus &lt;code&gt;{pipeline-name}/codecoverage&lt;/code&gt; from Azure Pipelines. Both Advanced Security checks need Advanced Security enabled on the repository and a build validation policy with the scanning tasks configured to wait for processing, otherwise the statuses don't reflect the latest scan. Everything else arrives through the &lt;a href="https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-statuses" rel="noopener noreferrer"&gt;PR Status API&lt;/a&gt;, and the calling identity needs Contribute to pull requests on the repository before it can post anything.&lt;/p&gt;

&lt;p&gt;Edition scope is worth pinning down here. The branch policies page covers Azure DevOps Services and Azure DevOps Server, so the policy mechanism is available on both. The reference of native first-party status checks is headed Azure DevOps Services, which is the list Microsoft maintains. A Server team configures status check policies the same way; the checks that exist out of the box are the Services-side ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the status check policy for a third-party reviewer
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/pr-status-policy" rel="noopener noreferrer"&gt;how-to for an external service&lt;/a&gt; walks through adding the policy under Branch policies, then Status checks. The fields are where the behavior gets decided.&lt;/p&gt;

&lt;p&gt;Policy requirement sets optional or required, and only required blocks completion. An optional policy still shows the status on the pull request, which is a reasonable way to run a reviewer in observe mode before it can hold up merges.&lt;/p&gt;

&lt;p&gt;Authorized identity restricts which identity's status counts toward the policy. Leaving it open means any account that can post a status to the repository can satisfy the check, which is a real gap in a large organization where integrations accumulate. Pinning it to the reviewer's service account or service principal is the tighter setup, and it turns credential rotation into a merge-gating concern rather than just an integration concern. The &lt;a href="https://mergerequests.dev/blog/ai-code-review-credentials-by-forge-what-expires-in-2026/" rel="noopener noreferrer"&gt;expiry paths for these integrations&lt;/a&gt; are worth checking against whatever you configure here.&lt;/p&gt;

&lt;p&gt;Reset conditions decide whether a posted status stays valid when the source branch changes. For a check tied to a specific commit, the documented guidance is to reset the status whenever there are new changes. Skip that and a reviewer's approval of an earlier revision keeps the gate open for code it never read.&lt;/p&gt;

&lt;p&gt;Policy applicability has two settings. Apply by default enforces the policy from pull request creation, and the PR can be exempted by posting &lt;code&gt;notApplicable&lt;/code&gt;. Conditional means the policy doesn't apply until the first status is posted, which supports an orchestration pattern where one policy evaluates which others should apply and then posts statuses to activate them.&lt;/p&gt;

&lt;p&gt;There's a practical detail that trips people up on the first setup. The status dropdown only lists genre and name values for services that have already posted at least one status to a pull request. A new integration that hasn't run yet won't appear in the list, so you type &lt;code&gt;genre/name&lt;/code&gt; directly into the field. Until the service posts, the policy shows as not set on the pull request, and per the table above that reads as pending.&lt;/p&gt;

&lt;h2&gt;
  
  
  Iteration status and when a re-review is required
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/pull-request-status" rel="noopener noreferrer"&gt;pull request extensibility page&lt;/a&gt; covers the difference between posting a status against a pull request as a whole and posting it against a specific iteration. Iteration status is what makes a check revision-specific: it lets the policy require that the latest iteration has a status of &lt;code&gt;succeeded&lt;/code&gt;, so a push invalidates the previous approval. That only works when reset conditions are set to reset on new changes, which the docs call out directly.&lt;/p&gt;

&lt;p&gt;There's a documented ceiling attached to it. A pull request with more than 100,000 modified files doesn't support iterations, so further commits land without creating a new iteration, and posting a status against a non-existent iteration returns an error. For a review integration that means the gate falls back to pull request level on very large changes. That's an edge case until an agent opens a branch-wide refactor, and then it isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Copilot branch policy that requests a review and nothing more
&lt;/h2&gt;

&lt;p&gt;Azure Repos has a Copilot code review feature, and its branch policy is easy to misread. The &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews" rel="noopener noreferrer"&gt;get started page&lt;/a&gt; states that feature enablement and automatic review are separate settings, and the "Automatically request Copilot code review" policy does what its name says: it adds Copilot as a reviewer on pull requests targeting the configured branch. Microsoft documents no route for Copilot to post a status check on Azure Repos, and none of the native checks in the status check reference belong to the feature. So this policy changes who reviews the pull request, and the merge gate stays where it was.&lt;/p&gt;

&lt;p&gt;Enablement runs across three scopes, which is worth planning for. A Project Collection Administrator turns the feature on for the organization, a Project Administrator can scope it per project, and a repository owner enables it per repository when project settings allow overrides. Effort level is set at the project level with an option to let repositories override, and higher effort consumes more tokens. Billing runs through an Azure subscription linked to the organization and Azure Cost Management, which is a different procurement path from a per-seat plan.&lt;/p&gt;

&lt;p&gt;The preview note attached to the feature states limited preview, no SLA, and that functionality may change or be removed. The documentation is scoped to Azure DevOps Services. Teams on &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-azure-devops-services-vs-server-per-tool/" rel="noopener noreferrer"&gt;Azure DevOps Server&lt;/a&gt; get none of it and need a self-hosted reviewer instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each AI reviewer's docs establish about gating
&lt;/h2&gt;

&lt;p&gt;I read what the vendors document for Azure Repos rather than assuming a general claim about blocking carries over to this forge.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Azure Repos route&lt;/th&gt;
&lt;th&gt;Documented blocking mechanism&lt;/th&gt;
&lt;th&gt;What it means for the gate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;PAT or Microsoft Entra service principal, plus a Service Hooks webhook&lt;/td&gt;
&lt;td&gt;Pre-Merge Checks run in off, warning or error mode; error blocks only when paired with the Request Changes workflow. Its Azure DevOps permission table lists posting statuses among the capabilities it needs.&lt;/td&gt;
&lt;td&gt;Blocking is configured inside CodeRabbit, and a status route is present in the documented permissions. Pairing it with a required status check policy is what makes the block affect Azure Repos completion.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;Portal connection to Azure DevOps; the deployment matrix marks on-prem unsupported and air-gapped N/A for Azure DevOps Cloud&lt;/td&gt;
&lt;td&gt;The severity threshold filters which findings appear as inline comments, and a below-threshold finding still appears in the summary&lt;/td&gt;
&lt;td&gt;Findings are advisory on Azure Repos. Self-hosted Azure Repos is not a documented deployment option, so the gate has to come from whatever posts a status.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kodus&lt;/td&gt;
&lt;td&gt;Azure Repos webhook through Service Hooks, with a signed token and one subscription per event type&lt;/td&gt;
&lt;td&gt;Suggestions post non-blocking by default; Request Changes is optional, and the compliance cookbook says to enable it so violations block merge. Status shows as a comment on Azure DevOps because there is no reaction API.&lt;/td&gt;
&lt;td&gt;Request Changes is a review state. Whether it gates completion depends on the branch policies on the target branch, so the status check policy is still the lever.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copilot code review&lt;/td&gt;
&lt;td&gt;Native, Services only, limited preview&lt;/td&gt;
&lt;td&gt;None documented; the branch policy requests a review&lt;/td&gt;
&lt;td&gt;Advisory. The gate remains a status check policy or the minimum reviewers policy.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two rows deserve a second look.&lt;/p&gt;

&lt;p&gt;Kodus's Azure Repos webhook is the one that requires an encrypted &lt;code&gt;token&lt;/code&gt; query parameter, produced by encrypting &lt;code&gt;CODE_MANAGEMENT_WEBHOOK_TOKEN&lt;/code&gt; with &lt;code&gt;CODE_MANAGEMENT_SECRET&lt;/code&gt; using AES-256-CBC, and Kodus returns 403 Unauthorized when it's missing. Each event type needs its own service hook subscription, so pull request created, updated, merge attempted and comment events mean four subscriptions. Create only the first one and updates and comments won't trigger a review, with nothing in the UI indicating the gap.&lt;/p&gt;

&lt;p&gt;Qodo's &lt;a href="https://docs.qodo.ai/install-qodo/deployment-model-support" rel="noopener noreferrer"&gt;deployment matrix&lt;/a&gt; is the most explicit vendor statement I've found on where each tool can run, and it marks Azure DevOps Cloud as on-prem unsupported with air-gapped N/A. The &lt;a href="https://docs.qodo.ai/on-prem/git-integration/install/azure-devops" rel="noopener noreferrer"&gt;on-prem Azure DevOps guide&lt;/a&gt; walks through Entra app registration and Service Hooks against &lt;code&gt;dev.azure.com&lt;/code&gt;, which are Azure DevOps Services constructs. Read together, Qodo on-premises targets Azure DevOps Services, and self-hosted Azure Repos isn't covered.&lt;/p&gt;

&lt;p&gt;CodeRabbit's &lt;a href="https://docs.coderabbit.ai/platforms/azure-devops" rel="noopener noreferrer"&gt;Azure DevOps page&lt;/a&gt; is detailed on setup, including the note that the Edit Subscriptions permission on Service Hooks cannot currently be granted through the UI and is granted per project, which is real work across a large organization. The &lt;a href="https://docs.coderabbit.ai/pr-reviews/pre-merge-checks" rel="noopener noreferrer"&gt;Pre-Merge Checks page&lt;/a&gt; is explicit that warning is the default enforcement mode and that error only blocks when paired with the Request Changes workflow, so a team that enables checks and assumes merges are gated has an open gate.&lt;/p&gt;

&lt;p&gt;If you want a self-hosted reviewer that posts statuses directly, &lt;a href="https://mergerequests.dev/blog/pr-agent-on-azure-devops-pipelines-branch-policies-webhooks/" rel="noopener noreferrer"&gt;PR-Agent wired into Azure Repos branch policies and Service Hooks&lt;/a&gt; is the configuration to study, because it runs in a pipeline you control and can call the PR Status API with a genre and name you choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check before you rely on a reviewer
&lt;/h2&gt;

&lt;p&gt;The gate is a branch policy, so the setup work happens in Azure Repos no matter which reviewer you pick. Before treating any AI reviewer as a merge gate, confirm that the service posts a status through the PR Status API, note the exact genre and name it uses, create a required status check policy with those values, and pin the authorized identity to the reviewer's service account. Then push a commit after a passing review and confirm the policy resets. A gate that stays green after a new commit is approving code nobody read.&lt;/p&gt;

&lt;p&gt;For teams that want the reviewer to stay advisory, the optional policy gives you the check on the pull request without blocking completion, and the status values still render in the Policies section. That's a sensible place to start, since it keeps the first rollout from freezing merges while you learn what the reviewer actually catches.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can an AI code reviewer block a merge in Azure Repos?
&lt;/h3&gt;

&lt;p&gt;Only if it posts a pull request status and a required status check branch policy matches that status's genre and name. Review comments and votes don't change whether a pull request can complete, because completion is governed by branch policies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the Automatically request Copilot code review policy block merges?
&lt;/h3&gt;

&lt;p&gt;No. That branch policy requests a Copilot review on pull requests targeting the configured branch. Microsoft documents no route for Copilot to post a status check on Azure Repos, and none of the native status checks in its reference belong to the feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens if a status check policy exists but the service never posts a status?
&lt;/h3&gt;

&lt;p&gt;The policy shows as not set on the pull request, and a notSet value is treated as pending, so a required policy blocks completion until the service posts a status.&lt;/p&gt;

</description>
      <category>azuredevops</category>
      <category>ai</category>
      <category>codereview</category>
      <category>devops</category>
    </item>
    <item>
      <title>What GitLab, Azure DevOps and Bitbucket hide in large PRs</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Mon, 19 Oct 2026 01:45:02 +0000</pubDate>
      <link>https://dev.to/emilreiter/what-gitlab-azure-devops-and-bitbucket-hide-in-large-prs-15o3</link>
      <guid>https://dev.to/emilreiter/what-gitlab-azure-devops-and-bitbucket-hide-in-large-prs-15o3</guid>
      <description>&lt;p&gt;A large pull request runs into two different limits, and they fail in different ways. The forge decides how much of the diff it will render, and past that point you get a partial view with a warning on screen. The reviewer decides how many files it will analyze, and past that point you get no review at all. Raise the first number and leave the second alone, and you still end up with a pull request that nobody, human or automated, actually looked at.&lt;/p&gt;

&lt;p&gt;That split matters more now that agent-authored changes arrive in bigger chunks. The two numbers also live in different places, are owned by different people, and get quoted as if they were one limit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The forge cap: how much of the diff renders
&lt;/h2&gt;

&lt;p&gt;GitLab is the only one of the three that publishes a full set of diff limits with both defaults and maximums, and it is the only one where the ceiling depends on the offering you are on. On &lt;a href="https://docs.gitlab.com/administration/diff_limits/" rel="noopener noreferrer"&gt;GitLab Self-Managed and GitLab Dedicated&lt;/a&gt;, the defaults are a 200 KB maximum diff patch size, 1,000 changed files, and 50,000 changed lines, raisable to 500 KB, 3,000 files, and 100,000 lines. When a diff reaches 10 percent of any of those three values, GitLab collapses the files behind an expand link. Past any of them, the diff is shown as Too large and cannot be expanded in the UI at all. The line that catches people out is that these limits apply to the UI and to the API endpoints that return diff information, so a bot reading the merge request through the API sees the same truncation a human does. On GitLab.com, the same page states that diff limits cannot be configured, which makes it the one GitLab offering where you have no lever.&lt;/p&gt;

&lt;p&gt;Bitbucket splits by edition, and the two editions behave nothing alike. &lt;a href="https://support.atlassian.com/bitbucket-cloud/docs/limits-for-viewing-content-and-diffs/" rel="noopener noreferrer"&gt;Bitbucket Cloud&lt;/a&gt; caps a single file's diff at 2,000 changed lines or 102,400 bytes of raw diff data, the entire diff at 8,000 changed lines, and the whole diff at 200 files. None of those are configurable; when you hit them the pull request stops rendering as one page and loads files individually instead. &lt;a href="https://support.atlassian.com/bitbucket-data-center/kb/the-diff-for-this-file-is-too-large-to-render/" rel="noopener noreferrer"&gt;Bitbucket Data Center&lt;/a&gt; works off &lt;code&gt;page.max.diff.lines&lt;/code&gt; (10,000 by default) and &lt;code&gt;page.max.changes&lt;/code&gt; (1,000 by default) in &lt;code&gt;bitbucket.properties&lt;/code&gt;. A Data Center admin can move those numbers, and a Cloud admin cannot.&lt;/p&gt;

&lt;p&gt;Azure Repos publishes its caps as notes inside the review flow rather than as a limits page. &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/review-pull-requests?view=azure-devops" rel="noopener noreferrer"&gt;Review and comment on pull requests&lt;/a&gt; states that the summary view does not show changes for a file larger than 0.5 MB, and that for a single file larger than 5 MB the diff view shows truncated content, with the docs pointing you at a local diff tool for the full thing. Those two pages carry the Services and Server monikers, so unlike Copilot code review, the rendering behavior is the same on both editions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Forge and edition&lt;/th&gt;
&lt;th&gt;Per-file cap&lt;/th&gt;
&lt;th&gt;Whole-diff cap&lt;/th&gt;
&lt;th&gt;Configurable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitLab Self-Managed / Dedicated&lt;/td&gt;
&lt;td&gt;part of a 200 KB patch size, 1,000 files, 50,000 lines set&lt;/td&gt;
&lt;td&gt;same set&lt;/td&gt;
&lt;td&gt;Yes, up to 500 KB, 3,000 files, 100,000 lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitLab.com&lt;/td&gt;
&lt;td&gt;same defaults, fixed&lt;/td&gt;
&lt;td&gt;same&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Cloud&lt;/td&gt;
&lt;td&gt;2,000 changed lines or 100 KB&lt;/td&gt;
&lt;td&gt;8,000 changed lines, 200 files&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Data Center&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;page.max.changes&lt;/code&gt; 1,000&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;page.max.diff.lines&lt;/code&gt; 10,000&lt;/td&gt;
&lt;td&gt;Yes, in &lt;code&gt;bitbucket.properties&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure Repos (Services and Server)&lt;/td&gt;
&lt;td&gt;summary view hides files over 0.5 MB; single file over 5 MB truncated in diff view&lt;/td&gt;
&lt;td&gt;not stated&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The second gate: the reviewer's own file cap
&lt;/h2&gt;

&lt;p&gt;The forge cap degrades a view. A reviewer's file cap does something harsher: it skips the pull request. That is a different failure mode, and it is the one that produces a merge request with zero automated comments and no obvious reason why.&lt;/p&gt;

&lt;p&gt;Kodus documents both numbers. The &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/flow" rel="noopener noreferrer"&gt;review flow page&lt;/a&gt; lists "PR exceeds the configured file limit" as a skip condition, and the &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/troubleshooting" rel="noopener noreferrer"&gt;troubleshooting page&lt;/a&gt; puts the working figure at 2,000 reviewable files after the ignored-file patterns are applied. A pull request with 2,500 files where 600 are lock files still gets reviewed, because the cap counts what is left after filtering. When it does skip, the status shows as skipped rather than a review, and on Azure DevOps and Bitbucket there is no reaction API, so that status arrives as a comment instead of a reaction. A team watching for a reaction on those two forges will see nothing.&lt;/p&gt;

&lt;p&gt;CodeRabbit does not publish a maximum diff size, so I am not going to invent one. What its &lt;a href="https://docs.coderabbit.ai/configuration/auto-review" rel="noopener noreferrer"&gt;automatic review controls&lt;/a&gt; document is volume management by commit and path rather than by size: &lt;code&gt;auto_pause_after_reviewed_commits&lt;/code&gt; defaults to 5 and pauses incremental reviews after that many reviewed commits, &lt;code&gt;drafts&lt;/code&gt; defaults to false so draft pull requests are skipped, &lt;code&gt;base_branches&lt;/code&gt; defaults to the default branch only, and &lt;code&gt;ignore_usernames&lt;/code&gt; skips whole authors. &lt;code&gt;path_filters&lt;/code&gt; is the lever for excluding lock files and generated code from a review. The practical consequence is that a 60-commit pull request can stop getting incremental reviews at commit five without anyone having configured anything, which reads as a broken integration unless you know the default is there.&lt;/p&gt;

&lt;p&gt;Qodo's constraint is about display rather than skipping. Its severity threshold applies to inline comments only, so a finding below the threshold still shows up in the summary, and the resolved-findings overflow section collapses on GitHub, GitLab and Azure DevOps but not on Bitbucket or Gerrit, where findings past the breakpoint do not display in the pull request. That is worth knowing before you conclude a reviewer found nothing on Bitbucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why raising the GitLab limit does not fix the skip
&lt;/h2&gt;

&lt;p&gt;The tempting move on self-managed GitLab is to raise the diff limits to their maximums and call the problem solved. That does address the truncation, including the API truncation, and it is genuinely the right call for a large monorepo. It does not touch the reviewer's own cap, which is a separate number in a separate product, and it does not help a team on GitLab.com where the value cannot be changed. If your chain includes a tool that skips at 2,000 files, a 3,000-file ceiling on the GitLab side just means GitLab will render a diff the reviewer will refuse to read.&lt;/p&gt;

&lt;p&gt;The same logic runs the other way. A team that tunes its reviewer's ignored-file patterns down to something aggressive will get reviews on pull requests whose diffs the forge still truncates. In that case the reviewer is commenting on a partial view, and a finding about a file that was never rendered is a finding about code it did not see.&lt;/p&gt;

&lt;p&gt;The judgment I would make from these numbers: for most teams the reviewer cap deserves attention before the forge cap does. Truncation is visible, the UI tells you a file was too large, and a human reviewer can still open the file locally. A skip is silent. It looks exactly like a reviewer that had nothing to say, and the pull request merges on that basis.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check before you tune anything
&lt;/h2&gt;

&lt;p&gt;Start by identifying the offering, because it decides whether you have a lever at all. GitLab Self-Managed and Bitbucket Data Center are tunable; GitLab.com and Bitbucket Cloud are not. Then write down the smallest cap anywhere in your chain, forge and reviewer, and treat that as your real limit rather than the largest one.&lt;/p&gt;

&lt;p&gt;If your pull requests are produced by coding agents, the file count grows faster than the line count, which is the axis these caps are usually set on. Filtering generated files and lock files out of review is the cheapest lever on both sides, since it reduces the number a reviewer counts. Where that is not enough, splitting by concern beats raising limits, because every number in the table above is enforced somewhere you may not control.&lt;/p&gt;

&lt;p&gt;Two related pieces go deeper on the self-managed side: &lt;a href="https://mergerequests.dev/blog/gitlab-self-managed-ai-review-that-follows-your-own-rules/" rel="noopener noreferrer"&gt;which AI review routes actually run on GitLab Self-Managed&lt;/a&gt; and &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-bitbucket-data-center-whats-native-what-isnt/" rel="noopener noreferrer"&gt;what is native on Bitbucket Data Center and what is not&lt;/a&gt;. For the Azure Repos edition split, &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-azure-devops-services-vs-server-per-tool/" rel="noopener noreferrer"&gt;Services versus Server per tool&lt;/a&gt; covers what changes when you are not on the hosted service.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does a forge's diff limit apply to the API as well as the UI?
&lt;/h3&gt;

&lt;p&gt;On GitLab it does. The documented diff limits apply to the UI and to the API endpoints that return diff information, so a review bot reading the merge request through the API sees the same truncation a human does. That is the detail that makes the limit a review problem rather than only a rendering problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I raise the diff limits on GitLab.com?
&lt;/h3&gt;

&lt;p&gt;No. GitLab documents diff limits as configurable on Self-Managed and Dedicated, and not configurable on GitLab.com.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Bitbucket Cloud's diff limit configurable?
&lt;/h3&gt;

&lt;p&gt;No. Cloud caps a single file at 2,000 changed lines or 102,400 bytes, the whole diff at 8,000 changed lines and 200 files, and none of those values can be changed. Bitbucket Data Center is the edition where an admin can raise the equivalent properties in &lt;code&gt;bitbucket.properties&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Free AI code review for GitLab, Azure DevOps and Bitbucket</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Wed, 14 Oct 2026 00:45:01 +0000</pubDate>
      <link>https://dev.to/emilreiter/free-ai-code-review-for-gitlab-azure-devops-and-bitbucket-5goe</link>
      <guid>https://dev.to/emilreiter/free-ai-code-review-for-gitlab-azure-devops-and-bitbucket-5goe</guid>
      <description>&lt;p&gt;Most free AI code review options assume the code lives on GitHub. On GitLab Self-Managed, Azure DevOps Server or Bitbucket Data Center, the realistic choices are an open-source reviewer you host yourself and pay only for the model calls, or a hosted tool's trial. The free-for-open-source programs that dominate "free code review tools" lists are gated on GitHub and on the repository being public there, which describes very few of the teams still running a self-managed forge.&lt;/p&gt;

&lt;h2&gt;
  
  
  What free means for a self-managed forge
&lt;/h2&gt;

&lt;p&gt;Self-hosted open source is the dependable category. You run the tool, it reads a git diff, and the only external dependency is a model endpoint you already control. That works behind a firewall because nothing outside has to reach into your forge.&lt;/p&gt;

&lt;p&gt;A hosted tool's free tier sits at the other end, and its shape moves. CodeRabbit's &lt;a href="https://www.coderabbit.ai/pricing" rel="noopener noreferrer"&gt;current pricing page&lt;/a&gt; lists Essentials at $24 per developer per month billed annually, Team at $48, Advanced at $72, and a custom Enterprise tier, with a 14-day trial on all of them. No free plan appears on that page, and self-hosting is listed as an Enterprise feature. A recommendation that starts with "it's free" ends, for a GitLab Self-Managed team, on a trial and then on a sales call.&lt;/p&gt;

&lt;p&gt;Forge-native features are the last corner. GitLab's &lt;a href="https://docs.gitlab.com/user/duo_agent_platform/flows/foundational_flows/code_review/" rel="noopener noreferrer"&gt;Code Review Flow page&lt;/a&gt; lists the tier as Free, Premium and Ultimate across GitLab.com, Self-Managed and Dedicated, and notes it can run with self-hosted models; what that costs depends on the Duo entitlement your instance carries, and the &lt;a href="https://mergerequests.dev/blog/gitlab-self-managed-ai-review-that-follows-your-own-rules/" rel="noopener noreferrer"&gt;edition split for AI review on self-managed GitLab&lt;/a&gt; is where the decision actually lands. Azure Repos has no comparable native reviewer on Server, because Copilot code review is documented for Services. Bitbucket's native AI review is Cloud-only, which the &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-bitbucket-data-center-whats-native-what-isnt/" rel="noopener noreferrer"&gt;Bitbucket Data Center breakdown&lt;/a&gt; covers end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-hosted routes that cover all three forges
&lt;/h2&gt;

&lt;p&gt;Three options are worth putting on the shortlist for a self-managed GitLab, an Azure DevOps Server behind a firewall, or a Bitbucket Data Center: PR-Agent, Alibaba's Open Code Review, and Kodus Community. They differ in how they attach to the forge, which matters more than the feature list when the forge is internal.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR-Agent after the Qodo donation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/The-PR-Agent/pr-agent" rel="noopener noreferrer"&gt;PR-Agent&lt;/a&gt; is a community-owned project that Qodo donated, and the repo now sits in the PR-Agent org under an MIT license. It is explicitly not Qodo's product for open-source projects, which lives elsewhere, and the README notes the project is in the process of being donated to an open-source foundation.&lt;/p&gt;

&lt;p&gt;The supported-platform matrix on &lt;a href="https://docs.pr-agent.ai/overview/supported_platforms/" rel="noopener noreferrer"&gt;the current PR-Agent docs&lt;/a&gt; lists Describe, Review, Improve, Ask, Add Docs and Help as supported on GitHub, GitLab, Bitbucket, Azure DevOps and Gitea, with CLI and app/webhook deployment available on all five. Gerrit and CodeCommit are registered providers kept out of that main table, and they do not support GitHub-flavored markdown, so &lt;code&gt;/describe&lt;/code&gt; drops the semantic file-type sections there.&lt;/p&gt;

&lt;p&gt;A few rows in that matrix are provider-specific, and they are the ones that decide whether the tool feels native on your forge. The tagging bot is GitHub-only. Several tools run but post their output as a comment instead of applying it where the provider cannot write files. &lt;code&gt;/help_docs&lt;/code&gt; has been disabled since v0.36.1 while a credential-exposure issue is fixed.&lt;/p&gt;

&lt;p&gt;Where a deployment lives is worth reading before you upgrade anything, because the Docker namespace moved. Releases from 0.34.2 are published under &lt;code&gt;pragent/pr-agent&lt;/code&gt;; anything up to and including v0.31 stays at the frozen &lt;code&gt;codiumai/pr-agent&lt;/code&gt; namespace with no new pushes. If a pipeline pins an old image reference, that is the first thing to fix.&lt;/p&gt;

&lt;p&gt;The newer part of PR-Agent is the instructions layer. &lt;a href="https://docs.pr-agent.ai/core-abilities/agent_skills/" rel="noopener noreferrer"&gt;Agent Skills&lt;/a&gt; let you keep a curated set of &lt;code&gt;SKILL.md&lt;/code&gt; files on the host and have their name, description and body injected into &lt;code&gt;/review&lt;/code&gt;, &lt;code&gt;/improve&lt;/code&gt;, &lt;code&gt;/describe&lt;/code&gt; and &lt;code&gt;/ask&lt;/code&gt;. Two constraints are worth knowing before you plan around it. Skills are disabled by default, and &lt;code&gt;skills.paths&lt;/code&gt; can only be set at host level, never from a repository's own &lt;code&gt;.pr_agent.toml&lt;/code&gt;, because a repo that could redirect the filesystem scan could point the tool at files like &lt;code&gt;~/.ssh/*&lt;/code&gt; and pull them into a model prompt. A repo can only opt in or size the token budget. The other constraint is architectural: PR-Agent makes single-shot model calls, so the standard's progressive-disclosure model does not apply, and every enabled skill's text goes into every pull request prompt up to the token cap. Files in &lt;code&gt;scripts/&lt;/code&gt; and &lt;code&gt;assets/&lt;/code&gt; are skipped, so a skill that depends on running a script will not work.&lt;/p&gt;

&lt;p&gt;Deployment detail per forge is where the interesting bits are, and I have separate notes on &lt;a href="https://mergerequests.dev/blog/pr-agent-on-self-managed-gitlab-pipeline-or-webhook/" rel="noopener noreferrer"&gt;running PR-Agent on self-managed GitLab&lt;/a&gt; and on &lt;a href="https://mergerequests.dev/blog/pr-agent-on-azure-devops-pipelines-branch-policies-webhooks/" rel="noopener noreferrer"&gt;PR-Agent on Azure DevOps&lt;/a&gt;, since Azure Repos needs Branch Policies rather than a YAML trigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Code Review
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/alibaba/open-code-review" rel="noopener noreferrer"&gt;Open Code Review&lt;/a&gt; is Alibaba's internal review assistant, released as an Apache-2.0 CLI. Because it operates on a git diff instead of on a forge API, it does not care where the repository is hosted, and it needs Git 2.41 or newer. Install is &lt;code&gt;npm install -g @alibaba-group/open-code-review&lt;/code&gt;, then &lt;code&gt;ocr config provider&lt;/code&gt; and &lt;code&gt;ocr config model&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The command set is broader than a single review pass. &lt;code&gt;ocr review&lt;/code&gt; covers staged, unstaged and untracked changes in the workspace, &lt;code&gt;ocr review --from main --to feature-branch&lt;/code&gt; covers a branch range, &lt;code&gt;ocr scan&lt;/code&gt; reviews whole files with no git history, and &lt;code&gt;ocr delegate&lt;/code&gt; lets a host coding agent perform the review itself, in which case no separate model key is needed.&lt;/p&gt;

&lt;p&gt;The project's headline claim is a precision argument, and the numbers are its own. Its benchmark is built from 50 popular repositories, 200 real pull requests, 10 languages and 1,505 annotated issues cross-validated by more than 80 senior engineers, and the README states that it beats a general-purpose agent on the same underlying model on precision and F1 while using roughly a ninth of the tokens. Recall is deliberately lower. Treat that as a design claim from the project rather than an independent result, and note that the trade-off it describes is real for review tooling: fewer comments that are more often correct reads better in a busy pull request than broad coverage with a long tail of noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kodus Community
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.kodus.io/en/how_to_use/pricing.md" rel="noopener noreferrer"&gt;Kodus&lt;/a&gt; publishes a free Community tier that runs self-hosted or on their cloud, with reviews unlimited on every plan because the model calls run on your own provider key. That combination is what makes it relevant here: free, self-hostable, and not gated on the repository being public on GitHub.&lt;/p&gt;

&lt;p&gt;Two limits shape whether it fits. Community allows up to 10 Kody Rules and 3 plugins, and a self-hosted instance running without a valid license evaluates at most 10 rules per review, oldest first, so an instance with a larger rule library will silently stop firing rules past that point. The &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/configs/rules_file_detection.md" rel="noopener noreferrer"&gt;rules file detection&lt;/a&gt; list is long for a tool at this stage: &lt;code&gt;AGENTS.md&lt;/code&gt; and its dotfile variants, &lt;code&gt;.cursorrules&lt;/code&gt; and &lt;code&gt;.cursor/rules/**/*.mdc&lt;/code&gt;, &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; and &lt;code&gt;.github/instructions/**/*.instructions.md&lt;/code&gt;, &lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;.windsurfrules&lt;/code&gt;, &lt;code&gt;.aider.conf.yml&lt;/code&gt;, &lt;code&gt;.sourcegraph/**/*.rule.md&lt;/code&gt;, plus a generic &lt;code&gt;docs/coding-standards/**&lt;/code&gt; pattern. Matching is case-insensitive, nested files are discovered and scoped to their directory, and &lt;code&gt;@file&lt;/code&gt; references inside a rule file are followed one level deep. Files that match the repository-rules template are imported verbatim without an LLM rewriting them, which is the difference between your standards surviving import and being paraphrased.&lt;/p&gt;

&lt;p&gt;Connecting it to a self-managed forge is where the free tier gets plainer. The quickstart documents OAuth (recommended) or token for GitHub and GitLab, and token only for Bitbucket and Azure DevOps, with no OAuth path for either. Internal GitLab, Bitbucket Data Center and Azure DevOps Server instances connect by allowlisting a fixed IP. On the licensing point, the repository is public and tagged open source, but GitHub's API reports the license as "Other" rather than an OSI identifier, so if an approved license matters to procurement, read the license file rather than the tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hosted free tiers, measured against self-managed editions
&lt;/h2&gt;

&lt;p&gt;CodeRabbit and Qodo are the two hosted tools most often recommended to teams asking this question, and neither free path is shaped for a self-managed forge. CodeRabbit's pricing page carries no free plan, only the 14-day trial, and separately lists per-developer hourly review limits that rise by tier, with usage-based reviews at $0.25 per reviewed file past the included allowance. Qodo's free offering for open-source projects is described on the PR-Agent README as a distinct product from the open-source agent, and it is aimed at public projects.&lt;/p&gt;

&lt;p&gt;For the on-prem side of both vendors, what they document differs by forge and edition, and the &lt;a href="https://mergerequests.dev/blog/self-hosted-ai-code-review-coderabbit-and-qodo-per-their-docs/" rel="noopener noreferrer"&gt;per-docs comparison of CodeRabbit and Qodo for self-hosted deployments&lt;/a&gt; is where that belongs. The short version for this page is that self-managed coverage is an enterprise arrangement in both cases, which is exactly why the free routes above exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free AI code review routes compared
&lt;/h2&gt;

&lt;p&gt;Self-hosted and free routes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;Cost model&lt;/th&gt;
&lt;th&gt;How it attaches to the forge&lt;/th&gt;
&lt;th&gt;Own model endpoint&lt;/th&gt;
&lt;th&gt;Limit that changes a rollout&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PR-Agent&lt;/td&gt;
&lt;td&gt;MIT, community-owned&lt;/td&gt;
&lt;td&gt;CLI, Docker, webhook/app; GitHub, GitLab, Bitbucket, Azure DevOps, Gitea&lt;/td&gt;
&lt;td&gt;Yes, via LiteLLM (Azure OpenAI, Bedrock, Ollama)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/help_docs&lt;/code&gt; disabled since v0.36.1; skills are text-only and loaded into every prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Code Review&lt;/td&gt;
&lt;td&gt;Apache-2.0&lt;/td&gt;
&lt;td&gt;CLI on a git diff, no forge integration&lt;/td&gt;
&lt;td&gt;Yes, or delegate to a host agent&lt;/td&gt;
&lt;td&gt;Requires Git 2.41; benchmark is the project's own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kodus Community&lt;/td&gt;
&lt;td&gt;Free tier, self-hosted or cloud&lt;/td&gt;
&lt;td&gt;PR bot; token-only connect for Bitbucket and Azure DevOps&lt;/td&gt;
&lt;td&gt;Yes, BYOK&lt;/td&gt;
&lt;td&gt;10 Kody Rules and 3 plugins; unlicensed self-hosted evaluates 10 rules per review&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Hosted tiers with a free entry point:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Free option as documented&lt;/th&gt;
&lt;th&gt;Self-managed editions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;14-day trial; no free plan listed on the pricing page&lt;/td&gt;
&lt;td&gt;Self-hosting listed as an Enterprise feature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;Free version for open-source projects&lt;/td&gt;
&lt;td&gt;Documented separately per forge and target; not stated on the pricing page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Picking one for a self-managed forge
&lt;/h2&gt;

&lt;p&gt;If the constraint is that no third party reaches into the forge, the decision is between two shapes of tool rather than three products. PR-Agent and Open Code Review both run as a CLI or webhook with a model endpoint you already have, and the difference is in the review model. PR-Agent reviews through the forge, which is why it has per-provider docs, comment commands and, on some providers, tools that can only post a comment rather than apply a change. Open Code Review reviews a diff, which is why it works anywhere and why it has no comment commands or PR descriptions at all. Choose PR-Agent if you want the reviewer to behave like a native bot in merge requests, and Open Code Review if you want a precision-biased pass over changes and whole files from a pipeline.&lt;/p&gt;

&lt;p&gt;Kodus Community is the option to look at when the reason you want a reviewer is your own written standards. Its rule import covers more of the instruction-file formats teams have already checked into repositories than the alternatives here, and per-directory scoping is built into detection, which matters in a monorepo. The trade-off is the ceiling on Community: 10 Kody Rules and 3 plugins, with the unlicensed self-hosted rule cap on top, so a team with a large standards library is choosing between paying for a licence and pruning rules.&lt;/p&gt;

&lt;p&gt;Whatever you pick, check the vendor or project page for your edition before you commit to it, because edition support and free-tier scope drift faster than the rest of the documentation. The Docker namespace change in PR-Agent and the absence of a free plan in CodeRabbit's current lineup are both recent examples of the same thing: a "free" answer that was true last year and is not true in your upgrade path.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
      <category>codereview</category>
    </item>
    <item>
      <title>AI code review credentials by forge: what expires in 2026</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Mon, 12 Oct 2026 01:45:01 +0000</pubDate>
      <link>https://dev.to/emilreiter/ai-code-review-credentials-by-forge-what-expires-in-2026-5bld</link>
      <guid>https://dev.to/emilreiter/ai-code-review-credentials-by-forge-what-expires-in-2026-5bld</guid>
      <description>&lt;p&gt;Originally published at &lt;a href="https://mergerequests.dev/blog/ai-code-review-credentials-by-forge-what-expires-in-2026/" rel="noopener noreferrer"&gt;mergerequests.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The credential your review bot authenticates with is the part of the setup that breaks first. Commenting on a merge request is the same job on GitLab, Azure DevOps and Bitbucket, but it is done by four different kinds of token, and two of those token types are being retired during 2026. Teams usually notice when the comments stop appearing while the pipeline stays green.&lt;/p&gt;

&lt;p&gt;The dates set the scope for this post. Global personal access tokens in Azure DevOps Services stop working on 1 December 2026, and &lt;a href="https://devblogs.microsoft.com/devops/retirement-of-global-personal-access-tokens-in-azure-devops/" rel="noopener noreferrer"&gt;Microsoft states that Azure DevOps Server is not affected&lt;/a&gt;. On Bitbucket Cloud, &lt;a href="https://support.atlassian.com/bitbucket-cloud/docs/revoke-an-app-password/" rel="noopener noreferrer"&gt;app passwords could no longer be created from 9 September 2025 and all remaining ones are disabled on 9 June 2026&lt;/a&gt;. GitLab splits project and group access tokens by offering, which decides whether the credential a bot needs exists at all on your instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the reviewer credential decides
&lt;/h2&gt;

&lt;p&gt;Four properties of a token shape how a review bot behaves, and none of them depend on the model behind it.&lt;/p&gt;

&lt;p&gt;The identity comes first. An OAuth app posts as a dedicated bot account, so the merge request shows something clearly not human. A personal token posts as whoever owns it, which puts a person's name on machine comments and removes the difference between a human review and a bot review from the audit trail. On a codebase with any compliance requirement, that usually settles the choice.&lt;/p&gt;

&lt;p&gt;Reach comes second. Scopes decide which repositories the token can read, and on Azure DevOps a personal access token cannot grant more permission than its owner has, so a bot running on a senior engineer's PAT carries that engineer's access to every project the token was scoped for.&lt;/p&gt;

&lt;p&gt;Write ability comes third, and this is where editions diverge. Approving, commenting, applying a suggestion and merging are separate permissions, and not every token type on every edition can do all of them.&lt;/p&gt;

&lt;p&gt;Lifetime comes last. GitLab invalidates a rotated token immediately, so rotation is a deploy rather than an edit. Azure DevOps deactivates PATs in Entra-backed organizations after 90 days without sign-in. Bitbucket Cloud tokens cannot be edited after creation, so a rotation means issuing a replacement and updating the integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitLab: access tokens are split by offering, and Self-Managed is the generous side
&lt;/h2&gt;

&lt;p&gt;This is the single most useful fact for a team on GitLab Self-Managed, and it runs the other way from what people assume about self-managed software. Per the &lt;a href="https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab/repository/files/doc%2Fuser%2Fproject%2Fsettings%2Fproject_access_tokens.md/raw?ref=master" rel="noopener noreferrer"&gt;project access token documentation&lt;/a&gt;, project access tokens require a Premium or Ultimate subscription on GitLab.com, where a trial is limited to one token. On GitLab Self-Managed and GitLab Dedicated they are available with any license, and the &lt;a href="https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab/repository/files/doc%2Fuser%2Fgroup%2Fsettings%2Fgroup_access_tokens.md/raw?ref=master" rel="noopener noreferrer"&gt;group access token documentation&lt;/a&gt; states the same for group tokens. A team on a free self-managed instance can hand a reviewer a project-scoped token with a defined role and scope, while a team on GitLab.com without a paid subscription cannot.&lt;/p&gt;

&lt;p&gt;Personal access tokens sit at Free, Premium and Ultimate on every offering, and the &lt;a href="https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab/repository/files/doc%2Fuser%2Fprofile%2Fpersonal_access_tokens.md/raw?ref=master" rel="noopener noreferrer"&gt;personal access token documentation&lt;/a&gt; gives the lifetime rules: 365 days by default, extendable to 400 days from GitLab 17.6 through a feature flag named &lt;code&gt;buffered_token_expiration_limit&lt;/code&gt;, with the instance administrator able to change the maximum. That default matters more than it looks, because a bot whose token was issued a year ago stops working on a date nobody wrote down.&lt;/p&gt;

&lt;p&gt;The cleaner identity is a &lt;a href="https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab/repository/files/doc%2Fuser%2Fprofile%2Fservice_accounts.md/raw?ref=master" rel="noopener noreferrer"&gt;service account&lt;/a&gt;. Service accounts do not use a seat, are always marked as external users, cannot sign in through the UI, and authenticate with a personal access token. Premium and Ultimate allow an unlimited number, while Free allows 100 per top-level group on GitLab.com and 100 for the entire instance on Self-Managed. A reviewer running as a service account survives staff changes; a reviewer running as a maintainer's PAT does not. The &lt;a href="https://mergerequests.dev/blog/gitlab-self-managed-ai-review-that-follows-your-own-rules/" rel="noopener noreferrer"&gt;self-managed GitLab setup that follows your own rules&lt;/a&gt; covers the configuration side of that, and the credential is the prerequisite for all of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure DevOps: PATs narrow to one organization, Server is untouched
&lt;/h2&gt;

&lt;p&gt;Microsoft's &lt;a href="https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops" rel="noopener noreferrer"&gt;personal access token page&lt;/a&gt; now opens with the retirement notice rather than the instructions: all existing global PATs stop working on 1 December 2026, and the guidance is to migrate to organization-scoped PATs or Microsoft Entra authentication. The same page tells you to avoid PATs where a better option exists and to prefer Entra tokens, managed identities or service principals for applications and automation, falling back to an organization-scoped PAT with the minimum scopes and shortest practical lifetime when a tool does not support Entra.&lt;/p&gt;

&lt;p&gt;For a reviewer bot that distinction is concrete. An organization-scoped PAT can only reach one organization, which is the intended outcome of the change, and a service principal or managed identity removes the human owner entirely. The global token was convenient because it reached every organization the user could see, and that is exactly the property being removed.&lt;/p&gt;

&lt;p&gt;PAT usage itself has not changed. Azure DevOps accepts one through an HTTP Basic header, base64-encoding the string &lt;code&gt;:{PAT}&lt;/code&gt; with the username left empty, and the token expires on the date set at creation, with a notification sent before it does. On an Entra-backed organization, signing in with a new PAT within 90 days is required or the token becomes inactive, which is a policy interaction worth knowing before a long-lived CI credential quietly goes dormant.&lt;/p&gt;

&lt;p&gt;Azure DevOps Server is a separate product line and the retirement notice does not apply to it. Server PATs are scoped to a collection rather than an organization, and Microsoft states that no changes are being made to global PATs there. A team on Server 2022 or 2020 that reads the announcement and starts a migration project is solving a problem it does not have. The &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-azure-devops-services-vs-server-per-tool/" rel="noopener noreferrer"&gt;edition differences between Azure DevOps Services and Server for code review tooling&lt;/a&gt; are wider than the credential, and the token change is one of the few places where Server comes out ahead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bitbucket Cloud: app passwords are gone, access tokens are per-resource
&lt;/h2&gt;

&lt;p&gt;Atlassian replaced app passwords with API tokens, and the &lt;a href="https://support.atlassian.com/bitbucket-cloud/docs/api-tokens/" rel="noopener noreferrer"&gt;API token page&lt;/a&gt; describes the shape: user-based, scoped at creation, optionally scoped to a single workspace, intended for a single purpose, and impossible to view or edit afterwards. Two limitations matter to a review bot. API tokens cannot be used to log in to bitbucket.org, and they cannot manage workspace actions.&lt;/p&gt;

&lt;p&gt;The other credential family on Cloud is access tokens, which are tied to a repository, project or workspace rather than a user. That fits a bot better because there is no human owner to lose access, with two catches. Workspace and project access tokens require the Premium plan, and each workspace, project and repository has a hard limit of 25 tokens that cannot be increased. A repository access token is available without Premium, which makes it the practical choice for a per-repository reviewer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bitbucket Data Center: the cleanest bot identity, with two catches
&lt;/h2&gt;

&lt;p&gt;Data Center keeps its own HTTP access tokens, and it has a credential advantage Cloud does not. Project and repository tokens require a Data Center license, and once you have one you can issue a token that belongs to a project rather than to a person, which is the cleanest bot identity on any of the three forges. Two documented limits follow from that. Project and repository tokens work with Bearer authentication only and must not be paired with a username in Basic authentication, which breaks the copy-paste example people reuse from Server PATs. And a token cannot merge a pull request, because a merge creates a commit and only users with a valid email address can do that. The token can perform pull request actions at repository write permission; the merge itself needs a user identity.&lt;/p&gt;

&lt;p&gt;Suggestion handling differs too, and it decides how much of a review a bot can finish on its own. GitLab merge request suggestion blocks are applied through the suggestions API and are available on Free tier. Bitbucket Data Center exposes an apply-suggestion endpoint, Bitbucket Cloud does not, and Azure Repos has no apply operation at all, so a bot there posts the replacement as comment text and a human applies it. On Bitbucket, &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-bitbucket-data-center-whats-native-what-isnt/" rel="noopener noreferrer"&gt;where the native AI review actually runs&lt;/a&gt; is a separate question from what the token is allowed to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credentials per forge and edition
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Forge and edition&lt;/th&gt;
&lt;th&gt;Practical bot credential&lt;/th&gt;
&lt;th&gt;What limits it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitLab.com&lt;/td&gt;
&lt;td&gt;Service account with a personal access token&lt;/td&gt;
&lt;td&gt;Project and group access tokens need Premium or Ultimate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitLab Self-Managed&lt;/td&gt;
&lt;td&gt;Project or group access token, or a service account&lt;/td&gt;
&lt;td&gt;100 service accounts for the instance on Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure DevOps Services&lt;/td&gt;
&lt;td&gt;Entra service principal or managed identity; organization-scoped PAT as fallback&lt;/td&gt;
&lt;td&gt;Global PATs stop working 1 December 2026; PATs go inactive after 90 days without sign-in in Entra-backed orgs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure DevOps Server&lt;/td&gt;
&lt;td&gt;Collection-scoped PAT&lt;/td&gt;
&lt;td&gt;Not affected by the global PAT retirement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Cloud&lt;/td&gt;
&lt;td&gt;Repository access token&lt;/td&gt;
&lt;td&gt;Workspace and project tokens need Premium; 25-token cap per resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Data Center&lt;/td&gt;
&lt;td&gt;Project or repository HTTP access token&lt;/td&gt;
&lt;td&gt;Requires a Data Center license; Bearer only; cannot merge a pull request&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What to check before the dates land
&lt;/h2&gt;

&lt;p&gt;The two retirements have different shapes. The Azure DevOps one is a hard stop on 1 December 2026 for global PATs, and the migration target already exists, so the work is finding every integration that still uses a global token. The Bitbucket one is already done: app passwords are disabled, and anything still holding one is broken now rather than later.&lt;/p&gt;

&lt;p&gt;On GitLab, the useful check is whether the bot is a service account or a person. A token owned by an engineer who leaves is a review process that stops without an error, and the offering you are on decides which token types you can issue in the first place.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
      <category>security</category>
    </item>
    <item>
      <title>PR-Agent on Azure DevOps: pipelines, Branch Policies, and webhooks</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Wed, 07 Oct 2026 00:15:01 +0000</pubDate>
      <link>https://dev.to/emilreiter/pr-agent-on-azure-devops-pipelines-branch-policies-and-webhooks-4ec2</link>
      <guid>https://dev.to/emilreiter/pr-agent-on-azure-devops-pipelines-branch-policies-and-webhooks-4ec2</guid>
      <description>&lt;p&gt;Azure Repos Git does not run a pipeline on a pull request because of a &lt;code&gt;pr:&lt;/code&gt; block in YAML. PR validation is implemented through branch policies, so a PR-Agent setup copied from the GitHub workflow does nothing until someone adds a Build Validation policy on the target branch. The &lt;a href="https://docs.pr-agent.ai/installation/azure" rel="noopener noreferrer"&gt;PR-Agent Azure DevOps page&lt;/a&gt; says this outright, and &lt;a href="https://raw.githubusercontent.com/MicrosoftDocs/azure-devops-docs/main/docs/pipelines/repos/azure-repos-git.md" rel="noopener noreferrer"&gt;Microsoft's pipeline documentation for Azure Repos Git&lt;/a&gt; states the same rule: to enable PR validation, configure the Build Validation policy for that branch.&lt;/p&gt;

&lt;p&gt;That difference decides the rest of the rollout, because the trigger and the identity the agent authenticates as both branch from it, and so does whether the bot can answer a comment at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Validation replaces the PR trigger
&lt;/h2&gt;

&lt;p&gt;The policy lives under Project Settings, Repositories, Branches. Select the target branch, open Branch Policies, and add the PR-Agent pipeline as a Build Validation policy marked Required. Then delete the &lt;code&gt;pr:&lt;/code&gt; section from &lt;code&gt;azure-pipelines.yml&lt;/code&gt;, since Azure Repos Git ignores it.&lt;/p&gt;

&lt;p&gt;Two conditions are easy to miss. You need to be a project administrator of the project that owns the repository to configure validation builds for an Azure Repos Git repo. And draft pull requests do not trigger a pipeline even when a branch policy is configured, so a team that opens PRs as drafts will not see a review until the PR is marked ready.&lt;/p&gt;

&lt;p&gt;There is a difference in what gets built, too. Validation pipelines run against the merge commit of the source and target branches. A push to the source branch carrying &lt;code&gt;[skip ci]&lt;/code&gt; in a commit message suppresses the pipelines triggered by that branch, while the Build Validation pipeline still runs on the merge commit. If you use &lt;code&gt;[skip ci]&lt;/code&gt; to control CI cost, it will not control this.&lt;/p&gt;

&lt;p&gt;The pipeline itself is short. It runs the prebuilt &lt;code&gt;pragent/pr-agent:latest&lt;/code&gt; image as a container with the entrypoint cleared, builds a PR URL out of the variables Azure Pipelines injects (&lt;code&gt;System.CollectionUri&lt;/code&gt;, &lt;code&gt;System.TeamProject&lt;/code&gt;, &lt;code&gt;Build.Repository.Name&lt;/code&gt;, &lt;code&gt;System.PullRequest.PullRequestId&lt;/code&gt;), sets &lt;code&gt;config__git_provider=azure&lt;/code&gt;, and calls the CLI three times for &lt;code&gt;describe&lt;/code&gt;, &lt;code&gt;review&lt;/code&gt; and &lt;code&gt;improve&lt;/code&gt;. The PAT and the model key come from a variable group, and the pipeline needs explicit permission to read that group or the job fails on an empty secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipeline mode cannot answer comments
&lt;/h2&gt;

&lt;p&gt;Azure Pipelines has no support for triggering a workflow from a pull request comment, and the PR-Agent docs say so plainly. A pure pipeline setup reviews every new pull request and cannot respond to &lt;code&gt;/review&lt;/code&gt; typed into a thread. That is the same shape as the &lt;a href="https://mergerequests.dev/blog/pr-agent-on-self-managed-gitlab-pipeline-or-webhook/" rel="noopener noreferrer"&gt;self-managed GitLab placement&lt;/a&gt;, where pipeline mode fires automatically and comment commands require the webhook server instead.&lt;/p&gt;

&lt;p&gt;On Azure Repos the webhook route is a manual service hook. You create it under Project Settings, Service hooks, with the trigger set to Pull request created for a review or Pull request commented on for a supported slash command, and API v2.0 is required for the comment event. The hook posts to your PR-Agent endpoint with a sporadic username and password pair you configure on both sides, sent as basic auth, which is why the endpoint has to be HTTPS.&lt;/p&gt;

&lt;p&gt;So the split matches the other forges: pipeline mode when you want describe, review and improve to fire automatically with no service to run, webhook when your team drives review from comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  PAT or DefaultAzureCredential
&lt;/h2&gt;

&lt;p&gt;The Azure DevOps provider takes either a personal access token or &lt;code&gt;DefaultAzureCredential&lt;/code&gt;. The PAT is quick to create, carries an expiration date, and API calls run under the identity of the user who created it. &lt;code&gt;DefaultAzureCredential&lt;/code&gt; uses a managed identity or a service principal, and creates a separate Azure DevOps identity for the agent through Microsoft Entra ID.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;org&lt;/code&gt; value has to be set in &lt;code&gt;.secrets.toml&lt;/code&gt; under &lt;code&gt;[azure_devops]&lt;/code&gt; either way. The PAT, when you use one, goes in the same file. With &lt;code&gt;DefaultAzureCredential&lt;/code&gt; you supply &lt;code&gt;AZURE_CLIENT_SECRET&lt;/code&gt; or rely on the managed identity and the Azure CLI for local runs. The service principal path is the one that keeps the reviewer's identity separate from a person's account, which matters the month that person leaves or their token expires.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the agent finds its own comments
&lt;/h2&gt;

&lt;p&gt;Once PR-Agent has posted in a thread it answers there, and it works out which comments are its own by reading its earlier ones. A generic mention such as &lt;code&gt;hi agent&lt;/code&gt; does not trigger a response. Before the first post on a pull request, or when the Azure DevOps identity changes, you set a stable identity in the &lt;code&gt;[azure_devops_server]&lt;/code&gt; section using a GUID or a unique name. During an identity transition the setting accepts a list.&lt;/p&gt;

&lt;p&gt;That section name is a trap of its own. &lt;code&gt;azure_devops_server&lt;/code&gt; is where the agent identity and webhook credentials are configured, and it is used for the provider regardless of which edition you run, so a team on the hosted service will still find itself editing a section labelled for the server edition.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the support matrix says works on Azure DevOps
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://docs.pr-agent.ai/overview/supported_platforms/" rel="noopener noreferrer"&gt;supported platforms matrix&lt;/a&gt; is worth reading before you promise anything to a team. Describe, Review, Improve, Ask, Add Docs and Help are supported on Azure DevOps. Generate Labels is applied, since the provider can set labels. Update CHANGELOG is posted as a pull request comment instead of being applied, because the provider cannot push files. Ask on code lines, Similar Issues and the tagging bot are not supported on Azure DevOps at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else runs on Azure Repos
&lt;/h2&gt;

&lt;p&gt;PR-Agent is not the only option, and the choice comes down to which identity the tool authenticates as and how the incoming webhook is secured.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.kodus.io/en/how_to_use/code_review/general_config/azure_devops_pat.md" rel="noopener noreferrer"&gt;Kodus&lt;/a&gt; connects to Azure DevOps through a PAT with a defined scope set: Analytics Read, Code Read &amp;amp; Write, Graph Read, Identities and Groups Read, Project and Team Read, User Profile Read. Code Write is the one that matters for posting review comments, since without it the connection looks healthy and no comments appear on the pull request. On a self-hosted install the &lt;a href="https://docs.kodus.io/en/how_to_deploy/platforms/azure_devops/azdevops_webhook.md" rel="noopener noreferrer"&gt;Azure Repos webhook&lt;/a&gt; needs a signed &lt;code&gt;token&lt;/code&gt; query parameter, an AES-256-CBC value derived from &lt;code&gt;CODE_MANAGEMENT_SECRET&lt;/code&gt; and &lt;code&gt;CODE_MANAGEMENT_WEBHOOK_TOKEN&lt;/code&gt;, and requests without it get a 403. That is a step GitHub, GitLab, Bitbucket and Forgejo connections do not need, and it is the kind of detail that stalls a self-hosted rollout on Azure Repos specifically. Kodus subscribes to four events: pull request created, updated, merge attempted, and commented.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;PR-Agent&lt;/th&gt;
&lt;th&gt;Kodus&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Trigger&lt;/td&gt;
&lt;td&gt;Build Validation policy, or a manual Azure service hook&lt;/td&gt;
&lt;td&gt;Azure service hook, created by the integration or registered by hand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;PAT, or DefaultAzureCredential via managed identity or service principal&lt;/td&gt;
&lt;td&gt;PAT with a fixed scope list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comment commands&lt;/td&gt;
&lt;td&gt;Webhook route only, API v2.0 required&lt;/td&gt;
&lt;td&gt;Pull request commented event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;td&gt;Docker image in a pipeline or a webhook server&lt;/td&gt;
&lt;td&gt;Self-hosted deployment supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webhook security&lt;/td&gt;
&lt;td&gt;Basic auth username and password&lt;/td&gt;
&lt;td&gt;Signed token query parameter, 403 without it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The edition question decides more than the tool
&lt;/h2&gt;

&lt;p&gt;None of this changes the fact that Azure DevOps Services and Azure DevOps Server are not the same target. &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-azure-devops-services-vs-server-per-tool/" rel="noopener noreferrer"&gt;Which AI review routes actually run on each edition&lt;/a&gt; is the part that decides whether a hosted reviewer is in scope at all, since vendor pages that document a PAT and a service hook against &lt;code&gt;dev.azure.com&lt;/code&gt; are describing the hosted service. A Server team that reads those pages and expects the same setup will spend a while chasing permissions that do not exist in the same form.&lt;/p&gt;

&lt;p&gt;The wider comparison of what each self-hosted reviewer supports across all three forges is in &lt;a href="https://mergerequests.dev/blog/pr-agent-on-gitlab-azure-devops-bitbucket-the-self-hosted-code-review-option/" rel="noopener noreferrer"&gt;PR-Agent on GitLab, Azure DevOps and Bitbucket&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the docs do not establish
&lt;/h2&gt;

&lt;p&gt;Cost per pull request for the pipeline route is not stated on the Azure DevOps page, and neither is whether the webhook route works against Azure DevOps Server behind an air gap. Both questions come up during planning, and neither has a number to cite from the vendor page. For those, the docs point at the general configuration reference and at the issue tracker for comment-trigger support.&lt;/p&gt;

</description>
      <category>azuredevops</category>
      <category>codequality</category>
      <category>devtools</category>
      <category>ai</category>
    </item>
    <item>
      <title>AI code review on self-managed GitLab, Azure DevOps and Bitbucket</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Mon, 05 Oct 2026 00:00:05 +0000</pubDate>
      <link>https://dev.to/emilreiter/ai-code-review-on-self-managed-gitlab-azure-devops-and-bitbucket-3e8i</link>
      <guid>https://dev.to/emilreiter/ai-code-review-on-self-managed-gitlab-azure-devops-and-bitbucket-3e8i</guid>
      <description>&lt;p&gt;Most "best AI code review tools 2026" comparisons are written as if the forge were GitHub and the deployment model were cloud. For a team on GitLab Self-Managed, Azure DevOps Server or Bitbucket Data Center, that list falls apart at the point where you try to install something. The features are real, the edition is wrong.&lt;/p&gt;

&lt;p&gt;The useful comparison for those teams is not a feature matrix. It is a deployment matrix, because the deployment model decides which entries on the feature list you can run at all. Below is what five tools document for their own supported platforms and editions, read from the vendor pages rather than from comparison posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The deployment model decides the shortlist
&lt;/h2&gt;

&lt;p&gt;A vendor's capability page tells you what the reviewer can do. The deployment page tells you where that reviewer can run, and it is usually a separate page with a different answer.&lt;/p&gt;

&lt;p&gt;Qodo makes this explicit with a &lt;a href="https://docs.qodo.ai/install-qodo/deployment-model-support" rel="noopener noreferrer"&gt;per-provider deployment table&lt;/a&gt; that splits four models: multi-tenant, single-tenant, on-premises and air-gapped. The rows matter more than the checkmarks. GitLab Self-Managed is listed as single-tenant, on-prem and air-gapped, with multi-tenant marked out. Bitbucket Data Center is on-prem and air-gapped only, with single-tenant marked out as well.&lt;/p&gt;

&lt;p&gt;That table is the single most useful artifact I have found for this beat, because it answers the question a self-managed team actually asks: can this thing run inside my network. Most tools do not publish the answer in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure DevOps: Services, Server, and where each tool stops
&lt;/h2&gt;

&lt;p&gt;Azure DevOps is two products with one name. Services is the cloud service (dev.azure.com). Server is the on-premises product, the rebranded TFS line, which is what most regulated and air-gapped teams actually run. Very few vendor pages separate them.&lt;/p&gt;

&lt;p&gt;GitHub Copilot code review for Azure Repos is the clearest example of why that separation matters. Per &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews?view=azure-devops" rel="noopener noreferrer"&gt;Microsoft's own page for the feature&lt;/a&gt;, it is scoped to Azure DevOps Services, is in limited preview with no Service Level Agreement, and requires a linked Azure subscription because usage bills through Azure Cost Management. TFVC repositories are not supported. Enablement is three-scoped: a Project Collection Administrator turns it on for the organization, a Project Administrator handles project defaults and repository overrides, and a repository owner enables it per repo. Version control aside, there is no Server edition of this feature documented.&lt;/p&gt;

&lt;p&gt;Qodo's table has a different shape for the same platform. Azure DevOps Cloud gets multi-tenant and single-tenant, and on-prem is marked out. That is a cloud-only path for Azure DevOps, which is a limitation worth knowing before you shortlist Qodo for an Azure DevOps Server migration.&lt;/p&gt;

&lt;p&gt;CodeRabbit reaches Azure DevOps through two paths. The &lt;a href="https://docs.coderabbit.ai/getting-started/quickstart" rel="noopener noreferrer"&gt;cloud quickstart&lt;/a&gt; lists Azure DevOps among the platforms you can connect with your existing account, and the &lt;a href="https://docs.coderabbit.ai/self-hosted/overview" rel="noopener noreferrer"&gt;self-hosted overview&lt;/a&gt; lists Azure DevOps among the platforms covered by the self-hosted agent. That second path is the one that matters for Server, because the agent runs inside your infrastructure and connects to the Git platform with a service account.&lt;/p&gt;

&lt;p&gt;I wrote up the Services versus Server split in more detail in the &lt;a href="https://mergerequests.dev/platform/azure-devops/" rel="noopener noreferrer"&gt;Azure DevOps platform notes&lt;/a&gt; if you need the per-feature breakdown rather than the deployment view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-managed GitLab and Bitbucket Data Center
&lt;/h2&gt;

&lt;p&gt;GitLab Self-Managed is where the self-hosted options cluster, because the platform itself is designed to run inside your network.&lt;/p&gt;

&lt;p&gt;CodeRabbit self-hosting covers GitLab self-managed directly. The gate is the license, not the platform: the self-hosted agent is Enterprise only, for customers with 500 or more user seats, ships as a container image you run on a server, a container platform or a serverless workload, and the deployment instructions are provided during onboarding rather than published. For a GitLab instance that cannot accept inbound connections, the CodeRabbit Reverse Tunnel keeps all connections outbound from your network. Code and pull request data stay inside your environment, and prompts and source leave it only to reach the LLM provider you configure.&lt;/p&gt;

&lt;p&gt;Qodo's row for GitLab Self-Managed is the most complete in that vendor's table: no multi-tenant, yes single-tenant, yes on-premises, yes air-gapped. For an air-gapped GitLab instance, that is one of the few vendor-documented paths I can point to.&lt;/p&gt;

&lt;p&gt;Bitbucket Data Center is the tightest of the three. Qodo lists it as on-prem and air-gapped only, with multi-tenant and single-tenant both marked out. CodeRabbit's self-hosted agent covers it. CodeRabbit's cloud quickstart also lists Bitbucket Data Center as a connectable platform, which is worth reading carefully, because the integration runs against your instance while the review runs in CodeRabbit's cloud. Which parts of the pipeline leave your network is the question to ask there, and it is different from the self-hosted case. I covered the native versus third-party breakdown of Bitbucket Data Center in &lt;a href="https://mergerequests.dev/blog/ai-code-review-on-bitbucket-data-center-whats-native-what-isnt/" rel="noopener noreferrer"&gt;what's native on Bitbucket Data Center and what isn't&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The open-source path, and what it asks you to run
&lt;/h2&gt;

&lt;p&gt;For teams that cannot buy an Enterprise tier, the open-source option is the one that covers the widest set of providers. PR-Agent, now community-owned after Qodo donated it, states support for GitHub, GitLab, Bitbucket, Azure DevOps and Gitea, with deployment through CLI, Docker, self-hosted webhooks or CI. It runs on any model reachable through LiteLLM, which includes Ollama for a fully local setup. The &lt;a href="https://github.com/the-pr-agent/pr-agent" rel="noopener noreferrer"&gt;repository&lt;/a&gt; also documents a Docker namespace migration: releases from 0.34.2 onward publish under &lt;code&gt;pragent/pr-agent&lt;/code&gt;, and anything pinned to the older &lt;code&gt;codiumai/pr-agent&lt;/code&gt; namespace is frozen at v0.31. If you are running it in a pipeline, that detail is the difference between a working upgrade and a broken one.&lt;/p&gt;

&lt;p&gt;The trade is maintenance. You run the service, you hold the provider key, and you own the prompt configuration. I wrote up &lt;a href="https://mergerequests.dev/blog/pr-agent-on-gitlab-azure-devops-bitbucket-the-self-hosted-code-review-option/" rel="noopener noreferrer"&gt;the PR-Agent self-hosted path across GitLab, Azure DevOps and Bitbucket&lt;/a&gt; separately, including the webhook and pipeline options per forge.&lt;/p&gt;

&lt;p&gt;Kodus takes a third approach on licensing. Its &lt;a href="https://docs.kodus.io/en/how_to_use/pricing.md" rel="noopener noreferrer"&gt;pricing documentation&lt;/a&gt; puts self-hosting in the free Community tier as well as Enterprise, with reviews unlimited on every plan because the model runs on your own provider key through BYOK. The documented Git integrations are GitHub, GitLab and Bitbucket, and Azure DevOps is not listed. Teams that need a self-hosted reviewer for GitLab or Bitbucket can start on the free tier; a team on Azure Repos should treat Kodus as unavailable rather than as a candidate to evaluate. The same docs put Community at up to 10 rules and 3 plugins, and the 2,000 changed-file cap applies to any plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each tool does with your team's rules
&lt;/h2&gt;

&lt;p&gt;Rules are where a review tool either matches your standards or produces generic comments, so the mechanism matters as much as the label.&lt;/p&gt;

&lt;p&gt;CodeRabbit offers path-based instructions on glob patterns plus AST-based instructions written with ast-grep, which lets you target structural code patterns instead of file paths. That is a meaningful distinction in a monorepo, where "all controllers" is easier to express as a syntax pattern than as a path.&lt;/p&gt;

&lt;p&gt;Kodus documents &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/configs/rules_file_detection.md" rel="noopener noreferrer"&gt;rule file detection&lt;/a&gt;, which imports rule files you already have from other AI coding tools, along with &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/configs/directory_level.md" rel="noopener noreferrer"&gt;directory-level settings&lt;/a&gt; for targeting folders in a monorepo and inheritance from global to repository to directory level. Kody Rules enforce a standard rather than suggest one, which is the part teams generally want when they say the reviewer should follow their conventions.&lt;/p&gt;

&lt;p&gt;PR-Agent takes the simplest route: JSON-based prompt configuration you edit in the repository. It is flexible and entirely on you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The comparison table
&lt;/h2&gt;

&lt;p&gt;Everything here comes from the vendor pages linked above. Where a vendor does not state something for a platform, the cell says so rather than guessing.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Azure DevOps&lt;/th&gt;
&lt;th&gt;GitLab Self-Managed&lt;/th&gt;
&lt;th&gt;Bitbucket Data Center&lt;/th&gt;
&lt;th&gt;Self-hosted / air-gapped&lt;/th&gt;
&lt;th&gt;Licensing gate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot code review&lt;/td&gt;
&lt;td&gt;Services only, limited preview, no SLA; Server not documented&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;Not stated for these forges&lt;/td&gt;
&lt;td&gt;Azure subscription for billing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;Cloud only; on-prem marked out&lt;/td&gt;
&lt;td&gt;Single-tenant, on-prem, air-gapped&lt;/td&gt;
&lt;td&gt;On-prem and air-gapped only&lt;/td&gt;
&lt;td&gt;Yes, per provider table&lt;/td&gt;
&lt;td&gt;On-prem deployments run on your Kubernetes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;Cloud connect and self-hosted agent&lt;/td&gt;
&lt;td&gt;Cloud connect and self-hosted agent&lt;/td&gt;
&lt;td&gt;Cloud connect and self-hosted agent&lt;/td&gt;
&lt;td&gt;Yes, container image; Reverse Tunnel for private networks&lt;/td&gt;
&lt;td&gt;Self-hosted is Enterprise, 500+ seats&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR-Agent (open source)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, CLI/Docker/webhooks&lt;/td&gt;
&lt;td&gt;None; community-maintained, you run it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kodus&lt;/td&gt;
&lt;td&gt;Not listed&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, Community and Enterprise&lt;/td&gt;
&lt;td&gt;Free Community self-hosted; BYOK for models&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What to check before you shortlist
&lt;/h2&gt;

&lt;p&gt;Two things decide more outcomes here than any feature comparison.&lt;/p&gt;

&lt;p&gt;The first is whether the vendor's platform list includes the edition you run, not the product line. Azure DevOps appears on nearly every list. Azure DevOps Server appears on far fewer, and Copilot code review is documented as Services-only while Qodo's Azure DevOps row marks on-prem out. If you are on Server, those two entries drop off and the shortlist gets short fast.&lt;/p&gt;

&lt;p&gt;The second is whether the review runs inside your network. A cloud connector pointed at a self-managed instance is a different security decision from an agent running on your own infrastructure, even when both get the same checkmark on a feature page. CodeRabbit's own documentation draws that line for you: the self-hosted agent keeps orchestration and results in your environment and sends prompts and source only to your configured model provider.&lt;/p&gt;

&lt;p&gt;If you want the wider view of what exists per forge, I keep the &lt;a href="https://mergerequests.dev/blog/free-ai-code-review-for-gitlab-azure-devops-bitbucket/" rel="noopener noreferrer"&gt;free and self-hosted options for GitLab, Azure DevOps and Bitbucket&lt;/a&gt; in one place, and the CodeRabbit and Qodo self-hosted editions on their &lt;a href="https://mergerequests.dev/blog/self-hosted-ai-code-review-coderabbit-and-qodo-per-their-docs/" rel="noopener noreferrer"&gt;own criteria&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The shortlist for a self-managed forge is narrower than the general 2026 comparison suggests, and it is narrower for a reason you can verify on each vendor's deployment page rather than take on faith.&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>gitlab</category>
      <category>azuredevops</category>
      <category>bitbucket</category>
    </item>
    <item>
      <title>AI code review that follows your team's rules: what each tool actually ingests</title>
      <dc:creator>Emil Reiter</dc:creator>
      <pubDate>Wed, 30 Sep 2026 00:15:10 +0000</pubDate>
      <link>https://dev.to/emilreiter/ai-code-review-that-follows-your-teams-rules-what-each-tool-actually-ingests-119c</link>
      <guid>https://dev.to/emilreiter/ai-code-review-that-follows-your-teams-rules-what-each-tool-actually-ingests-119c</guid>
      <description>&lt;p&gt;"Follows our coding standards" is the phrase teams use when they mean "does not post the same generic nit for the fourth time." It sounds like one feature. It is at least three, and they fail in different ways.&lt;/p&gt;

&lt;p&gt;The mechanisms are: a rule file the tool reads and treats as review criteria, a per-path instruction that scopes guidance to a directory, and an enforcement rule with a pass or fail attached. A tool can ship one of these and call the result "custom standards." Whether that is enough depends on what your team actually needs, and whether it runs on the edition you are on.&lt;/p&gt;

&lt;p&gt;That last part matters more than the feature list. On GitLab Self-Managed, Azure DevOps Server and Bitbucket Data Center, hosted rule ingestion is the first thing to disappear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three mechanisms that get called "your standards"
&lt;/h2&gt;

&lt;p&gt;An ingested rule file is the lowest-effort option. You already have a &lt;code&gt;CLAUDE.md&lt;/code&gt;, an &lt;code&gt;AGENTS.md&lt;/code&gt;, a &lt;code&gt;.cursorrules&lt;/code&gt;, or a &lt;code&gt;docs/coding-standards/&lt;/code&gt; folder in the repo. The reviewer scans for those files and uses their content as review criteria. The upside is that the standards document already exists and both humans and coding agents read it. The downside is that the file is guidance, not a check. The reviewer interprets it, and interpretation is inconsistent across runs.&lt;/p&gt;

&lt;p&gt;A per-path instruction is a mapping from a glob to free text. You tell the reviewer that anything under &lt;code&gt;src/controllers/**&lt;/code&gt; should be checked for auth, input validation, and direct database calls that bypass the ORM. This is more precise than a global guideline file because the guidance only applies where it belongs, which is the difference between useful and noisy in a monorepo.&lt;/p&gt;

&lt;p&gt;An enforcement rule with a verdict is the strictest option. The rule has a severity, a path scope, and it either fires or it does not. This is what teams reach for when the requirement is "the reviewer must block this," and it is the mechanism least likely to be available on every plan. Severity levels and the ability to gate a merge are where vendors draw plan lines.&lt;/p&gt;

&lt;p&gt;The practical consequence: if your team's real complaint is that the reviewer misses your conventions, a rule file and per-path instructions handle it. If the complaint is that the reviewer is inconsistent and you need a hard stop, only the third mechanism does that, and it may sit behind a paid tier or a licensed self-hosted deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What CodeRabbit ingests, and where it stops
&lt;/h2&gt;

&lt;p&gt;CodeRabbit detects guideline files automatically and applies them as review criteria with no configuration. The &lt;a href="https://docs.coderabbit.ai/knowledge-base/code-guidelines" rel="noopener noreferrer"&gt;code guidelines docs&lt;/a&gt; list the patterns: &lt;code&gt;**/AGENTS.md&lt;/code&gt;, &lt;code&gt;**/.cursorrules&lt;/code&gt;, &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;, &lt;code&gt;.github/instructions/*.instructions.md&lt;/code&gt;, &lt;code&gt;**/CLAUDE.md&lt;/code&gt;, &lt;code&gt;**/.windsurfrules&lt;/code&gt;, &lt;code&gt;**/.clinerules/*&lt;/code&gt;, &lt;code&gt;**/.rules/*&lt;/code&gt;, among others. Matching is case-sensitive, so a file named &lt;code&gt;claude.md&lt;/code&gt; is not picked up.&lt;/p&gt;

&lt;p&gt;Scoping is directory-based. A &lt;code&gt;CLAUDE.md&lt;/code&gt; at the repo root applies to everything; &lt;code&gt;src/backend/.cursorrules&lt;/code&gt; applies only under &lt;code&gt;src/backend/&lt;/code&gt;. When directory placement does not match the files a guideline should govern, you switch to the object form of &lt;code&gt;filePatterns&lt;/code&gt; with an explicit &lt;code&gt;applyTo&lt;/code&gt; glob. That is the per-path mechanism, and it is the one that makes a monorepo workable.&lt;/p&gt;

&lt;p&gt;Guidelines can also come from another repository, written as &lt;code&gt;repo:path&lt;/code&gt; or &lt;code&gt;owner/repo:path&lt;/code&gt;. Here the edition split shows up. On GitHub the source and reviewed repos must share an organization, on GitLab they must share a top-level group, and Bitbucket Cloud must share a workspace. The docs mark the Bitbucket entry &lt;strong&gt;Cloud Only&lt;/strong&gt;. Cross-repo guideline reuse is not a path available on Bitbucket Data Center.&lt;/p&gt;

&lt;p&gt;One trap worth calling out because it is easy to hit: adding a guideline filename like &lt;code&gt;CLAUDE.md&lt;/code&gt; to &lt;code&gt;path_instructions&lt;/code&gt; does not use it as a guideline. It tells the reviewer to review that file as changed code. Use &lt;code&gt;filePatterns&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qodo's governance layer
&lt;/h2&gt;

&lt;p&gt;Qodo routes rule and standards questions to its governance area rather than its review area. The &lt;a href="https://docs.qodo.ai/code-governance" rel="noopener noreferrer"&gt;code governance docs&lt;/a&gt; describe Review Standards as turn "your organization's engineering conventions into something that can actually be enforced," with rule enforcement as the explicit, checkable form. There is also a &lt;code&gt;REVIEW.md&lt;/code&gt; instructions file and rule generation from PR history indexing.&lt;/p&gt;

&lt;p&gt;The difference from CodeRabbit's approach is where the configuration lives. CodeRabbit reads files that are already in the repo. Qodo's standards are managed as governance objects in the portal, which suits an org that wants one set of rules across every repository without relying on each repo carrying the right file. It also means the standards are not part of the codebase, so a review of a rule change is not a code review.&lt;/p&gt;

&lt;p&gt;Both approaches are legitimate and they fail differently. Repo-resident files drift when teams copy them and forget to update. Portal-managed rules drift when the portal is edited and nobody notices. Pick based on which of those two failure modes your team already handles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kodus and rule files
&lt;/h2&gt;

&lt;p&gt;Kodus ships rule following as a first-class path rather than a side feature. Its &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/configs/kody_rules" rel="noopener noreferrer"&gt;Kody Rules overview&lt;/a&gt; splits rules into file-level and pull-request-level, with each rule carrying a severity of Critical, High, Medium or Low and a path scope using globs. Rules can reference other files with &lt;code&gt;@file:src/services/userService.ts&lt;/code&gt; or &lt;code&gt;@repo:team/api-standards&lt;/code&gt; to check consistency against a standard outside the reviewed repo, and can call MCP functions during evaluation.&lt;/p&gt;

&lt;p&gt;The distinction that matters for teams already using a coding agent: &lt;a href="https://docs.kodus.io/en/how_to_use/code_review/configs/rules_file_detection" rel="noopener noreferrer"&gt;rules file detection&lt;/a&gt; imports the same files CodeRabbit does, plus more, including &lt;code&gt;.sourcegraph/**/*.rule.md&lt;/code&gt;, &lt;code&gt;.opencode.json&lt;/code&gt;, &lt;code&gt;.aider.conf.yml&lt;/code&gt; and &lt;code&gt;docs/coding-standards/**/*&lt;/code&gt;. Unlike CodeRabbit's case-sensitive matching, Kodus matches case-insensitively. Nested files are scoped automatically: a &lt;code&gt;services/billing/CLAUDE.md&lt;/code&gt; is imported and scoped to &lt;code&gt;services/billing/**&lt;/code&gt;. Files it generates rules from are re-synced when a PR closes, and &lt;code&gt;@kody-ignore&lt;/code&gt; keeps a file in the repo without it becoming an enforced rule.&lt;/p&gt;

&lt;p&gt;There are two limits to plan around. On a self-hosted instance running without a valid license, the docs state that at most &lt;strong&gt;10 rules are evaluated per review&lt;/strong&gt;, oldest first, and rules past the tenth silently do not fire. Licensed self-hosted and cloud instances have no such limit. The Community plan lists "Up to 10 Kody Rules." So the self-hosted Community edition is where rule-following gets capped, which is the opposite of how most vendors structure self-managed editions.&lt;/p&gt;

&lt;p&gt;Kodus also runs self-hosted and supports bring-your-own model keys on every plan, so on a firewalled GitLab, Azure DevOps Server or Bitbucket Data Center the rule evaluation happens against your endpoint rather than a vendor tenant. That is the same reasoning that makes the open-source CLI route attractive on those forges, and the trade-off is the rule-count cap at the free tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing the mechanisms
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Ingested rule files&lt;/th&gt;
&lt;th&gt;Per-path instructions&lt;/th&gt;
&lt;th&gt;Enforced severity / gate&lt;/th&gt;
&lt;th&gt;Self-managed edition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;Auto-detect of AGENTS.md, CLAUDE.md, .cursorrules and similar&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;path_instructions&lt;/code&gt; and &lt;code&gt;filePatterns&lt;/code&gt; with &lt;code&gt;applyTo&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Custom checks listed in docs&lt;/td&gt;
&lt;td&gt;Yes, per &lt;a href="https://mergerequests.dev/blog/self-hosted-ai-code-review-coderabbit-and-qodo-per-their-docs/" rel="noopener noreferrer"&gt;its self-hosted docs&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;REVIEW.md&lt;/code&gt; instructions&lt;/td&gt;
&lt;td&gt;Governance objects, portal-managed&lt;/td&gt;
&lt;td&gt;Review Standards with rule enforcement&lt;/td&gt;
&lt;td&gt;On-premise deployment documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kodus&lt;/td&gt;
&lt;td&gt;Rule file detection across 11+ tool formats, case-insensitive, nested scoping&lt;/td&gt;
&lt;td&gt;File-level and PR-level rules with glob path scope&lt;/td&gt;
&lt;td&gt;Critical / High / Medium / Low severity&lt;/td&gt;
&lt;td&gt;Self-hosted on every plan, BYOK; 10-rule cap without a license&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitLab Duo&lt;/td&gt;
&lt;td&gt;Custom instructions and Duo context&lt;/td&gt;
&lt;td&gt;Not stated in the same shape&lt;/td&gt;
&lt;td&gt;Depends on the code review feature in use&lt;/td&gt;
&lt;td&gt;See the &lt;a href="https://mergerequests.dev/blog/gitlab-self-managed-ai-review-that-follows-your-own-rules/" rel="noopener noreferrer"&gt;self-managed rules page&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cross-repo guideline sources are the row where editions diverge most. CodeRabbit documents them as Cloud Only on Bitbucket. Kodus's &lt;code&gt;@repo:&lt;/code&gt; reference works from a rule definition and is not gated to a single forge. If your standards live in one repo and your services live in forty, that difference is the deciding one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check before you commit
&lt;/h2&gt;

&lt;p&gt;The question to ask a vendor is not whether it supports custom rules. Every tool above answers yes. Ask which mechanism it uses, whether the rules live in the repo or in a portal, and whether the rule limit changes on the self-managed edition you would actually deploy.&lt;/p&gt;

&lt;p&gt;For most teams on GitLab, Azure DevOps or Bitbucket, the sequence that works is: put your standards somewhere the team already reads them, point the reviewer at that file, and let per-path instructions handle the directories where generic guidance is worse than none. Add severity-gated rules only where a missed check has a real cost, because hard stops create merge friction that a reviewer's opinion does not.&lt;/p&gt;

&lt;p&gt;And if you are on a self-managed forge, verify the edition before the feature. The rule-following story on a hosted tier and the rule-following story on the on-prem edition are frequently documented on different pages, and only one of them applies to where your code actually lives.&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>ai</category>
      <category>gitlab</category>
      <category>azuredevops</category>
    </item>
  </channel>
</rss>
