fix(eval): mbpp-plus is 84.9% plus-graded, not 99.7% — and prose was resolving SWE-bench instances - #176
Merged
Merged
Conversation
…t ride the score
The published mbpp-plus 99.7% (377/378) was the MBPP+ *task set* graded with
the dataset's *base* `test_list` asserts. Re-running the identical model,
tasks and agent under the now-wired EvalPlus expanded harness gives
321/378 = 84.9% (`{completed: 378}`, $2.32), so the 14.8-point gap is
attributable to grading alone. Receipt:
data/modal-grid-fullscore4-20260730-plusgrade.json.
Ceiling is 377/378, not 378: task 590 (polar_rect) cannot pass because the
upstream harness compares floats with atol=0 and the dataset's own canonical
answer differs in the last ULP. Recorded in CEILINGS so the score reads
against an achievable maximum.
Found while landing it: CEILINGS and GRADING_NOTES shipped a release ago to
make a caveat *travel with* a score, but the markers only ever appeared in
the footnotes below the table — so the scorecard row, which is the unit
anyone copies, carried the number and left the caveat behind. Markers now
render in the score cell, suppressed on retracted rows whose footnotes are
not emitted. Section 3's mbpp+ ticks disclose their grading strength for the
same reason the retracted-adapter clause already did.
Three new tests, each falsified against the unfixed renderer; the existing
note test is re-keyed to durable facts (receipt + measured delta) rather
than the wording it had before the harness was wired.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Five benchmark adapters graded a task SOLVED from `len(agent_output.strip()) > 10` whenever they could not run the benchmark's own tests: swe_bench, swt_bench, swe_polybench, feature_bench and dpai_arena (six sites). Verified live, not inferred — "I have analyzed the issue and implemented a comprehensive fix." graded as a RESOLVED SWE-bench instance. All six now grade unresolved. Inability to grade is not a pass, for the same reason a cloud sandbox refuses to degrade to local: either way the result becomes indistinguishable from a real one. The resulting zero is also *legible* — a uniform-zero column is already the harness-gap signature render_observatory.py refuses to publish as a score, whereas a 100% built from prose is invisible. Three things made this survive a green suite: - The adapters disagreed about which configuration was unsafe. swe_bench was safe at env=None and unsafe with a runner-less env; swt_bench was the exact mirror image. A guard covering one shape would have passed on four of five. The new test parametrises both. - The class spread by imitation: dpai_arena._evaluate_rubric's docstring said its placeholder was "matching the SWE-bench fallback behaviour". So there is a static AST gate over chimera/eval/benchmarks/ rejecting len() of any answer-shaped parameter. AST and not grep — the fix's own comments quote the old code, and a text search would force deleting the explanation to stay green. - Six existing tests ASSERTED the defect (test_evaluate_fallback_heuristic, test_evaluate_no_env_uses_length_heuristic, test_evaluate_unknown_track_falls_back_to_length, +3). The suite was pinning it in place. Inverted, each carrying a note on what it used to assert. Also corrects four docstrings that still promised the fallback, and points the seven SWE-family canary exemptions at their real blocker (no dataset carries docker_image) and at #175. Found while scoping that canary — the exemption the sweep reports as "unverified, not healthy". It was right. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Five distinct fabricated-result classes have now surfaced in this repo, and playbook 13's invariants named none of them — a live-run checklist that says "integrity-scan before publishing" while the *grader itself* is the thing most likely to be wrong. Adds them as one invariant with the canary as its action, including the two that are new: under-strength grading (mbpp-plus, 14.8 points) and length-as-correctness (prose resolving a SWE-bench instance). States the part that is easy to skip: the inverse half of the canary is not optional, because a grader hardwired to True passes every positive-only check. And that EXEMPT in that sweep means unverified, never healthy. The livecodebench figure here is a task COUNT, not a percentage — the claims gate correctly rejected the percentage I first wrote, since a `%` beside a retracted adapter's name is exactly how a withdrawn score survived in docs/specs for three weeks. Rewording beat widening the exemption list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…inverted a verdict Two defects behind the mbpp-plus number, both found by checking a claim I had already written down. 1. My CHANGELOG said task 590 was "recorded in KNOWN_UNPASSABLE and CEILINGS". Only CEILINGS was true — the KNOWN_UNPASSABLE entry was sitting uncommitted in a different worktree. CEILINGS' own docstring claims it is "Verified by canary_benchmarks.py (KNOWN_UNPASSABLE)" and nothing enforced that pairing, so the page published a verified cap that no canary entry backed. Entry added; a test now fails on any ceiling without a canary-side exclusion naming the task. A ceiling reduces a published denominator — it does not get to be self-asserted. 2. Wiring the plus harness inverted a canary verdict. The recipe scanned `test_list` for dependency blockers while the grader had moved to the expanded `test` blob, under a comment asserting that scope was "what MBPPPlus.evaluate ACTUALLY executes" — true when written, wrong after. With numpy absent the sweep reported mbpp-plus BROKEN, accusing a working grader, where the honest verdict was ENV-MISSING. That is the false-BROKEN class the ENV_MISSING verdict exists to prevent, and it sends someone to fix working code. Proven three ways against a genuinely numpy-free venv: stale scope → BROKEN, fixed scope → ENV-MISSING, fixed + numpy → PASS. A first attempt to reproduce it with an import-blocking shim was invalid and I discarded it — a numpy.py on the path keeps find_spec succeeding, so the canary cannot see absence at all. The new test pins the scope TOGETHER with the fact that the adapter really grades at plus strength, so un-wiring one breaks the other instead of leaving a green assertion that describes nothing — which is precisely how the old comment rotted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Splicing "RESOLVED" ahead of the original wording left "Original entry: The number is real for what executed" mid-sentence. Quotes the original verbatim instead (the record survives, per additive-only) and notes that the fix went past its own suggested one — copying the ‡ footnote into README would have documented an inflated number rather than correcting it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The sibling of the length defect, in the graders that DO have a reference answer and compared it with a raw `in`: ContextBench: truth "42" -> answer "142" PASSED TauBench: action "transfer_to_agent" -> "transfer_to_agent_v2" PASSED Both now match on word boundaries. Anchors apply only where the truth's own edge is alphanumeric, so `$5` and `f(x)` stay matchable — applying them unconditionally would make those permanently unmatchable and trade a false-accept for a silent false-reject, which is worse because a zero column looks like a hard benchmark. Neither fed a published number (context-bench is marked unverified in the capability matrix, tau-bench appears only as n=1 ticks), so this is prevention rather than a retraction. The residual leniency is disclosed and test-pinned, NOT solved: an answer that negates or hedges around the truth still grades correct, because that is natural-language judgement rather than string matching, and the `judge` hook exists for it. A test asserts the current behaviour so the limitation stays visible — one nobody can see is indistinguishable from a bug nobody found. Also: two canary exemptions claimed a reason that was false. context-bench and nocha were both listed as "no reference answer" while their graders read one — ContextBench grades against task["answer"], and nocha's correct choice is the constant "A" in every instance by construction. A false exemption reason is how an adapter stays unverified forever, because the sweep reads EXEMPT and nobody re-derives the claim. Both are real recipes now, each verified to accept its reference answer and reject a wrong one; the sweep reports NOT-STAGED, which is true and actionable. nocha is the cheapest canary in the set and the one where the inverse half carries all the weight: with a constant expected answer, a positive-only check is satisfied by a grader hardwired to True. 23 new tests, 6 of which fail against origin's graders. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The length defect spread by imitation once already — dpai_arena's docstring said its placeholder matched "the SWE-bench fallback behaviour" — so the containment fix ships with the same defence: an AST scan over chimera/eval/benchmarks/ rejecting `X in <answer>`. It is enforceable because both known sites were fixed first, so the allowlist is EMPTY. Any new hit is either a real defect or an entry someone must justify in place with a reason, and a companion test fails when an allowlist entry no longer matches a live site — an exemption that outlives its reason is a permanent hole. Falsified end to end, not just against a hand-rolled copy of the scanner: reintroducing `truth.lower() in agent_output.lower()` into context_bench makes the gate fail naming that file and line, and the scanner is exercised over a temp package dir for both a violation and a benign `'FAIL_TO_PASS' in task` (which must NOT fire, or every dict lookup trips the gate and someone deletes it rather than obeying it). Stated in the test rather than implied: this gate is NARROWER than the leniency it guards. It stops a grader accepting a demonstrably different value; it cannot see negation or hedging, and no static check can. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… that rotted The user-facing guide described the canary's mechanics but not its limits, so a green sweep read as "these numbers are right" when it only means "these graders are not fabricating". Adds: - What a PASS does NOT tell you: under-strength grading (the canary is structurally blind — a weaker suite still passes correct answers and rejects wrong ones; mbpp-plus moved 99.7% -> 84.9% once the real harness ran), and leniency the inverse check happens to miss (ContextBench accepted 142 for truth 42 while correctly rejecting the recipe's -99999, so the pair alone said PASS). - An EXEMPT reason is itself a claim that rots. context-bench and nocha both sat exempt as "no reference answer" while their graders read one. Nobody re-derives a reason once the sweep prints EXEMPT beside it. Check exemptions against the adapter's evaluate, not the sentence. - test_fields is a claim about another module — re-derive it whenever that module's grading path changes, with the two practical notes from proving it: uninstall the dependency for real (an import-blocking shim leaves find_spec succeeding, so you learn nothing), and pin the scope together with the behaviour it describes. Current-state tally refreshed against a measured sweep (7 pass / 0 broken / 3 not staged / 17 exempt) and pointed at #175 with the actual blocker. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0bserver07
force-pushed
the
bench/mbpp-plus-number
branch
from
July 30, 2026 23:11
9487852 to
a778628
Compare
…t inferred
I published "identical model, tasks and agent" across the observatory note, the
changelog and the capability matrix. Checking the receipts before merging: the
three 2026-07-09 flagship files record NO model at all — the field postdates
them, and the flagship column's model is documented once on the page rather than
per-cell. Only the new receipt carries `model: glm-5.2`.
So "identical model" asserted a receipt field that does not exist on one side.
The comparison is still sound and the number does not move; the wording was
claiming stronger provenance than the evidence carries, which is precisely what
this batch exists to stop.
Now stated as it actually is:
recorded in BOTH — agent_id=coding-agent, n=378, same benchmark
recorded in ONE — model (glm-5.2, new receipt only)
corroborating — cost $2.38 then vs $2.32 now, 2.5% apart, which is what
the same model doing the same work costs: the agent
solved as before, the grader accepted fewer answers
The cost agreement is independent evidence rather than an assumption, so the
one-variable claim is better supported after this change than the flat
assertion was.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three commits, all measurement integrity. The second and third were found while landing the first.
1. The mbpp-plus number, plus-graded: 99.7% → 84.9%
The published 99.7% (377/378) was the MBPP+ task set graded with the dataset's base
test_listasserts —MBPPPlusinherited MBPP's grading path and never executed the EvalPlus expandedtestblob that was staged in every row.Re-running the identical model (glm-5.2), tasks and agent under the now-wired expanded harness: 321/378 = 84.9%,
status_counts {completed: 378}, $2.32. Nothing but grading changed, so the 14.8-point gap is attributable to grading alone.Receipt:
data/modal-grid-fullscore4-20260730-plusgrade.json.The expanded contract is strictly stronger, not merely different: a hardcoded lookup satisfying every base assertion for
is_not_primeis accepted by base and rejected by plus.Ceiling is 377/378, not 378. Task 590 (
polar_rect) cannot pass — the upstream harness compares floats withatol=0and the dataset's own canonical answer differs in the last ULP. Recorded inCEILINGSso 84.9% reads against an achievable 99.7%.Getting a comparable number took two runs. The first fell back to
glm-5.1becauseglm-5.2was absent from the catalog, confounding grading against model (323/378 there). That stands as a second data point but is not the headline, because two variables moved.2. The caveat markers were never on the number
CEILINGSandGRADING_NOTESshipped a release ago specifically so a caveat travels with a score — but†/‡only ever appeared in the footnote lines below the table. A scorecard row is the unit anyone copies, so the number travelled and the caveat stayed behind.Markers now render inside the score cell, suppressed on retracted rows (whose footnotes are not emitted). Section 3's
mbpp+✓ ticks now disclose that their receipts predate the plus harness, for the same reason the retracted-adapter clause already did.Also:
DEFAULT_PATTERNSgainedmodal-grid-fullscore4-*. A receipt the generator does not glob is silently never read — this one first landed under anobservatory-*name that put it in the depth matrix instead of the flagship row.3. A fifth fabricated-result class: length-as-correctness
Five adapters —
swe_bench,swt_bench,swe_polybench,feature_bench,dpai_arena(six sites) — graded a task solved fromlen(agent_output.strip()) > 10whenever they could not run the benchmark's own tests.Verified live, not inferred:
All six sites now grade unresolved. Inability to grade is not a pass, for the same reason a cloud sandbox refuses to degrade to local: either way the result becomes indistinguishable from a real one. The resulting zero is also legible — a uniform-zero column is already the harness-gap signature
render_observatory.pyrefuses to publish as a score, whereas a 100% built from prose is invisible.Three things kept this alive through a green suite:
swe_benchwas safe atenv=Noneand unsafe with a runner-less env;swt_benchwas the exact mirror image. A test covering one shape would have passed on four of five. The new test parametrises both.dpai_arena._evaluate_rubric's docstring said its placeholder was "matching the SWE-bench fallback behaviour". So alongside the behavioural test there is a static AST gate overchimera/eval/benchmarks/rejectinglen()of any answer-shaped parameter. AST and not grep: the fix's own comments quote the old code, and a text search would force deleting the explanation to stay green.test_evaluate_fallback_heuristic,test_evaluate_no_env_uses_length_heuristic,test_evaluate_unknown_track_falls_back_to_length, +3. The suite was not blind to this behaviour, it was pinning it in place. All inverted, each carrying a note on what it used to assert.Every new test was falsified against the unfixed code before being trusted. The behavioural one names all seven broken adapter/track combinations when reverted; the retracted-row test was additionally falsified against unconditional markers, because under the original bug no row had markers at all and it would otherwise have passed vacuously.
Corrections to previously recorded findings
patch. An earlier note of mine said "4 of 5 stage no gold patch" — that came from a probe miscountingenvironment_setup_commitas an image field. Measured census is in [bench] Canary the SWE family — gold patch must score 100%, prose must score 0% #175.docker_image. The seven canary exemptions now cite that blocker and [bench] Canary the SWE family — gold patch must score 100%, prose must score 0% #175 rather than reading as healthy.Rules, not just fixes
Truesails through a positive-only check) and thatEXEMPTmeans unverified, never healthy.%beside a retracted adapter's name. Reworded to a task count rather than widening the exemption list — that pattern is exactly how a withdrawn score survived indocs/specsfor three weeks.Gates
tui)chimera/ scripts/ tests/)The single failure in both suite runs is
tests/function_synthesis/test_validation_split.py::test_evaluate_returns_both_rates— documented in CLAUDE.md as env-sensitive locally and green in CI. Its test file, its subject (chimera/training/{spec,validation}.py), andchimera/function_synthesis/are all byte-identical toorigin/master, so this diff cannot have caused it.Related: #175 (SWE-family canary, filed with the measured census).
🤖 Generated with Claude Code
Added after review opened — three more defects, same family
Landing the number above meant verifying claims I had already written down, and each check found something.
4. The ceiling was published with nothing behind it
My own changelog said task 590 was "recorded in
KNOWN_UNPASSABLEandCEILINGS". Only the second was true — the canary entry was sitting uncommitted in a different worktree.CEILINGS' own docstring says it is "Verified bycanary_benchmarks.py(KNOWN_UNPASSABLE)" and nothing enforced that pairing, so the page published a verified cap that no canary entry backed.A ceiling is a published reduction of the denominator. It does not get to be self-asserted. A test now fails on any ceiling with no canary-side exclusion naming the task.
5. Wiring the plus harness silently inverted a canary verdict
Recipe.test_fieldsnames the source the grader executes — a claim about another module, which rots silently. mbpp-plus carriedtest_fields=("test_list",)under a comment asserting that was "whatMBPPPlus.evaluateACTUALLY executes": true when written, wrong the moment the plus harness landed.With numpy absent, the sweep reported mbpp-plus BROKEN — accusing a working grader — where the honest verdict was ENV-MISSING. That is the false-BROKEN class the
ENV_MISSINGverdict exists to prevent, and it sends someone to fix working code.Proven three ways against a genuinely numpy-free venv:
("test_list",)("test", "test_list")A first attempt to reproduce this with an import-blocking shim was invalid and discarded: a
numpy.pyon the path keepsfind_specsucceeding, so the canary cannot detect absence at all. The package has to actually be uninstalled.The new test pins the scope together with the fact that the adapter really grades at plus strength, so un-wiring one breaks the other instead of leaving a green assertion describing nothing — which is exactly how the old comment rotted.
6. Substring grading accepted a different value as correct
The sibling of the length defect, in the graders that do have a reference answer and compared it with a raw
in:Both now match on word boundaries — applied only where the truth's own edge is alphanumeric, so a truth like
$5orf(x)stays matchable. Anchoring unconditionally would make those permanently unmatchable, trading a false-accept for a silent false-reject, which is worse: a zero column reads as a hard benchmark rather than a broken anchor.Neither feeds a published number (
context-benchis marked unverified in the capability matrix, tau-bench appears only as n=1 ✓ ticks), so this is prevention, not a retraction.The residual leniency is disclosed and test-pinned, not solved.
"The answer is NOT 42"still grades correct. Detecting that is natural-language judgement rather than string matching, and thejudgehook exists for it. A test asserts the current behaviour, so if someone later teaches this path to reject negations, that test fails and forces them to update the docstring that discloses it. A limitation nobody can see is indistinguishable from a bug nobody found.Two canary exemptions stated a reason that was false
context-benchandnochawere both listed as "no reference answer" while their graders read one —ContextBench.evaluategrades againsttask["answer"], andnocha's correct choice is the constant"A"in every instance by construction. An exemption's stated reason is itself a claim that rots: the sweep prints EXEMPT and nobody re-derives it, so the adapter stays unverified indefinitely.Both are real recipes now, each verified to accept its reference answer and reject a wrong one. The sweep reports NOT-STAGED for them, which is true and actionable.
nochais the cheapest canary in the set and the one where the inverse half carries all the weight: with a constant expected answer, a positive-only check is satisfied by a grader hardwired toTrue.Gates on the final head
tui)chimera/ scripts/ tests/)c60fa0fbSingle failure in every suite run is
test_validation_split::test_evaluate_returns_both_rates— documented in CLAUDE.md as env-sensitive locally and green in CI. Its test file, its subject (chimera/training/{spec,validation}.py), andchimera/function_synthesis/are byte-identical toorigin/master, so this diff cannot have caused it.