Skip to content

Review policyengine-uk 2.151.0 as an exact Budget wheel beside 2.147.2 - #38

Merged
MaxGhenis merged 4 commits into
mainfrom
d2011-uk-2151-support
Oct 26, 2026
Merged

MaxGhenis merged 4 commits into
mainfrom
d2011-uk-2151-support

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Draft; review fix pushed, re-review pending. This adds policyengine-uk 2.151.0 as an exact, reviewed model version beside 2.147.2. It changes no binding pin.

Why now

d2011 chose the Microcosm cut the UK Budget dashboard certifies. Max ruled A on 25 October: María's 2.151.0 national and local-area pair, cut a6299504, built at PolicyEngine/microcosm#1396 (67ee2ddf3), whose uv.lock pins the 2.151.0 wheel this PR attests. The release is due around 23:00Z on Monday. The triple-lock bridge slot opens at 07:00Z on Tuesday. d1983 put the binding rebuild on #715's certified pair. That ruling's reason (Microcosm, clean data) holds for either cut, so this repo follows the pair d2011 certifies; the d2011 note says so. This PR does the version review ahead of time, so the switch (#39, stacked on this) is one pin commit after the release rather than a review on the critical path.

What changes

  • model_horizon: UPSTREAM_2151 / UPSTREAM_2151_PARAMETERS name the 2.151.0 bytes, and check_upstream() accepts exactly 2.151.0. The 2.147.2 absence guards (#2576's builders, the Savings Credit maximum, #2340's age addition) apply to it too. Any other version still fails closed.
  • Household income lists (review fix, a9b25b9). household_tax.py and household_benefits.py are now guarded on 2.125.1, 2.147.2 and 2.151.0. engine.household_income_bridge imports their lists and mirrors household_benefits' council tax and uprating terms, and both change in 2.151.0. A test requires every policyengine_uk.variables module the package imports to be guarded on each live cut.
  • data/certification/d2011-model-wheel.json: the wheel attestation, with archive SHA-256 equal to PyPI's metadata and all 3,176 RECORD members checked for digest and size. The generator first reproduced the committed d1983-model-wheel.json byte for byte. Core 3.33.3 is unchanged.
  • docs/d2011-upstream.md: every changed guard read against 2.147.2 (5 of 33 modules, all 11 parameter files), what it means for the engine, and all 27 PRs merged in the range, each read and classified. docs/d1983-upstream.md records the household-list additions from 2.125.1 to 2.147.2.
  • Tests: the Budget-wheel tests run on both wheels, each with its own expected benefit index. New tests cover the guard maps and the absence guards on 2.151.0.
  • docs/REBUILD.md: what changes under d2011 A.

What 2.151.0 changes for this model

  • #2557. gov.benefit_uprating_cpi follows September CPI, so April 2027's benefit uprating uses the path's September 2026 input (3.5% on the committed inputs), not 2.147.2's installed calendar-2026 forecast. path_following already has this branch.
  • The Pension Credit guarantee, both Savings Credit thresholds and the six pension-age HB allowances now name lagged calendar CPI themselves, the projection they reached through gov.benefit_uprating_cpi on 2.147.2. #2576 is not in 2.151.0, so d1753's question is unchanged.
  • gov_tax gains gambling duty and gov_spending gains Widowed Parent's Allowance. fiscal_variables reads the installed lists. Household tax and household benefits gain the same two, so they cancel in household_income_bridge.
  • LTT and LBTT (#2315, #2329). expected_ltt and expected_lbtt (in gov_tax) now add the annual tax instead of multiplying it by 0.045, and residential lease rent is exempt. They depend on country, property values and rent, not income or the State Pension, so they move the gov_tax level, not the reforms' changes.
  • Also read: current_education carry-forward (#2403), which reaches Pension Credit's qualifying young person and the SDP non-dependant test; SPP as earnings (#2368); CTR for UC claimants (#2552); IR-ESA ending on UC (#2563); declared-basis energy projection (#2571). Bridge step (a) measures them with the rest of the model change.
  • Unchanged: State Pension formulas, State Pension age, Scenario and reform application, and every builder model_horizon extends.

Not in this PR (the pin switch, after d2011 and the release)

pyproject.toml, requirements-lock.txt, CI, datasets.py (the a6299504 artifact's revision and SHA-256, the release's version and manifest digest), config.PRIMARY_DATASET, data/binding-bridge.pending.json's endpoints, and the release wording in pipeline.py and engine.py. That is #39.

Invariants

  • check_upstream() accepts exactly the reviewed versions and refuses any changed byte in a guarded file, and any absent-guarded file present, for both 2.147.2 and 2.151.0.
  • Every policyengine_uk.variables module the package imports is guarded on 2.125.1, 2.147.2 and 2.151.0. The exception is the age addition, imported only to detect it, whose absence is guarded on 2.147.2 and 2.151.0.
  • On each Budget wheel, path_following's benefit check uses the index that wheel's gov.benefit_uprating_cpi names, and the run fails on any other index.
  • The guarantee override leaves the installed Savings Credit and HB projections unchanged on both wheels (no #2576 builders).

Verification

No survey or Microcosm simulation was run. Details are in docs/d2011-upstream.md.

  • CI: passes on 2.147.2 (the binding environment).
  • 2.151.0 environment (the same lock with only policyengine-uk changed):
    • Model-facing tests: 379 passed, 5 skipped. The 2 failures are test_datasets' pin-agreement tests, which fail by design because the binding pin is still 2.147.2.
    • The changed tests: 22 passed, 0 skipped at a9b25b9. On 2.147.2 they give 17 passed and 5 skipped, the 2.151.0-only cases.
    • At a9b25b9, check_upstream() passes on 2.125.1, 2.147.2 and 2.151.0. A changed digest for either household list is refused on each. test_model gives 26 passed on 2.151.0 and 23 passed, 3 skipped on 2.147.2. test_state_pension_age_addition and test_engine_pure give 50 passed on each.
    • check_state_pension_upstream.py --expect-age-addition absent and housing_benefit_passport_preflight() pass.
    • The installed wheel matches the attestation's 3,176 members.
  • Dependent projections: the guarantee, Savings Credit and pension-age HB amounts for 2026–2039 equal 2.147.2's to within £1.2×10⁻¹³ a week.
  • Independent review: GPT-6.1 Sol on 35def04 asked for the household-list guards, the LTT/LBTT audit rows and the module count; a9b25b9 makes all three. Re-review pending.

d2011 update (25 Oct ~20:50Z): Max ruled A. The triple-lock rebuild follows the certified 2.151.0 pair, with the a133 fallback if it isn't certified by Tue 27 Oct 18:00Z. The pin switch is #39, stacked on this.

🤖 Generated with Claude Code

d2011's recommended pair (Microcosm a6299504, microcosm#1396) runs on
policyengine-uk 2.151.0. Add its source guards, wheel attestation and
file-by-file audit against 2.147.2, and run the Budget-wheel tests on both.
No binding pin moves: #715's 2.147.2 / a133f37a pair stays pinned until
d2011 is ruled and a certified release exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
uk-triple-lock Ready Ready Preview Oct 26, 2026 12:40am UTC

Request Review

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…2.151.0 change

Review of 35def04: engine.household_income_bridge imports household_tax's and
household_benefits' lists and mirrors household_benefits' council tax and
uprating terms, but neither file was guarded, and both change in 2.151.0
(gambling_duty, widowed_parents_allowance). They are now guarded on 2.125.1,
2.147.2 and 2.151.0, with tag and installed-wheel bytes checked, and a test
requires every policyengine_uk.variables module the package imports to be
guarded on each live cut.

The d2011 audit now covers all 27 PRs merged between 2.147.2 and 2.151.0,
including LTT/LBTT (#2315, #2329), current_education (#2403), SPP (#2368),
CTR (#2552), ESA (#2563) and energy projection (#2571). The guard count is
33, not 30. d1983's audit records the 2.125.1 to 2.147.2 household-list
additions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 25, 2026
…nding

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…9 and #2569 exactly

Review of a9b25b9: the band above GBP 2m on lease rent is 2% from 7 February
2020 (SSI 2020/24), not 5% from 25 January 2019; #2129 and #2569 change release
scripts and a lock workflow, not uv.lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 26, 2026 04:06
@MaxGhenis
MaxGhenis merged commit 0672237 into main Oct 26, 2026
6 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Merge audit (head bcd807e44ff65a5b96094941b9f1cb1dbdb38b81).

  • Independent review: GPT-6.1 Sol, hard tier, three rounds.
    • Round 1 (35def04): REQUEST_CHANGES. The household tax and benefit lists engine.household_income_bridge mirrors were unguarded, and the LTT/LBTT audit was incomplete.
    • Round 2 (a9b25b9): REQUEST_CHANGES. The audit omitted #2329's non-residential LBTT rent correction, and two PR descriptions were wrong.
    • Round 3 (bcd807e): APPROVE, no defects. The numbers were rechecked: £23,500 on 2.147.2 and £20,500 on 2.151.0 for £2.1m new non-residential rent; the old expected_lbtt was £1,057.50.
  • Guards. Round 2 verified:
    • 240/240 digest comparisons against the release tags and installed wheels;
    • 11/11 regression mutants rejected;
    • check_upstream() passing on 2.125.1, 2.147.2 and 2.151.0.
  • CI: every check passes on the latest run at this head (Pipeline, Dashboard, Vercel).
  • Scope:
    • This PR adds 2.151.0 support: source guards, tests and the 2.147.2-to-2.151.0 audit.
    • It moves no binding pin, dataset or primary; Bind the d2011 pair: UK 2.151.0 and Microcosm a6299504 (policyengine.py 6.11.1) #39 does that, and is still pending the policyengine.py release.
    • Protected material is untouched: expected_value.py, redact_records/RECORD_FIELDS, the frozen C2 section, handoffs and receipts.
    • No survey or Microcosm simulation was run.
  • Gates:
    • checks green on the latest run;
    • MERGEABLE, not a draft, no CHANGES_REQUESTED review;
    • the hard review approves this exact head;
    • merged with a merge commit, as this repository's history does.

🤖 Generated with Claude Code

MaxGhenis added a commit that referenced this pull request Oct 26, 2026
Both conflicts resolve to this branch's side: the #40 text it cherry-picked, with
a6299504 named, and the pair's re-pointed registry entry. #38's final LBTT and
#2129/#2569 audit wording comes from main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis deleted the d2011-uk-2151-support branch October 26, 2026 05:37

This branch was successfully deployed

1 active deployment
Preview — bcd807e4 Deployed Oct 26, 2026 by vercel[bot]
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