Context
Code review across the #166 benchmark PRs (S-NIAH #170, LongBench-v2 CodeQA #171, OOLONG-Pairs #169) surfaced a consistent, growing pattern of technical debt as more benchmark families get added:
-
Materializer duplication (rule of three, now hit). _encode_json, _write_exclusive (atomic no-overwrite write via tempfile+fsync+hardlink), and the HTTP-download-with-User-Agent-and-error-wrap pattern are copy-pasted byte-for-byte across benchmarks/oolong.py, benchmarks/sniah.py, and benchmarks/longbench_codeqa.py (and presumably benchmarks/oolong_pairs.py). This is the atomic-write contract CLAUDE.md documents as load-bearing for the immutable-artifact guarantee — a future fix to it needs applying in every copy or it silently diverges. Extract into shared infrastructure (e.g. benchmarks/_materialize.py) with encode_json, write_exclusive, and a parameterized download helper.
-
_policy_for_task in benchmarks/live.py accretes a hardcoded if benchmark_id == "..." branch per benchmark. Now 3 branches (OOLONG task-shape fallback, s-niah, longbench-v2-codeqa); 4 more benchmarks are already planned in the manifest (BrowseComp-Plus, OOLONG-Pairs, TAG-Bench, +1). BenchmarkSpec in benchmarks/models.py has no field for per-benchmark guidance, so there's no data-driven home for it — every new benchmark means another elif in shared infrastructure. Consider declaring semantic_policy/guidance on the manifest's benchmark entry so _policy_for_task looks it up instead of growing forever.
-
exact_match scorer sniffs domain shape. benchmarks/scoring.py's exact_match now branches on expected in {"a","b","c","d"} to apply multiple-choice-specific leniency (added for LongBench-v2 CodeQA), mixing implicit domain logic into a scorer 3+ benchmarks depend on. A future benchmark whose real answer happens to be a bare 'a'-'d' character would silently inherit letter-extraction semantics it never asked for. Consider a distinct multiple_choice ScorerKind declared explicitly in the manifest instead.
-
Manifest snapshot duplication. Per-run manifest snapshots (rlm-paper-v1-oolong-2026-07-17.json, -sniah-, -longbench-v2-codeqa-) each re-embed full arm/model/limits blocks rather than referencing a shared definition, and which sibling benchmarks each snapshot marks "ready" is inconsistent across branches (undocumented, easy to get wrong when a reader materializes only what they think they need).
Not blocking
None of these are correctness bugs in the current, merged state — all are flagged PLAUSIBLE/cleanup-severity in review, not CONFIRMED bugs. This is deferred cleanup, not a blocker for #166's remaining merges.
Context
Code review across the #166 benchmark PRs (S-NIAH #170, LongBench-v2 CodeQA #171, OOLONG-Pairs #169) surfaced a consistent, growing pattern of technical debt as more benchmark families get added:
Materializer duplication (rule of three, now hit).
_encode_json,_write_exclusive(atomic no-overwrite write via tempfile+fsync+hardlink), and the HTTP-download-with-User-Agent-and-error-wrap pattern are copy-pasted byte-for-byte acrossbenchmarks/oolong.py,benchmarks/sniah.py, andbenchmarks/longbench_codeqa.py(and presumablybenchmarks/oolong_pairs.py). This is the atomic-write contract CLAUDE.md documents as load-bearing for the immutable-artifact guarantee — a future fix to it needs applying in every copy or it silently diverges. Extract into shared infrastructure (e.g.benchmarks/_materialize.py) withencode_json,write_exclusive, and a parameterizeddownloadhelper._policy_for_taskinbenchmarks/live.pyaccretes a hardcodedif benchmark_id == "..."branch per benchmark. Now 3 branches (OOLONG task-shape fallback, s-niah, longbench-v2-codeqa); 4 more benchmarks are alreadyplannedin the manifest (BrowseComp-Plus, OOLONG-Pairs, TAG-Bench, +1).BenchmarkSpecinbenchmarks/models.pyhas no field for per-benchmark guidance, so there's no data-driven home for it — every new benchmark means another elif in shared infrastructure. Consider declaringsemantic_policy/guidanceon the manifest's benchmark entry so_policy_for_tasklooks it up instead of growing forever.exact_matchscorer sniffs domain shape.benchmarks/scoring.py's exact_match now branches onexpected in {"a","b","c","d"}to apply multiple-choice-specific leniency (added for LongBench-v2 CodeQA), mixing implicit domain logic into a scorer 3+ benchmarks depend on. A future benchmark whose real answer happens to be a bare 'a'-'d' character would silently inherit letter-extraction semantics it never asked for. Consider a distinctmultiple_choiceScorerKinddeclared explicitly in the manifest instead.Manifest snapshot duplication. Per-run manifest snapshots (
rlm-paper-v1-oolong-2026-07-17.json,-sniah-,-longbench-v2-codeqa-) each re-embed full arm/model/limits blocks rather than referencing a shared definition, and which sibling benchmarks each snapshot marks "ready" is inconsistent across branches (undocumented, easy to get wrong when a reader materializes only what they think they need).Not blocking
None of these are correctness bugs in the current, merged state — all are flagged PLAUSIBLE/cleanup-severity in review, not CONFIRMED bugs. This is deferred cleanup, not a blocker for #166's remaining merges.