ETB-05. Unscorable read as behavior-absent

The evaluator trusts “could not score” as “safe”. “Could not score” is conflated with “the attack did not succeed.”

Fix

Distinguish could-not-score from safe at the type level.

In the study

10 instances

Of

76

01How it happens

What the scorer reads that the policy can write.

A result the evaluator could not produce is recorded as a negative result. A red-team scorer that errors, is refused, or gets a hedged answer records that the attack did not succeed. A guardrail that only scans part of the input treats the unscanned part as clean. A training loop feeds an unrewarded rollout into the advantage calculation as a default 0.0, as if it had been scored.

The effect is a safety number that improves when the measurement fails. Public cases include red-team scorers that conflate couldn't-score, errored, blocked and hedged with attack-did-not-succeed, a composite AND scorer that masks a confirmed true with a could-not-score false, and moderation guardrails that scan only the trailing user turn.

ETB-05 differs from ETB-04 in where the failure goes. ETB-04 removes the sample from the denominator. ETB-05 keeps it and gives it the wrong value.

The rule all ten mechanisms break: a score must be a function only of state the evaluated system cannot reach. The full taxonomy

02Example

The pattern, and the fix.

Illustrative Python, reduced to the line that matters. The public reports below link the real code.

Trusts the evaluated system
def attack_succeeded(response) -> bool:
    return classifier(response) == "harmful"   # error, refusal, empty reply: all read as "attack failed"
Fixed
class Outcome(Enum):
    SUCCEEDED = "succeeded"
    FAILED = "failed"
    UNSCORABLE = "unscorable"   # reported separately, never folded into FAILED
03Questions

Is “no harmful output detected” the same as “safe”?

Only if the detector actually ran on all of the output and returned a result. If it errored, was refused, or skipped part of the input, the honest result is unscorable, and it has to be reported as such rather than folded into safe.

How do I keep unscorable results from reading as safe?

Make unscorable a separate value in the type, not a boolean false. Report its count next to the success rate, so a run that could not measure anything cannot look like a run where nothing happened.

04Public reports

Every public report in this class.

Filed upstream with a proposed patch between March and July 2026, from the study's public evidence table. Titles are the reports' own.

2026-06-18

BerriAI/litellm #30723

Mask PII in tool-call arguments for Presidio pre-call and Anthropic response

2026-06-18

BerriAI/litellm #30730

Lakera v2 guardrail: flagged=True with empty payload takes mask-and-allow branch but masks nothing

2026-06-18

BerriAI/litellm #30729

OpenAI & Azure moderation guardrails only scan the trailing user turn: system/assistant content is never moderated

2026-06-18

microsoft/PyRIT #2042

Surface unscoreable sub-scores that mask composite true/false verdicts

2026-06-18

microsoft/PyRIT #2044

Scorers conflate couldn't-score / errored / blocked / hedged with attack-did-not-succeed, under-reporting jailbreaks

2026-06-18

microsoft/PyRIT #2043

Composite AND scorer silently masks a confirmed true with a could-not-score false

2026-06-18

safety-research/bloom #56

Unscoreable judge result must not read as behavior-absent

2026-06-25

langfuse/langfuse #14576

Ingestion masking only covers the OTEL path; legacy public API ingestion (processEventBatch) flows to storage unmasked

2026-07-16

huggingface/trl #6427

Return None for unrewarded rollouts to prevent default-0.0 advantage poisoning

2026-07-16

huggingface/trl #6426

Port unscorable-mask reward defense from GRPO

Cite as: Kearney, John. The Evaluator Trust Boundary: A defect class in AI evaluation infrastructure, its prevalence across 36 organizations, and its removal by training. Preprint, Authensor, Inc., 2026. doi:10.5281/zenodo.21633620. Check your own judge for ETB-01 with etb-scan.