Continuity Bench

How well do models detect continuity errors in novel-length fiction, and what does each detection cost?

The question

Can a cheap non-generative classifier, escalating to an LLM only when unsure, match full-context LLM accuracy on continuity errors for a fraction of the cost?

Not measured for Jev itself: no Jev run has been recorded, so no number on this page is Jev’s.

J +0.26495% CI +0.075 to +0.435

What is measured: with a stand-in in Jev’s slot, local_oracle_llama3.1:8b_contradiction clears zero — the only interval on this board that excludes it. That run is handed a hand-built state, so it is the architecture’s ceiling rather than a runnable pipeline. Whether Jev clears it is a separate question, and an unrun one.

Leaderboard

294 items from 31 novels, corpus continuity_v0.jsonl

How each run behaves

Recall against false-positive rate. The diagonal is guessing: distance above it is J, position along it is only how readily a run flags anything. Top-left is the good corner.

0.00.00.20.20.40.40.60.60.80.81.01.0guessingfalse-positive raterecalllaya_english - J 0.019, recall 0.236, FPR 0.217, localization 0.000, $0.00000 per passagelaya_englishalways_clean - J 0.000, recall 0.000, FPR 0.000, localization 0.000, $0.00000 per passagealways_cleanalways_error - J 0.000, recall 1.000, FPR 1.000, localization 0.020, $0.00000 per passagealways_errorlocal_llama3.1:8b_high - J 0.000, recall 0.981, FPR 0.981, localization 0.365, $0.00000 per passage

F1, for comparison

Dashed line: flagging every passage scores 0.667 while discriminating nothing. This is why F1 is not the headline.

0.000.200.400.600.801.00laya_englishlaya_english - F1 0.325, recall 0.236, FPR 0.217, localization 0.000, $0.00000 per passage0.325always_cleanalways_clean - F1 0.000, recall 0.000, FPR 0.000, localization 0.000, $0.00000 per passage0.000always_erroralways_error - F1 0.667, recall 1.000, FPR 1.000, localization 0.020, $0.00000 per passage0.667local_llama3.1:8b_highlocal_llama3.1:8b_high - F1 0.662, recall 0.981, FPR 0.981, localization 0.365, $0.00000 per passage0.662F1

No run has cost API money yet, so there is no cost axis to draw. The cost-vs-quality view appears once a paid or hosted run lands.

ModelTrivial floor
predictorJJ 95% CIrecallFPRAUCF1precisionlocalization$/passageitems
laya_english+0.019-0.139 to +0.176 ‡0.3250.5210.2360.2170.000$0.00000212
always_clean+0.000-0.025 to +0.025 •0.0000.0000.0000.0000.000$0.00000294
always_error+0.000-0.025 to +0.025 •0.6670.5001.0001.0000.020$0.00000294
local_llama3.1:8b_high+0.000-0.061 to +0.061 •0.6620.5000.9810.9810.365$0.00000212

• the interval is tight and contains zero: that run is measured to have no discrimination. ‡ the interval is wide and contains zero: that run establishes nothing either way, usually too few items.

How this is measured

Continuity errors are injected into passages of public-domain novels at a known location, and every injected passage ships with the same passage unedited as its control, so the false-positive rate is measured on exactly the same text as the recall. Splits are assigned per novel, so no novel appears in both dev and test.

The headline metric is J = recall − false-positive rate, not F1. On a balanced paired corpus, flagging every passage scores precision 0.500, recall 1.000 and therefore F1 0.667 while discriminating nothing at all — a real model has scored exactly that here. J is 0 for any such constant strategy and 1 for a perfect one.

Every run carries a 95% Wilson interval. An interval that is tight and contains zero means the run is measured to have no discrimination; one that is wide and contains zero means the run establishes nothing. Those are marked differently because they mean opposite things.

Before any model was run, the corpus was attacked with zero-cost heuristics, including one that pools novel-wide name statistics the way someone who downloaded the dataset would. The best reached J +0.066, so the benchmark is not simply leaking its own injection method.

Benchmark integrity

The strongest zero-cost heuristic reaches J +0.020. A benchmark whose errors could be found by a regex would not be measuring reasoning.

The diagnostics exploit the release format rather than the text: pair_diff_targeted reaches J +0.408 by diffing the two halves of a matched pair. That is why the published test split ships one half of each pair and holds its labels back.

The ceilings are fed a hand-built story state instead of one the pipeline extracted: local_oracle_llama3.1:8b_contradiction reaches J +0.264 that way. They bound what the architecture could do given perfect state, which is not what a deployed system has, so they are reported here rather than ranked.

predictorJJ 95% CIrecallFPRAUCF1precisionlocalization$/passageitems
pair_diff_targeted+0.408+0.307 to +0.4890.5801.0000.4080.0001.000$0.00000294
local_oracle_llama3.1:8b_contradiction+0.264+0.075 to +0.4350.6450.6230.6700.4060.437$0.00000212
pair_leak+0.150-0.008 to +0.300 ‡0.6180.5610.6870.5371.000$0.00000294
laya_oracle_english_contradiction+0.066-0.116 to +0.243 ‡0.5890.5260.6700.6040.169$0.00000212
trait_disagreement+0.020-0.018 to +0.058 •0.0401.0000.0200.0001.000$0.00000294
corpus_prior+0.007-0.117 to +0.130 ‡0.2700.5090.1840.1770.296$0.00000294
narration_person+0.000-0.160 to +0.160 ‡0.4950.5000.4900.4900.111$0.00000294
rarest_name+0.000-0.025 to +0.025 •0.6670.5001.0001.0000.211$0.00000294
singleton_name+0.000-0.093 to +0.093 •0.6460.5000.9120.9120.149$0.00000294

What this does not show