Every finding cites the rule that fired.
AI-text forensics in Rust. It runs in this tab, nothing you paste leaves the page, and below threshold it refuses to guess.
Paste anything. Watch it get read.
Three verbs on one engine. lint names the tells, fix rewrites them without a model in the loop, and who attributes the text to a model family or says it cannot. All of it compiled to wasm and running on your machine.
The numbers, as measured.
The catalog is four 2026 model families harvested through one gateway, about 300 samples each, held out by prompt so no prompt lands on both sides of the split. The threshold is derived from that split rather than picked. Precision is the fixed point, and coverage is whatever falls out of it.
The catalog is the deliverable.
Mining produces one row per feature with a column per family, so habits read straight across. Here is how often each family reaches for the word honest, per thousand words of its own output, read out of the catalog at build time rather than typed into this page.
It never returns a percentage, and it never calls a person a machine.
A single tell proves nothing. Clustering is the only honest signal, so lint reports a density and a band rather than a verdict.
Attribution has the same discipline built in. A five-way classifier must pick one of five, whatever you show it, which is why the first version named a model for 45% of genuine human writing. The catalog now carries a rejection class, and text that ranks into it gets no match at any confidence.
Closed-set attribution is stylometric and probabilistic. It degrades on short text, on edited text, and on models that were never harvested. It is a forensic aid with cited evidence, not proof of authorship.