Kaniscope

What the reviewer actually filed

Every AI reviewer claims it finds real bugs. Almost none of them publish the times it was wrong. This page is our scoreboard, false-positive column included, and an account of the things we still cannot honestly measure.

81%
precision
59
confirmed findings
14
false positives
37
graded rounds

How this is scored

After a review lands, a human reads it against the code and writes a verdict for every finding: confirmed (a real problem), false positive (it is not a problem, or the diagnosis is wrong), out of scope (real, but not something this PR should be asked about), or missed (a problem someone found later that the reviewer said nothing about). Precision is confirmed / (confirmed + false positives). Nothing is scored by a model, and nothing is scored by the reviewer itself.

There is no recall number on this page, and that is deliberate. A miss only enters the table when a human later found the bug and remembered to write it down, so the “missed” column is a floor, never a rate. We had a recall figure once; auditing it showed it was an artefact of how the corpus recorded line numbers, and a shuffled control scored higher than the real reviewer. We deleted it rather than quote it. Until the measurement is sound, the honest answer to “what is your recall?” is that we do not know.

The rounds

One row per review. r1, r2… are re-reviews of the same pull request after the author pushed fixes. Most of these repositories are private, so they appear by letter — the counts are what matters, and inventing public rows to look better would defeat the purpose of the page.

daterepositoryPRround confirmedfalse posworst FP out of scopemissedprecision
2026-07-27private A#1020001
2026-07-27private A#1033000100%
2026-07-27private A#1042000100%
2026-07-27private A#1051000100%
2026-07-27private A#106210067%
2026-07-30private B#2628211167%
2026-07-30VinaText#10r102BLOCKING000%
2026-07-30VinaText#10r22000100%
2026-07-30VinaText#20r105MEDIUM000%
2026-07-30VinaText#20r20070
2026-07-31pr-review-core#28r101BLOCKING000%
2026-07-31pr-review-core#28r201MEDIUM000%
2026-07-31pr-review-core#312002100%
2026-08-02private C#100001
2026-08-02VinaText#358001100%
2026-08-02private D#25r12011100%
2026-08-02private D#25r22000100%
2026-08-02private D#272003100%
2026-08-02private D#29r12000100%
2026-08-02private D#29r21000100%
2026-08-04private C#16r11003100%
2026-08-04private C#16r21002100%
2026-08-04private C#16r31001100%
2026-08-04private C#16r41000100%
2026-08-04private C#16r50000
2026-08-05private C#191000100%
2026-08-05kaniscope-action#601000%
2026-08-05private D#350001
2026-08-05pr-review-core#351000100%
2026-08-15private E#63r12014100%
2026-08-15private E#63r22013100%
2026-08-15private E#63r31012100%
2026-08-15private E#63r43002100%
2026-08-15private E#63r53001100%
2026-08-18private F#16001100%
2026-08-26private G#141LOW0180%
2026-08-27wincrust#1311BLOCKING0150%
37 rounds5914123281%

Where the false positives landed

Not all wrong findings cost the same. A wrong LOW is noise you scroll past. A wrong BLOCKING tells someone to stop shipping over a bug that is not there, and it is the one that makes people uninstall a reviewer. Four of ours were BLOCKING, and they are the reason severity calibration is a standing piece of work rather than a solved problem.

severity of the false positivecount
BLOCKING4
MEDIUM6
LOW1
unlabelled3

The pattern in the table above is worth noticing too: on the pull requests that got a second round (r1r2), precision usually goes up. The first pass on an unfamiliar codebase is the noisy one.

Against another reviewer

We ran Kaniscope over 30 public pull requests that CodeRabbit had already reviewed, and lined the findings up by file and line (within ±8 lines counts as the same place). 263 findings across both.

bucketfindingsshare
both reviewers, same place2811%
theirs only12447%
ours only11142%

This is not a scoreboard, and we will not present it as one. Neither column is ground truth. A CodeRabbit finding is another model’s opinion, not a verified defect — so “theirs only” is a list of candidates, not a list of our misses, and “ours only” is as likely to be our false positive as their miss. Even the overlap proves little: two models share false positives routinely. The only thing here that was graded by a human is the table further up this page.

One signal in it does not depend on ground truth, though, and it does not flatter us: the shape of what each reviewer raised alone. By their own labels their 124 unique findings were 68 Major and 11 Critical. By ours, our 111 were 61 LOW and 7 HIGH. Whatever the truth of the individual findings, we are producing more low-severity material on the side where we are alone, and their unique findings cluster in functional correctness, data integrity and stability. That is the gap we are working on, and it is why this page exists in the state it is in rather than a tidier one.

Reproduce it

examples/bench.rs in the engine scores the reviewer against a corpus of pull requests with known issues and reports precision, recall, F1 and token cost, so a feature can be A/B’d by re-running with the flag flipped. It is a dry run — it posts nothing — and it needs your own model key. Blast radius, complexity metrics and the choice of backend were all measured this way. Blast radius, for the record, showed no recall improvement on well-named repositories; it stays on because it may still help on large monorepos, not because we measured it helping.

How this compares to a per-seat reviewer →