v1.20.0 — signal accuracy
Scoring changes for ordinary browsers. If you have tuned custom thresholds, re-check them — legitimate visitors now score lower.
Two signals no longer scored
webdriver_configurable and chrome_runtime_missing were reported as Playwright artifacts and scored in the headless category. Neither indicates automation.
Measured in Chrome 150, driven by a person, with navigator.webdriver === false:
signals reported: ["webdriver_configurable", "chrome_runtime_missing"]
webdriver_configurable— WebIDL definesnavigator.webdriveras configurable, so every browser reports the descriptor exactly as a patched one does.chrome_runtime_missing—chrome.runtimeis only exposed to a page when an extension declaresexternally_connectablematching it, so an ordinary Chrome on an ordinary site has none.
Both are now ignored, in the client and in all three servers — the servers too, because deployed clients will keep sending them for a while.
| before | after | |
|---|---|---|
| a genuine Chrome, headless category | 0.771 | 0 |
| a genuine Chrome, overall score | ~0.23 | 0.111 |
webdriver_deleted and playwright_globals are unchanged. Deleting the property or injecting framework globals is deliberate tampering that no shipped browser does, and automated browsers remain identified by navigator.webdriver being true.
Agent detection is unaffected: benchmark true-positive rate stays at 97.33%, with every captured agent class at 100%.
Touch form submissions
The submit classifier consulted only keydown and mousedown, within 100ms of the submit event. touchstart was recorded but never read, so a tap whose compatibility mousedown lagged was read as a programmatic submit — as was any click-to-submit slower than 100ms on a loaded device.
It now selects by time rather than by the last five events, considers touchstart, and allows 500ms.
Benchmark
bench/capture/normalize.js now reproduces a measured browser rather than an idealised one. It previously pinned the navigator.webdriver descriptor non-configurable and supplied a chrome.runtime object, which made the human panel cleaner than any real browser and left it unable to observe signals attached to those properties.
The rule is now recorded in the harness: anything pinned during normalization is a signal the panel cannot see, so pin as little as possible and pin it to measured values. All 22 personas were re-captured against the corrected normalization.
The proof-of-work pacing in the replayer is also more precise, so replayed solves land inside the server's accepted timing band rather than near its edges.
Human panel false-positive rate remains 0.00%, now measured on a panel that carries what a real browser carries.
Upgrading
No API or configuration changes. Scores move downward for legitimate visitors and are unchanged for automation.