Repository navigation
Fix Pension Credit and pension-age Housing Benefit earnings uprating - #2576
Conversation
|
UK hub handoff — draft stacked on #2557; runtime validation and impact pending. Head:
Workspace artifacts: |
…phase-in The three Housing Benefit allowances for those who reached State Pension age before April 2021 are the Pension Credit standard minimum guarantee plus the maximum Savings Credit (HB A3/2021, paragraphs 3-5); every published amount from 2019-20 to 2026-27 is that sum rounded up to the next 5p. Uprating the whole allowance by earnings overstated the CPI part. Keep the published amounts and derive later years as the projected guarantee plus the projected maximum, after general uprating, as the Savings Credit threshold already is. April 2027: 265.8706 a week single and lone parent, 398.22025 couple, before rounding. A reform setting the Savings Credit phase-in rate to zero divided by zero while rebuilding the system. A zero rate pays no Savings Credit at any threshold, so that year now keeps the threshold in force before it. The synthetic property test built its Pension Credit and HB nodes from empty dicts, which Core reads as parameters, so it failed with AttributeError before checking anything (CI run 39826914200, shard 3). Build the nodes explicitly, and extend it to the higher allowances and to arbitrary phase-in paths including zero. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d one A dated change to a higher pension-age HB allowance is kept for its year and prior law resumes after it. A change to the guarantee moves the allowance derived from it in that year only, and leaves the lower allowance, which has its own earnings projection, unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
UK hub hand-off: review fixes pushed. Ready for the hub's independent review at Head: Review (
Tests (local, foreground,
CI on
Impact (run 39897398176, pass;
The review fixes alone, against the Depends on: nothing open (#2557 merged). No Max decision is pending. Axiom: rulespec-uk#366 queued, unchanged; the HB composition adds no statutory rule. Open items for review:
Do not merge from this job; the hub dispatches the GPT-6.1 Sol review at |
Brings in #2557 (the base this PR was stacked on, now merged) and the other PRs merged since, so the PR workflow runs against main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aggregate impact on certified data: passBase Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 53 (thresholds in Notes
Moves flagged for review
13 more flags are in the report artifact. Receipts by tax head
Spending by benefit and service
Caseloads
Government balance, each component counted once
Model totals
Household income totals
Poverty rates
People in poverty
Inequality
Mean household net income in each side's own deciles
Standard reform costings (change in gov_balance)
Standard reforms: change in each reform's target
Household net income by decileMean change in household net income per household, and as a share of the decile's base income; households stay in the base run's deciles.
No change in any year: population. Checks failing on both base and head (1)
Counted-once checkEach of 84 components was raised by £1 per unit in 2026-27, and every head of its totals was read household by household: its own head must rise by exactly £1, no other tax head may move, no other benefit may rise, and the model's own total must move by what its heads moved. A head that breaks a rule is measured again twice: with every other head held at its baseline value, and with every other head held at its value after the first £1 while the component rises again. It fails where either still shows the response. 0 failed; 0 were skipped. Provenance
Dataset: Receipts by tax head: head levels
Spending by benefit and service: head levels
Caseloads: head levels
Government balance, each component counted once: head levels
Model totals: head levels
Household income totals: head levels
Population: head levels
Poverty rates: head levels
People in poverty: head levels
Inequality: head levels
Mean household net income in each side's own deciles: head levels
Standard reform costings (change in gov_balance): head levels
Standard reforms: change in each reform's target: head levels
|
|
Merged by the UK hub (Claude session 8e19f9d5) at head
TV licence receipts fall £0.9m to £1.9m, because more over-75s on Pension Credit get a free licence. Nothing moves before 2027-28.
|
Resolves three conflicts with #2576, which counts statutory paternity pay as Housing Benefit earnings: both docstrings now name paternity pay and the tax before the winter fuel payment charge, and the net earnings tests keep #2576's two paternity pay cases and this branch's charge case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes F1 from the #2557 review. This PR was stacked on #2557 (head
9f2ebfc829684052b526b06874f3c6f725ec608d). #2557 merged on 23 October 2026 at 04:16Z (merge commitb1dbf8b03), and GitHub retargeted this PR to main. It is still a draft: the hub owns review and landing.The April 2027 Pension Credit standard minimum guarantee previously rose only 2.3%, below May–July 2026 earnings growth of 3.9%. This PR projects the guarantee, and the three lower pension-age Housing Benefit personal allowances that equal it, using the earnings input the triple lock already uses. The Savings Credit maximum is uprated by September CPI. Projected Savings Credit thresholds are
SMG − maximum / phase_in. The three higher pension-age HB allowances areSMG + maximum. Published historical amounts are retained.I read SSAA 1992 s150A: subsection (1)(d) includes the guarantee and (2) sets an earnings minimum. There is no additional CPI floor. The projection uses earnings alone and holds amounts when earnings fall; discretionary published increases remain explicit. This differs from the State Pension triple lock. The new earnings index retains full precision so rounding index levels cannot undercut the earnings floor.
Review fixes (head
566b0b9aa)The hub's review of
2db324bb6(~/reviews/uk-hub/reviews/uk2576/REVIEW_2576.md) approved the guarantee correction and raised two P2s. Both are fixed, along with a third defect found while running the tests.housing_benefit/allowances/{single,couple,lone_parent}/aged.yaml). DWP HB circular A3/2021 paragraph 3 says each is "the Standard Minimum Guarantee (in Pension Credit) plus the maximum amount of Savings Credit".2db324bb6instead uprated the whole allowance by earnings, which overstated the part that follows CPI.uprating.create_pension_age_allowances.pyruns after general uprating, on the main tree and its baseline copy, as the threshold projection does. For each year after an allowance's last published amount, it sets the allowance to the projected guarantee plus the projected maximum.SMG + 0.6 × (SMG − threshold)rounded up to the next 5p.{"gov.dwp.pension_credit.savings_credit.rate.phase_in": {"2027": 0}}raisedZeroDivisionError: float division by zerowhile the system was rebuilt. I reproduced this by swapping the reviewed head's projector into the current build. A zero rate pays no Savings Credit at any threshold, and the maximum then fixes none. So a year with a zero rate keeps the threshold in force before it: £208.07 for 2027-28. The reform now builds and pays £0 Savings Credit in 2027-28. 2028-29 matches current law.2db324bb6it failed withAttributeError: 'Parameter' object has no attribute 'add_child', before checking anything (run 39826914200, shard 3). Its synthetic tree built the Pension Credit and HB nodes from empty dicts, which Core parses as parameters. The nodes are now built explicitly. The test now also covers the higher allowances and arbitrary phase-in paths, including zero.Under a reform, the derived allowance reads the reformed guarantee and maximum, as the threshold does. A dated change to an allowance itself is kept for its period, and prior law resumes after it. A test runs both cases.
April 2027 hand calculations (weekly, before rounding)
The lone-parent allowances equal the single ones. At
2db324bb6the higher allowances were £256 × 1.039 = £265.984 and £383.35 × 1.039 = £398.30065.Sources: DWP 2026–27 rates, HCWS1101, HB A3/2021, and the completed ONS KAC3 May–July earnings and D7G7 September CPI inputs adopted by #2557. The DWP single Savings Credit maximum is £17.96. These are projections, before future ministerial rounding or discretionary uplifts.
Invariants
Each holds for every earnings, CPI and phase-in path.
test_pension_credit_uprating.pychecks each with Hypothesis on a synthetic tree built from the production parameter files, and in current law through 2039.Validation
All runs were local, in the foreground, with
-n 2and BLAS/OpenMP threads at 2. Each test run started with load1 at most 88, and free disk was 110–111 GB (decimal) at every check.policyengine_uk/tests/test_pension_credit_uprating.py: 33 passed. The new reform test passed separately, withtest_council_tax_reduction_young_person_properties.py(7 passed).test_dwp_published_rates.py,test_housing_benefit_pension_age_cohorts.py,test_september_cpi_uprating.pyandtest_state_pension_credit_qualifying_age.py: 1,399 passed and 65 skipped. The three higher allowances now skip the published-rate continuity check as "not uprated", which the outcome allowlist accepts. Invariant 2 covers their projection.uvx ruff format --check .(1,925 files),uvx ruff check .andgit diff --checkpassed.tax_benefit_system.py(W1-owned) gains only one import and two calls to the new projection, beside the threshold projection. No other W1 or W3 file changes.Impact
Aggregate impact run 39897398176 passed. It compares #2557 head
9f2ebfc82with this head566b0b9aa, both onenhanced_frs_2024_25.h5(policyengine-uk-data 1.58.1), for fiscal years 2025-26 to 2031-32. No check broke and none was fixed. The one failing check, "VAT is never negative", fails on both sides. 56 moves are flagged for review, as at2db324bb6. The spending changes are:The review fixes alone, measured against the
2db324bb6run (39826945528) on the same base and data, lower HB spending by £0.21m in 2027-28, rising to £0.44m in 2031-32. They lower CTR by £0.09m to £0.23m, and total government spending by £0.30m to £0.68m. Pension Credit is unchanged. These are allowed bug-fix aggregate changes. No local microsimulation or dataset build was run.Code changes run 39897395365 on this head is in progress. I dispatched both runs once at 03:53Z: the PR still targeted #2557's branch then, and these workflows trigger only on PRs to main. The retarget did not start the
pull_requestruns; only Fix evidence ran.Reproducer: policyengine_uk/tests/test_pension_credit_uprating.py::test_zero_phase_in_reform_builds_and_pays_no_savings_credit, policyengine_uk/tests/test_pension_credit_uprating.py::test_higher_hb_allowances_keep_each_part_on_its_own_index, policyengine_uk/tests/test_pension_credit_uprating.py::test_baseline_smg_and_hb_respect_the_earnings_floor_in_every_projected_year, policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/pension_age_earnings_uprating.yaml::April 2027 higher single pension-age HB allowance is the guarantee plus the Savings Credit maximum, policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/guarantee_credit/standard_minimum_guarantee.yaml
axiom: TheAxiomFoundation/rulespec-uk#366 queued
The existing parity issue covers s150A(1)(d)/(2) and records the signed-corpus/encoder blocker. rulespec-uk#367 covers the linked prices-review provision. The higher HB allowances add no statutory rule: Schedule 3 states each year's amount, and the guarantee-plus-maximum composition only projects the unpublished years. No billed signed-encoder run is authorized in this job. The hub owns independent review and landing.
🤖 Generated with Claude Code