Repository navigation
Conversation
Budget 2026 paragraph 6.254 and the policy costings (page 23) raise the Income Tax trading allowance from £1,000 to £3,000 from 6 April 2027, to be legislated in Finance Bill 2026-27 (Table 6.1, item 15). The £1,000 YAML cases move to 2026-27; new 2027-28 cases cover full relief at £3,000, the cliff just above it, partial relief and expenses above the allowance. The property test's allowance and boundary draws move to £3,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…7-28 Budget 2026 paragraphs 6.246 and 6.247 add 2 percentage points to the savings and property rates from 6 April 2027, on top of Budget 2025's 22%, 42% and 47%: 24%, 44% and 49% (Table 6.1, items 61 and 62). Property rates apply in England, Wales and Northern Ireland, which the model already does (Scottish taxpayers' property income stays on the Scottish rates); savings rates apply UK-wide. Finance cost relief reads the property basic rate, so it rises to 24%, as the costing note says. The ISA cash-interest charge reads the savings basic rate (SI 2026/1018 reg. 22A(3)), so it rises too. Tests: hard-coded 22/42/47% expectations recomputed at 24/44/49%; new Budget 2026 YAML cases for each band and country; property tests for the exact 2-point rise, Scotland's exclusion from property rates, UK-wide savings rates and the finance cost relief bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Budget 2026 (paragraph 6.211; policy costings page 13) extends the 5p cut from 1 January 2027 to 1 July 2027. On that date rates rise by 5p and are uprated by RPI, then by RPI each 1 April from 2028. Other road fuels keep a proportionate cut to the same date. - petrol_and_diesel.yaml: 52.95p to 30 June 2027; the January and March 2027 steps are gone. The generator now uprates the 57.95p pre-cut rate by 2026 RPI on 1 July 2027, then each 1 April from 2028. - lpg.yaml, natural_gas.yaml: full rates from 1 July 2027. - Tests and the excise duty engineering note follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Budget 2026) Budget 2026 (paragraph 6.210; policy costings page 12) extends the temporary 0% rate from 31 March 2027 to 1 July 2027, and expects it to apply UK-wide from April 2027 (section 4.3: "Extended VAT relief is expected to apply in Northern Ireland from April 2027"). - great_britain.yaml: 5% returns on 1 July 2027, not 1 April. - northern_ireland.yaml: 0% from 1 April to 30 June 2027. - Tests follow the new day weights: FY 2026-27 GB 178/365 at 5%, NI 360/365; FY 2027-28 280/366 at 5% in every nation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Budget 2026 (paragraph 6.24; section 4.3; Table 6.1 item 1) gives £100 to
households in council tax bands A to D in England, delivered by local
authorities from January 2027. The devolved governments get a Barnett
share instead, which the model does not allocate.
- Parameters gov.treasury.household_energy_payment.{amount, bands,
countries}: £100 in model year 2026 only, bands A to D, England.
- Variable household_energy_payment, counted in household_benefits,
gov_spending and pre_budget_change_household_benefits as the Energy
Bills Rebate is, with its own fiscal partition head and programme entry.
- council_tax_band defaults to D, so 2026 England fixtures with no band
now carry the £100; their expected totals are updated and say so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From 6 April 2027 to 5 April 2030, people over State Pension age, or reaching it within the tax year, get a non-refundable Step 6 Income Tax reduction of 20% of the full new State Pension above the Personal Allowance, rounded up to the pound (£94 in 2027-28), tapered by £1 for every £3 of total income above the full new State Pension (Budget 2026 paragraph 6.182, policy costings p. 63, HM Treasury explainer). Each Step 6 reduction is capped at the tax the earlier ones leave (utils/income_tax_reductions.py); finance cost relief now uses the same helper. Universal Credit's deduction for tax on earnings reads income_tax_subtractions, so it sees the allowance. Also pins the Household Energy Payment outside HBAI income, as the 2022 council tax rebate is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Budget 2026 (paragraph 6.13, costings p. 16) replaces the withdrawal of Carer's Allowance in full above the weekly earnings limit with a 100% taper on the earnings above it, in England and Wales, from a date within 2030-31. Until DWP confirms the date the taper starts on 6 October 2030; the day-weighted share gives 2030-31 182 of its 365 days. The weekly excess over the limit is a variable of its own, which the gainful-employment test now reads. 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: 134 (thresholds in New warnings
Notes
Moves flagged for review
94 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 92 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
|
Five existing test files pinned values that Budget 2026 changes in current law: - the property basic rate and the savings rates from 2027-28 are 24%, not 22% (property income rate reforms, finance cost relief accounting, the savings starting rate path, and the ISA cash interest charge, which is at the savings basic rate in force for the year under SI 2026/1018 reg. 15); - the trading allowance is £3,000 from 2027-28, which sets relevant UK earnings for pension relief; - the Household Energy Payment is in household_benefits in 2026-27 but not in HBAI income. The finance cost relief bound now reads the property basic rate from the parameters and pins the uncapped case Hypothesis found. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From 6 October 2030 the Budget 2026 taper pays the rate less the earnings above the limit in England and Wales, so a carer £1 over it keeps most of the allowance. The case now checks only that the earnings count as gainful employment; test_carers_allowance_earnings_taper.py checks the amounts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The October 2026 EFO (paragraph 3.19) forecasts the 1 July 2027 rate at 60.59p: the 57.95p pre-cut rate uprated by RPI growth in the year to 2027 Q1. calculate_fuel_duty_rates.py now starts the schedule there (CUT_END_RATE) instead of uprating 57.95p by calendar 2026 RPI, which gave 59.75p on the March EFO and would give 60.03p on the October one. Each 1 April step from 2028 still applies the previous calendar year's RPI. This matches the duty path #2717 uses to derive road fuel volumes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…per pays In 2030-31 the taper covers 182 of the year's 365 days, so a carer over the earnings limit is paid in those weeks only. carers_allowance took a full year of overlapping benefits off that part-year amount: a carer earning £250 a week with £40 a week of State Pension got £0 instead of 182/365 x (rate - £46 - £40) x 52 = £234.54. The new carers_allowance_share_of_year_payable gives the share of the year the earnings condition lets the allowance be paid; the taper and the overlap deduction both use it. Adds the worked case, full-year and below-limit checks, and a property test of the weekly overlap rule over the paid weeks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pped The relief is limited to the tax left after earlier reductions. Where that capped the Budget 2025 relief, the 2-point rise in the rates raises the cap too, so the relief can rise by more than 2% of the costs: with £7,800 of other tax credits it goes from £86 to £240. The property test now applies the 2-point bound only where the old relief was its full 22%, and a worked test pins the capped case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HBAI counted the 2022 £150 Council Tax Rebate and the Energy Bills Support Scheme as miscellaneous income (HBAI quality and methodology report FYE 2023), so the tests' premise that the rebate stayed out of HBAI was wrong. The payment is the same kind of support to the same bands, so it now raises hbai_household_net_income by £100. The variable and docs also say who it goes to (the householder liable for council tax on their main home, most exempt households included) and what the model cannot see: households whose landlord is liable are paid. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Budget 2026 restores fuel duty on 1 July 2027 "uprated in line with RPI", then each 1 April from 2028 (costings page 13), and LPG and natural gas take the proportionate cut to the same date. Their full rates came back unuprated. calculate_fuel_duty_rates.py now writes all three schedules: the full rate times RPI growth to 2027 Q1 (4.5565%, which gives the OBR's 60.59p for petrol and diesel) on 1 July 2027, then the previous calendar year's RPI each April, with RPI uprating metadata after 2031. LPG is 33.05p and natural gas 25.83p from 1 July 2027. Also corrects the petrol schedule's comment, which still described the calendar-2026 step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Checked against what Microcosm needs to score the Budget measures (PolicyEngine/microcosm#1418). This PR covers most of the engine side. Three things look missing:
For the Carer's Allowance taper, the newly entitled carers come from the data's The next Microcosm national and local-area pair waits for this PR's release, with #2712. |
…ax Allowance Main's cliff probe froze a £1.01 step for current law in 2028. The Budget 2026 Pension Tax Allowance takes the claimant out of Income Tax at the boundary, and Pension Credit counts income net of tax, so guarantee credit now ends at £13,165 of private pension rather than £13,315 and the step is £1.61. Main's value is kept as the case with the allowance off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In 2030-31 an amount before the couple restriction or the overlap rule carries the parts of the year only where the simulation calculates it with the model's own formula: no input supplies it, and no reform neutralizes it or puts a formula of its own in its place. The payment takes the same decision from both stages, so a reform that changes only the partner's award before the couple limit gets the whole year's restriction and the whole year's overlap for both partners, and a reform amount equal to the model's no longer passes as the model's. A reform that updates a stage but keeps its formula keeps the parts of the year. calculated_by moves from the benefit cap variable to utils/formula_origin.py so both can use it. The Pension Tax Allowance YAML header gives the taper's end unrounded (13,318.973), so 13,318.98 in whole pence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…match Review round 6 found that a reform can keep the model's formula and add defined_for, which changes the amount but not the formula. The formula test alone then trusted the parts of the year and erased an eligible partner's award before the overlap rule. carries_parts_of_year now asks both: does the simulation calculate the stage with the model's formula, and does it equal, for every member of the benefit unit, what the parts of the year give, to half a penny. The masking case is a regression test. Also answers round 6's wording notes: the changelog says the remaining stages get the whole year's treatment, the assumptions page states the value condition and the per-variable limitation, and formula_origin's docstring is active. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Four files conflicted: - the petrol and diesel schedule and its two tests: keep the Budget 2026 schedule (60.59p on 1 July 2027) and rerun calculate_fuel_duty_rates.py --update on the October RPI forecast, which moves the April steps to 63.21p, 65.13p, 67.07p and 68.61p (2028-31) and regenerates LPG and natural gas; the hand-computed rates in test_fuel_duty_schedule.py, petrol_and_diesel_schedule.yaml and road_fuel_gases.yaml follow; - main's re-based Pension Credit boundary test: keep main's threshold, allowance and £0.87 step with the Pension Tax Allowance off, and pin £1.98 with it on (guarantee credit now ends at £13,280 of private pension). The October forecast raises the April 2028 new State Pension by 3.4%, so the 2028-29 Pension Tax Allowance case moves to a £13,480.26 threshold and a full allowance of £183. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round 7 found two gaps in round 6's check of a Carer's Allowance stage. Half a penny treated a fraction of a penny as nil, but the couple restriction picks whoever has an award. A reform masking a male head's £0.0026 under the taper kept him picked for those weeks and took £2,301.24 from the partner. matches_parts_of_year now also requires the amount to be positive exactly where the parts of the year give an award. The payment read carers_allowance_pre_couple_limit before checking carers_allowance_pre_overlap, so a reform deriving the earlier stage from the payment, which a supplied pre-overlap award had kept calculable, raised a cycle. The payment now reads the earlier stage only where the model calculates the pre-overlap award (calculated_by_model). Tests: the no-reform fraction of a penny keeps the parts of the year; masking it at either stage gives the whole year; the cycle case pays £600. Also: the merge review's wording fixes (the Pension Credit boundary is a £5 grid point, road_fuel_gases.yaml's header and the road fuel volume comment carry the October rates and the Budget 2026 schedule), and active voice in the PR's docs, descriptions and comments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A couple caring for the same person jointly elect which of them has the entitlement (SSCBA 1992 s.70(7ZA)(a)). The data don't record the election, so the couple restriction now keeps the partner with the larger candidate award and breaks ties in #2632's order (reported recipient, head, eldest). Before 2030-31 every positive award is the same rate, so nothing changes. Under the 2030-31 taper the old head-first order could pay a couple less than the cliff edge (head £250/wk, partner £200/wk, £40 State Pension each: £1,742.41 against £2,935.13), and a fraction of a penny for the head took the whole 2031-32 award from the partner. Now one partner holds the award for the year, which also ends the Pension Credit carer addition counting two carers. Enhanced FRS 2024-25 Carer's Allowance totals don't change (£5,260.2m in 2030, £5,396.34m in 2031). Also answers round 8's P3s: a 2031-32 mask case that couldn't fail now asserts the partner's award, passives in the test module and the payment's documentation, the HALF_PENNY comment, the maximising paragraph, and the council tax band sentence. Tests: the taper module (63 passed; 9 fail on 8db87df's rule), with a new property that the taper never leaves a couple below the cliff edge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round 9 approved the couple election with four P3s: - "one partner has the award for the year" holds for the awards the model calculates (earnings and the limit in whole pence put a tapered award at least a penny below the full rate); a supplied award within a few millionths of a pound can tie in float32, and the docs now say so; - "nothing changes before 2030-31" holds for the model's own awards; a supplied candidate that differs decides the election in any year; - under the election no payment shows the sign check in matches_parts_of_year, so a direct test now covers it (it fails without the check; the six payment cases pass either way); - passives in the test module and the assumptions page. From the rulespec-uk parity notes: natural gas fuel duty from 1 July 2027 is HM Treasury's published 25.82p a kilogram (OOTLAR Annex A), a hundredth of a penny below the RPI uprating's 25.83p. calculate_fuel_duty_rates.py now writes the published rates and stops if one is more than a hundredth of a penny from the uprating; the April steps follow (26.94p, 27.76p, 28.59p, 29.24p). The Northern Ireland electricity VAT and Household Energy Payment parameters now cite paragraphs 3.4 and 3.5 of the Budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…'s checks Round 10 approved with three P3s: - one partner has the award for the year where the model reads earnings itself, in whole pence against a whole-pence limit. An input that supplies the earnings above the limit bypasses that reader and can tie the two awards in float32 (round 10: both stages still count as the model's), while a supplied award gets the whole-year restriction and one recipient. The assumptions page, the pre-overlap documentation and the changelog now name that boundary; - calculate_fuel_duty_rates.py's refresh instructions now include PUBLISHED_RATES, and main() checks the OBR's uprating and HM Treasury's published petrol and diesel rate separately, so each error names the constant at fault; - passives in the generator and its notes, the excise docs, the fuel test and the carer test docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In 2030-31 the couple election runs on the weeks before the taper and the weeks under it separately. Where a head over the earnings limit had the full rate under the taper (a reform setting the taper rate to zero, an input or reform setting is_gainfully_employed_for_carers_allowance, or an excess of a millionth of a pound), the two awards tied, the tie order gave the head the taper weeks and the partner the weeks before, both partners counted as entitled, and the Pension Credit carer addition doubled. Where both partners have the same award for a part of the year, the couple now elect the one with the larger award over the year, then #2632's order. A partner below the limit keeps the award all year at any taper rate of zero or more. At the Budget's taper rate, with the model's own earnings, partners on either side of the limit never tie and partners on the same side have equal annual awards, so nothing changes there. Tests: a property at taper rates of 0 and 0.0001, and three examples (zero taper rate, supplied gainful-employment flag, a millionth over the limit) checking the partner keeps the award with one carer addition. All four fail without the tie-break. Also: the fuel duty script checks all three fuels before writing any file, says what to do when HM Treasury's rates no longer match a new forecast, and states that petrol and diesel's published rate must equal the uprating; the assumptions page names the stage whose supplied value keeps one recipient and drops the float32 account; reduced passives in the excise docs, fuel duty comments and changelog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Float32 keeps a millionth of a pound of excess; it is the tapered award that rounds to the full rate when float32 takes the excess from it. The two test comments now say so, and name the case a 0.0001 taper rate covers (a head a penny over the limit). Comments only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hand-off to the UK hubHead: db33fab (ready for review, mergeable). Independent review: 14 rounds. The code rounds approve this head. Round 14 requested changes to the body's Impact section and this comment; a delta check (r14b) confirmed those fixes, and asked for three more wording fixes, now in.
Passed locally:
CI at db33fab: every check passed ( Depends on: nothing open. #2717 (October EFO) is in main, and 9917bfa merges it into this branch. Holds:
What this changes beyond the Budget measures:
Conflicts to watch:
Impact (CI report, matches 8db87df):
Follow-ups still to do (not in this PR):
Axiom parity: TheAxiomFoundation/rulespec-uk#507, #454, #349, #467, #508, #506 and #348, all in the queue. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test came from #2746 after this branch's CI ran. Its default band D household in England now gets the £100 payment in 2026, so gross, net and HBAI income each rise by 100. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Interaction with #2751 (State Pension rates rounded to the nearest 5p) #2751 (draft, held under d2161 like this PR) rounds each projected State Pension weekly rate to the nearest 5p, as each Up-rating Order does. The full new State Pension becomes £250.70, £259.20 and £265.70 for 2027-28 to 2029-30, where the unrounded projection gave £250.71, £259.24 and £265.72. This PR's Pension Tax Allowance threshold is 52 × that rate, so it becomes £13,036.40, the explainer's figure, and the 2028-29 full allowance falls from £183 to £182. Merged together, 4 of the 15 cases in
The variable's documentation also mentions the unrounded £13,036.97. The patch below makes all 15 cases pass on a local merge of this head (c086c49) with #2751. Whichever PR lands second should apply it. National effect on this PR's allowance (certified Enhanced FRS 2024-25, this head vs the local merge):
Patch for this PR after #2751diff --git a/policyengine_uk/tests/policy/reforms/oct_2026_budget/pension_tax_allowance.yaml b/policyengine_uk/tests/policy/reforms/oct_2026_budget/pension_tax_allowance.yaml
index 11fd8f44b..1dff6ea74 100644
--- a/policyengine_uk/tests/policy/reforms/oct_2026_budget/pension_tax_allowance.yaml
+++ b/policyengine_uk/tests/policy/reforms/oct_2026_budget/pension_tax_allowance.yaml
@@ -7,16 +7,14 @@
# above the full new State Pension.
#
# The full new State Pension is 52 weeks at the weekly rate. The model
-# projects the April 2027 rate unrounded, 241.30 x 1.039 = 250.71, so the
-# threshold is 13,036.97, where HM Treasury's explainer gives 13,036.40
-# (250.70 a week). The full allowance is 94 on either: 20% x (13,036.97 -
-# 12,570) = 93.39. The allowance runs out at 13,036.973 + 3 x 94 =
-# 13,318.973, so 13,318.98 is the first income in whole pence with none (the
-# explainer's "13,319 or more").
+# projects the April 2027 rate as the Up-rating Order rounds it, 241.30 x
+# 1.039 = 250.7107 to the nearest 5p, 250.70, so the threshold is 13,036.40,
+# as in HM Treasury's explainer. The full allowance is 94: 20% x (13,036.40 -
+# 12,570) = 93.28, rounded up. The allowance runs out at 13,036.40 + 3 x 94 =
+# 13,318.40 (the explainer's "13,319 or more" in whole pounds).
#
# The first five cases are the worked examples in HM Treasury's Pension Tax
-# Allowance explainer, on its inputs. Jonathan's allowance is 19p more than
-# the explainer's 44 because the threshold is 57p higher.
+# Allowance explainer, on its inputs.
- name: Tom, below the Personal Allowance, has no tax to remove
period: 2027
@@ -53,7 +51,7 @@
pension_tax_allowance: 80
income_tax: 0
-- name: Jonathan, deferring his pension with income in the taper, gets 44.19
+- name: Jonathan, deferring his pension with income in the taper, gets 44
period: 2027
absolute_error_margin: 0.01
input:
@@ -62,12 +60,12 @@
property_income: 1_186.40
output:
total_income: 13_186.40
- # 94 - (13,186.40 - 13,036.97) / 3; the explainer, on 13,036.40, gives 44
- pension_tax_allowance: 44.19
+ # 94 - (13,186.40 - 13,036.40) / 3
+ pension_tax_allowance: 44
# The Personal Allowance covers the salary and 570 of the property
# profit; 616.40 x 24% (the Budget 2026 property basic rate) = 147.94
income_tax_pre_charges: 147.94
- income_tax: 103.75
+ income_tax: 103.94
- name: Nadia, above 13,319, gets no allowance
period: 2027
@@ -89,24 +87,24 @@
absolute_error_margin: 0.01
input:
age: 70
- # Just above 13,036.97 + 3 x 94
- state_pension: 13_318.98
+ # 13,036.40 + 3 x 94
+ state_pension: 13_318.40
output:
pension_tax_allowance: 0
- # 748.98 x 20%
- income_tax: 149.80
+ # 748.40 x 20%
+ income_tax: 149.68
- name: A pound before the end of the taper leaves a third of a pound
period: 2027
absolute_error_margin: 0.01
input:
age: 70
- state_pension: 13_317.98
+ state_pension: 13_317.40
output:
- # 94 - (13,317.98 - 13,036.97) / 3
+ # 94 - (13,317.40 - 13,036.40) / 3
pension_tax_allowance: 0.33
- # 747.98 x 20% = 149.60, less the allowance
- income_tax: 149.27
+ # 747.40 x 20% = 149.48, less the allowance
+ income_tax: 149.15
- name: Scottish taxpayers get the allowance at 20%, capped at their starter-rate tax
period: 2027
@@ -130,11 +128,11 @@
private_pension_income: 13_186.40
region: SCOTLAND
output:
- # 94 - 149.43 / 3; at the 19% starter rate the full allowance would have
- # been 89, leaving 39.19
- pension_tax_allowance: 44.19
+ # 94 - 150 / 3; at the 19% starter rate the full allowance would have
+ # been 89, leaving 39
+ pension_tax_allowance: 44
# 616.40 x 19% = 117.12
- income_tax: 72.93
+ income_tax: 73.12
- name: Someone under State Pension age with the same income gets nothing
period: 2027
@@ -197,11 +195,12 @@
absolute_error_margin: 0.01
input:
age: 70
- # The threshold is 52 weeks of the April 2028 new State Pension: 13,480.26
- # on the October 2026 forecast, so 20% x (13,480.26 - 12,570) = 182.05 and
- # the full allowance is 183. 300 above the threshold takes 100 off it.
- private_pension_income: 13_780.26
+ # The threshold is 52 weeks of the April 2028 new State Pension: 13,478.40
+ # (259.20 a week) on the October 2026 forecast, so 20% x (13,478.40 -
+ # 12,570) = 181.68 and the full allowance is 182. 300 above the threshold
+ # takes 100 off it.
+ private_pension_income: 13_778.40
output:
- pension_tax_allowance: 83
- # 1,210.26 x 20% = 242.05, less the allowance
- income_tax: 159.05
+ pension_tax_allowance: 82
+ # 1,208.40 x 20% = 241.68, less the allowance
+ income_tax: 159.68
diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/reliefs/pension_tax_allowance.py b/policyengine_uk/variables/gov/hmrc/income_tax/reliefs/pension_tax_allowance.py
index ed73da7ef..163b8b068 100644
--- a/policyengine_uk/variables/gov/hmrc/income_tax/reliefs/pension_tax_allowance.py
+++ b/policyengine_uk/variables/gov/hmrc/income_tax/reliefs/pension_tax_allowance.py
@@ -13,9 +13,8 @@ class pension_tax_allowance(Variable):
"the full new State Pension above the Personal Allowance, rounded up to "
"the pound (£94 in 2027-28). It falls by £1 for every £3 of total "
"income above the full new State Pension, which is the tax year's 52 "
- "weeks at the weekly rate, so it follows any change to that rate. The "
- "model projects the rate unrounded, so the threshold is £13,036.97 in "
- "2027-28 where HM Treasury's explainer gives £13,036.40. It is "
+ "weeks at the weekly rate, so it follows any change to that rate "
+ "(£13,036.40 in 2027-28, as in HM Treasury's explainer). It is "
"non-refundable: it is "
"deducted at Step 6 after the reductions listed before it in "
"income_tax_subtractions, only so far as there is Step 5 tax left, " |
|
Okay, I'll leave the merge call to you for when everything is ready. |
|
Sync after the current queue. This PR merges cleanly with main today, but not after the queue lands. A local merge of main
One more needs fixing with no conflict to flag it: The UK hub is rehearsing that merge locally now and will push the sync once main holds those PRs, so nobody needs to merge main here in the meantime. The result will follow in a comment on this PR. |
Ready for review. Don't merge yet: Budget week's merge rules and d2161 (no automatic agent merges in policyengine-uk until Max rules) both hold it.
This moves the Autumn Budget 2026 household measures from the dashboard repo's reforms (PolicyEngine/uk-autumn-budget-dashboard-2026#290) into current law. It is one PR so the merge queue runs once. It supersedes #2713, #2714, #2715 and #2718, none of which remains open.
Sources:
None of the measures is law yet; each parameter says so.
Trading allowance (item 15)
Paragraph 6.254 and costings p. 23 set the allowance at £3,000 from 6 April 2027. The parameter gets a new
2027-04-06: 3_000value.trading_allowance_deductionalready reads it, so Income Tax and Class 4 NI follow.Known gap: the allowance also covers miscellaneous income (ITTOIA s. 783B), but the model applies it only to trading income. #290's review (issuecomment-6472453512) bounds the missing cost at about £71m in 2027-28.
Tests:
Savings and property income rates (items 61, 62)
Paragraphs 6.246 and 6.247 set 24%, 44% and 49% from 6 April 2027. The property rates apply in England, Wales and Northern Ireland; the savings rates UK-wide. The existing formulas already do the rest:
property_income_tax.formula_2027).rates.property.basic, so it becomes 24%, in line with costings p. 74.One consequence: under the model's reading of ITTOIA s. 274AA(5), Scottish landlords' relief also rises to 24%, while their property tax doesn't change.
Tests:
tests/policy/reforms/oct_2026_budget/savings_property_income_rates.yaml;test_budget_2026_savings_property_rates_properties.py. Mutation check: with the higher property rate at 43%, invariant 1 fails.The higher relief can also change the property allowance election. A Scottish landlord with £500 of rent and £435 of finance costs uses the £1,000 allowance at 22%, since the relief (£95.70) is worth less than the £100 of tax the allowance saves. At 24% the relief is £104.40, so the model drops the allowance: property income tax rises from £0 to £100 and income tax falls by £4.40. The model makes that choice only where it lowers the person's income tax (
uses_property_allowance). The rate identities hold for people whose election doesn't change, and a worked test covers this case.Fuel duty (item 3)
Paragraph 6.211 extends the 5p cut to 1 July 2027. Costings p. 13: "On 1 July 2027, fuel duty rates will increase by 5ppl and will be uprated in line with the Retail Prices Index (RPI). From 1 April 2028, fuel duty rates will be uprated annually in line with RPI." Other fuels get "a proportionate percentage cut (equivalent to 5ppl from the main fuel duty rate of 57.95 ppl)".
Changes:
calculate_fuel_duty_rates.pyuprates each full rate by RPI growth in the year to 2027 Q1 (4.5565%, economy Table 1.7). For petrol and diesel that is the OBR's 60.59p (October 2026 EFO ¶3.19: "from 52.95 pence per litre to 60.59 pence per litre"); the script refuses to write a different figure;On #2717's October 2026 RPI forecast, now merged in, the April steps are 63.21p (2028), 65.13p, 67.07p and 68.61p (2031).
Day-weighted model-year rates (p/litre):
Electricity VAT (item 2)
Paragraph 6.210 extends the zero rate "to 1 July 2027. This is expected to apply UK-wide from April 2027". The parameter changes:
Day-weighted model years:
The dashboard (#290, 5d18a5e2) weights 2027-28 differently. It uses April to June's share of a year's domestic electricity use (22.30%), where this PR uses the day share (86 of 366, 23.50%). For the dashboard's £1,040 electricity bill, the 2027-28 saving is £11.04 there and £11.64 here.
This PR doesn't change how the model projects electricity spending.
uprate_energymoves it by headline CPI from the dataset's declared price basis (calendar 2024 for the managed Microcosm bundle) and holds it flat where a dataset declares none (Enhanced FRS, priced at April 2026 Ofgem rates). The Treasury costing (p. 12) grows "nominal consumer expenditure on electricity" instead, price and volume together. The OBR's Table 1.20 electricity series is a wholesale price in £/MWh, not a bill. Its nearest retail series, Table 1.19 "Utilities", covers more than electricity and is post-measures, so it already contains this VAT cut. On it, spending would be about 1.1% lower in 2026-27 and 1.4% lower in 2027-28 than on CPI: roughly £8m and £4m off the costing's £755m and £305m. A pre-measures retail electricity index would be a separate change.Household Energy Payment (item 1)
Paragraph 6.24 and paragraph 3.5: £100 for households in council tax bands A to D in England, which local authorities pay from January 2027.
Changes:
gov.treasury.household_energy_payment.{amount, bands, countries}and variablehousehold_energy_payment;household_benefits,gov_spendingandpre_budget_change_household_benefits, as the Energy Bills Rebate does;Not modelled:
Fixture fallout:
council_tax_banddefaults to D, so 2026 England fixtures with no band now carry the £100. The PR updates seven tests' totals, each with a comment.Pension Tax Allowance (item 52)
Sources:
The allowance is a non-refundable Step 6 reduction from 6 April 2027 to 5 April 2030:
gov.dwp.state_pension.new_state_pension.amount, so it follows any change to that rate, dated or undated. The model projects the April 2027 rate unrounded (241.30 × 1.039 = £250.711, from published inputs), so the threshold is £13,036.97, where the explainer gives £13,036.40, which is 52 × £250.70. Neither the explainer nor the Budget states the weekly rate, so the model doesn't enter £250.70; the gap closes when the uprating order sets the rate.Changes:
gov.hmrc.income_tax.reliefs.pension_tax_allowance.{in_effect, rate, taper}. There is no threshold parameter: the formula reads the new State Pension rate (above). An earlier version kept the explainer's £13,036.40 uprated by the new State Pension amount, which divided by zero under a nil-rate reform (CI at 835a765); 7de3747 uprated it by the triple lock index instead, which round 4 showed cut it loose from rate reforms (a pensioner on £15,600 under a £300 rate paid £606).pension_tax_allowance, last inincome_tax_subtractions.utils/income_tax_reductions.earlier_tax_reductions, gives that order.property_finance_cost_reliefnow uses the helper too, which avoids a dependency cycle.utils/uc_income_tax.py) takes theincome_tax_subtractionsentries off the tax on earnings. It handles finance cost relief separately, against the tax on property income first. So it picks up the allowance with no change of its own. This settles @PavelMakarchuk's point on Budget day: announced measures uk-autumn-budget-dashboard-2026#290 (issuecomment-6472987762). His mixed-age couple comes out at an allowance of £93.28, UC −£51.30 and net income +£41.97.pension_tax_allowanceas a component ofincome_tax.Later years: the model recomputes the allowance each year as 20% × (threshold − Personal Allowance): £183 in 2028-29 and £250 in 2029-30 on the October 2026 forecast. Someone on exactly the full new State Pension and nothing else pays no Income Tax at any rate (a Hypothesis property over rates from £0 to £400 a week). Uprating the £94 instead would leave someone on exactly the full new State Pension owing about £85 in 2028-29, which breaks the guarantee in ¶3.19 and ¶6.182.
~/reviews/uk-hub/RULINGS.mdlogs the reading.Conflict to watch: draft #2545 restructures Step 6. Whichever lands second moves
pension_tax_allowanceinto the new structure.Tests:
tests/policy/reforms/oct_2026_budget/pension_tax_allowance.yaml, 15 cases:tests/test_pension_tax_allowance_properties.py. Mutation check: with a 20% taper in place of 1 in 3, the first property fails. The full new State Pension pays no Income Tax without a reform, with the rate at £300 for 2028-29 only (allowance £606), and at any undated rate from £0 to £400 a week; the dated and undated reform tests fail on both earlier threshold versions.tests/test_pension_tax_allowance_universal_credit.py: Pavel's couple, and the same income as a private pension (UC unchanged).Carer's Allowance taper (item 7)
Sources: paragraph 6.13 and costings p. 16. In England and Wales, the withdrawal of the allowance in full above the weekly earnings limit becomes a 100% taper on the earnings above it.
Start date: the costings say only "within the 2030-31 financial year, with a precise start date confirmed in due course". Until DWP confirms it, the model starts on 6 October 2030.
appliesis day-weighted (fiscal_year_blend), so 2030-31 carries 182 of 365 days. That is in line with Table 6.1's −£40m, then −£80m.Changes:
gov.dwp.carers_allowance.earnings_taper.{applies, rate, countries}.carers_allowance_weekly_earnings_above_limit, using the existing pence rule.is_gainfully_employed_for_carers_allowancenow reads it.carers_allowance_pre_couple_limitpaysrate − taper × excess, floored at zero, where the taper applies.carers_allowance_pre_overlap, and through itcarers_allowanceand UC unearned income (income_definitions/unearned.yaml), read the new amount.limit_carer_benefit_to_one_partnernow gives the allowance to the partner with the larger award before overlap, and the fixed order breaks ties, in 2030-31 after the larger award over the year (logged in the UK hub's rulings under P4, the rule for elections that Autumn Budget 2026 measures in current law #2719 already applies to the property allowance). Before 2030-31 the model's own awards are equal, so nothing changes for them (round 9 compared 20,736 household-years from 2026 to 2029 on five carer benefits, and every value matched), though a supplied candidate award that differs decides the election in any year; on the Enhanced FRS 2024-25 no benefit unit has both partners caring 35 hours or more, so the change moves no aggregate in 2030-31 or 2031-32 either. It matters for households where both partners care for the same person.utils/carers_allowance_taper.py, read bycarers_allowance_pre_couple_limit,carers_allowance_pre_overlapandcarers_allowance). Both rules work week by week:carers_allowance_pre_overlapcarries no dates, so it still meets the whole year's overlapping benefits (round 2 caught the earlier fix dropping the deduction there);carers_allowance_pre_overlapiscarers_allowance_pre_couple_limittimes the share of those parts the couple restriction keeps, andcarers_allowancetakes the overlapping benefits off for the share kept. A value supplied for either intermediate, or a reform that neutralizes one, therefore reaches the payment (round 3 caught the round 2 fix recomputing the award and bypassing both);defined_for, say), since the formula can't show that. Such acarers_allowance_pre_couple_limitgets the whole-year couple restriction and the whole year's overlap, and such acarers_allowance_pre_overlapthe whole year's overlap. Each stage asks two things of the stage before it (carries_parts_of_yearinutils/carers_allowance_taper.py): whether the simulation calculates it with the model's formula (no input supplies it, no reform neutralizes it, and the formula's code is the model's, bycalculated_by, now inutils/formula_origin.py), and whether, for every member of the benefit unit, it equals what the parts give, to half a penny and positive exactly where they give an award, since the couple restriction picks whoever has an award (calculated_by_modelandmatches_parts_of_year). The payment asks both of both stages, and readscarers_allowance_pre_couple_limitonly where the model calculatescarers_allowance_pre_overlap, so a supplied or reformed pre-overlap award needs nothing before it. Rounds 4 to 6 caught the earlier tests. On value alone, a reform giving the partner £1,000 paid £0, and a reform changing only the partner's award, or setting the model's own amount, took off half the head's State Pension (the model paid £200.55 too much). On formula alone, a reform that kept the formula but addeddefined_for: is_femaleleft a female partner, whose male head has no award, with nothing in place of £4,542. Within half a penny alone, a mask that took away a male head's fraction of a penny still picked the head for the weeks under the taper, and the model paid the partner £2,301.24 too little (round 7). The sign check stays; under the election a fraction of a penny never outranks a full award, so that case now pays the partner in full with or without a mask, and a direct test ofmatches_parts_of_yearcovers the check, since no payment shows it. A reform that changes only a stage's label keeps the parts of the year. The formula test covers the whole variable, so a reform that wraps a stage's formula to change one person's amount moves every amount to the whole-year treatment; round 6 accepts this as a deliberate limitation, and the assumptions page states it;receives_carers_allowancetrue (round 3). The model pays a penny left over: float32 stores £5,000.01 as £5,000.0098 (round 4 caught a £0.01 cutoff dropping it).is_entitled_to_carer_benefitname one carer. The Pension Credit carer addition for the couple above is £2,793.27, the same as for a couple both within the limit. (Before the election, both partners of a couple straddling the limit counted as entitled for the year, and the addition came to £5,586.55.)would_claim_carers_allowance; there is no new draw.Dependencies:
gov.dwp.carers_allowance.earnings_limitas it stands, and the tests read the limit and rate from the parameter tree, so they hold before and after Project the minimum wage rates by the OBR's national living wage forecast #2700.carers_allowance_weekly_earnings_above_limit.Tests:
tests/test_carers_allowance_earnings_taper.py.tests/policy/reforms/oct_2026_budget/carers_allowance_earnings_taper.yaml).is_gainfully_employed_for_carers_allowance, an excess of a millionth of a pound) check that the partner under the limit keeps it and the couple get one Pension Credit carer addition; all four fail without round 11's tie-break. On 8db87df's rule, 9 tests fail: both new couple examples (one case of the over-the-limit pair), the fraction-of-a-penny case in both years, the pre-overlap mask in both years, and all three properties.carers_allowance_pre_couple_limit(£0 and £1,000), and neutralizing either intermediate pays nothing, in 2030-31 and 2031-32; a Hypothesis property that an overlapping benefit equal to the award leaves no payment or receipt; and the two 2030-31 properties also check anything paid is at least half a penny. The 10 new tests fail on 835a765. Round 4's: reforms replacingcarers_allowance_pre_couple_limit(£1,000 to the partner) andcarers_allowance_pre_overlap(£1,000 less £400 of State Pension for a head over the limit), and a penny left after overlap on £1,000.01 and £5,000.01; the 2030-31 replacement cases and the £5,000.01 cases fail on 7de3747. Round 5's: reforms that set the partner's award before the couple limit to nil, scale it by 1.0001 or add a penny, leaving the head's as the model's (the head gets the whole-year restriction and £400 off: the model's award less £400); a reform settingcarers_allowance_pre_overlapto the model's own amounts (the whole year's £400 off each); a reform that relabels both stages, which keeps the model's parts-of-year payment; and a Hypothesis property that 2030-31 pays any award a reform sets before the couple limit as 2031-32 does, and as the whole-year rule gives (the partner with the larger award, the head on a tie, less the whole year's State Pension). The four 2030-31 partner and model's-own cases fail on f51c6dc; removing the payment's check ofcarers_allowance_pre_couple_limitfails the three partner cases and the property. Round 6's: a reform addingdefined_for: is_femaletocarers_allowance_pre_couple_limit, for a couple with a male head and a female partner, leaves the partner's award to the overlap rule and pays it less £400 of State Pension; it fails on bffa9e8, and fails again without the value check, while removing the formula check fails the model's-own case. The relabelling test now subclasses both stages with a new label and keeps their formulas. Round 7's: a head £0.0001 a week inside the taper; a reform masking that fraction of a penny at either stage; and a reform derivingcarers_allowance_pre_couple_limitfrom the payment, withcarers_allowance_pre_overlapsupplied, which pays £600 with no cycle. On 9917bfa the two 2030-31 mask cases and the 2030-31 cycle case fail; at 8db87df, removing the positive-award check fails both mask cases, and removing the payment's early origin check fails the cycle case. Under the election, the fraction-of-a-penny cases expect the partner's whole award, less £400, in both years, with or without the mask.OBR October 2026 EFO
María's #2717 moves the economic assumptions to the October EFO, so this PR doesn't. An independent import of the same tables agreed with #2717 on 122 changed values to 0.005pp; the rest differ only where #2717 makes a deliberate choice (2025 revised, smoothed 2032+ joins, OBR private rents, road fuel re-derived). GitHub records #2717's merge at 00:05Z on 29 October (1688f98), and 9917bfa merges main into this branch. The merge conflicted in four files:
calculate_fuel_duty_rates.py --updateon the October RPI forecast (petrol and diesel 63.21p, 65.13p, 67.07p and 68.61p each April from 2028, in place of 62.41p to 67.54p; LPG and natural gas likewise), and recomputes the hand-worked rates intest_fuel_duty_schedule.py,petrol_and_diesel_schedule.yamlandroad_fuel_gases.yaml. Update the economic assumptions to the October 2026 EFO #2717 derives road fuel volumes at the same 60.59p path;The October forecast also moves the Pension Tax Allowance after 2027-28 (£183 in 2028-29 and £250 in 2029-30, from £159 and £226): the threshold follows the new State Pension, which rises 3.4% in April 2028 on the October forecast, against 2.5% before. The 2028-29 YAML case moves with it: £300 over the £13,480.26 threshold leaves £83 of the £183.
Invariants
vat_changeis zero.hbai_household_net_income(tests/test_household_energy_payment_income_measures.py).test_road_fuel_gases_get_the_same_rpi_uprating).Review
Round 1 (GPT-6.1 Sol, at e5e8942) requested changes on nine findings. Here is where each stands:
is_gainfully_employed_for_carers_allowance); #2543 (draft) fixes it, storing the limit in penceRound 2 (GPT-6.1 Sol, at 1386278) confirmed findings 1, 3, 4, 8 and 9 resolved and 2, 5 and 7 deliberately deferred, and requested changes on four more:
Round 3 (GPT-6.1 Sol, at 835a765) confirmed all four round 2 findings resolved and requested changes on three more:
carers_allowance_pre_couple_limitorcarers_allowance_pre_overlapno longer reached the paymentreceives_carers_allowancetrueIt also measured the annual-flag limitation; the Carer's Allowance section now gives its effects as measured.
CI at 835a765 also failed two of main's State Pension tests on the merge ref: 835a765 uprated the Pension Tax Allowance threshold by the new State Pension amount, so a reform setting that amount to nil divided by zero. 7de3747 uprated it by the triple lock index instead.
CI at 7de3747 failed one of main's tests on the merge ref:
test_guarantee_credit_boundary_matches_mainfroze a £1.01 step in household net income where guarantee credit ends in 2028, for an 85-year-old on private pension. The Pension Tax Allowance takes them out of Income Tax at that point, and Pension Credit counts income net of tax (pension_credit_income.py), so guarantee credit ends at £13,165 of private pension rather than £13,315 and the step is £1.61. With the allowance off it is main's £1.01. f51c6dc merges main and pins both cases.Round 4 (GPT-6.1 Sol, at 7de3747) confirmed round 3's findings 2 and 3 resolved and finding 1 partly, and requested changes on three:
carers_allowance_pre_couple_limitwith positive amounts still lost the award in 2030-31: the shares rebuilt eligibility from the original rulesIt also flagged two wording points: the assumptions page implied the couple restriction applies to a supplied
carers_allowance_pre_overlap, and this body still named the old uprater. The round 4 fixes answer both.Round 5 (GPT-6.1 Sol, at f51c6dc) confirmed round 4's findings 2 and 3 resolved, checked the £1.61 Pension Credit step (£5 less £2 of Pension Credit, £1.06 of Housing Benefit and £0.33 of Council Tax Reduction; £1.01 with the allowance off), found no deleted-parameter readers, and requested changes on one:
carers_allowance_pre_overlapto the model's own amounts, took off only the taper share of the head's State Pension (the model paid £200.55 too much)It also noted that #2726 leaves round 1's finding 7 to #2543; the round 1 table now says so. And £13,318.97 leaves a fraction of a penny (the end is £13,318.973), so the taper line now says £13,318.98.
Round 6 (GPT-6.1 Sol, at bffa9e8) confirmed round 5's finding resolved (the four 2030-31 cases pass, and fail on the round 5 formulas), matched baseline Carer's Allowance to round 5 exactly on 792 household-years, found every variable registered once after the
calculated_bymove, and requested changes on one:defined_for, which changes the amount but not the formula, so the formula test alone trusted the parts of the year: a female partner whose male head has no award lost their whole £4,942 before overlapIt also asked for four wording fixes: "the remaining stages" in the changelog and invariants, "the model paid £200.55 too much", a passive in
formula_origin.py, and the stale round line below. 7279bfb fixes all four. It accepted, as a deliberate limitation, that a reform wrapping a stage's formula moves untouched people to the whole-year treatment too; the assumptions page now says so.9917bfa then merges main, which now has #2717's October 2026 EFO (see that section).
Round 7 (GPT-6.1 Sol, at 9917bfa) confirmed round 6's reproducer and four wording notes resolved, matched baseline Carer's Allowance to bffa9e8 on 792 household-years on the same economic assumptions, checked the merge, and requested changes on two:
carers_allowance_pre_couple_limitbefore checkingcarers_allowance_pre_overlap, so a reform deriving the earlier stage from the payment, which a supplied pre-overlap award had kept calculable, raised a cycleIt also listed passives in this PR's text, written before round 6: 8db87df rewrites them in the helper, the changelog, the Household Energy Payment docs and variable, the parameter descriptions and comments, and this body. And it noted that
axiom: queuedneeds a rulespec-uk issue.A second GPT-6.1 Sol review checked only the merge and approved it: all 59 main-only files match main, the fuel generator reproduces all three forecast blocks, and the £1.98 decomposes into £3 less Guarantee Credit, £1 more Savings Credit, £0.78 less Housing Benefit and £0.24 less Council Tax Reduction. It asked for four wording fixes, all in 8db87df: the boundary is a £5 grid point, not an exact cutoff;
road_fuel_gases.yaml's header kept March rates; the road fuel volume comment inyoy_growth.yamlcalled the Budget 2026 schedule future law; and the merge date (the merge commit carries 22:22Z on 28 October, GitHub's merge record 00:05Z on 29 October).Round 8 (at 8db87df) approved provisionally, but its lane had no shell, so it read the code and ran nothing. Its read-through found round 7's findings resolved and raised P3s: a 2031-32 mask case that couldn't fail, a wrong count of round 7's failing cases in this body, passives in the test module, the payment's documentation, the Household Energy Payment docs and this body, and two consistency notes (the
HALF_PENNYcomment, and the assumptions page's paragraph on maximising). b428941 fixes them all, and I ran the checks it couldn't:The same probe found a larger problem. With the head's excess at the rate rounded to the penny (£96.44), the head keeps £0.0048 a week, and the old order picked the head: the couple got £2,313.89 in 2030-31 and nothing in 2031-32, where the partner alone would get £4,615.13 and £4,715.42. That led to the couple election above (b428941).
Round 9 (at b428941) had a shell and approved. It reran the taper module (63 passed; on 8db87df's rule 9 fail and 3 pass, the 9 that the test list above names), compared 20,736 household-years from 2026 to 2029 under both rules on Carer's Allowance, Carer Support Payment, the carer premium, the UC carer element and the Pension Credit carer addition (all 145,152 values matched), and reproduced the £1,742.41 couple against £2,935.13 and the Pension Credit addition of £5,586.55 against £2,793.27. It raised four P3s, which ab9d57b fixes:
carers_allowance_pre_couple_limitthat an input supplies carries no dates, so the restriction keeps one recipient for the whole year (round 10 checked both). The assumptions page, the pre-overlap documentation and the changelog now say so (round 10 asked for this boundary in place of ab9d57b's "awards the model calculates"; round 11 found it still incomplete, and the tie-break below replaces it);matches_parts_of_year. A direct test of the function now fails without the check, while the six payment cases still pass;Round 9 also showed the cost of comparing awards before overlap, which the assumptions page states. Take a couple on £250 and £200 a week where only the partner has £100 a week of State Pension. The election picks the partner, whose pension takes the whole 2030-31 payment, where the head would get £1,307.97 (I reproduced both figures). An election on the payment after overlap would pick the head, but it would also change #2632's convention before 2030-31, where a head whose State Pension exceeds the rate keeps the entitlement unpaid today, so it goes to a follow-up. On the Enhanced FRS no couple has both partners caring 35 hours or more, so neither rule moves an aggregate.
ab9d57b also takes two notes from the rulespec-uk parity issues:
calculate_fuel_duty_rates.pynow writes the published rates for all three fuels, and stops if one is more than a hundredth of a penny from the uprating; the natural gas April steps follow (26.94p, 27.76p, 28.59p and 29.24p);Round 10 (executed, at ab9d57b) approved. It ran 139 Python tests, mutated the sign check out (only the new direct test failed), checked 160 household-years across four regions, Carer's Allowance and Carer Support Payment from 2026 to 2035 and 150,003 earnings amounts a year from 2030 to 2035 without a selection collision (the closest tapered award sits 1,310 float32 steps below the full rate), matched the three July 2027 rates to Annex A and all 15 written steps to the script, and confirmed paragraph 3.4 on PDF page 49 and paragraph 3.5 from page 49 to page 50. It raised three P3s, which ae88f0c fixes:
carers_allowance_pre_couple_limitgets the whole-year restriction and one recipient;PUBLISHED_RATES, and its petrol and diesel check tests the OBR's uprating and HM Treasury's rate separately, so each error names the constant at fault (round 10 got an error blaming RPI growth for a published rate);Round 11 (at ae88f0c) ran twice, as an in-session Opus review and as GPT-6.1 Sol on Subfleet, and both requested changes on the same finding. The model's own earnings reader keeps a tapered award about a penny below the full rate, but a reform setting the taper rate to zero gave a head over the limit the full rate under the taper. The awards then tied, the tie order picked the head for the taper weeks and the partner for the weeks before, both partners counted as entitled, and the Pension Credit carer addition doubled (£5,586.55 against £2,793.27). On Sol's grid of 2,374 couples, 2,273 split at a taper rate of zero, 381 at 0.000001, 3 at 0.0001, 1 at 0.0003 and none from 0.001. Setting
is_gainfully_employed_for_carers_allowanceby input or reform, or replacing the formula for the earnings above the limit, did the same. ce9b262 fixes it as both reviews proposed: where the two partners' awards for a part of the year are equal, the couple elect the one with the larger award over the year, then #2632's order. A partner below the limit then keeps the award all year at any taper rate of zero or more. Sol ran the same fix in memory and found no split couple at eight taper rates from 0 to 2, with the 64 taper tests and 21 other carer property tests passing. At the Budget's taper rate, with the model's own earnings, partners on either side of the limit never tie (round 10's closest tapered award sat 1,310 float32 steps below the full rate), and where partners on the same side have the same positive award for a part of the year, their awards over the year tie as well, so the tie-break changes nothing there. ce9b262 also:carers_allowance_pre_couple_limitthat an input supplies, since the restriction comes beforecarers_allowance_pre_overlap, and the model takes a value that an input supplies there as it stands;CUT_END_RATE;Round 12 (GPT-6.1 Sol, executed, at ce9b262) approved. It reran both round 11 reports' route tables: every route that gave the head the full rate under the taper now keeps one recipient, a
carers_allowance_pre_couple_limitthat an input supplies or a reform changes keeps the whole-year selection, and acarers_allowance_pre_overlapthat an input supplies or a reform changes still stands as the input or reform gives it, by design. It found no split couple on Sol's 2,374-couple grid at eight taper rates from 0 to 2, nor in either 3,195-couple float32 sweep, and 48 further route and rate combinations passed. At the Budget's taper rate, Carer's Allowance, Carer Support Payment, the carer premium, the UC carer element and the Pension Credit carer addition matched ae88f0c exactly across 34,560 household-years (2026 to 2035, four nations). The taper module passed (68); on ae88f0c's rule exactly the four new tests fail. The fuel script passed its 75 tests, regenerated all three files byte for byte, and left all three unchanged when a bad LPG or natural gas rate followed a consistent RPI refresh. It judged the annual award before the reported recipient defensible: a reported head £50 over the limit at a zero taper rate now leaves the partner the year and one £2,793.27 addition, where the old rule split it and paid £5,586.55. A negative taper rate can still split the year (at −1, £3,797.13 and £2,514.44, two entitlement flags); the text claims only rates of zero or more. Its three P3s:Round 13 (GPT-6.1 Sol, executed, at db33fab) approved. It confirmed that the delta changes comments only (the syntax trees and the non-comment tokens match), ran both comments' claims (at a taper rate of 0.0001, £204.01 a week gives the full float32 rate of £96.4448; float32 keeps an excess of 1e-6 as 9.999999974752427e-07, and the award stays the full rate), matched this body's round 12 numbers to its report, and passed the taper module (68). Its two P3s touch only this body: a "positive" missing from the same-side tie, and four reduced passives. The body now answers both.
Differences from the dashboard
The dashboard (#290) carries its own copies of these measures. They differ from this PR in:
is_SP_ageasks whether a person reaches it by 6 October; this PR and the explainer use the tax year);A list with effects goes to #290 separately.
Impact
CI's aggregate impact report at db33fab (run, comment) compares main (2d437eb) with the merge of this PR into main, on the Enhanced FRS 2024-25 (policyengine-uk-data 1.58.1), for 2025-26 to 2031-32. Every figure matches the run at 8db87df, so rounds 11 to 13 change no result at the Budget's taper rate. No check breaks. One check,
sign:vat(76 records with negative VAT), fails on main too. The report flags 134 moves for review; a flag doesn't fail the job. 2025-26 doesn't change.Change from main:
inert:household_energy_payment, concerns the new payment, which pays only in 2026-27. It lists 2025-26, 2027-28 and 2028-29 as zero for every unit.disqualifying_benefits). Both parents' adjusted net income stays far below the £100,000 limit either way. On main the family keeps the small award and gets no Tax-Free Childcare worth more: A small Universal Credit award ends Tax-Free Childcare worth more, so removing the two-child limit leaves some families worse off #2689 already reports that limitation, which predates this PR.Distribution, with each household in its decile on main (mean change per household):
In 2026-27, 84.1% of people gain more than £1 and 0.0% lose more than £1; from 2028-29, about 57% lose more than £1. The Gini coefficient (equivalised HBAI income before housing costs) falls by 0.0005 to 0.0006 in every year from 2026-27. The report's flags on deciles 9 and 10 (−£2,046 and +£2,521 in 2027-28) come from its other decile table, which ranks households on each side separately, so a household that crosses a decile boundary moves both deciles' means. On main's deciles the two lose £83 and £376.
Poverty:
Checks
household_benefitswithout the Household Energy Payment. e5e8942 moves them to the Budget values; the six files pass locally (137 tests)uc_statutory_pay,warm_home_discount,hbai_property_income,trading_loss_household_income). Each pinned 2026 HBAI income for a band D household in England without the £100 Household Energy Payment, which round 1 moved into HBAI; 835a765 adds it and fixes the comments that said HBAI leaves it outtest_state_pension_components.py(a nil new State Pension rate divided by zero in the Pension Tax Allowance threshold's uprating); 7de3747 fixes it, and on a local merge with main that file and the PTA properties pass (38 tests)test_guarantee_credit_boundary_matches_main(the 2028 step where guarantee credit ends moves from £1.01 to £1.61 under the allowance); f51c6dc merges main and pins both cases, which pass locally (3 tests)calculated_by(31 files, 588 passed); the four 2030-31 partner and model's-own cases fail on f51c6dc; removing the payment's check ofcarers_allowance_pre_couple_limitfails the three partner cases and the 2030-31 v 2031-32 property failcalculated_by(31 files, 590 passed); thedefined_forcase fails on bffa9e8, and again when the value check goes; removing the formula check fails the model's-own casematches_parts_of_yeartest fails without the sign check), fuel duty schedule (75), fuel duty and excise YAML (18), Treasury and VAT YAML (56)~/reviews/ab26-baseline/impact-trace/taper_only.py)Reproducer: policyengine_uk/tests/policy/reforms/oct_2026_budget/savings_property_income_rates.yaml; policyengine_uk/tests/policy/reforms/oct_2026_budget/pension_tax_allowance.yaml; policyengine_uk/tests/test_carers_allowance_earnings_taper.py::test_ten_pounds_over_the_limit_takes_ten_pounds_off; policyengine_uk/tests/test_fuel_duty_schedule.py::test_scheduled_rate_on_each_date; policyengine_uk/tests/test_domestic_electricity_vat.py::test_rates_change_on_each_scheduled_date; policyengine_uk/tests/policy/baseline/gov/treasury/household_energy_payment/household_energy_payment.yaml; policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/allowances/trading_allowance_deduction.yaml
axiom: TheAxiomFoundation/rulespec-uk#507 queued (Pension Tax Allowance) | TheAxiomFoundation/rulespec-uk#454 queued (Carer's Allowance taper) | TheAxiomFoundation/rulespec-uk#349 queued (fuel duty) | TheAxiomFoundation/rulespec-uk#467 queued (electricity VAT) | TheAxiomFoundation/rulespec-uk#508 queued (Household Energy Payment) | TheAxiomFoundation/rulespec-uk#506 queued (savings and property rates) | TheAxiomFoundation/rulespec-uk#348 queued (trading allowance)
🤖 Generated with Claude Code