Skip to content

fix(benchmarks): reproduce.sh --only fails closed on a selector that runs nothing - #550

Merged
cdeust merged 1 commit into
mainfrom
fix/reproduce-only-fail-closed
Sep 9, 2026
Merged

cdeust merged 1 commit into
mainfrom
fix/reproduce-only-fail-closed

Conversation

@cdeust

@cdeust cdeust commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

benchmarks/reproduce.sh --only compared its value token for token against longmemeval, locomo, beam and decision-ids, while the script itself prints the artifact names longmemeval-s and beam-100K. Passing one of those, or any typo, matched no benchmark: the script built the package, started and stopped an ephemeral container, wrote MANIFEST.json and START_SNAPSHOT.json, measured nothing and exited 0.

Observed on 2026-09-09 while re-measuring v4.20.0, and reproduced on main before writing the fix (see the test plan). An empty run that reports success is the silent fallback this repository forbids elsewhere.

The fix

A new sourced library, benchmarks/lib/bench_only.sh, on the pattern of benchmarks/lib/bench_regression.sh: bench_only_canonical_token maps the two aliases to the tokens want_bench matches, and validate_only rewrites ONLY as canonical comma-separated tokens or fails closed with exit 2 and the accepted list on stderr. It runs at the end of parse_args, before check_reranker_cell, so before any uv run or container start. An empty token (leading, trailing or doubled comma) is rejected too; read -a would otherwise drop a trailing empty field silently.

benchmarks/README.md documents the aliases and the fail-closed behaviour. --ablate-on takes benchmark names through the same alias table but is not validated here; noted, not folded in.

Type of change

  • Bug fix

Test plan

RED, on main, before the change: bash benchmarks/reproduce.sh --only bogus --no-ablation --results-dir <tmp> exited 0 after building the package, starting container cortex-bench-pg-17377, and writing MANIFEST.json and START_SNAPSHOT.json; no error, nothing measured.

GREEN, after: the same invocation prints error: --only 'bogus' selects no benchmark; nothing would run. plus the accepted list, exits 2 in well under a second, and writes nothing. ONLY="longmemeval-s,beam-100K" is rewritten to longmemeval,beam.

tests_py/benchmarks/test_reproduce_only_validation.py, 11 tests: alias normalisation for each alias and a mixed list, decision-ids accepted, unknown token, unknown token in a list, trailing and leading empty tokens all rejected with the accepted list named, empty --only meaning every benchmark, and one end-to-end test of the real script that needs neither Docker nor a synced environment because validation precedes both.

Mutations these catch: removing the alias table (the normalisation cases fail), removing the empty-token guard (the trailing-comma case passes silently again), and moving validate_only after check_reranker_cell or the container start (the end-to-end test would need Docker and stop returning in under a second).

Gates on the final state: bash -n on both scripts, shellcheck -S warning clean on the new library (the three SC2034 warnings on reproduce.sh pre-date this change and CI's shellcheck step covers workflow files only), ruff check and ruff format --check on the tree, scripts/check_craftsmanship.py, scripts/check_doc_claims.py, and tests_py/benchmarks/test_bench_regression_datasets.py still green.

  • All existing tests pass.
  • New tests added for new behavior.
  • Mutation survival check: listed above.
  • Manual verification: the RED and GREEN runs above.

Audit notes

Self-review plus the RED/GREEN evidence. A fresh-context review is requested before merge.

Reviewer checklist

  • CHANGELOG.md updated under Fixed.
  • Documentation updated (benchmarks/README.md).
  • No secrets or PII in the diff.
  • CI passes on the latest commit.

🤖 Generated with Claude Code

…runs nothing

--only was compared token for token against longmemeval, locomo, beam
and decision-ids, while the script itself prints the artifact names
longmemeval-s and beam-100K. Passing one of those, or any typo, matched
no benchmark: the script built the package, started and stopped an
ephemeral container, wrote MANIFEST.json and START_SNAPSHOT.json,
measured nothing and exited 0. Reproduced on main before the change.

A sourced library, benchmarks/lib/bench_only.sh, maps the two aliases
to the tokens want_bench matches and fails closed on an unknown or
empty token with exit 2 and the accepted list, at the end of
parse_args, before any uv run or container start. Empty tokens are
detected on the whole string first, because read -a drops a trailing
empty field.

Eleven tests pin the alias table, the rejection cases and the script's
end-to-end behaviour, which now needs neither Docker nor a synced
environment. README row and CHANGELOG entry added.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@cdeust

cdeust commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

ZETETIC-REVIEW: APPROVE

Verdict on head 5060595.

An independent fresh-context reviewer read the library as a hostile shell reviewer and found no bug: the unset-or-empty ONLY check is placed so set -e does not misfire; the comma-wrap check catches leading, trailing and doubled commas before the read -a split, which drops a trailing empty field and is why the whole-string check has to come first; the negated command substitution and the validate_only || exit 2 guard are both set -e safe. Placement confirmed from the source: validate_only runs inside parse_args, which main calls first, before the Docker checks, any uv run, and the container start.

Verified by the reviewer from a detached scratch worktree at this head: shellcheck -S warning clean on the new library; the 11 tests pass; the end-to-end GREEN run exits 2 with no results directory and no container created; RED confirmed on main, where the library does not exist and the test file fails. I had reproduced RED on main earlier the same way the PR body describes: exit 0, container cortex-bench-pg-17377 started and stopped, MANIFEST.json and START_SNAPSHOT.json written, nothing measured.

One SHOULD-FIX, non-blocking and disclosed in the PR body: --ablate-on flows through the same alias table and is not validated here; whether the downstream Python rejects an unknown name is a separate question and stays out of this change, which is the installer-style discipline of keeping a delivery to its subject.

CI on this head: 24 pass, 4 skipping, zero failures.

@cdeust
cdeust merged commit 7153f6d into main Sep 9, 2026
28 checks passed
@cdeust
cdeust deleted the fix/reproduce-only-fail-closed branch September 17, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant