Eleven evaluation tools and leaderboards that reported a score over a
set that was not the set they claimed. Every one reproduced from the outside, from public
code and what the vendor itself prints.
knn is the part nobody prints
Every score in machine learning is a fraction. Almost every dashboard prints the
quotient and hides the denominator. So when the denominator moves — because rows
were dropped, because a buffer swallowed a block, because a suite collected nothing,
because a run covered a different set — the number stays green and no reader can
tell. That single failure mode is what this page is a register of, and it is the only
thing I work on.
The same seam, opened deliberately
In April 2026 a Berkeley RDI team — Hao Wang, Qiuyang Mang, Alvin Cheung, Koushik
Sen and Dawn Song — pointed an automated agent at eight leading agent benchmarks and
took near-perfect scores on all of them without solving a single task. It
never touched the problems. It attacked the harness. Their summary is one sentence:
The implicit promise is simple: a higher score means a more capable system.
That promise is broken.
Berkeley RDI, April 2026
The part that concerns this page is how SWE-bench Verified fell. Not a clever
solver: a ten-line conftest.py whose pytest hook rewrites every outcome to
passed. Five hundred instances resolved, nothing solved.
That is the same seam as the LangSmith entry in the register below, which I reported to
LangChain on 13 August and which they confirmed in writing the next day — a pytest
status hook reporting a clean green over a suite that had lost seven of its ten cases.
One was an exploit; one was an accident. From the number, a reader cannot tell
them apart. That is the whole problem, and it is the reason the accident is the
more expensive of the two: an adversary has to be invited in, while a renamed directory
arrives on its own, on a Tuesday, in your own repository.
Check your own run, before it ships
No recomputation after the fact can catch the worst case. Once seven of ten items are
gone, the report and the recheck agree — both read 1.0000, because both
are dividing by seven. Catching it needs the intended denominator pinned before
the run, and the receipt recomputable afterwards by someone who trusts neither party.
That is a zero-dependency CLI you can install and run in the next minute:
pip install runreceipt
runreceipt selftest → probes all seven rules both ways before you trust it
runreceipt fix → pins the intended set and its hash, before the run
runreceipt verify → recomputes the denominator from the run’s own artefact
runreceipt recheck → re-derives a receipt you were handed, trusting neither party
The self-test is not decoration. Every rule is probed in both directions — it must
fire on the defect and stay silent on the honest run — against twelve fixtures, seven
of which are the defects in the register below, reproduced from shipped releases. If a rule
has stopped working, the tool says so and refuses, with its own exit code: 0
consistent, 2 findings, 3 artefact unreadable, 4 the
instrument failed its own probe. There is deliberately no code that means probably
fine.
It has no dependencies on purpose: it is the thing that checks the other tools, so it
imports none of them. Live on PyPI,
one page of documentation at runreceipt.surge.sh,
and the recheck page reproduces a
verdict from a receipt in your browser, with nothing uploaded anywhere.
And for a number someone has already published, without any pipeline at all: paste a rate
and the population it claims to be over, and every integer is enumerated — either a
list of counts that produce it, or the closed fact that none does. Seven controls have to
pass before a verdict is shown, two of them added on 21 August, when the tool cleared nine
figures it should have refused. The denominator
check →
The register
Each entry was reported to the vendor before it appeared here, with the reproduction
and the fix. Where a vendor has confirmed it in writing, that is marked. Nothing below
is a vulnerability, a leak, or anyone’s private data: every one of these is
recoverable from a public page or a public repository.
Inspect (UK AISI)
accuracy 1.000, stderr 0.0003 of 10 scoredmeasured 22 Aug 2026
The best-behaved framework I have tested still hands the leaderboard a survivor mean, and calls it stderr 0.000
Inspect is the one that does most of this right, and the entry is here for that
reason rather than in spite of it. Its default is safe: fail_on_error
defaults to None, and a run that hits a sample error stops with
status: error and publishes no results at all. I verified that first,
because a gate that only ever fires has not been tested. It also does something no
other tool in this register does — it writes down what it lost, in
results.completed_samples beside results.total_samples.
The gap is one step downstream, and it is a gap you walk into by doing the sensible
thing. A long agent run cannot use that default: one flaky container and hours of
work are discarded, so real evals set a tolerance. With the tolerance above the
actual error rate — the only setting that survives contact with a real
harness — ten samples go in, seven raise inside the solver, three are scored,
and this is what comes back:
Two things travel out of that run. The counts, which stay in the log file. And the
number, 1.000, which is what a leaderboard row, a system card, or a CI
threshold actually consumes. Nothing downstream is obliged to open the log. The
stderr is the sharper end of it: 0.000 is a claim of
certainty, computed over three items, at the exact moment the run is least certain
it measured anything.
I ran a second, identical evaluation with nothing failing. Ten of ten scored,
accuracy 1.000, stderr 0.000, status: success.
The two headline lines are byte-for-byte the same. That is the
finding: not that Inspect discards the count, but that the count it keeps never
reaches the place where someone decides whether a model is ready.
So this entry ships with the fix rather than the complaint. A gate reads any
.eval log and replaces the point estimate with the interval the metric
could occupy over the set that was asked for — the survivors’ sum is
fixed, each lost sample lands somewhere in [0, 1], and nothing in the arithmetic
assumes anything about why a sample died:
always_right.accuracy reported 1.0000
denominator 3 scored of 10 asked for [OVER SURVIVORS]
over the set that was asked for, the same run is somewhere in [0.3000 .. 1.0000]
It carries seven controls that probe the gate itself in both directions, including
a negative control that feeds the checker a deliberately wrong answer and demands the
word DEAD back — and it exits 4, refusing to give any
verdict, if one of them stops working. Both fixtures are real Inspect logs, generated
against mockllm/model at no API cost, so anyone can rerun the whole thing
in a minute without a key.
page says n = 1,2233 rows solve to 1543reported 15 Aug 2026
Three leaderboard rows were scored over 1543 items and ranked against rows scored over 1,223
public validation 20 + private validation 300 + test 1223 = 1543
The TaxEval v2 page documents its test set as 1,223 samples, and lists two
validation sets alongside it. Three model rows do not fit 1,223 under any epoch
count; they fit 1543 exactly — which is the sum of all three components the
page itself lists, and is prime, so it is not 1,223 counted some whole number of
times. Those rows sit in the same sorted column as 128 rows that do fit 1,223.
No row on the site publishes a sample count. Every row publishes accuracy and a
standard error, and for a proportion those two printed numbers are a system of two
equations in two integers, which has a unique solution over the range the printed
precision brackets. The counts are therefore not estimated. They are solved. The
control that rules out rounding: each model is scored twice, in two tabs, over the
same set — and the recovered count agrees in 128 of 128 cases, and 47 of 47
on their GPQA board. A rounding artefact would wander between tabs. It does not.
Separately on that GPQA board, where the page states 198 questions, one model
solves to 197 — and 197 is prime.
Epoch AI
34 of 813 rowsdisagree with the stated setreported 14 Aug 2026
The denominator was recovered from the decimal itself, and 34 rows do not match the set they claim
Same method, run against a published benchmark table: 34 rows out of 813 recover a
denominator that is not the set size the page states. Two of the recovered values
are 197 and 1319, both prime, so neither can be explained as the documented set
scored a whole number of times.
The finding has a corollary that matters more than the rows: rounding a
score to four decimal places or fewer destroys the denominator. Below that
precision the recovery is no longer unique, and a reader who tries anyway will get a
confident wrong answer. Publishing one integer per row costs nothing and removes the
need for anyone to invert an error bar to learn what a score was computed over.
Langfuse
UI: 8 items, accuracy 1.00092 items failed
92 items failed, so the run reported 8 items at perfect accuracy
The denominator counted survivors. Of 100 items, 92 failed before they could be
scored and left the set entirely; the remaining 8 all passed. The dashboard
therefore reported a complete run of 8 items at accuracy 1.000 — correct
arithmetic over the wrong set, and no field anywhere in the view says the run was
asked for 100.
promptfoo
threshold gate: passtests collected: 0
A suite that collected zero tests passes its own threshold
passRate = 0/0 = NaN · NaN < threshold → false → gate does not fire
The pass rate over an empty suite is not a number, and every comparison against
not-a-number is false — including the one that is supposed to fail the build.
So the single check whose job is to notice that quality dropped is structurally
incapable of firing on the case where quality is unmeasured. A misconfigured glob,
a renamed directory, a bad filter: the run goes green and reports nothing missing.
DeepEval
report: passmetric verdict: False
A metric returned False and the reporting layer wrote None over it
The judged verdict was negative. On the way from the metric to the report, the
value became None — and a missing verdict is not treated as a
failure, it is treated as nothing to report. The run reads as passing. The layer
that overwrote the answer is the layer whose only job is to display it, which is
why nobody inspecting the metric ever sees the problem.
LangSmith · LangChain
100% pass3 of 10 cases ranreported 13 Aug 2026
confirmed by vendor
100% over a suite that shrank from ten cases to three
A pytest status hook reported every collected case as passing, over a suite that
had lost seven of its ten cases before execution. The summary line is honest about
the three and silent about the seven, and there is no printed total to compare it
against. A green wall after a refactor that quietly stopped collecting most of the
suite looks exactly like a green wall after a good run.
LangChain confirmed it in writing the next day:
We agree that the pytest plugin can present an incomplete test run
misleadingly, and we're tracking a product-quality fix to report incomplete suites
accurately.
LangChain, 14 August 2026
The same reply contains the sentence I now quote more often than the finding itself.
Declining to treat it as a security matter, they noted that the behaviour
“does not alter pytest's underlying test results or exit status”
— which is precisely correct, and precisely the reason a reader believes the
green. The exit status is clean because the work that would have failed was never
attempted.
Galileo
0 rows processed128 rows processed
The flush buffer was doing double duty as the row counter
Rows are flushed in blocks of 128, and the number surfaced to the user is what is
left in the buffer rather than what went through it. A run whose size is an exact
multiple of the block size therefore reports that it processed nothing — and
a run of 130 reports 2. The buffer is an implementation detail that became the
published denominator.
SWE-bench
leaderboard: 3 rows abovea 4th-place row was dropped
A bare except swallowed the row that belonged in fourth place
One submission’s row never reached the public leaderboard: the code path that
assembles the table catches every exception without distinguishing them, so a single
malformed field removes an entrant instead of reporting an error. The board looks
complete. There is no count of rows attempted next to the count of rows shown, so
the absence cannot be seen from the page.
A broader read of the same leaderboard turned up seven separate defects, including
one submission appearing as two rows, and independently verified entries ranking
below unverified ones because the sort ignores the verification flag.
Ragas
SKIPPED counted as success11 months in the open
A skipped case counted toward the success total for eleven months
A case that never ran was tallied with the cases that passed. The behaviour sat in
released code for eleven months, which is the part worth dwelling on: this class of
defect does not announce itself, does not page anyone, and does not appear in a bug
tracker, because the observable symptom is a number that looks fine.
Weights & Biases
monitor: greennothing was being watched
confirmed by vendor
A monitor that stays green over a set that shrank to nothing
All three points I raised were confirmed. Their own summary of the behaviour is the
clearest statement of the whole class:
…stays green until someone re-runs it.
Weights & Biases, 11 August 2026
That is the definition of the problem. A status that can only be falsified by
re-doing the work is not a status; it is a memory of a status, presented as a
current one.
The same check, run outside machine learning
The arithmetic does not care what the population is made of, and the cheapest way to show
that a method is a method rather than a knack is to run it somewhere else. Nine worked
examples, each one free, each one recomputed live in your own browser with its controls
visible — and each one a case where a number in commercial use cannot be rebuilt
from what its own source prints:
A published growth figure rebuilt from the free public record, windows aligned day for
day, every API URL printed so the count can be disagreed with line by line —
the count under the percentage.
Ten numbers for how many US employers cover GLP-1 drugs, spread from 15% to 67%, where
nine clear the arithmetic and the spread turns out to be
which employers were counted, not what employers do. This is
also the page where my own tool was wrong first.
An award percentage I reported as impossible and then
retracted myself, with what survives the retraction, and every
step rerunnable on the three source PDFs.
Signing does not help. A signature attests that a result is the one
that was produced. It says nothing about what the result was produced over. There is no
cryptographic operation that can attest to absence — that no row was
dropped between the harness and the report — because absence leaves nothing to
sign. Every finding above would survive a fully signed pipeline intact.
Alerting does not help either, because nothing crashed. In each case
the software completed, returned, and printed a number in range. Monitoring watches for
the run that fails; this is the run that succeeds over less than it was asked to cover.
And a passing test suite is exactly what a shrunken suite looks like.
The green wall is produced identically by the good case and the empty one. That is why
the check has to be arithmetic on the denominator, run before the result ships, by
someone whose only job is to try to make it fail.
What this register does not claim
No claim about cause or intent. Where a row does not fit its stated
set, I state the arithmetic and stop. Why the run covered a different set is the
vendor’s to determine; several of the findings above have innocent explanations
and are still defects, because the reader cannot tell either way.
No claim of harm, and no security claims. Nothing here is an
exploit, and nothing here required access I was not given by a public page.
Columns I could not read, I did not report. On two of the boards
above, the pooled summary columns do not solve uniquely, so I make no statement about
them at all — including one specific row that fits no convention I tried, which I
am not presenting as a defect.
Where only one instrument speaks, that is said out loud. Every
number above was recomputed by at least two independent methods, one of which knows
nothing about the other’s assumptions. The handful of rows where the second
method is silent were flagged as such in the report the vendor received.
Three of these findings started as mistakes of mine and were caught by a control before
they left the house: I once published a false finding by checking an object where I should
have checked a field. That is why every claim here carries a control designed to fail, and
why the report a vendor gets includes the controls that did fail on me first.
The arrangement
Standing monthly work on your agent evaluations, before the results ship rather than
after: the harness read the way the Berkeley agent read those eight, the denominators
recovered from what your runs report, the cases that silently left the set, and a
reproduction for each one that you can run without me.
I am one person and this is the only thing I work on. The register above is seventeen days
of it, two entries confirmed in writing by the vendors concerned, and one — Inspect
— where the finding arrives with the gate that closes it.
Monthly
400 USD for up to three evaluation suites, benchmarks or
boards.
With your pipeline
500 USD monthly, including the internal runs and the CI
gate, not only what you publish.
First month
3 000 USD, which is the month that does the deep read of
the harness.
If nothing is found
The entry month costs nothing. If the deep read turns up no case that left the set
unreported and no score that disagrees with the set it claims, you owe nothing and we
stop there.
By the hour
Also available as contract work on a specific harness, if a standing arrangement is
the wrong shape for the problem.
Written to whoever owns the number, not to a support queue — and I would rather
show you a week of it than describe it.
igor@greenthatlies.com