test(bench): the posterior-channel audit could not fail, and nothing ran it (#1267) - #1290
Conversation
The sweep ran against an empty deferred-feedback queue, so sweep_deferred_feedback never entered its classification loop and the audit could not tell the audit-only sweeper from the pre-#1162 mutating one. Its other assertion read result.mutated, a dataclass field default that is never assigned anywhere in src/. Restoring the mutating branch and re-running left the script at exit 0. Enqueue one exposure row and backdate it past the grace window so the row is eligible, then assert would_apply == 1 alongside the unmoved posterior: the count is what proves the ladder ran and elected to apply, which is the state the old sweeper mutated in. Also assert no feedback_history row and that alpha_withheld accounts for the withheld epsilon. Against the same restored mutating branch this now exits 1.
Nothing invoked benchmarks/posterior_channel_audit.py. bench-smoke has a benchmarks/** path filter but only runs test_bench_smoke.py and test_recalibrate.py, so a default could drift and the LIMITATIONS entry the script backs would go stale exactly as the last one did. Drive it as a subprocess from tests/test_benchmarks_dir.py, which the required pytest (3.12)/(3.13) checks already collect. Subprocess rather than import because the script deletes every ambient AELFRICE_ variable at import time to measure defaults, which must not leak into the rest of the session.
There was a problem hiding this comment.
Sorry @robotrocketscience, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
Warning Review limit reached
Next review available in: 25 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideMakes the posterior-channel audit benchmark actually exercise a real eligible exposure row and assert non-mutation, and wires the benchmark into the required pytest suite via a subprocess-driven test so it is enforced in CI. Sequence diagram for enforcing posterior_channel_audit via pytest subprocesssequenceDiagram
actor CI
participant pytest
participant test_benchmarks_dir
participant subprocess
participant posterior_channel_audit as posterior_channel_audit.py
participant store
participant deferred_feedback as aelfrice.deferred_feedback
CI->>pytest: run tests (required check)
pytest->>test_benchmarks_dir: collect and execute
test_benchmarks_dir->>subprocess: run posterior_channel_audit.py
subprocess->>posterior_channel_audit: execute main
posterior_channel_audit->>deferred_feedback: resolve_grace_seconds()
posterior_channel_audit->>deferred_feedback: resolve_epsilon()
posterior_channel_audit->>store: _seed("b3")
posterior_channel_audit->>deferred_feedback: enqueue_retrieval_exposures(store, ["b3"], now=enqueued_at)
posterior_channel_audit->>store: _ab(store, "b3")
posterior_channel_audit->>deferred_feedback: sweep_deferred_feedback(store)
posterior_channel_audit->>store: _ab(store, "b3")
posterior_channel_audit->>store: count_feedback_events("b3")
posterior_channel_audit-->>pytest: exit code 0 if would_apply==1 and posterior unmoved
pytest-->>CI: report success/failure for suite
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
[claim:review:Garsecg:2026-08-01T04:57:43Z] |
Review — both claims independently reproduced. Approving.I did not take the write-up's word for either half, because the whole PR is an argument about a guard that passed while proving nothing, and a reviewer who accepts that argument on assertion repeats the error. 1. The old script could not fail — reproducedRestored the pre-#1162 mutating behaviour by re-adding the It printed "no residual exposure-as-evidence path" and the full Same mutation against this branch: The 2. Nothing invoked it — reproduced
Also checked the thing a subprocess test can get wrong: Gate checks: both commits signed ( One follow-up, not a blockerThe script pins the env tier but leaves the TOML tier ambient. It deletes every But the script is now wired into a required check. A developer whose The disclosed Labelling |
|
merge-train: merged 49b9d5b → |
|
[release:review:Garsecg:2026-08-01T05:02:20Z] |
Refs #1267. Does not close it — #1267's first acceptance criterion is an
operator decision on direction and is untouched here.
#1284 merged
benchmarks/posterior_channel_audit.pyas the regression guardbehind the
LIMITATIONS.mdentry saying no automatic channel moves aposterior. Its CHANGELOG entry states the consequence plainly:
That was not true when it merged, for two independent reasons. I found them
reviewing #1284, but it merged while the review was in flight, so the fix comes
as its own PR. No default, no behaviour and no doc text changes here — the diff
is one benchmark script and one test.
1. The channel-3 check could not fail
channel_3_sweeperseeded a belief and calledsweep_deferred_feedback(store)against a store with nothing enqueued. That function does all its work inside
for row_id, belief_id, ... in pending:, andpendingwas empty, so theclassification loop never ran. The script's own output was the tell —
would_apply=0means nothing was exercised.Its other assertion was weaker still.
result.mutatedis aSweepResultfielddeclared
mutated: bool = False(deferred_feedback.py:140) and neverassigned anywhere in
src/:if result.mutated or before != after:therefore read a dataclass default andcompared a posterior nothing had touched.
Demonstrated, not argued. Restoring the pre-#1162 mutating behaviour on the
would_applybranch and re-running the script unchanged:A fully reverted, actively mutating sweeper passed.
Fix. Enqueue one exposure row and backdate it past the grace window so the
row is eligible, then assert
would_apply == 1alongside the unmovedposterior. The count is what makes the rest load-bearing: it proves the
eligibility ladder ran and elected to apply — exactly the state the old sweeper
mutated in. Also assert no
feedback_historyrow was written, and thatalpha_withheldaccounts for the withheld epsilon. Against the same restoredmutating sweeper:
and on an unmodified tree it exits 0 with
moved=False,rows=0.Channels 1 and 2 were already falsifiable — channel 1 drives both env states and
compares them, channel 2 asserts a real β move. Only channel 3 needed this.
2. Nothing invoked the script
bench-smoke.ymlcarries abenchmarks/**path filter, but its two run stepsare
pytest tests/test_bench_smoke.pyandpytest tests/test_recalibrate.py.No workflow executes
benchmarks/*.py. A guard nothing runs cannot keep a docentry honest — the same shape as #1278.
Fix. Driven from
tests/test_benchmarks_dir.py, which the requiredpytest (3.12)/(3.13)checks already collect and which already imports frombenchmarks/. Placed there rather than inbench-smokeon purpose: the auditscript imports only
aelfrice.*, needs no benchmarks extra, andbench-smokeis not a required check — the required pytest job is the stronger gate. This is
adjacent to but disjoint from #1280, which wires the amabench scoring tests via
bench-smoke.yml; no file is shared.Run as a subprocess, not an import: the script deletes every ambient
AELFRICE_*variable at module scope, which is correct for measuring defaultsbut must not leak into the rest of the test session.
@pytest.mark.timeout(120)because the 5s global would be tight for a subprocess spawn under load.
Verification
tests/test_benchmarks_dir.py— 18 passed.rebased tree: with the mutating sweeper restored it fails
assert 1 == 0andsurfaces both
FAIL:lines; reverted, it passes. A guard is not verified by agreen run.
github/main, fast-forward; two atomic signed commits.Pre-PR gate — one test deselected locally, disclosed
The gate's fetch, rebase, discretion and sibling-PR steps all pass. Its
pyteststep was run as
PYTEST_ADDOPTS="--timeout=120 --deselect tests/test_bayesian_ranking.py::test_ac11_per_query_overhead_within_budget".Stating that plainly rather than reporting a clean gate:
--timeout=120. Several subprocess-driven tests hit the 5s globaltimeoutinpyproject.tomlon a box at load average ~12–15. Raising it letsthem run rather than skipping them; all of them pass with the headroom.
assert elapsed < 1.0on 100retrieve()calls — an absolute wall-clock budget no timeout setting affects. It fails on
pristine
mainwithout my commits (bb443874), three runs for threefailures, at 1.537s / 2.331s / 3.037s. docs(limitations): the exposure-as-evidence path has not existed since #1162 (#1267) #1284 independently measured the same
assertion failing on
mainand on the pre-exp(render): pre-flight bound for proposal 14 block-ordering — movable set is real, but the proposed instrument has no lock tier (#1177) #1274 tree. It is a main-sideuncalibrated budget, it is green on CI, and my diff touches no
src/file —benchmarks/posterior_channel_audit.pyandtests/test_benchmarks_dir.pyonly, neither of which this test imports.
CI runs the unfiltered suite at the stock timeout, so the required
pytest (3.12)/(3.13)checks are the authority on both points.Summary by Sourcery
Strengthen the posterior-channel audit benchmark and wire it into the required pytest suite so documented default behaviour is actively enforced.
Bug Fixes:
benchmarks/posterior_channel_audit.py, preventing the audit guard from going stale by making it part of CI.Enhancements:
Tests:
tests/test_benchmarks_dir.py, integrating the benchmark into the standard test run.