Repository navigation
slice-10: post-quali calibration - #23
Merged
Meerav29 merged 2 commits intoOct 25, 2026
Merged
Conversation
…-miss listing Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bZTZNWERoJTnjfEPcTL8U
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bZTZNWERoJTnjfEPcTL8U
Meerav29
pushed a commit
that referenced
this pull request
Oct 25, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eih57hVHzqtaRFaQqnXdmG
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.
Tracking: #19. Closes
docs/phase2-status.mdcaveat 1 on the code side ("Calibration was not re-checked for post-quali"). Nothing here has been run against the real data.What this slice does
gp backtest --post-qualinow collects podium calibration for the post-quali arm, using the same rows and shape as the pre-weekend arm.calibration_podium_postquali.csv: one row per scored driver per round that post-quali scored. Its columns arep_podium_pred, podium_actual, season, round.calibration_podium.csvgets the same two trailing columns, so the original two columns keep their names and order.backtest_summary.json→calibration_podium: a binned table plus an ECE.precovers every scored round and is always written.--post-qualithe block also haspostqualiandpre_paired.pre_pairedis the pre arm restricted to the rounds post-quali scored, so you can comparepre_paired.eceandpostquali.eceover the same races.postquali_worse_roundsin the summary lists rounds where post-quali winner log loss exceeds pre-weekend's by more than 1.0 nats (POSTQUALI_WORSE_THRESHOLD_NATS), worst first. Each entry hasseason, round, log_loss_pre, log_loss_postquali, delta, grid_pole_driver, actual_winner. This is a list only. It feeds no verdict and claims no diagnosis.score_roundaddsactual_winnerandgrid_pole_driverto every row ofbacktest_metrics.csv. They are read from the race rows:finish_position == 1, andgrid_position == 1, the same grid post-quali conditions on.Diff: 252 added, 10 deleted across 4 files (
src/backtest.py, one new test file,decisions.md,queue.md).Review pack
About 20 minutes.
docs/autopilot/decisions.md(3 min). They set the bin scheme and ECE, and the 1.0-nat threshold.calibration_summaryandpostquali_worse_roundsinsrc/backtest.py(5 min). Together they are about 50 lines.PYTHONPATH=src pytest tests/test_postquali_calibration.py -qoutputs/phase2_2022_2025/, but that directory predates this slice and has no post-quali calibration rows, so the post-quali ECE needs a re-run:PYTHONPATH=src python -m cli backtest --seasons 2022-2025 --rounds all --method nuts --post-qualiThen compare
calibration_podium.pre_pairedwith.postqualiinbacktest_summary.json. Check thatpostquali_worse_roundscontains 2022 R13, 2022 R14 and 2024 R21. A cheaper smoke test is--seasons 2025 --rounds coarse; the gate will report invalid, but the calibration block is still written.Acceptance criteria
calibration_podium_postquali.csvin the same shape as the pre-weekend file.test_end_to_end_writes_both_calibration_files_and_both_summariesruns the realrun_backtest(post_quali=True)ondata/driver_rounds_fixture.csvwith ADVI. It asserts that both CSVs exist with identical columns and the same row count. In this test, NUTS conditioning is swapped for a 200-step ADVI fit to keep it to seconds.test_the_post_quali_arm_adds_one_calibration_row_per_scored_drivercovers the arm on its own (20 rows, 3 podium hits).test_binned_table_and_ece_match_a_hand_computationchecks ECE = 2/5·0.05 + 3/5·0.45. Further tests cover a perfectly calibrated arm (ECE 0), p = 1.0 landing in the top bin, and an empty arm reportingece: nullrather than 0. The end-to-end test asserts the three blockspre,pre_pairedandpostquali, each with bin counts summing to n.test_only_rounds_worse_by_more_than_the_threshold_are_listed_worst_firstcovers: deltas of +2.4 and +1.5 listed in that order; +1.0 (exactly at threshold), −0.5 and a NaN round excluded.test_post_quali_summary_carries_the_listing_and_its_thresholdchecks that the listing is JSON-serializable.test_score_round_names_the_pole_sitter_and_the_winnerchecks both names against the fixture's 2024 R1 rows.Evidence, from a fresh Python 3.11 venv (pymc 5.28.5, arviz 0.23.4):
That is 326 before this slice (the slice-9 review count) plus 9 new tests.
Tests fail without the change. On base
auto/queue, the new file errors at import because the new names don't exist. I also applied five mutations to this branch'ssrc/backtest.py. Each produced1 failed, 22 passedacross the new file andtest_backtest_postquali.py:run_backtestno longer passescalibration_rowsto the arm>=instead of>grid_pole_driveralways NoneNot caught: restricting
pre_pairedto the post-quali rounds. The fixture backtest scores a single round (2024 R2), sopreandpre_pairedare identical there, and replacingpre_pairedwithprewould pass. The code is a three-line merge on(season, round)inrun_backtest. Please read it there.Decisions made without you
Both are recorded in
docs/autopilot/decisions.md, 2026-10-25.phase2-status.mdalready reads the pre file ("the 0.5-0.6 bin"), and an n-weighted absolute-gap ECE. To make that ECE comparable across arms, I addedpre_pairedand theseason, roundcolumns. Rejected: quantile bins, which give each arm different edges so the tables can't be read side by side. Also rejected: comparing against all-roundspreonly, which would let a failed post-quali round change one side and not the other.phase2-status.mdnames (deltas 2.39, 2.24, 1.57). I can't tell from the sandbox how many of the other ten worse rounds clear it. Rejected: any positive delta, which lists all 13, most of them noise. Also rejected: a threshold relative to pre log loss, which is harder to read.Deliberately not included
p_winorp_points. The queue asks for the podium file's shape only.confidence.pyor the pkl.How to revert
git revert <merge commit>onauto/queue. The only shape change is two trailing columns oncalibration_podium.csvand new keys inbacktest_summary.json/backtest_metrics.csv, which nothing in the repo reads.Generated by Claude Code