Repository navigation
v0.3.1
What is new since 0.3.0
Fail a CI job on a finding. deviant-scan --fail-on-findings exits 1 when the scan reports a finding. Leads from --inventory do not count, a usage error still exits 2, and without the flag the exit status is 0, so adding it to a job cannot break the job by surprise. docs/using-in-ci.md explains the statuses and gives a workflow with pinned actions.
A fix found by checking against real bugs. In a group where nearly every item follows the rule, the exceptions are now listed as leads however many there are. Before, a fixed limit of 8 hid them: in a project where 174 of 199 actions were pinned, the 25 that were not never appeared. The limit still applies below 85% agreement.
Measured on real bugs, not planted ones. The scanner alone, with no AI, was run on the commit just before each of 35 fixes from public history. It pointed at 25 (22 before the fix above): all 13 unpinned actions, all 3 missing timeouts, 8 of 12 missing permissions blocks, and 1 of 7 missing-auth bugs. The missing-auth result is low for a reason the docs now state: a bug that every similar item shares has no protected sibling to compare with, so this method cannot see it. See bench/results/real-bugs.md, and bench/real_bug_recall.py to reproduce it.
Tests and docs. Property-based tests now check, over thousands of generated inputs, that results do not depend on the order items arrive in, that the text escaping leaves no control characters, and that neither detector crashes on arbitrary bytes or text. The docs record a run of the Claude skill against a repository built to give it instructions: it followed none of them.
Benchmarks, stated plainly
On a sealed fresh set of 99 planted bugs, Claude reading the code alone found 45% and Claude with the Deviant skill found 35%. Precision is not measured. See bench/results/fresh-set-benchmark.md.