Reports

How we run detection tests.

This page has no date in its URL on purpose. It describes the method every published run follows, so a run can be read, disputed and repeated without reading the run before it.

What a run is

A run is one dated session in which a set of browsers visits a set of detectors through a set of proxy exits, and the outcome of every visit is written down, including the visits that failed and the ones our own tooling broke. Runs are published monthly. Each one is a sample of a moving target, not a certification: detectors change, addresses change reputation, and a result from last month is evidence about last month.

Everything a run touches is public and none of it requires anyone's cooperation, so the whole thing is repeatable by a reader with a free account and an afternoon.

Environment

Subjects

A single-product screenshot is not a measurement. Every run that compares anything states what it compared against, and the baseline is chosen to be the thing readers actually weigh us against rather than the thing we look best next to. In practice that means an open-source automation stack with a stealth plugin: free, widely used, and specifically built to hide automation tells.

The baseline is left unhelped on purpose. No timezone override, no locale override, no proxy wiring borrowed from us. Handing it our configuration would measure our configuration twice. Where the baseline leaks something that could be fixed by hand, the run says so: the question is who keeps that list current across browser releases, not whether a fix exists.

Result vocabulary

Five values, and they are not interchangeable. Collapsing them into pass/fail is what turns a measurement into marketing.

ValueMeaning
passThe visit completed and the value it produced was consistent with the identity the profile announced.
failThe visit completed and the value contradicted the announced identity. A leak, not a wall.
blockedThe target refused the visit: an HTTP 403, a challenge page, or an interstitial instead of content.
inconclusiveThe check ran but produced no readable result. Recorded as a gap in our measurement, never scored as a pass.
errorThe harness or the browser died before a result existed. Nothing was measured.

Two consequences worth stating. A check our harness broke is inconclusive or error, never quietly dropped and never rounded up to a pass. And a detector that let a browser through while that browser announced a contradiction is recorded as both: the detector passed it, the coherence check failed it.

Proxies, and why some detectors need a different design

The exit address is a variable, and on some checks it is the dominant one. Anything that scores address reputation cannot be measured by sending two browsers through the same address minutes apart: the second visitor from an address that was just used on the same target is in a different situation from the first, and a single burned address blocks both arms and looks like agreement.

So a stateful detector gets a paired design:

Stateless checks do not need this and are run through a single shared exit, which is why one run can carry segments with different designs. The dataset keeps them apart; averaging across them would produce a number nobody measured.

Timezone, locale and geolocation follow the exit address automatically in our product. Where a subject's timezone or language disagrees with its exit, that is a recorded result, not a configuration mistake we corrected before publishing.

Known biases

Corrections

Retractions stay on the page and in the data. When a later measurement contradicts something an earlier run asserted, the original paragraph is left standing and the correction is written next to it, and the machine-readable file carries the same retraction in its notes. A report that quietly edits away the parts that turned out wrong is worth less than one that keeps them.

The data files

Every run publishes the same three things: the prose, a JSON file, and a CSV of the same rows. Field names are fixed once published; a correction ships as a new file rather than a silent rewrite.

PathWhat it is
/reports/<run>The written report for one run.
/reports/<run>/data.jsonThat run's results, one object per check.
/reports/<run>/data.csvThe same rows, flattened for a spreadsheet.
/reports/dataEvery run, the field reference, and the licence.
/reports/all.jsonEvery run in one file.
/api/v1/reportsThe same data over a no-key public API.

All of them are served with Access-Control-Allow-Origin: *, so they can be fetched from your page rather than retyped into it. The field-by-field reference lives on the dataset page.

Licence

The results and this method page are published under CC BY 4.0. Use them anywhere, including commercially, including in a comparison that disagrees with us. The one condition is attribution, and every run page carries a ready-to-paste citation at the bottom.

Most recent run: Detection run, August 2026.