v0.2.0 — Watermark Inspector
Watermark Inspector
A third tab that runs every detector on one input and reports each separately, grouped into character, metadata and statistical layers, all through one result contract (js/detectors.js, exported verbatim by Copy JSON report):
status ∈ detected | clean | uncertain | unavailable | not_tested | not_applicable | error, plus confidence / score / threshold / evidence[] / note / requires_key / requires_model / local / heuristic / meta.
- Detector and cleaner are separate. Clean (Layer A) & re-inspect shows every detector before/after and says whether the statistical verdicts moved.
- A heuristic never says "detected". Stylometry (new
js/stylometry.js, port of upstreamscore_stylometry.py, parity-tested) is capped at uncertain. - "Unavailable" is not "clean". On the hosted page the statistical rows report unavailable and the Overall line says statistical watermarks were not tested.
Statistical sidecar (optional, local only)
sidecar/unmark_stat.py — Kirchenbauer/KGW and SynthID-Text detection with the reference transformers detectors, public experiment keys and the MIT Bayesian detector bundles from xlr8harder/synthid for Qwen/Qwen3-4B-Instruct-2507, plus demo generation with a chosen key. serve_local.py --stat-upstream … proxies it same-origin (/stat/*, key server-side, browser Authorization never forwarded). Off by default; see sidecar/README.md.
Parity anchors
service/scripts/text_unicode.py=cd21c5700184a6bb4a43089f546531a2692bf140413954ea9b93f4a67f1f3a5e(unchanged)service/scripts/image_meta.py=422dbbea5eff172b78a6f38ade753d11857d62ff4811b97084000062c5622e4a(unchanged)service/scripts/score_stylometry.py=cd3dae134d5f641120218fd525afd523d4a0bfb52d4d73c0e92dc04e3bcc6d59(new)
This repository still does not contain the upstream server; it is a client plus an optional local sidecar.