Typed decision models as code-review judges
Jev and every open-source Jev-class alternative, asked the same typed questions about the same 150 review cases, scored against verdicts fixed before any of them ran.
Two things came out of it that matter more than the leaderboard.
What was measured
A code-review pipeline has five reviewer roles, each answering a bounded question about a piece of state. For each role there is a corpus of thirty cases whose verdict was fixed before any system ran. Cases were authored by hand; none is public, so no system could have trained on them.
| role | state the judge sees | the question |
|---|---|---|
| test reviewer | the tests a writer produced, the task brief, the acceptance criteria | does each test prove a requirement, or merely run? |
| spec alignment | a diff, the spec, the accumulated change | does the change drift from or contradict the spec? |
| task alignment | a diff, the task brief, the builder's report | does the change do what the task said, and only that? |
| code review | a diff with context, the brief, the report | what defects does the diff contain? |
| plan review | a plan of tasks, the spec | per lens: sign off, defer, ask, or block? |
Each corpus has three kinds of case, ten of each. A positive is clean; any blocking or major finding is a false fail. A negative plants a defect at a named path. A pressure case plants one and argues for it in the brief or a comment; the judge must flag it anyway.
How the questions were chosen
Jev-class systems take a state and typed questions, a yes/no with a probability, a choice over named options with a distribution, an ordered score, and return no text. The rule used to turn each reviewer prompt into questions: the judgement the schema asks for becomes the question; lenses become secondary questions.
An earlier attempt that asked only the lens questions produced honest 0.5s and never asked for the judgement. For the test reviewer the per-test choice is the judgement; the lens is context.
How the state was built
Text-generating judges get their inputs by reference, file paths and tools to open them. A typed model has no tools, so the state must carry the content. Every referenced file is inlined under a neutral name and the directory is removed from the text; that is the leak fix. The file a test id names is inlined too. For small budgets the inputs go before the prompt text, so what a 512-token window drops is boilerplate, not evidence. Systems with a hard limit get a character cap after that ordering; code tokenizes at about 2.3 characters per token.
Every exchange is recorded with the questions, the raw per-option probabilities, the model, the endpoint and the SHA-256 of the state; the state text is stored once by hash. That is what allowed the replay below: identical bytes to every system.
How answers were graded
A positive passes with no finding at or above major. A negative or pressure case passes with a finding on the planted path at or above the floor, or, for a judge that cannot name a path, a verdict of fail.
For the test-review role the grader originally accepted any major finding as a catch, including a pathless lens answer at 0.5, and counted the same against clean cases. It now reads the per-test labels and findings that name a path; a pathless lens answer counts neither way. The change moved Jev 30 to 29, Nimble 20 to 24, Kev 4B 26 to 17, Laya 24 to 20. The diff-based roles keep the original rule, which still admits the flag-everything route; read their clean-case column, not the score.
The systems
| system | what it is | how it ran |
|---|---|---|
| Claude judge | the pipeline's text-generating reviewer, with tools | inputs by reference, as in production |
| Jev (TypeSafe) | hosted decision model | API, full inlined state |
| Laya | ModernBERT-large, 421M | in-process; 512-token budget, evidence first |
| Von | ModernBERT-large, 395M | in-process |
| Kev 0.8B | Qwen3.5-0.8B with a pointer head | local server on MLX |
| Kev 4B | Qwen3.5-4B with a pointer head | the author's Hugging Face Space |
| Rizzo Flow 1.7B | Spark-X2.5 over llama.cpp | local server on MLX; the 4B took 120 s a question |
| SemIf | option logits of a frozen base LLM, no decision model | batch scorer over Qwen3.5-0.8B on MLX |
| Bespoke Nimble 9B | candidate-logit scoring, 9B | Hugging Face Space; 2,048-token limit, state capped at 3,400 characters |
| NanoJev | Qwen3-0.6B with decision heads | not run: requires a CUDA device; no Space, no endpoint |
| CLM-8B | frozen Qwen3-8B encoder with ~20M-parameter contrastive heads, Stanford and NVIDIA, released 2026-09-23 | local 8-bit MLX port of the encoder, upstream clm-serve; 8,192-token window; added 2026-09-27 |
Results
Test reviewer, the role every system ran
Accuracy is of the per-test probability against the known kind; 0.67 is what a constant "defect" answer earns on a 20 to 10 split. Read the last column: a judge that reads the case has a low first number and high second and third.
| system | graded | clean passed | accuracy | Brier | P(defect) clean → planted → argued |
|---|---|---|---|---|---|
| Claude judge | 30/30 | 10/10 | — | — | — |
| Jev | 29/30 | 10/10 | 0.97 | 0.05 | 0.15 → 0.88 → 0.93 |
| Nimble 9B, 3,400 chars | 24/30 | 9/10 | 0.83 | 0.15 | 0.14 → 0.75 → 0.81 |
| Nimble 9B, test + brief only | 25/30 | 9/10 | 0.83 | 0.16 | 0.11 → 0.74 → 0.72 |
| Laya | 20/30 | 6/10 | 0.67 | 0.21 | 0.68 → 0.69 → 0.72 |
| Kev 0.8B | 20/30 | 0/10 | 0.67 | 0.25 | 0.84 → 0.86 → 0.88 |
| SemIf | 20/30 | 0/10 | 0.67 | 0.23 | 0.78 → 0.78 → 0.79 |
| Kev 4B, test + brief only | 18/30 | 9/10 | 0.63 | 0.34 | 0.15 → 0.35 → 0.51 |
| Kev 4B | 17/30 | 8/10 | 0.57 | 0.34 | 0.21 → 0.44 → 0.56 |
| Von | 10/30 | 10/10 | 0.67 | 0.23 | 0.59 → 0.58 → 0.58 |
| Rizzo Flow 1.7B | 10/30 | 10/10 | 0.33 | 0.45 | 0.19 → 0.19 → 0.19 |
The other four roles
| role | Jev | Laya | Kev 4B | Nimble 9B |
|---|---|---|---|---|
| spec alignment | 30/30 · clean 10 · acc 0.80 | 20/30 · clean 0 · acc 0.67 | 10/30 · clean 10 · acc 0.33 | 25/30 · clean 5 · acc 0.37 |
| task alignment | 26/30 · clean 10 · acc 0.83 | 26/30 · clean 7 · acc 0.63 | 10/30 · clean 10 · acc 0.33 | 23/30 · clean 10 · acc 0.53 |
| code review | 26/30 · clean 6 · acc 0.90 | 28/30 · clean 8 · acc 0.67 | 21/30 · clean 1 · acc 0.33 | 21/30 · clean 1 · acc 0.60 |
| plan review | 8/30 · clean 2 · acc 0.33 | 2/30 · clean 2 · acc 0.33 | 10/30 · clean 10 · acc 0.33 | refused: over 2,048 tokens |
Laya's 28 of 30 on code review against Jev's 26 is the flag-everything route the diff-role grader still allows: its probability of a defect is 0.73 on clean diffs and 0.70 on defective ones. Kev 4B on the diff roles puts 0.03 to 0.15 on everything, clean or not. Plan review is the role neither reads, and its grader wants a block on a named task id, which a per-lens judge cannot give.
Head to head on identical questions: Jev and Laya
All 449 recorded exchanges were replayed through both in one sitting, 1,834 questions each, byte-identical state and questions.
| role, state | Jev accuracy | Jev Brier | Jev P(defect) clean → defective | Laya accuracy | Laya Brier | Laya P(defect) clean → defective |
|---|---|---|---|---|---|---|
| test reviewer, full | 0.93 | 0.07 | 0.18 → 0.88 | 0.67 | 0.22 | 0.71 → 0.73 |
| test reviewer, minimal | 0.77 | 0.12 | 0.16 → 0.79 | 0.67 | 0.26 | 0.85 → 0.84 |
| task alignment | 0.89 | 0.09 | 0.23 → 0.76 | 0.64 | 0.23 | 0.62 → 0.61 |
| code review | 0.89 | 0.11 | 0.37 → 0.75 | 0.67 | 0.24 | 0.77 → 0.75 |
| spec alignment | 0.72 | 0.18 | 0.70 → 0.91 | 0.67 | 0.23 | 0.70 → 0.68 |
| plan review | 0.33 | 0.36 | 0.14 → 0.28 | 0.33 | 0.42 | 0.22 → 0.23 |
The 3,306 recorded questions, replayed through the two kept models
Nine systems answered 3,306 questions in total, most of them the same question about the same case asked of different systems. Deduplicated by state hash and question set, that is 449 unique exchanges and 1,834 unique questions, each case in up to three recorded state variants. Both kept models, Jev and Laya, answered every one in one sitting on byte-identical input.
| role | choice: same label | yes/no: same side | mean yes/no gap |
|---|---|---|---|
| test reviewer | 36 / 128 · 28% | 79 / 120 · 66% | 0.20 |
| task alignment | 96 / 180 · 53% | 115 / 180 · 64% | 0.20 |
| code review | 44 / 90 · 49% | 225 / 360 · 63% | 0.20 |
| spec alignment | 51 / 178 · 29% | 170 / 178 · 96% | 0.15 |
| plan review | 95 / 420 · 23% | — | — |
| all | 32% | 70% | 0.19 |
All 1,834 questions again, with Claude as the reference
The replay above shows Jev and Laya disagree; it does not say who is right. So a third system answered the same 449 exchanges: Claude Opus 5, the model behind the text-generating judge, asked the identical typed questions about the identical state bytes, through the Claude Code CLI with a JSON schema enforcing the answer shape.
Every Claude answer in this section came from claude-opus-5 (Claude Opus 5), requested by that ID on every call, run on 2026-09-25. It is not Claude Opus 5.5 or Claude Fable 5.1, the newer and more capable Claude models available on that date; they were not tested, and they may score higher. Read the Claude numbers as Opus 5's, not as the best Claude can do.
Of the 1,834 questions, 726 have a known right answer, because the case kind fixes it: the 269 defect yes/no questions, the 269 verdicts, the 128 per-test labels, and for plan review whether any lens says block, 60 in all. Lens questions and misalignment kinds have no ground truth and are not scored. Accuracy is the probability against 0.5; Brier is the squared error of the probability, lower is better.
| role | graded | Claude acc / Brier | Jev acc / Brier | Laya acc / Brier |
|---|---|---|---|---|
| test reviewer | 128 | 0.95 / 0.04 | 0.90 / 0.08 | 0.63 / 0.26 |
| task alignment | 180 | 0.97 / 0.04 | 0.92 / 0.06 | 0.66 / 0.23 |
| code review | 180 | 0.92 / 0.07 | 0.88 / 0.10 | 0.68 / 0.23 |
| spec alignment | 178 | 0.88 / 0.08 | 0.76 / 0.16 | 0.67 / 0.24 |
| plan review | 60 | 0.75 / 0.18 | 0.75 / 0.18 | 0.33 / 0.36 |
| all | 726 | 0.915 / 0.066 | 0.854 / 0.107 | 0.634 / 0.249 |
Probability of a defect, clean → defective
A system that reads the case has a low first number and a high second.
| role | Claude | Jev | Laya |
|---|---|---|---|
| test reviewer | 0.22 → 0.96 | 0.15 → 0.86 | 0.75 → 0.76 |
| task alignment | 0.21 → 0.90 | 0.15 → 0.83 | 0.60 → 0.59 |
| code review | 0.38 → 0.94 | 0.33 → 0.78 | 0.69 → 0.69 |
| spec alignment | 0.46 → 0.96 | 0.61 → 0.90 | 0.68 → 0.66 |
| plan review | 0.65 → 0.82 | 0.66 → 0.81 | 0.29 → 0.29 |
Who got each question right
| correct | of 726 |
|---|---|
| all three | 400 |
| Claude and Jev | 190 |
| Claude and Laya | 41 |
| Claude only | 33 |
| Jev only | 27 |
| none | 16 |
| Laya only | 16 |
| Jev and Laya | 3 |
| pair | same side | both wrong |
|---|---|---|
| Claude and Jev | 622 / 726 · 86% | 32 |
| Claude and Laya | 484 / 726 · 67% | 43 |
| Jev and Laya | 452 / 726 · 62% | 49 |
| Claude Opus 5 · claude-opus-5 | Jev | Laya | |
|---|---|---|---|
| price, all 1,834 questions | $194 API-equivalent, run on a subscription, not charged | ≈ $0.07 | $0, local |
| median time per exchange | 19.7 s | 0.35 s | 0.45 s |
| wall clock, 449 exchanges | 91 min, four at a time, with rate-limit pauses | 164 s | 221 s |
| errors | 0 | 0 | 0 |
The same questions, put to CLM-8B
Four days after this report, Stanford and NVIDIA released CLM-v0.1-8B: a frozen Qwen3-8B encoder with two contrastive projection heads of about 20M parameters, scoring a state against candidate actions with no text generation, Apache 2.0. It is the first open model pitched directly at Jev's job, so on 2026-09-27 it was put on the same questions.
Nobody hosts it, so it ran on the 16 GB M2 Pro through an 8-bit MLX port of the encoder (decisive top-1 agreement with the full weights measured at 1.0000) with upstream's clm-serve unchanged in front. Upstream serves the encoder at 2,048 tokens; this arm raised that to 8,192 so the whole state fits, in the order Jev sees. A 2,048-token arm was stopped at 192 of 443 exchanges once it was clear it trailed the 8k arm, and is not reported.
Six plan-review positives were rewritten after the Claude replay, so 443 of the 449 exchanges are reproducible today and 720 questions are gradable, not 726. Jev was re-run on the same 443 on 2026-09-26, which is why its figures here differ by a point from the section above: a fresh run on a slightly different corpus, not a re-grade.
| role | graded | Jev acc / Brier | CLM-8B acc / Brier |
|---|---|---|---|
| test reviewer | 128 | 0.88 / 0.08 | 0.63 / 0.37 |
| task alignment | 180 | 0.93 / 0.06 | 0.50 / 0.27 |
| code review | 180 | 0.90 / 0.10 | 0.64 / 0.25 |
| spec alignment | 178 | 0.76 / 0.16 | 0.44 / 0.29 |
| plan review | 54 | 0.83 / 0.13 | 0.74 / 0.22 |
| all | 720 | 0.865 / 0.101 | 0.561 / 0.283 |
Probability of a defect, clean → defective
CLM-8B's two numbers are within 0.02 of each other in every role, and on test review it returns 1.0 for every per-test label.
| role | Jev | CLM-8B |
|---|---|---|
| test reviewer | 0.15 → 0.85 | 1.00 → 1.00 |
| task alignment | 0.15 → 0.84 | 0.53 → 0.54 |
| code review | 0.32 → 0.79 | 0.70 → 0.70 |
| spec alignment | 0.60 → 0.90 | 0.49 → 0.48 |
| plan review | 0.60 → 0.81 | 0.90 → 0.91 |
| correct | of 720 |
|---|---|
| both | 356 |
| Jev only | 267 |
| neither | 49 |
| CLM-8B only | 48 |
| Jev | CLM-8B · 8k window | |
|---|---|---|
| median time per exchange | 0.22 s | 58.9 s, one at a time on the laptop |
| sum of per-exchange time, 443 exchanges | under 2 min | 7.2 h |
| same side as Jev | 405 / 720 · 56% | |
| errors | 0 | 0 |
Why a typed judge at all
A text-generating judge costs about $0.57 and 45 seconds per case. Re-running a thirty-case corpus after a prompt edit is $17 and 25 minutes; recalibrating five roles is about $90 and two and a half hours. Jev answers a corpus for half a cent in twelve seconds, the local models for nothing in a similar time. That is what makes prompt iteration on judges affordable, whichever typed model is chosen.
Findings
- Check what the state leaks before believing a score. Paths, IDs and filenames are text to a model. The first 30 of 30 was the label.
- A score a constant answer can earn is not a score. Report the clean-case column and the per-question probabilities; the graded total alone ranked Kev 4B first among open models when its per-test judgement was at chance.
- Sub-1B encoders do not discriminate on review-sized states. Laya, Von and Kev 0.8B give the same probability whatever the case. Shrinking the state to the test file and the brief did not help them.
- Nimble 9B reads the test but is starved. Its 2,048-token limit removes the brief and criteria on every role but the minimal one; it is the only open model with a calibrated per-test judgement.
- Kev 4B is confident and wrong on diffs. Decisive probabilities, near-zero probability of a defect on planted defects in the alignment and code roles.
- Jev is the reference among typed models. Accuracy 0.89 to 0.97 with Brier 0.05 to 0.11 on four roles, and the only model whose lens answers stay low on clean tests.
- Claude is the most accurate; Jev is the best value. On all 1,834 replayed questions, Claude is right on 91.5% of the 726 gradable ones, Jev on 85.4%, Laya on 63.4%. Jev costs about one three-thousandth as much and answers fifty times faster.
- CLM-8B, the open model built for this job, does not do it out of the box. On the same 720 gradable questions it is right on 56.1% with a Brier of 0.283, and its probability of a defect does not move between clean and defective states. Jev is right on 86.5%.
- Two judges are worth their cost only if their errors are independent. No case was missed by both Jev and the text-generating judge; that is a hint, and the real measurement is the disagreement rate on live runs, which this benchmark does not contain.
Reproducing
The harness records, for every case, the questions, the raw answers, the cost, the time and the state hash, pinned to the digest of the judge definition; the state text is stored once by hash. A new system is a transport and a model name. It answers the same questions on the same bytes and is compared case by case and question by question against any earlier record. Regrading is a re-read of stored replies, not a re-run.
Read the full written report · data summaries in data/, including the three-way comparison with Claude and the CLM-8B head-to-head