Benchmarks
Every number on this page is reproducible from the repository (python -m cypherquill.judge.train, python -m benchmarks.loop_bench, python -m benchmarks.speed_bench, python -m benchmarks.report). All authors and models labelled "held-out" or "unseen" were excluded from training.
Headline: Your Style on the live product
3 held-out human writers (Reddit/blog). Voice imported from 20 of their own posts. 3 genuine ChatGPT/GPT-4 drafts rewritten per round. Feedback between rounds: accept the best round-1 output, thumbs-down the worst. Test accounts deleted afterwards. Run on https://cypherquill-mvp.fly.dev (production config, commercial-safe judge, trial plan -> claude-sonnet-5-5 writes, claude-haiku-5-5 checks), 2026-11-09.
| Text | Reads like the writer โ | Reads like AI โ |
|---|---|---|
| The ChatGPT draft, unchanged | 6 | 67 |
| Rewritten: voice built from the writer's posts only | 90 | 2.6 |
| Rewritten after one round of feedback (accept the best, ๐ the worst) | 94 | 3.1 |
n=9 drafts per round. Directional evidence that feedback helps, not a significance test. For reference, held-out authors' own unseen writing scores a median of 95 against their own voice, and different authors score a median of 7.
Judge v0 โ authorship verification (held-out authors)
Training data: 14,107 passages by 406 authors across blogs, Reddit, IMDb reviews, Reuters news and Project Gutenberg books. Authors are split into encoder-fit (55%), head-fit (15%) and held-out test (30%, 125 authors). Negatives are drawn from the same domain, so the judge can't win on genre.
Task: is query passage q (~250 words) by the author of a profile built from k other passages?
| Profile size k | EER โ | AUC โ | Baseline EER (char n-gram cosine) |
|---|---|---|---|
| 1 | 0.310 | 0.750 | 0.349 |
| 3 | 0.229 | 0.853 | โ |
| 5 | 0.212 | 0.866 | โ |
| 10 | 0.179 | 0.898 | 0.289 |
By domain (k=10):
| Domain | EER | AUC |
|---|---|---|
| blog | 0.160 | 0.914 |
| books | 0.182 | 0.901 |
| news | 0.241 | 0.814 |
| 0.181 | 0.900 | |
| reviews | 0.150 | 0.932 |
Ablation (k=10): learned-encoder cosine alone gives EER 0.327 (LDA view) and 0.295 (SVD view). The authorship head, which fuses four embedding views with grouped stylometric feature distances, brings it to 0.179. The product thresholds come from the head-fit split: "elevated" link risk at p โฅ 0.52 (EER point) and "high" at p โฅ 0.89 (1% false-positive rate).
Judge v0 โ model-likeness (LLM-ness) head
Protocol. Training uses human text plus generations from: cohere, cohere-chat, deepseek/deepseek-v4-flash, deepseek/deepseek-v4-pro, google/gemini-3.6-flash, google/gemini-3.7-flash, mistral, mpt, qwen/qwen3.6-35b, qwen/qwen3.8-27b, qwen/qwen3.8-max. Every other model is unseen, including whole vendors that never appear in training: OpenAI (GPT-3/3.5/4 and the 2026 luna/sol/gpt-5.6 models), Anthropic, Meta, Moonshot, xAI, Zhipu and NVIDIA. Each model is scored against matched human text from the same dataset or domain, so the head can't win on genre. The head ensembles an interpretable 155-feature model with a topic-masked char 2-5grams model. Sparse c and blend weight chosen on the calibration split of seen models only.
Mean AUC across unseen models: 0.928 (0.975 for models with n โฅ 30). Seen models on held-out prompts: pooled AUC 0.971.
| Unseen model | AUC โ | AUC dense-only | Recall@0.5 | n | Compared against |
|---|---|---|---|---|---|
llama-chat | 0.996 | 0.996 | 1.00 | 301 | RAID human (same prompts) |
gpt4 | 0.994 | 0.995 | 0.99 | 306 | RAID human (same prompts) |
mistral-chat | 0.993 | 0.991 | 0.99 | 301 | RAID human (same prompts) |
moonshotai/kimi-k3 | 0.988 | 0.977 | 0.95 | 300 | rasbt/human-vs-ai-50k human (same dataset) |
openai/gpt-5.6-luna-pro | 0.988 | 0.957 | 0.98 | 162 | Reddit human (same domain) |
openai/luna-medium | 0.986 | 0.975 | 0.92 | 300 | rasbt/human-vs-ai-50k human (same dataset) |
z-ai/glm-5.3 | 0.983 | 0.937 | 0.98 | 166 | Reddit human (same domain) |
mpt-chat | 0.982 | 0.977 | 0.97 | 293 | RAID human (same prompts) |
chatgpt | 0.978 | 0.974 | 0.95 | 307 | RAID human (same prompts) |
openai/sol-medium | 0.963 | 0.955 | 0.78 | 229 | rasbt/human-vs-ai-50k human (same dataset) |
gpt3 | 0.958 | 0.970 | 0.90 | 119 | RAID human (same prompts) |
nvidia/nemotron-3.5-lightning | 0.938 | 0.879 | 0.90 | 154 | Reddit human (same domain) |
anthropic/claude-haiku-4-5 | 0.937 | 0.965 | 0.92 | 12 โ ๏ธ small n | textsightai/ai-text-detection-benchmark-2026 human (same dataset) |
x-ai/grok-4.6 | 0.927 | 0.743 | 0.83 | 174 | Reddit human (same domain) |
openai/gpt-oss-120b | 0.792 | 0.745 | 0.33 | 12 โ ๏ธ small n | textsightai/ai-text-detection-benchmark-2026 human (same dataset) |
openai/gpt-4.1 | 0.739 | 0.687 | 0.50 | 12 โ ๏ธ small n | textsightai/ai-text-detection-benchmark-2026 human (same dataset) |
anthropic/claude-opus-5 | 0.637 | 0.454 | 0.17 | 12 โ ๏ธ small n | textsightai/ai-text-detection-benchmark-2026 human (same dataset) |
Seen models (held-out prompts):
| Model | AUC | Recall@0.5 | n |
|---|---|---|---|
google/gemini-3.6-flash | 0.997 | 0.99 | 70 |
qwen/qwen3.6-35b | 0.997 | 0.99 | 71 |
qwen/qwen3.8-max | 0.996 | 1.00 | 33 |
google/gemini-3.7-flash | 0.993 | 0.98 | 43 |
deepseek/deepseek-v4-flash | 0.987 | 0.91 | 70 |
deepseek/deepseek-v4-pro | 0.972 | 0.97 | 29 |
cohere-chat | 0.953 | 0.89 | 303 |
cohere | 0.950 | 0.87 | 116 |
mistral | 0.925 | 0.85 | 119 |
mpt | 0.903 | 0.78 | 118 |
False positives on genuine human writing from held-out authors. These authors are never seen by any head. This is the number that matters for a steering signal:
| Domain | Human passages flagged โฅ0.5 โ | Median score | n |
|---|---|---|---|
| blog | 2.6% | 0.006 | 192 |
| books | 7.1% | 0.013 | 56 |
| news | 1.6% | 0.026 | 64 |
| 12.5% | 0.083 | 112 | |
| reviews | 0.0% | 0.001 | 76 |
Human false-positive rate at 0.5: 0.080 overall (authorship-human: 0.05, raid: 0.15, rasbt/human-vs-ai-50k: 0.04, textsightai/ai-text-detection-benchmark-2026: 0.11).
Strongest interpretable features (dense-model coefficients; positive = more model-like):
para_len_mean (-1.93), lower_start_rate (-1.07), word_len_mean (+1.05), semicolon_rate (-0.85), heading_rate (+0.74), sent_len_mean (-0.69), p3_rate (+0.64), fw_a (+0.63), opener_diversity (-0.61), sent_bin_1_5 (-0.59), sent_bin_6_10 (-0.58), hapax_rate (-0.51)
> How to read this. Model-likeness is a style signal that we use to steer writing toward a human register. It isn't a forensic AI detector, and we don't sell it as one. The newest models in the strongest families (for example Claude Opus 5) are the hardest to tell from human prose. Human writing sometimes reads as model-like too. That's fine for steering a rewrite, and it would be wrong for accusing anyone.
Commercial-safe judge (production default)
models/judge-v0-cs is trained only on sources whose terms allow commercial use: Reddit (webis/tldr-17, CC BY 4.0), Project Gutenberg (public domain), and the RAID and 2026 LLM sets minus IMDb-derived rows. It drops the Blog Authorship Corpus, IMDb62 and Reuters C50, which are research or non-commercial only. To make up for them it adds 209 extra Reddit and Gutenberg training authors (scripts/data/fetch_commercial_extra.py) and 1200 passages of formal human prose from the Wikipedia 2023-11 dump (CC BY-SA, scripts/data/fetch_formal_human.py). The Docker image uses it by default (CQ_JUDGE_DIR).
Head-to-head on the same held-out authors, all 5 domains. Every variant uses one author-to-split assignment, so no test author is ever trained on. Blog, news and reviews are entirely out-of-domain for the commercial-safe judge (python -m benchmarks.compare_judges).
| Metric | Research judge (judge-v0) | Commercial-safe (judge-v0-cs) |
|---|---|---|
| Authorship EER, k=1 โ | 0.302 | 0.312 |
| Authorship EER, k=10 โ | 0.200 | 0.240 |
| LLM-ness mean AUC, 17 unseen models โ | 0.928 | 0.946 |
| Human false positives, held-out blog โ | 2.6% | 8.3% |
| Human false positives, held-out books โ | 7.1% | 7.1% |
| Human false positives, held-out news โ | 1.6% | 14.1% |
| Human false positives, held-out reddit โ | 12.5% | 2.7% |
| Human false positives, held-out reviews โ | 0.0% | 0.0% |
| Human false positives, mean โ | 4.8% | 6.4% |
The commercial-safe judge spots AI-style writing slightly better. It gives up some authorship precision, and it still over-flags formal news-wire prose, because it has no commercially licensed newswire to learn from. Licensed news and blog corpora, or design-partner data, are the first data task after launch.
Rewrite loop โ claude-cli (sonnet / checks: haiku) ยท steered and scored by the research judge (judge-v0)
Held-out authors only. 28 documents, generated 2026-11-08T15:44:03. Each document is rendered four ways: unchanged, a plain "rewrite this" LLM call, our prompt with no judge feedback (1 pass), and the full judge-guided loop (โค3 passes).
Voice transfer between two human writers (author A's text โ B's voice; stress test) โ n=12
| Variant | Distance from A โ | Consistency with B โ | Model-likeness โ | Facts kept | All goals met |
|---|---|---|---|---|---|
| Source (unchanged) | 22.6 | 8.5 | 16.3 | โ | 0.00 |
| Raw LLM rewrite | 71.9 | 11.6 | 41.0 | 0.96 | 0.08 |
| Proselike draft only | 82.7 | 32.2 | 13.1 | 0.87 | 0.17 |
| Proselike loop | 89.4 | 30.5 | 6.3 | 0.87 | 0.33 |
Loop: 2.76 passes per paragraph on average (cap 3), 7.8 model calls per document, meaning check passed on 75% of documents, 23.7 s per document.
Anonymize (author A's text) โ n=8
| Variant | Distance from A โ | Distinctiveness โ | Model-likeness โ | Facts kept | All goals met |
|---|---|---|---|---|---|
| Source (unchanged) | 25.2 | 58.1 | 0.6 | โ | 0.12 |
| Raw LLM rewrite | 74.4 | 31.1 | 27.9 | 0.85 | 0.38 |
| Proselike draft only | 78.2 | 41.5 | 20.1 | 0.92 | 0.50 |
| Proselike loop | 78.0 | 41.8 | 14.7 | 0.93 | 0.62 |
Loop: 2.82 passes per paragraph on average (cap 3), 12 model calls per document, meaning check passed on 88% of documents, 21.1 s per document.
Your Style: AI-written draft โ the writer's own voice (Lanes A & B) โ n=8
| Variant | Reads like the writer โ | Reads like AI โ | Facts kept | All goals met |
|---|---|---|---|---|
| Source (unchanged) | 6.3 | 79.5 | โ | 0.00 |
| Raw LLM rewrite | 7.1 | 76.2 | 0.93 | 0.00 |
| Proselike draft only | 33.0 | 48.5 | 0.93 | 0.25 |
| Proselike loop | 32.9 | 34.4 | 0.90 | 0.38 |
Loop: 2.62 passes per paragraph on average (cap 3), 5.2 model calls per document, meaning check passed on 100% of documents, 17.9 s per document.
Unit economics (measured tokens, list prices)
Per 1,000 source words the loop made 38 model calls and sent about 89,503 system-prompt tokens (mostly cache reads), 19,699 uncached input tokens and 5,725 output tokens. Estimated from prompt sizes; system prompt cached within a document; judge scoring is local cpu (~$0).
| Model tier | $/1k words | $/user/month @50k words | Gross margin Solo $29 | Gross margin Pro $49 |
|---|---|---|---|---|
| opus-5.5 write + haiku-5.5 checks (default) | 0.2443 | 12.21 | 58% | 75% |
| sonnet-5.5 write + haiku-5.5 checks | 0.1297 | 6.48 | 78% | 87% |
| haiku-5.5 everything | 0.0085 | 0.42 | 98% | 99% |
Judge scoring runs on our own CPU and is effectively free (see speed below), so model spend is the only variable cost.
Rewrite loop โ claude-cli (sonnet / checks: haiku) ยท steered and scored by the commercial-safe judge (judge-v0-cs)
Held-out authors only. 20 documents, generated 2026-11-08T16:47:46. Each document is rendered four ways: unchanged, a plain "rewrite this" LLM call, our prompt with no judge feedback (1 pass), and the full judge-guided loop (โค3 passes).
Voice transfer between two human writers (author A's text โ B's voice; stress test) โ n=8
| Variant | Distance from A โ | Consistency with B โ | Model-likeness โ | Facts kept | All goals met |
|---|---|---|---|---|---|
| Source (unchanged) | 11.3 | 12.1 | 17.0 | โ | 0.12 |
| Raw LLM rewrite | 63.0 | 8.1 | 32.9 | 0.89 | 0.00 |
| Proselike draft only | 79.3 | 28.4 | 4.6 | 0.88 | 0.38 |
| Proselike loop | 77.3 | 31.0 | 6.0 | 0.85 | 0.25 |
Loop: 2.91 passes per paragraph on average (cap 3), 8 model calls per document, meaning check passed on 75% of documents, 23.7 s per document.
Anonymize (author A's text) โ n=6
| Variant | Distance from A โ | Distinctiveness โ | Model-likeness โ | Facts kept | All goals met |
|---|---|---|---|---|---|
| Source (unchanged) | 1.4 | 35.9 | 4.9 | โ | 0.00 |
| Raw LLM rewrite | 52.3 | 26.6 | 27.8 | 0.88 | 0.33 |
| Proselike draft only | 77.2 | 25.4 | 19.0 | 0.90 | 0.67 |
| Proselike loop | 77.4 | 21.2 | 19.2 | 0.90 | 0.83 |
Loop: 2.50 passes per paragraph on average (cap 3), 6.7 model calls per document, meaning check passed on 100% of documents, 16.4 s per document.
Your Style: AI-written draft โ the writer's own voice (Lanes A & B) โ n=6
| Variant | Reads like the writer โ | Reads like AI โ | Facts kept | All goals met |
|---|---|---|---|---|
| Source (unchanged) | 9.6 | 82.8 | โ | 0.00 |
| Raw LLM rewrite | 11.1 | 70.2 | 0.91 | 0.00 |
| Proselike draft only | 44.5 | 39.0 | 0.92 | 0.33 |
| Proselike loop | 52.3 | 34.1 | 0.91 | 0.33 |
Loop: 2.67 passes per paragraph on average (cap 3), 5.3 model calls per document, meaning check passed on 100% of documents, 18.1 s per document.
Unit economics (measured tokens, list prices)
Per 1,000 source words the loop made 34 model calls and sent about 84,668 system-prompt tokens (mostly cache reads), 18,570 uncached input tokens and 5,656 output tokens. Estimated from prompt sizes; system prompt cached within a document; judge scoring is local cpu (~$0).
| Model tier | $/1k words | $/user/month @50k words | Gross margin Solo $29 | Gross margin Pro $49 |
|---|---|---|---|---|
| opus-5.5 write + haiku-5.5 checks (default) | 0.2469 | 12.34 | 57% | 75% |
| sonnet-5.5 write + haiku-5.5 checks | 0.1303 | 6.51 | 78% | 87% |
| haiku-5.5 everything | 0.0085 | 0.42 | 98% | 99% |
Judge scoring runs on our own CPU and is effectively free (see speed below), so model spend is the only variable cost.
Loop design iterations (same 28 held-out cases)
| Version | Persona goals met | Anonymize goals met | Voice goals met |
|---|---|---|---|
| v1_serial-revision | 0.33 | 0.38 | 0.25 |
| current: judge-informed drafting, best-of-2 judge reranking, minimal-edit revisions, house-voice anonymize | 0.33 | 0.62 | 0.38 |
Voice stability over time โ claude-cli:sonnet
Automated stand-in for the spec's "week-1 vs week-8" reader test. Week 1 renders fresh sources and publishes them to history; week 8 renders different sources against the grown history. A cross-validated classifier (judge embeddings + 155 features) then tries to tell the batches apart. โ0.5 means indistinguishable.
| Comparison | Classifier accuracy |
|---|---|
| Persona week 1 vs week 8 | 0.45 |
| Control: same human, early vs late passages | 0.70 |
| Control: two different humans | 1.00 |
Persona consistency gauge: week 1 43, week 8 42, against 10 for the unrendered source passages. 2 personas. Small samples, so treat ยฑ0.15 as noise.
Judge speed (CPU only)
Machine: Apple M1, Darwin, single process. Artifact size: 38.4 MB. Load: 0.12 s.
- Full score report (3 gauges + tells + portrait, ~238 words): p50 11.5 ms, p95 15.7 ms
- Fingerprint from 200 samples: 1.43 s
- Batch model-likeness throughput: 147.3 texts/s on one process
Known limitations
- Short text is hard. Single ~250-word passage vs. single passage gives EER โ0.3. Profiles of 10+ samples are much better, which is why Real Voice asks for 30โ200 samples. Gauges show a reliability label below 150 words.
- English only (spec ยง5 cut list).
- Model coverage. The unseen-model set includes 2025โ26 frontier models from public datasets. The newest vendors change quickly, so retrain monthly (
python -m cypherquill.judge.train). - Human blind tests. The spec's "week-1 vs week-8" human readers test runs in production through
/lineupand the in-app Blind check. The live accuracy is reported at/api/admin/metrics(blind_lineup.accuracyagainstchance). - Remote large encoder (
docs/REMOTE_MODELS.md) is the expected path to EER โ0.1. It is a placeholder in this build.