You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Builds of the same code calibrate to two different weight sets #598
Pull request builds of the same data code calibrate to two distinct sets of weights. The targets are identical between them, and the difference is about five times the run-to-run dropout noise.
Evidence
Five pull request builds ran on one data code state: main from b34a4ea to 2b9c1c2 changed only CI and docs. They were docs-only, changelog-only and CI-only PRs, all TESTING builds at 32 epochs, on the same runner image (ubuntu24/20261004.327). The national rows of each run's final-epoch constituency_calibration_log.csv (epoch 30), compared pairwise as per-target change in |estimate / target − 1|:
Pair
Per-target change, p99
Max
Max on obr/*, ons/uk_population, dwp/* (159 targets)
Within group A: runs 38006434333, 37960852139
0.025
0.040
0.027
Within group B: runs 37959581668, 38009046475, 37864653693
0.031–0.039
0.077–0.179
0.013–0.020
Between A and B
0.163–0.170
0.607–0.620
0.210–0.215
The national share of targets within 10% stays within 0.646–0.655 in every build.
Per target, the two groups differ most on CGT bands, the benefit cap totals and the UC payment distribution.
Every constituency target value is identical across the five builds. Every national target value is identical too, except the Scottish council tax bands that Scottish council tax targets change with whether a download succeeds #596 explains. That difference doesn't follow the groups: run 38009046475 has group A's Scottish targets and group B's fit.
Neither runner region nor image follows the groups: region is centralus and eastus in both.
So something in the data build itself, before calibration, takes one of two states. The dropout noise is the much smaller within-group spread, which #507 seeds.
Why it matters
The W3 no-worsening gate compares a pull request's build with its base's, under a matched protocol. A same-code difference this large in either direction swamps the changes it is meant to attribute: 0.21 on key OBR and DWP targets. It has to be found and removed, or measured and allowed for, before a per-target comparison can gate.
Next step
Diff the pre-calibration datasets of two builds from different groups, as aggregates by variable. The divergent step probably shows up as an imputed variable whose totals take two values. Candidates are any imputation or download with unseeded randomness or order dependence.
The same nondeterminism, measured on model outputs.#602's CI runs policyengine-uk's aggregate-impact tool on both builds of a pull request, with the model held fixed (policyengine-uk 2.122.2, identical runtimes), and compares national aggregates.
#602 changes only CI, so both builds come from the same data code. Even so, in run 38802651315 the head build differs from the base build by:
capital gains tax: +£0.90bn (2025-26) to +£1.14bn (2031-32) a year, about 1.7%;
child poverty after housing costs: +0.76 to +1.04pp, relative and absolute;
child poverty before housing costs: +0.58 to +0.69pp;
337 moves above the report's flag thresholds in all.
The fit comparison in the same run moved 12 of 644 national targets to a worse error band, at the top of the 2–12 range of the five same-code builds above. The CGT and UC lines match this issue's largest per-target differences (CGT bands, the UC payment distribution).
So until this is fixed, a data PR's aggregate moves of this size can't be attributed to its change. #602 flags them but fails only on broken checks for that reason. These are national aggregates from the PR comment, which is already public; no record-level value is involved.
Activity
MaxGhenis commentedon Oct 16, 2026
The same nondeterminism, measured on model outputs. #602's CI runs policyengine-uk's aggregate-impact tool on both builds of a pull request, with the model held fixed (policyengine-uk 2.122.2, identical runtimes), and compares national aggregates.
#602 changes only CI, so both builds come from the same data code. Even so, in run 38802651315 the head build differs from the base build by:
The fit comparison in the same run moved 12 of 644 national targets to a worse error band, at the top of the 2–12 range of the five same-code builds above. The CGT and UC lines match this issue's largest per-target differences (CGT bands, the UC payment distribution).
So until this is fixed, a data PR's aggregate moves of this size can't be attributed to its change. #602 flags them but fails only on broken checks for that reason. These are national aggregates from the PR comment, which is already public; no record-level value is involved.
🤖 Generated with Claude Code
Report duplicate target names, scope known gaps to a build kind, and …
Diagnostic only: excuse every top UC payment band in release builds (#…
Diagnostic only: excuse every top UC payment band in release builds (#…