Code review

Three files changed
Forty-seven call paths touched

Niro reviews every changed line against the call graph behind it - the callers it breaks, the tests that never cover it, the repos it reaches. What lands on your PR looks exactly like this.

Put it on a PR Read one finding
3
comments posted
5
withdrawn, with reasons
41s
push to posted
payments-core · PR #447 · fix: retry policy from config review complete
niro-reviewbotcommented on retry-policy.tsblocking
graph-impact

maxRetries now comes from config. 47 call paths reach this line across 6 repos - 43 of them have no covering test. The nearest is checkout-api, which retries on the user's card.

PaymentProcessor.execute ↳ StripeClient.charge payments-core ↳ CheckoutService.submit checkout-api ✗ no test ↳ RefundWorker.retry billing-jobs ✗ no test
Confidence: 96%survived the challenge pass
5 findings withdrawn by the challenge passhidden from humans
Anatomy

Every finding carries
its own evidence

Four parts, always the same four. A claim without them is withdrawn before you see it.

01 · the pass
Which reader found it

Every comment names its pass - graph-impact, security, patch-drift - so you can turn off the ones that waste your time, per repo.

02 · the claim
One sentence, one risk

What breaks, stated flatly. No severity theatre, no paragraph of hedging - the claim is falsifiable or it does not post.

03 · the trace
The call paths, verbatim

Read from CodeGraph, not inferred from the diff. Caller by caller, repo by repo, with the untested paths marked ✗.

04 · the survival
Proof it was argued with

Confidence and the challenge verdict, on the comment itself. A finding that could not defend itself never reached you.

The noise math

A reviewer who flags everything
gets ignored

The same diff, reviewed twice. On the left, every comment a diff-only linter bot posted. On the right, the ones that survived Niro’s challenge pass - where each finding has to justify itself against the graph before it reaches you.

diff-only tooling14
styleLine exceeds 120 characters.
stylePrefer const over let.
lintUnused import java.util.Optional.
lintMethod exceeds 40 lines.
nitConsider renaming tmp2 for clarity.
maybePossible null dereference on customer.
infoTODO found; consider filing a ticket.
+ 7 more nobody read
niro, after the challenge3
graph-impactPaymentProcessor.execute
47 callers across 6 repos, 43 with no covering test.
securityAuthFilter.java:88
Token compared with equals - timing attack, reachable from a public endpoint.
patch-driftapplication.yml
Config changed without the code that reads it - the reader lives in another repo.
3 posted · 5 withdrawn with reasons · 0 repeated advice
Why the graph

Diffs show what moved. Graphs show what breaks.

CodeGraph holds every call path across your repositories. Review reads it before commenting - so "three files changed" becomes forty-seven call paths, each checked for a covering test.

6
repos reached
47
call paths read
blast radius · retry-policy.ts:L47
RetryPolicy.of(config.maxRetries()) ↳ PaymentProcessor.execute payments-core ↳ StripeClient.charge payments-core ↳ CheckoutService.submit checkout-api ↳ CartController.pay checkout-api ↳ RefundWorker.retry billing-jobs ↳ InvoiceRetrier.run billing-jobs ↳ SubscriptionRenewal.charge subscriptions ↳ DunningJob.retryFailed subscriptions 41 further paths · expand in console
Fig. 1 - read from CodeGraph · 11ms · nothing inferred from the diff
The manifest

Eleven passes.
Each one a flag you own.

Every pass is one capability with one prompt behind it, off by default. This is the full list - nothing runs that is not on it.

graph-impact
security
patch-drift
code-redundancy
api-contract
migration-safety
test-coverage
static-code
guidelines
compliance
challenge
argues with all
✓ 3 stand
posted to the PR
✗ 5 refuted
withdrawn · reasons logged
How it runs

In your PRs,
on your terms

01
A GitHub App, not a bot account

Installed against the repos you choose. Reviews arrive as PR comments where the conversation already is.

02
One egress point for every model call

Nothing calls a provider directly. What leaves is auditable in one place.

03
Your diff is not in the logs

No source, no diff content, no prompts. Paths and counts only - written into the service principles, not bolted on.

04
Off until you turn it on

Every pass is flag-gated and defaults off. Adoption is a decision, not a surprise.

FAQ

Before you point
it at a repo

Which platforms does PR review support?

GitHub today, as a GitHub App installed against the repositories you choose rather than a bot account holding a seat. GitLab, Bitbucket and Gitea are indexed over an access token, but do not yet receive review comments.

Will it flood our pull requests?

Ten passes read the diff and an eleventh argues with all of them; whatever it refutes is withdrawn before a human sees it. Every capability is also flag-gated and defaults off, so adoption is a decision rather than a surprise - you turn on the passes that earn their place.

Does this replace human review?

No. It reads the graph behind the diff and reports the call paths a diff view cannot show you, including which of them no test covers. Deciding what to do about them is still a reviewer's job.

Does our diff reach your logs, or a model provider directly?

Neither. No source, no diff content and no prompts are written to logs - paths and counts only, written into the service principles rather than bolted on afterwards. Every model call goes through one gateway, so what leaves is auditable in a single place.

Next

Point it at
one noisy repo

The one where review comments are ignored. Compare what gets posted with what your current tooling posts.

Get set up Measure the difference