demo

See how the bot reviews

We built 13 applications across 11 languages and opened a pull request in each one. The bot reviewed them exactly as it reviews working code. Nothing is hidden: open a request and read the comments in full.

What is real here, and what is not

  • The applications are synthetic. We wrote them ourselves, for this demo. This is not somebody's production and not a customer's code: showing code that is not ours is something we will never do.
  • Some of the defects were planted by us. We put a few typical mistakes into every request on purpose — otherwise there would be nothing to review.
  • The runs are real. These are live pull requests in open repositories. The bot wrote the comments; we did not edit them, did not delete the weak ones and did not rewrite the wording.
  • The bot found more than we planted. Every request holds findings we did not plan — including a couple of genuine mistakes in our own demo code. They are visible in the same threads.
  • The numbers on the cards are the bot's own threads. Not averaged and not «up to 40%»: count the comments in the request and you get the same figures. Open them and check.
  • Half of the gates are still red. The developer fixed a couple of bugs in each request, not all of them — so the check stays red where blocking findings are still open. We left it that way: a green screenshot would say less.

A demo shows what a review looks like. Whether it is useful to your team is answered only on your code and your rules: put it on a single repository and see.

by stack

One repository per language

Every repository holds the team's agreements (docs/adr) and a review config with the rules derived from them. Those are what the bot checks — which is why the findings speak the language of the project instead of talking in generalities.

TypeScript

Angular

preset: angular

Catalogue: filter by brand, and a live cart badge

findings
12
blocking the merge
2
with an «Apply» button
1
CatalogFilterComponent injects CatalogApi directly and calls fetchBrands() from the component, bypassing the facade layer entirely (ADR-001).

TypeScript

NestJS

preset: nestjs

Reports: revenue for a period, broken down by order

findings
13
blocking the merge
4
with an «Apply» button
1
findItems is awaited inside a for-of loop over the period’s orders, issuing one DB query per order — exactly the N+1 pattern ADR-002 bans.

TypeScript

React

preset: react

Catalogue: filter by brand, and a live cart badge

findings
8
blocking the merge
3
with an «Apply» button
2
CartBadge now imports and calls cartStore.subscribe/getState directly instead of going through the existing useCart facade hook.

Python

Django

preset: django

Reports: revenue for a period, broken down by order

findings
16
blocking the merge
6
with an «Apply» button
2
All the business logic — period filtering, per-order aggregation, pushing to analytics — lives in the APIView.get method instead of a service layer, violating ADR-001.

Go

Gin

preset: gin

Reports: revenue for a period, broken down by order

findings
19
blocking the merge
9
with an «Apply» button
3
Errors from time.Parse for “from” and “to” are discarded. A malformed date silently becomes the zero time, turning the request into an unbounded “since the beginning of time” query instead of returning a 400.

Java

Spring Boot

preset: spring

Reports: revenue for a period, broken down by order

findings
9
blocking the merge
3
with an «Apply» button
1
revenueForPeriod computes totalCents only from the single Page<Order> returned for the requested page — the headline figure of the report is wrong for any period longer than one page.

Kotlin

Android · Compose

preset: android

Catalogue: filter by brand

findings
12
blocking the merge
3
with an «Apply» button
2
BrandFilter takes CatalogRepository as a parameter and calls repository.fetchBrands() itself, instead of receiving state from the ViewModel.

Ruby

Rails

preset: rails

Reports: revenue for a period, broken down by order

findings
12
blocking the merge
5
with an «Apply» button
2
total_cents for the whole report is summed from lines, which is built from the already paginated orders relation — the period total silently becomes the page total.

PHP

Laravel

preset: laravel

Reports: revenue for a period, broken down by order

findings
12
blocking the merge
3
with an «Apply» button
5
->get() loads every paid order in the period with no upper bound, which ADR-002 bans for any list that grows with the data.

Rust

Actix Web

preset: actix

Reports: revenue for a period, broken down by order

findings
10
blocking the merge
5
with an «Apply» button
2
query.from and query.to are raw strings taken from the request and parsed with .unwrap() — a malformed date panics the handler instead of answering 400.

C#

ASP.NET Core

preset: aspnet

Reports: revenue for a period, broken down by order

findings
16
blocking the merge
5
with an «Apply» button
3
A new HttpClient() is created on every Send call instead of coming from IHttpClientFactory — the socket-exhaustion pattern the team’s rules single out by name.

Dart

Flutter

preset: flutter

Catalogue: filter by brand

findings
12
blocking the merge
3
with an «Apply» button
4
BrandFilter instantiates CatalogRepository directly and calls it from the widget, bypassing CatalogNotifier entirely.

Swift

iOS · SwiftUI

preset: ios

Catalogue: filter by brand

findings
12
blocking the merge
4
with an «Apply» button
3
BrandsLoader, owned by BrandFilterView, constructs its own CatalogRepository and APIClient instead of getting brand data through CatalogViewModel.
if github.com is blocked for you

Here is that same summary, in full

In some corporate networks the public GitHub is unreachable. So that the demo does not turn into a set of dead links for you, here is the summary from the Java / Spring Boot request — this is what a developer sees in the pull request itself.

ReviewGatethe bot's comment in the request

🤖 ReviewGate — AI review

The new revenue report endpoint has a serious correctness bug: it computes the total revenue only from the current page of orders instead of the whole period, so numbers finance relies on will be wrong whenever a period has more orders than the page size. The report list endpoint also lacks a hard cap on page size, the AnalyticsClient the PR describes as pushing the report to the BI dashboard is never actually invoked anywhere, and the financial report endpoint has no authorization check.

Preset: spring.

❌ Severity gate (critical) failed: 1 blocking finding.

Findings: 3 (🔴 1 · 🟠 2); new inline comments: 2.
From earlier runs — already under review, not duplicated: 1.

▸ 🔬 Run diagnostics

⚙️ This review: 33.9K tokens in (1K of them from cache) · 36.1K out · ≈ 0.85 $

The cost line is not our accounting but a function of the bot: it prices the run against the rates you put in your config, in your currency. The collapsed «Run diagnostics» block expands inside the request: it shows which models were called and what the judge dropped. There is no code in that block — only metadata.

what to look at

What to look for in an open request

Comments on the lines

Findings are anchored to the lines of the diff. Open the Files changed tab — they sit where a developer reads them.

The summary and the severity gate

A single comment with the outcome of the run and a verdict. Every demo sets the threshold at critical, so the check stays red until the blocking findings are closed.

The «Run diagnostics» block

A collapsed block inside the summary: which models were called, how many tokens went out, what the judge dropped or downgraded and why. There is no code in it — only metadata.

The «Apply» buttons

Some findings carry a ready fix: the platform shows a button and the edit lands in the branch in one click. The bot offers such a fix only where it is confident.

The conversation in a thread

In every request a developer argues with one of the findings, and the bot answers in the same thread — sometimes holding its ground with a walk through the code, sometimes agreeing with the nuance it had missed.

The same bot, on your repository

The demo was reviewed by an ordinary ReviewGate — the same engine and the same settings from .reviewgate/config.yml that you install in your own perimeter. The only difference is that these repositories are public: your code stays where it is.