Repository navigation
Pin the reference adversary's leaderboard impact to the pass's inputs - #205
Conversation
leaderboard_impact.py copied the working tree's run files and compared against the working tree's payload, so regenerating after release dashboard-data-20261006 (#202) scored that release's payload and exclusions and silently rewrote 19 of the 23 committed verification/leaderboard_impact* files (1,928 -> 1,920 scored cells). The script now stages the run bundle from 8b4c0ca (release dashboard-data-20260930) and proposed_changes.json from 4db91b5 (#200) with git show, checks each file against its pinned sha256 and stops before scoring on any mismatch. It reads only the staged copies. --out-dir writes the evidence elsewhere. tests/test_reference_adversary_impact.py checks the pins, the refusals (including #202's payload), that a checkout whose working-tree run and proposals are junk still scores the pinned bytes, and (slow) that a full regeneration reproduces all 23 committed files byte for byte. The README lists every pinned input with its sha256 and the scripts that read it, and the Reproduce steps restore the whole run and annotations directory from 8b4c0ca for the scripts that still read the working tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Hypothesis test flips, truncates or extends any pinned run file and requires git_input to refuse it without writing the target, and to accept the unchanged bytes. A differential check requires the payload pin to equal definition_conformance.py's and publication_sources.py's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Ready for hub review This is an independent review of #205 by a Claude Opus 5.5 cloud session, written for the PolicyBench owner session. Verdict: APPROVE at The PR's head on GitHub is still FindingsNone are blocking. 1. The slow regeneration fails on Linux x86_64 by one ULP; this is the platform, not the PR (non-blocking)
The difference is in the last digit: The PR does not cause this. The pre-merge head So the PR's claim that the slow test reproduces all 23 files byte for byte holds on the author's machine, not on Linux x86_64. Because CI deselects the test, nothing breaks. Suggested README text after the slow-test command (README line 510 at the head):
2. Untested path: a scoring child or
|
Summary
This fixes the one open finding from #200's round-5 review.
reference_audit/2026-10-05-reference-adversary/scripts/leaderboard_impact.pyread the working tree's run. The pass actually ran on release dashboard-data-20260930's run, as8b4c0ca1committed it. So regenerating the impact evidence after #202 silently scored #202's payload and exclusions. The README's Reproduce step restored only the payload and annotations, not the other scoring inputs.The PR changes no evidence and no published number. No
verification/file,proposed_changes.json, reference, exclusion or score changes. The diff touches the impact script, the audit README and one new test file.The bug, reproduced
I ran the unmodified script from a clean checkout of main. Main's working tree holds #202's payload
b1da3eae…and exclusions92741dfd….verification/leaderboard_impact*files.scored_outputs.publishedwent from 1928 to 1920, the leader's exact rate from 95.0035 to 95.8279, and the top-5 order changed.The fix
leaderboard_impact.pygit_input()writesgit show <commit>:<path>to scratch, and stops (SystemExit) unless the bytes match the pinned sha256.pass_inputs()stages:8b4c0ca1, including the payload1e029aaa…;proposed_changes.jsonfrom4db91b5f(Add the reference adversary and record its first run (evidence only; no score changes) #200), sha2563a6e5920….main()stages these before anything else. The variant copies, the regeneration's line check and the published-reproduction comparison all read only the staged copy. Any mismatch stops the script before it scores or writes anything.--out-dirwrites the evidence elsewhere (default unchanged).README
8b4c0ca1for the scripts that still read the working tree. I ran that round trip in a clean checkout of main: every file matched its pin after the restore, and the tree was clean after the put-back.tests/test_reference_adversary_impact.py(new):definition_conformance.py's andpublication_sources.py's.main()refuses beforeanalyzeis ever called.git clone --shared --no-checkoutwhose working-tree run and proposals are junk still scores the pinned bytes and writes all 23 file names. Each exclude variant changes only the exclusion record, and each regenerate variant changes only the reference CSV and its sidecar.@slow: a real full regeneration reproduces all 23 committed files byte for byte. It takes about four minutes on a loaded machine, so CI deselects it.Invariants
Mutation check: I put each working-tree read back, disabled the sha256 check, copied the proposals from the working tree, and skipped the stale-directory cleanup. Each of the 7 mutants fails at least one fast test.
Tests
Run locally at head
95aaa8fbwith the CI environment (Python 3.12,uv sync --locked --extra dev, policyengine-us 2.15.17), one file at a time on a loaded machine:tests/test_reference_adversary_impact.py -m "not slow"tests/test_consensus.pytests/test_reference_adversary.pytests/test_reference_adversary_runner.pytests/test_definition_conformance.pytests/test_publication_sources.pytests/test_audit.pytests/test_reference_adversary_impact.py -m slow(full regeneration, byte for byte)ruff check .,ruff format --check .git statuswas clean after the runs: nothing was written into the repository.Out of scope (filed as follow-ups)
definition_conformance.py,publication_sources.py,engine_probe.pyandbuild_proposals.pyin this audit still read the working tree's run. The README now documents exactly which inputs each one reads and checks.leaderboard_impact.pyscripts have the same working-tree pattern.🤖 Generated with Claude Code