A score tells you something broke. This tells you what.
The taxonomy is fixed in code, so failures stay comparable across runs and across models. It is the part that turns a number into a decision.
Why a closed vocabulary
“Hallucination: 4 → 11” is actionable. “Quality got worse” is not.
An LLM judge asked for free-text criticism will produce something different every run. That text is genuinely useful to read once. It is useless as a metric, because you cannot count it, chart it, or compare it across two prompt versions without reading everything again.
So the judge returns two things: a weighted score along the rubric, and a mode drawn from a closed set. The score tells you the magnitude of a change. The mode tells you the kind. Both are numbers, both aggregate, and the free-text reasoning is still retained for the case you actually want to investigate.
Keeping unknown in the vocabulary matters as much as the other eleven. A taxonomy with no escape hatch gets abused: real failures get shoved into the nearest bucket to avoid an error, and the distribution stops meaning anything. A growing unknown rate is a measurable signal that the taxonomy needs work — which is the point.
“The output satisfies the format, grounding, relevance, category, and brevity requirements. However, materiality is somewhat overstated as high because the headline reports losses rather than an event that breaks rules, changes markets, or demonstrates a comparable systemic consequence.”
failure mode reasoning_error · score 0.94 — a case that still failed the rubric at 94% of its weighted points
Reading a distribution
One mode dominating is a different bug from five modes appearing
A single mode, suddenly
Almost always structural: a contract changed, a field was renamed, a length limit was hit. Fix is usually mechanical and obvious once named.
format_violation ×32Many modes, slowly
The hard case. Quality drifting across several dimensions at once, none of them crossing a pass threshold. This is what a mean-score brake is for.
4 modes · small countsRuntime errors
Not a quality signal at all. Separated out so that a flaky gateway cannot masquerade as a prompt regression and send you chasing the wrong fix. Transient failures are retried before they are ever recorded; if every case errors, the run reports that nothing was measured and exits non-zero rather than reporting a pass-rate drop.
runtime_error · excludedOne caveat worth knowing before you trust a number
Model endpoints are not deterministic, including at temperature 0. Measured on this harness: three identical requests to the same endpoint at temperature 0 returned three different completions, and a --repeats 3 run over six cases flagged 6 of 6 as flaky.
That is a property of the models, not a defect in the harness — but it decides how you read a result. A single sample per case cannot separate a real regression from sampling noise, so a gated run with no repeats now warns that its regression verdict may be noise. If a number matters, run it again with --repeats 3 and look at the flakiness count before you act on it.
See the taxonomy applied to a real dataset.
The worked example shows all four modes a single prompt revision can introduce, with the raw gate output.