Skip to content

Count corporate SDLT once and let SDLT abolition remove all of it - #2235

Merged
MaxGhenis merged 9 commits into
mainfrom
fix/corporate-sdlt-double-count
Oct 22, 2026
Merged

MaxGhenis merged 9 commits into
mainfrom
fix/corporate-sdlt-double-count

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2159

Summary

Corporate SDLT was counted twice in household_tax, gov_tax and pre_budget_change_household_tax, and abolishing SDLT left one copy of it in all three. This PR counts it once and makes abolition remove all of it. It also adds a tax-head partition, specified independently of the model's own lists, with tests that every total counts each of its heads exactly once.

National effect on certified data: all three totals fall by £3.131bn a year from 2025-26 to 2030-31, and household net income rises by the same amount. Poverty rates don't change. Measured by real runs, below.

The bug

  • expected_sdlt returned stamp_duty_land_tax + property_sale_rate + corporate_sdlt (variables/gov/hmrc/expected_sdlt.py on main).

  • GOV_TAX_VARIABLES, HOUSEHOLD_TAX_VARIABLES and PRE_BUDGET_CHANGE_HOUSEHOLD_TAX_VARIABLES list both expected_sdlt and corporate_sdlt, so corporate SDLT entered each total twice.

  • gov.hmrc.stamp_duty.abolish zeroed expected_sdlt only. corporate_sdlt, listed separately, survived abolition in full.

  • property_sale_rate is a share (0.045, unit /1), and adding it gave every household £0.045 of SDLT, including households in Scotland and Wales. Add dataset schema, remove State variables and add HBAI net income #1155 turned the original * into +.

    The datasets don't need the scaling anyway. policyengine-uk-data draws purchasers directly: property_purchased is a seeded draw at 3.85% in datasets/frs.py. So stamp_duty_land_tax is already the expected liability.

The fix

  • expected_sdlt returns stamp_duty_land_tax: the household's own purchases and leases only.
  • corporate_sdlt returns 0 when gov.hmrc.stamp_duty.abolish is set.
  • No household is sdlt_liable once SDLT is abolished, so the stamp_duty_land_tax liability is zero too. Before, it kept showing the pre-abolition liability. expected_sdlt keeps its own check, so abolition also zeroes it when the liability is entered directly.
  • The totals' lists are unchanged, so each part is counted once, and abolition zeroes both.
  • The high value council tax surcharge tests drop five property_sale_rate: 0 overrides that existed only to cancel the stray £0.045.

Tax-head partition

The file is policyengine_uk/data/fiscal_partition.yaml (plain YAML, schema_version: 1). Main has carried it since #2335 (the aggregate impact report), describing the model before this fix: expected_sdlt as one head holding both parts, and corporate_sdlt under model_double_counts. This PR gives corporate SDLT its own head, empties model_double_counts, and adds the fields, coverage, exclusions and guards below. Main's spending side (gov_spending, household_benefits and their 58 heads) is unchanged.

Heads. Each head is one row of the OBR's current receipts table (EFO November 2025, Table A.5), split by payer or nation where the model splits it, and measured by exactly one variable. Its fields:

  • obr_line, or not_an_obr_current_receipt with a reason (for example, student loan repayments are a financial transaction);
  • obr_table_3_1, the line of the March 2026 EFO's Table 3.1 that holds it, where that table's footnotes say so;
  • report_group and payer;
  • the totals it belongs to;
  • sign, and zero_at_baseline for the reform-only heads;
  • reads, which declares the reads that are eligibility rather than inclusion.

SDLT is two heads on one receipts row ("Property transaction taxes"): sdlt_household (expected_sdlt) and sdlt_corporate (corporate_sdlt).

Coverage. The 29 heads sit on 12 of Table A.5's 30 tax rows. uncovered_receipts lists the other 18 (corporation tax, inheritance tax, air passenger duty and so on), so every row is either measured or declared uncovered.

Exclusions. 73 variables that must never be summed alongside the heads, each with its kind:

  • component: inside a head, e.g. stamp_duty_land_tax, the NI classes, the income tax parts and reductions.
  • measure_within: e.g. salary_sacrifice_pension_ni_*, already charged through employment_income.
  • composite: e.g. corporate_tax_incidence, which is corporate_sdlt + business_rates.
  • duplicate: baseline_business_rates.
  • baseline_measure: baseline_vat.
  • assessment: a tax amount worked out for a means test or a ceiling, e.g. uc_income_tax_on_earnings, ni_class_4_maximum.
  • change_measure: a wage change already inside the incomes a head taxes, e.g. employer_ni_fixed_employer_cost_change.

Overlap guards.

  • SDLT is split between household and company payers.
  • SDLT, LTT and LBTT are geographically exclusive, and so are council tax and NI domestic rates.
  • VAT and employer NI appear as a level in gov_tax and as a change in household_tax, never in the same total.
  • Council tax is counted gross, with Council Tax Reduction counted as spending. The OBR's row is net of reduction schemes, so comparisons need the reduction netted off.
  • income_tax includes the High Income Child Benefit Charge, so benefits must be counted gross of it.
  • Business rates, corporate SDLT and three reform-only heads (corporate tax change, carbon tax, land value tax) share the shareholding key; each is a different receipt.
  • Private school VAT may overlap VAT on imputed consumption.

Independence. The heads come from the OBR table and each variable's formula, not from the model's lists; a differential test compares the two. A second specification was written blind by a GPT-6.1 Sol lane that was not allowed to read the model's lists or this file (~/reviews/uk-corporate-sdlt-2159/spec-out.md). Reconciling the two:

Blind specification This partition
Same variable for income tax, both NI heads, VAT, private school VAT, fuel, alcohol and tobacco duties, VED, the licence fee, business rates, CGT, NI domestic rates, the surcharge, both SDLT heads and the four hypothetical taxes Agreed
Council tax: the net variable council_tax_less_benefit, matching the OBR's net receipts Kept gross council_tax, which is what the totals sum, with the reduction in spending. Recorded on the head and as a guard
LTT and LBTT: the unscaled liabilities, because expected_ltt and expected_lbtt discount twice Kept the variables the totals sum, with #2246 noted on both heads. #2315 fixes it
Student loan repayments: outside both tax totals Kept as the model counts them, flagged not_an_obr_current_receipt for separate reporting
VAT change, employer NI response incidence, the two unallocated tax changes: exclusions from a total of levels Heads of the totals that use them, zero_at_baseline
18 receipt rows with no household measure Adopted as uncovered_receipts
About 20 further exclusions (income tax reductions, Class 4 ceiling, Universal Credit tax assessments, wage-change measures) and three guards Adopted
stamp_duty_land_tax still shows a liability after abolition Fixed here: abolition now makes no household sdlt_liable

I checked the two OBR claims I adopted at the source: Table A.5's rows and footnotes, and the OBR's council tax page (receipts include Northern Irish domestic rates and are net of reduction schemes).

Shared with the aggregate impact report. #2335's report, now on main, reads this file directly for its tax heads, spending heads and partition identity, and each side of its comparison reads its own copy. Its partition, guard and measurement tests pass on the merged state (see Tests).

Invariants

  1. Partition, differential. For each total, the variables the model sums are exactly the partition's heads for it, each listed once. No exclusion is listed. Every tax row of Table A.5 is a head's row or declared uncovered, never both.
  2. No overlap, traced. Within a total, no head's formula reaches another head of that total unless the partition declares the read. The declared reads are TV licence → over-75 discount → Pension Credit income → income tax and NI, and private school VAT → attendance imputation. Every declared read must still occur. Since Impute UC deductions in constituency and local-authority runs #1905 the attendance imputation runs only in simulations built from data, so the trace follows the same households both as a situation and as if built from data.
  3. Coefficient one. Raising any head by 1,024, with every other input unchanged, raises each total that includes it by exactly 1,024 per member, and moves no other head of those totals.
  4. Identity. On random households, in 2025-2030, at current law and with SDLT or council tax abolished, each total equals the sum of its heads, less those dropped_when names. Every sign: nonnegative head is ≥ 0. Every zero_at_baseline head is 0 at current law. At most one of SDLT, LTT and LBTT is non-zero per household.
  5. SDLT once. expected_sdlt equals stamp_duty_land_tax. Removing corporate SDLT revenue lowers each total by exactly corporate_sdlt. Abolition lowers each total by exactly stamp_duty_land_tax + corporate_sdlt, and leaves stamp_duty_land_tax, expected_sdlt and corporate_sdlt all zero. With a dataset, weighted corporate_sdlt is the corporate revenue statistic.
  6. Abolition removes SDLT and nothing else. A Welsh shareholder keeps business rates and loses corporate SDLT.

Tests

File Covers
tests/test_fiscal_partition.py 1–4 (schema, differential, traced guard, 29 perturbation cases, Hypothesis identity)
tests/test_sdlt_counted_once_properties.py 5 (Hypothesis, two households, 2024–2027)
tests/policy/baseline/gov/hmrc/stamp_duty/corporate_sdlt.yaml, expected_sdlt.yaml, sdlt_liable.yaml Fixed cases for 5 and 6

Red on main, green here. I ran the final test_fiscal_partition.py (static, traced and SDLT perturbation cases) against main's model code (3f174d0):

  • the traced guard fails for all three totals, because expected_sdlt reaches corporate_sdlt;
  • raising corporate_sdlt by 1,024 moves gov_tax by 2,048.

After merging main (2f4021a29, then 8c1b54dd9), run locally on a shared and heavily loaded host, from the locked environment, without microsimulation tests and with at most four workers:

  • test_fiscal_partition.py, test_sdlt_counted_once_properties.py and the aggregate impact tests: 280 passed and 1 failed, the declared-reads case described under "Main merged in". After the fix, the five traced-graph cases pass.
  • test_weighted_incidence.py: 19 passed after its fix.
  • The stamp duty and council tax YAML directories, and every other YAML file that asserts household_tax, gov_tax, expected_sdlt or corporate_sdlt: 86 passed.
  • The partition and SDLT property tests again, with main's property transaction, purchase schedule, data-built imputation, spending and benefit property tests: 66 passed and none failed before I stopped the run, because the host was saturated.
  • ruff format --check . is clean, and the fix-evidence checker passes.

CI at 8c1b54dd9: all 16 checks pass, including the five Python test shards, the YAML tests, aggregate impact and fix evidence.

National impact (real runs, 11 October)

Setup.

  • Data: policyengine-uk-data 1.58.0, enhanced_frs_2024_25.h5, sha256 5ba399ea5ab9a6c7d4e9aaf6c623080beb34d9ad5f330f6244dbad72b8d960b6, the certified release.
  • Code: base is main at 6d89338 and head is this branch's model code. Both are policyengine-uk 2.126.8.
  • Runtime: both use policyengine-core 3.33.0, the certified bundle's core. The repo lock pins 3.32.27.
  • Each figure is a weighted total from Microsimulation runs: no scaling and no interpolation. 36 runs in all: 2 versions × 3 scenarios × 6 years.

Current law, £bn a year

2025-26 2026-27 2027-28 2028-29 2029-30 2030-31
gov_tax, base 978.967 1,021.444 1,060.540 1,096.037 1,133.645 1,172.964
gov_tax, head 975.836 1,018.312 1,057.409 1,092.905 1,130.514 1,169.833
Change in gov_tax, household_tax, pre_budget_change_household_tax and gov_balance −3.131 −3.131 −3.131 −3.131 −3.131 −3.131
Change in household_net_income +3.131 +3.131 +3.131 +3.131 +3.131 +3.131
expected_sdlt, base → head 19.448 → 16.316 20.440 → 17.308 21.414 → 18.283 22.393 → 19.262 23.395 → 20.264 24.493 → 21.362

The −£3.131bn is £3.130bn of corporate SDLT plus about £1.4m of stray £0.045s across roughly 31m households. corporate_sdlt (£3.130bn) and stamp_duty_land_tax are unchanged.

Accounting checks on the data

Check (every year 2025-26 to 2030-31) Base Head
gov_tax change from zeroing corporate SDLT revenue, ÷ corporate_sdlt 2.0000 1.0000
Corporate SDLT left after abolition £3.130bn £0
Households with ≥2 of SDLT, LTT, LBTT non-zero 86–96 0
Non-finite outputs none none

SDLT abolition costing. The measured effect barely moves. Abolishing SDLT changes gov_tax by −£20.440bn on base and −£20.438bn on head in 2026-27, and likewise in every year. Base's baseline held corporate SDLT twice and its abolished scenario once, so the difference was one copy either way. What changes is the level of both scenarios.

Distribution. Head − base, in household net income per household, weighted mean £, 2026-27:

D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 All
45.94 60.27 53.38 86.63 81.15 82.47 93.36 114.09 164.62 223.17 99.84

Corporate SDLT is allocated by shareholding, so the removed copy is worth more to higher deciles. The other years are in the evidence folder.

Poverty. BHC and AHC, absolute and relative: unchanged to four decimal places in every year. HBAI income does not read these variables; hbai_excluded_income lists corporate_tax_incidence, but no current HBAI income formula reads it.

Things this does not change

Follow-ups.

  • LTT and LBTT are discounted twice (expected_sdlt adds the property sale rate; expected_lbtt and expected_ltt discount purchases twice #2246). On 1.58.0 in 2026-27, LBTT is £2.31bn but expected_lbtt is £0.104bn. Land transaction tax is £0.070bn but expected_ltt is £0.003bn. The partition records this as a data_note on both heads. The fix should follow this PR's convention, the purchase draw being the expectation.
  • Corporate SDLT is held at 2020 revenue. £0.705bn residential plus £2.425bn non-residential, from gov.hmrc.stamp_duty.statistics, never uprated. Update corporate SDLT and business rates statistics and project them with OBR receipts #2322 updates it.
  • Alcohol, tobacco and vehicle excise duties are £0 for every household on 1.58.0 in every year. Recorded as data_notes; the aggregate impact report flags inert heads.
  • Private school VAT is zero at current law. gov.contrib.labour.private_school_vat is 0, so the head is reform-only. A guard records the possible overlap with VAT on imputed consumption. Charge VAT on private school fees at current law #2319 addresses it.
  • 76 households have negative VAT on 1.58.0 (−£72m weighted in 2026-27), from negative imputed consumption or full-rate share. Recorded on the vat head; policyengine-uk-data#565.
  • uk-data test. policyengine-uk-data's tests/test_property_purchased.py compares weighted expected_sdlt with total SDLT receipts, using wide bounds (£5–50bn). expected_sdlt is now household-only (£17.3bn in 2026-27), still inside the bounds. A tighter benchmark should add corporate_sdlt. That change goes in the batched data release.

Main merged in (21 October)

2f4021a29 merges main at 6ac87fb04 (policyengine-uk 2.146.0) into this branch, and 8c1b54dd9 on top fixes the traced-reads test. One textual conflict, two semantic ones:

  • fiscal_partition.yaml (both sides added it). This PR's tax side whole: the sdlt_corporate head, an empty model_double_counts, Table A.5 rows, uncovered receipts, 73 exclusions and 11 guards. Main's spending side whole: the gov_spending and household_benefits totals and their 58 heads. Main's tax heads, exclusions and guards are a subset of this PR's, with sdlt_corporate in place of sdlt_household wherever corporate SDLT is meant. Main's correction to the salary sacrifice note is kept (the excess is added back to ni_class_1_income).
  • tests/test_weighted_incidence.py (added on main on 16 October) abolished SDLT only to keep the household purchase charge out of household_tax, and expected corporate SDLT to survive abolition. Abolition now removes corporate SDLT too, so its corporate incidence case got £1.00 for £1.50 on the merged tree. The abolition line is gone: no household in that test buys property, so expected_sdlt is zero without it, and the test still checks the £150 × shareholding allocation, now with corporate SDLT counted once in household_tax.
  • tests/test_fiscal_partition.py::test_declared_reads_occur failed on the merged tree. Main's Impute UC deductions in constituency and local-authority runs #1905 gate stops attends_private_school before it reads income unless the simulation was built from data, and the test traced a household situation. The reads still happen in every data-built simulation, which is what the partition describes, so the trace now covers both (invariant 2).
  • tests/aggregate_impact/test_aggregate_impact_measure.py: the test of how a declared double count from few records is suppressed now builds the partition in its pre-fix shape, since the shipped one declares none. The certified-data guard docstring no longer calls Corporate SDLT is counted twice in household and government tax totals #2159 open. The partition changelog fragment is now a changed entry, since main already ships the file.
  • Main hasn't changed the three totals' lists since 12 October. Nothing new on main adds expected_sdlt or corporate_sdlt to a total, and there is no new tax head.

Aggregate impact CI

The Aggregate impact workflow (run, comment) measured base main 9d81a5dfa8 against GitHub's merge commit for this head (6d80d1afd1), both on enhanced_frs_2024_25.h5 (policyengine-uk-data 1.58.1), for 2025-26 to 2031-32. Result: pass, and no check is broken by this change.

  • gov_tax, household_tax, pre_budget_change_household_tax and gov_balance each fall by £3.13bn in every year, and household net income rises by £3.13bn.
  • Receipts with each component counted once fall by £1.4m a year: the stray £0.045s. The household SDLT head falls by £3.13bn, and the new corporate head carries £3.13bn.
  • Counted-once check: each of 84 components was raised by £1, and none failed. The base's declared double count (corporate_sdlt inside expected_sdlt, £3.13bn) is gone on the head.
  • Poverty, inequality, population and each standard reform's target are unchanged in every year. The standard reform costings move by less than £5,000 a year.
  • Mean household net income rises in every decile: by £44 to £60 in decile 1, and by £217 to £230 in decile 10 (£98 to £100 across all households). In every year, 75.9% of people gain more than £1, and none lose more than £1.
  • The only check failing on both sides is negative VAT for 76 households (policyengine-uk-data#565).

This agrees with the real runs of 11 October above: −£3.131bn a year on 1.58.0.

Merge

Lands on the UK hub's gates. The SDLT and land freeze that kept this a draft was lifted for the Budget on 21 October. Evidence and scripts for the real runs above: ~/reviews/uk-corporate-sdlt-2159/ (impact.py, compare.py, impact.md, the runs).

axiom: n/a: this corrects how the model's tax totals add up its own variables (corporate SDLT incidence, a modelling convention), not a statutory rule rulespec-uk encodes

🤖 Generated with Claude Code

Reproducer: policyengine_uk/tests/policy/baseline/gov/hmrc/council_tax/high_value_council_tax_surcharge.yaml, policyengine_uk/tests/policy/baseline/gov/hmrc/stamp_duty/corporate_sdlt.yaml, policyengine_uk/tests/policy/baseline/gov/hmrc/stamp_duty/expected_sdlt.yaml, policyengine_uk/tests/policy/baseline/gov/hmrc/stamp_duty/sdlt_liable.yaml::No household is liable once Stamp Duty is abolished, policyengine_uk/tests/test_fiscal_partition.py::test_partition_schema, policyengine_uk/tests/test_fiscal_partition.py::test_partition_heads_are_the_variables_each_total_sums

@MaxGhenis
MaxGhenis requested a review from vahid-ahmadi October 9, 2026 14:33
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Local targeted runs at 685c1e7 (policyengine-uk installed editable, Python 3.13), through the shared heavy-test lock. CI runs the full suite.

  • policyengine-core test on tests/policy/baseline/gov/hmrc/stamp_duty/corporate_sdlt.yaml, expected_sdlt.yaml and tests/policy/baseline/gov/hmrc/council_tax/high_value_council_tax_surcharge.yaml: 22 passed.
  • pytest policyengine_uk/tests/test_sdlt_counted_once_properties.py: 1 passed (15 Hypothesis examples, derandomised) in 97 s.

An independent review is running; findings will follow here.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Independent review (GPT-6.1 Sol, 9 Oct) asked for changes; all addressed at 2d606f7ca:

  • Effect section was wrong (major). Abolition does not save £3.13bn more: the old abolished scenario still carried corporate SDLT, so abolition saved S + C + r before and S + C now. The body now gives the per-household algebra and labels it as deduced from the formulas, not measured on production data.
  • Docstring overstated the data (minor). expected_sdlt now says the FRS-based datasets impute an annual purchaser indicator with a seeded draw (policyengine-uk-data datasets/frs.py:1874-1879).
  • uk-data consumer (minor). tests/test_property_purchased.py:74 compares weighted expected_sdlt with total receipts; noted as a follow-up for the next batched data release.
  • Added Fixes #2159 and the axiom: line; the HVCTS note now says five overrides were removed.

Mutation check, run locally: with expected_sdlt adding corporate_sdlt back, corporate_sdlt.yaml failed 3 of 5 cases and the property test failed at its first assertion (test_sdlt_counted_once_properties.py:144). Restored; the working tree is clean.

MaxGhenis and others added 3 commits October 11, 2026 11:07
expected_sdlt added corporate_sdlt, and household_tax, gov_tax and
pre_budget_change_household_tax list both, so corporate SDLT was counted
twice. gov.hmrc.stamp_duty.abolish zeroed expected_sdlt only, leaving one
copy of corporate SDLT in the totals after abolition.

expected_sdlt is now the household's own SDLT (stamp_duty_land_tax), and
corporate_sdlt returns 0 when SDLT is abolished. The totals lists are
unchanged, so each part is counted once.

expected_sdlt also added property_sale_rate (a 0.045 share) as pounds, a
slip from #1155, which changed the multiplication to an addition. Population
datasets already mark only purchasers, so no scaling is applied; the
high-value surcharge tests no longer need to zero the parameter.

Adds YAML cases and a Hypothesis property test on a two-household
population (baseline, abolition, and corporate SDLT revenue set to zero).

Fixes #2159

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine_uk/data/fiscal_partition.yaml divides the tax totals into heads,
one OBR current-receipts line per head (split by payer where the model
splits it), each measured by one variable. It lists the variables that must
never be summed alongside the heads, with the reason, and the places double
counting could occur. The heads were written from the OBR classification
and the variables' formulas, not from GOV_TAX_VARIABLES and its siblings.

test_fiscal_partition.py checks the two specifications against each other:
- each total sums exactly the partition's heads for it;
- traced: no head reaches another head of its total unless the partition
  declares the read (the TV licence discount's Pension Credit test, the
  private school attendance imputation), and every declared read occurs;
- perturbation: raising one head by 1,024 raises each total that includes
  it by 1,024 per member and moves no other head of that total;
- on random households, 2025-2030, at current law and with SDLT or council
  tax abolished: each total equals the sum of its heads, signs hold,
  reform-only heads are zero at current law, and at most one of SDLT, LTT
  and LBTT is non-zero.

On main's formulas the traced test fails for all three totals (expected_sdlt
reaches corporate_sdlt) and raising corporate_sdlt moves gov_tax by 2,048.

Adds corporate SDLT fixtures for a Welsh shareholder: abolition removes
corporate SDLT and keeps business rates. Trims the SDLT property test to 10
examples now that the identity test covers abolition too.

Refs #2159

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the fix/corporate-sdlt-double-count branch from 2d606f7 to 02a3c1e Compare October 11, 2026 15:43
Each head now records the line of OBR EFO March 2026 Table 3.1 that holds
it, where the table's footnotes say so ("Capital taxes" includes capital
gains tax and property transaction taxes; "PSNB-neutral receipts" includes
council tax), and null where they don't (vehicle excise duty, the licence
fee, Northern Ireland domestic rates). A sources block records what was
read and when. The schema test checks the values against the table's
lines. The excise heads' data notes cite issues 1872-1874.

Refs #2159

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 11, 2026
YAML cases hand-compute LBTT (SSI 2015/126 Tables A and B, first-time
buyer relief) and LTT (WSI 2018/128 Tables 1 to 3) on purchases in
Scotland and Wales and check expected = liability = the household's
tax totals. The Hypothesis test checks expected equals realised and,
independently, that zeroing every LTT and LBTT rate lowers each total
by exactly the liabilities. A differential test compares the model with
the statutory tables; the schedules it has stale (issues 1795, 1796) are
strict expected failures.

On the #2235 head (41e970b), 9 of the 17 YAML cases and the property
test fail; here all pass.

The partition's data notes now give the measured 1.58.0 figures.

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

Copy link
Copy Markdown
Collaborator Author

Stacked on this PR: #2319 (fixes #2318) makes VAT on private school fees current law from 1 January 2025 (Finance Act 2025 ss.47 and 49), and updates this file's private school entries to match:

  • private_school_vat is no longer zero at baseline and moves to gov_tax only;
  • a new private_school_vat_change head in household_tax;
  • the exclusion baseline_private_school_vat;
  • the vat guard becomes overlapping_base;
  • the identity property draws pupils.

#2319 is rebased on 5f08c244c. Once this merges, #2319 retargets to main.

MaxGhenis added a commit that referenced this pull request Oct 11, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 11, 2026 19:31
The aggregate impact report (#2335) adds gov_spending, household_benefits
and spending_heads to fiscal_partition.yaml. The tax tests now check the
three tax totals only, require that spending heads borrow no tax head id or
variable and that no spending head names a tax total, and apply dropped_when
to the tax totals alone. Checked against #2335's file with these tax
sections merged in: this file's tests and #2335's partition and guard tests
pass.

The vat head records that 76 households have negative VAT on
policyengine-uk-data 1.58.0 (consumption or the full-rate expenditure share
is negative in the data; policyengine-uk-data issue 565).

Refs #2159

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the fix/corporate-sdlt-double-count branch from 5f08c24 to 47eb1f7 Compare October 11, 2026 23:32
…ility

A second specification of the tax heads was written from OBR EFO November
2025 Table A.5 and the variables' formulas by a reviewer who was not shown
the model's lists or the partition file. Reconciling the two:

- obr_line is now the Table A.5 row (SDLT, LTT and LBTT sit on "Property
  transaction taxes"; the surcharge and Northern Irish domestic rates on
  "Council tax"), and uncovered_receipts lists the 18 rows the model has no
  household measure for. The schema test checks that the heads' rows and
  the uncovered rows account for every tax row of the table.
- Council tax is recorded as gross of Council Tax Reduction, which the model
  counts as spending; the OBR's row is net. A guard says so.
- About 20 more exclusions: income tax reductions, the Class 4 ceiling,
  the tax amounts Universal Credit assesses, wage-change measures, and
  Child Benefit net of the High Income Child Benefit Charge. Two new kinds,
  assessment and change_measure, hold the ones a means test may read.
- Where the blind specification chose a different variable (net council
  tax, unscaled LTT and LBTT, student loans outside the totals), the head
  says so.

Both specifications flagged that stamp_duty_land_tax still showed a
liability after gov.hmrc.stamp_duty.abolish. No household is sdlt_liable
once SDLT is abolished, so the liability is now zero too; expected_sdlt
keeps its own check for a liability entered directly.

Refs #2159

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

Copy link
Copy Markdown
Collaborator

Thanks Max. Reviewed at 3ada49f. The fix is right and the partition is a really useful guard. Nothing blocking from me; a few small points below.

What I checked

  • The bug is real on main. expected_sdlt adds corporate_sdlt (expected_sdlt.py:15-18), and gov_tax.py, household_tax.py and pre_budget_change_household_tax.py all list both, so corporate SDLT goes in twice and abolition leaves one copy behind.
  • The fix. expected_sdlt is now just stamp_duty_land_tax, corporate_sdlt is zero under gov.hmrc.stamp_duty.abolish, and sdlt_liable turns off with it. The only readers of sdlt_liable are stamp_duty_land_tax (defined_for) and the tests, so making it abolition-aware doesn't reach anything else. corporate_tax_incidence and hbai_excluded_income now lose corporate SDLT under abolition too, which is what you'd want.
  • Tests. I used a fresh uv sync environment in a worktree (policyengine-core 3.32.27), not the shared venv. At the head, the two new Python files pass (40), and so do the stamp duty and council tax YAML directories (36). I copied the new tests onto main (0bc08f2), and they fail there: 6 of the 40 Python tests (the traced guard for all three totals, sdlt_corporate entering once, the sum identity, and the SDLT property test) and 13 of 24 YAML cases.
  • National effect. I re-ran it on the certified Microcosm UK 2024-25 release (sha256 aa31bdf6…) rather than the Enhanced FRS, comparing the PR's merge base (3f174d07) with the head in the same environment:
2025-26 2029-30
gov_tax, base → head 911.695 → 908.564 1,060.817 → 1,057.686
Change in gov_tax, household_tax, pre_budget_change_household_tax −3.131 −3.131
Change in household_net_income +3.132 +3.131
Saving from abolishing SDLT, base → head 18.286 → 18.285 21.873 → 21.872

So the −£3.131bn reproduces on a second dataset. Abolition now removes exactly stamp_duty_land_tax + corporate_sdlt (£15.155bn + £3.130bn in 2025-26), where base left the £3.130bn corporate copy in.

  • Other users. policyengine.py, the API and the 2026 Budget dashboard don't read expected_sdlt or corporate_sdlt directly; they get the corrected totals. policyengine-uk-data's test_sdlt_total_reasonable reads expected_sdlt against a £5–50bn band, which the new value still clears.

Findings

  1. Scorecard evidence goes stale (should, other repo). policyengine-scorecard's docs/uk_replay/evidence/classification_sources.json keeps a copy of the old expected_sdlt.py source, and its budget_2018:tax:016 row lists expected_sdlt as a mechanism variable. Neither breaks, but the snapshot will no longer match, so it's worth refreshing when this lands.
  2. SDLT and LTT/LBTT are now on different bases until Stop discounting LTT and LBTT twice #2315 (should). expected_sdlt is the unscaled liability, while expected_ltt.py:13-15 and expected_lbtt.py:13-15 still multiply by property_sale_rate. That was already inconsistent on main, and the partition records it under expected_sdlt adds the property sale rate; expected_lbtt and expected_ltt discount purchases twice #2246, so it's fine here. But it means Welsh and Scottish property transaction taxes are about 4.5% of what they should be in the same totals, so I'd merge Stop discounting LTT and LBTT twice #2315 straight after this.
  3. property_sale_rate has only those two readers left (nit). Once Stop discounting LTT and LBTT twice #2315 lands it may be unused. Its description ("This percentage of properties are sold every year") and the TODO in stamp_duty/property_sale_rate.yaml could say it's only the LTT/LBTT scaling, or the parameter could go.
  4. The level is still high (outside this PR). On certified Microcosm 2025-26, household SDLT is £15.16bn plus £3.13bn corporate, £18.3bn in all. policyengine-uk-data's own test cites £13.9bn of official SDLT for 2024-25. The double count was part of the gap and this PR removes it. The rest looks like the purchase rate or the price distribution in the data, which deserves its own issue.

Happy to approve once you've seen these. None of them needs a change in this PR.

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 21, 2026 23:33
Resolve the add/add conflict in policyengine_uk/data/fiscal_partition.yaml:
keep this branch's post-fix tax partition (sdlt_corporate head, empty
model_double_counts, Table A.5 rows, uncovered receipts, exclusions and
guards) and main's spending totals and spending heads unchanged, with
main's corrected salary sacrifice note.

Follow the fix through main's newer tests: test_weighted_incidence no longer
abolishes SDLT to keep the purchase charge out (abolition now zeroes
corporate SDLT too, and expected_sdlt no longer carries it or the stray
0.045); the aggregate-impact measure test builds the pre-fix partition for
its declared double count; the certified guard docstring no longer calls
#2159 open. The partition changelog fragment becomes a changed entry, since
main already ships the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's #1905 gate stops attends_private_school before it reads income unless
the simulation was built from data, so tracing a household situation no
longer saw private_school_vat's declared reads of income tax, NI and council
tax. Those reads still happen in every data-built simulation, which is what
the partition describes. traced_reads now traces the same households twice,
once with built_from_dataset set, and takes the union, so the undeclared-read
guard and the exclusion check cover both paths. Format the measure test's
pre-fix partition helper.

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

Copy link
Copy Markdown
Contributor

Aggregate impact on certified data: pass

Base 9d81a5dfa8 against head 6d80d1afd1, both on enhanced_frs_2024_25.h5 (policyengine-uk-data 1.58.1, sha256 056e80fd8e91), fiscal years 2025-26 to 2031-32. Each year is a full microsimulation run on each side.

Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 182 (thresholds in report_spec.yaml; a flag does not fail the job).

Workflow run and full report

Notes

  • This change edits the fiscal partition; review the partition diff alongside the moves it explains.
  • The check double_count_present:corporate_sdlt ran on the base but not on the head (the partition changed).
  • In the years a figure from fewer than 10 records is suppressed (spending.disabled_students_allowance), every total containing it, and the decile incomes, are rebuilt from their other components, so no published total includes it. Those totals are marked †. A change is withheld where the two sides leave out different figures and can't be lined up.
  • Stamp duty land tax paid by companies (receipts.sdlt_corporate) is measured on the head only.
  • corporate_sdlt, counted again inside expected_sdlt (double_counts.corporate_sdlt) is measured on the base only.

Moves flagged for review

Measure Year Base Head Change
Stamp duty land tax on the household's own purchases 2031-32 £12.64bn £9.51bn -£3.13bn
Stamp duty land tax on the household's own purchases 2030-31 £12.23bn £9.09bn -£3.13bn
Stamp duty land tax on the household's own purchases 2029-30 £11.81bn £8.68bn -£3.13bn
Stamp duty land tax on the household's own purchases 2028-29 £11.40bn £8.26bn -£3.13bn
Stamp duty land tax on the household's own purchases 2027-28 £10.98bn £7.85bn -£3.13bn
Stamp duty land tax on the household's own purchases 2026-27 £10.56bn £7.42bn -£3.13bn
Stamp duty land tax on the household's own purchases 2025-26 £10.06bn £6.93bn -£3.13bn
gov_balance 2025-26 £366.28bn £363.15bn -£3.13bn
gov_balance 2026-27 £391.92bn £388.79bn -£3.13bn
gov_balance 2027-28 £422.75bn £419.61bn -£3.13bn
gov_balance 2028-29 £448.90bn £445.77bn -£3.13bn
gov_balance 2029-30 £476.64bn £473.51bn -£3.13bn
pre_budget_change_household_tax 2025-26 £488.34bn £485.21bn -£3.13bn
household_tax 2025-26 £496.17bn £493.03bn -£3.13bn
gov_balance 2030-31 £504.36bn £501.23bn -£3.13bn
pre_budget_change_household_tax 2026-27 £514.54bn £511.41bn -£3.13bn
household_tax 2026-27 £522.66bn £519.53bn -£3.13bn
gov_balance 2031-32 £536.06bn £532.93bn -£3.13bn
pre_budget_change_household_tax 2027-28 £540.10bn £536.97bn -£3.13bn
household_tax 2027-28 £548.45bn £545.32bn -£3.13bn
pre_budget_change_household_tax 2028-29 £561.60bn £558.47bn -£3.13bn
household_tax 2028-29 £570.64bn £567.51bn -£3.13bn
pre_budget_change_household_tax 2029-30 £583.57bn £580.44bn -£3.13bn
household_tax 2029-30 £592.85bn £589.72bn -£3.13bn
pre_budget_change_household_tax 2030-31 £607.75bn £604.62bn -£3.13bn
household_tax 2030-31 £617.30bn £614.17bn -£3.13bn
pre_budget_change_household_tax 2031-32 £634.11bn £630.98bn -£3.13bn
household_tax 2031-32 £644.01bn £640.87bn -£3.13bn
gov_tax 2025-26 £902.51bn £899.38bn -£3.13bn
Decile 1: mean household_net_income per household 2027-28 £17,934 £17,994 +£60
gov_tax 2026-27 £942.37bn £939.24bn -£3.13bn
Decile 1: mean household_net_income per household 2028-29 £17,991 £18,051 +£59
Decile 1: mean household_net_income per household 2029-30 £18,328 £18,387 +£59
gov_tax 2027-28 £979.31bn £976.18bn -£3.13bn
Decile 1: mean household_net_income per household 2030-31 £18,506 £18,565 +£59
Decile 1: mean household_net_income per household 2031-32 £18,680 £18,739 +£58
gov_tax 2028-29 £1,012.51bn £1,009.38bn -£3.13bn
gov_tax 2029-30 £1,048.79bn £1,045.66bn -£3.13bn
gov_tax 2030-31 £1,085.73bn £1,082.60bn -£3.13bn
gov_tax 2031-32 £1,126.61bn £1,123.48bn -£3.13bn

142 more flags are in the report artifact.

Receipts by tax head

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Stamp duty land tax on the household's own purchases -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn
Stamp duty land tax paid by companies (new: head levels) £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn

Spending by benefit and service

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed

Caseloads

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed

Government balance, each component counted once

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Government receipts, each component once -£1.4m -£1.4m -£1.4m -£1.4m -£1.4m -£1.4m -£1.4m
Government balance, each receipt once -£1.4m † -£1.4m † -£1.4m † -£1.4m † -£1.4m † -£1.4m † -£1.4m †

Model totals

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
gov_tax -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn
household_tax -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn
pre_budget_change_household_tax -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn -£3.13bn
gov_balance -£3.13bn † -£3.13bn † -£3.13bn † -£3.13bn † -£3.13bn † -£3.13bn † -£3.13bn †

Components the model counts twice

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
corporate_sdlt, counted again inside expected_sdlt (removed: base levels) £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn

Household income totals

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Household net income +£3.13bn † +£3.13bn † +£3.13bn † +£3.13bn † +£3.13bn † +£3.13bn † +£3.13bn †

Mean household net income in each side's own deciles

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Decile 1: mean household_net_income per household +£44 † +£45 † +£60 † +£59 † +£59 † +£59 † +£58 †
Decile 2: mean household_net_income per household +£62 † +£61 † +£61 † +£61 † +£61 † +£60 † +£57 †
Decile 3: mean household_net_income per household +£59 † +£58 † +£58 † +£58 † +£57 † +£59 † +£62 †
Decile 4: mean household_net_income per household +£88 † +£88 † +£74 † +£72 † +£73 † +£69 † +£69 †
Decile 5: mean household_net_income per household +£87 † +£85 † +£82 † +£83 † +£83 † +£84 † +£82 †
Decile 6: mean household_net_income per household +£75 † +£76 † +£74 † +£66 † +£65 † +£63 † +£65 †
Decile 7: mean household_net_income per household +£90 † +£90 † +£87 † +£94 † +£93 † +£94 † +£92 †
Decile 8: mean household_net_income per household +£121 † +£116 † +£116 † +£119 † +£120 † +£119 † +£118 †
Decile 9: mean household_net_income per household +£157 † +£160 † +£162 † +£163 † +£163 † +£162 † +£163 †
Decile 10: mean household_net_income per household +£230 † +£228 † +£226 † +£221 † +£221 † +£220 † +£217 †

Standard reform costings (change in gov_balance)

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp -£879 -£713 -£318 +£1,281 +£843 +£2,195 -£3,280
Raise higher rate by 1pp +£694 +£618 +£599 +£1,257 -£2,036 -£651 -£897
Raise personal allowance by ~800GBP/year +£634 +£721 -£405 -£777 -£516 -£1,150 -£4,146
Raise child benefit by 25GBP/week per additional child +£30 +£242 +£192 +£9 -£323 +£83 -£825
Reduce Universal Credit taper rate to 20% -£330 -£124 +£59 -£69 -£84 +£18 +£18
Raise Class 1 main employee NICs rate to 10% -£4,610 +£2,378 +£1,872 +£720 -£672 -£1,336 +£371
Raise VAT standard rate by 2pp -£256 +£390 +£812 +£2,524 -£2,565 -£4,675 -£2,753
Raise additional rate by 3pp -£326 -£102 +£681 +£2,005 -£230 -£260 +£702
Raise the Universal Credit standard allowance by 10% -£12 +£176 +£56 -£57 -£436 -£16 +£267
Raise the State Pension by 10% +£102 +£64 -£260 -£207 +£965 -£402 +£677

Household net income by decile

Mean 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.

Base decile 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Decile 1 +£44 (+0.2%) +£45 (+0.2%) +£60 (+0.3%) +£59 (+0.3%) +£59 (+0.3%) +£59 (+0.3%) +£58 (+0.3%)
Decile 2 +£62 (+0.2%) +£61 (+0.2%) +£61 (+0.2%) +£61 (+0.2%) +£61 (+0.2%) +£60 (+0.2%) +£57 (+0.2%)
Decile 3 +£59 (+0.2%) +£58 (+0.2%) +£58 (+0.2%) +£58 (+0.2%) +£57 (+0.2%) +£59 (+0.2%) +£62 (+0.2%)
Decile 4 +£88 (+0.2%) +£88 (+0.2%) +£74 (+0.2%) +£72 (+0.2%) +£73 (+0.2%) +£69 (+0.2%) +£69 (+0.2%)
Decile 5 +£87 (+0.2%) +£85 (+0.2%) +£82 (+0.2%) +£83 (+0.2%) +£83 (+0.2%) +£84 (+0.2%) +£82 (+0.2%)
Decile 6 +£75 (+0.2%) +£76 (+0.2%) +£74 (+0.1%) +£66 (+0.1%) +£65 (+0.1%) +£63 (+0.1%) +£65 (+0.1%)
Decile 7 +£90 (+0.2%) +£90 (+0.2%) +£87 (+0.1%) +£94 (+0.2%) +£93 (+0.2%) +£94 (+0.2%) +£92 (+0.1%)
Decile 8 +£121 (+0.2%) +£116 (+0.2%) +£116 (+0.2%) +£119 (+0.2%) +£120 (+0.2%) +£119 (+0.2%) +£118 (+0.2%)
Decile 9 +£157 (+0.2%) +£160 (+0.2%) +£162 (+0.2%) +£163 (+0.2%) +£163 (+0.2%) +£162 (+0.2%) +£163 (+0.2%)
Decile 10 +£230 (+0.2%) +£228 (+0.2%) +£226 (+0.2%) +£221 (+0.2%) +£221 (+0.2%) +£220 (+0.2%) +£217 (+0.2%)
all +£100 (+0.2%) +£100 (+0.2%) +£100 (+0.2%) +£99 (+0.2%) +£99 (+0.2%) +£98 (+0.2%) +£98 (+0.2%)
Year People gaining over £1 People losing over £1
2025-26 75.9% 0.0%
2026-27 75.9% 0.0%
2027-28 75.9% 0.0%
2028-29 75.9% 0.0%
2029-30 75.9% 0.0%
2030-31 75.9% 0.0%
2031-32 75.9% 0.0%

No change in any year: population; poverty rates; people in poverty; inequality; standard reforms: change in each reform's target.

Checks failing on both base and head (1)
  • VAT is never negative (sign:vat): 2025-26: 76 units below zero, a weighted £-54,797,972 in total; 2026-27: 76 units below zero, a weighted £-56,271,349 in total; 2027-28: 76 units below zero, a weighted £-57,609,146 in total
Counted-once check

Each 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
Side Commit Runtime Environment hash Partition hash Time
base main 9d81a5dfa8 uk 2.146.2 (files 582dff2713e2), core 3.33.2, py 3.13.16 aarch64 6a24b7ff580b f210f83d5be4 1571.66s
head #2235 merged into main 6d80d1afd1 uk 2.146.2 (files baa41fd27523), core 3.33.2, py 3.13.16 aarch64 6a24b7ff580b d4c1e9f08160 1558.54s

Dataset: hf://policyengine/policyengine-uk-data-private/enhanced_frs_2024_25.h5@2526edbbb687a3b54dbb11272e5389e4b62d2ac2, sha256 056e80fd8e9151d78f432a25cde863340baee81304c6216a37fb575ce8563784 (verified on both sides), policyengine-uk-data 1.58.1.

Receipts by tax head: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Income tax £299.29bn £319.01bn £336.47bn £351.62bn £367.17bn £385.29bn £403.59bn
National Insurance (employee and self-employed) £52.58bn £54.94bn £56.75bn £58.48bn £60.62bn £62.57bn £65.03bn
National Insurance (employer) £152.64bn £159.18bn £164.14bn £168.73bn £176.11bn £181.72bn £188.90bn
Employer NI change borne by capital £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Employer NI change borne by consumers £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Capital gains tax £12.62bn £13.06bn £13.55bn £14.04bn £14.54bn £15.09bn £15.65bn
Student loan repayments £7.83bn £8.12bn £8.35bn £8.56bn £8.79bn £9.04bn £9.38bn
VAT £253.71bn £260.53bn £266.72bn £273.14bn £279.83bn £286.71bn £293.71bn
Change in VAT from its baseline £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
VAT on private school fees £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Fuel duties £24.53bn £24.64bn £26.64bn £26.69bn £26.42bn £25.76bn £26.35bn
Alcohol duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Tobacco duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Vehicle excise duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
TV licence fee £4.28bn £4.43bn £4.44bn £4.46bn £4.48bn £4.51bn £4.53bn
Council tax £49.56bn £52.45bn £55.78bn £59.39bn £62.98bn £66.74bn £70.70bn
High value council tax surcharge £0.00bn £0.00bn £0.00bn £0.48bn £0.49bn £0.51bn £0.52bn
Northern Ireland domestic rates £0.55bn £0.58bn £0.61bn £0.63bn £0.67bn £0.70bn £0.73bn
Business rates £31.73bn £31.73bn £31.73bn £31.73bn £31.73bn £31.73bn £31.73bn
Stamp duty land tax on the household's own purchases £6.93bn £7.42bn £7.85bn £8.26bn £8.68bn £9.09bn £9.51bn
Stamp duty land tax paid by companies £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn
Land transaction tax (Wales) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Land and buildings transaction tax (Scotland) £0.01bn £0.01bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn
Unspecified tax change borne by capital £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Unspecified tax change borne by consumers £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Wealth tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Wealth tax excluding the main residence £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Land value tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Carbon tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Spending by benefit and service: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
State Pension £122.15bn £126.64bn £127.57bn £129.47bn £133.29bn £137.24bn £141.32bn
Pension Credit £6.68bn £7.07bn £7.06bn £7.13bn £7.26bn £7.39bn £7.49bn
Winter Fuel Payment £1.70bn £1.68bn £1.59bn £1.58bn £1.57bn £1.55bn £1.52bn
Pension Age Winter Heating Payment (Scotland) £0.19bn £0.20bn £0.20bn £0.21bn £0.21bn £0.22bn £0.22bn
Universal Credit £78.81bn £83.11bn £84.93bn £86.69bn £87.61bn £89.03bn £90.35bn
Housing Benefit £8.59bn £8.93bn £9.19bn £9.34bn £9.61bn £9.87bn £10.15bn
Council Tax Reduction £1.99bn £2.03bn £2.08bn £2.13bn £2.18bn £2.23bn £2.29bn
Employment and Support Allowance (income-related) £2.12bn £2.18bn £2.23bn £2.28bn £2.33bn £2.39bn £2.45bn
Employment and Support Allowance (contribution-based) £5.22bn £5.36bn £5.49bn £5.62bn £5.76bn £5.90bn £6.04bn
Jobseeker's Allowance (income-based) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Jobseeker's Allowance (contribution-based) £0.29bn £0.30bn £0.30bn £0.31bn £0.32bn £0.33bn £0.33bn
Income Support £0.12bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Working Tax Credit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Child Tax Credit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Incapacity Benefit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Personal Independence Payment £27.05bn £28.19bn £28.94bn £29.64bn £30.37bn £31.11bn £31.87bn
Disability Living Allowance £7.52bn £7.83bn £8.04bn £8.24bn £8.44bn £8.65bn £8.86bn
Attendance Allowance £8.71bn £9.08bn £9.32bn £9.55bn £9.78bn £10.02bn £10.26bn
Carer's Allowance £4.50bn £4.69bn £4.81bn £4.93bn £5.05bn £5.17bn £5.29bn
Carer Support Payment (Scotland) £0.31bn £0.32bn £0.33bn £0.34bn £0.35bn £0.36bn £0.36bn
Carer's Allowance Supplement (Scotland) £0.00bn £0.04bn £0.04bn £0.04bn £0.04bn £0.04bn £0.04bn
Severe Disablement Allowance £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn
Industrial Injuries Disablement Benefit £0.51bn £0.52bn £0.53bn £0.54bn £0.56bn £0.57bn £0.59bn
Armed Forces Compensation Scheme £0.61bn £0.62bn £0.64bn £0.65bn £0.67bn £0.69bn £0.70bn
War Widow's or Widower's Pension £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Child Benefit £16.23bn £16.91bn £17.32bn £17.73bn £18.16bn £18.60bn £19.04bn
Scottish Child Payment £0.50bn £0.52bn £0.53bn £0.55bn £0.56bn £0.57bn £0.58bn
Two Child Limit Payment (Scotland, counterfactual) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Healthy Start vouchers £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn
Maternity Allowance £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Statutory Maternity Pay £3.32bn £3.41bn £3.49bn £3.57bn £3.66bn £3.75bn £3.84bn
Statutory Paternity Pay £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Statutory Sick Pay £1.13bn £1.16bn £1.19bn £1.22bn £1.25bn £1.28bn £1.31bn
Sure Start Maternity Grant £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn
Bereavement Support Payment £0.67bn £0.69bn £0.70bn £0.72bn £0.74bn £0.76bn £0.78bn
Tax-Free Childcare £0.55bn £0.56bn £0.57bn £0.58bn £0.60bn £0.61bn £0.59bn
Extended childcare entitlement £2.66bn £3.14bn £3.23bn £3.30bn £3.38bn £3.47bn £3.55bn
Universal childcare entitlement £3.32bn £3.59bn £3.69bn £3.78bn £3.88bn £3.99bn £4.08bn
Targeted childcare entitlement £0.57bn £0.60bn £0.62bn £0.63bn £0.65bn £0.66bn £0.67bn
Care to Learn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Childcare Grant £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Parents' Learning Allowance £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn
Adult Dependants' Grant £0.06bn £0.06bn £0.04bn £0.04bn £0.04bn £0.04bn £0.04bn
Travel Grant £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed
16 to 19 Bursary Fund £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
NHS spending £204.68bn £205.46bn £206.22bn £207.04bn £207.96bn £208.89bn £209.79bn
State education spending £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn
Transport subsidy spending £25.15bn £25.25bn £25.34bn £25.44bn £25.55bn £25.67bn £25.78bn
Cost-of-living support payment £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Energy Bills Rebate £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Energy Price Guarantee subsidy £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Basic income £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Disability basic income £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Other public spending budget change £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Caseloads: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
State Pension 11,308k 11,208k 10,906k 10,812k 10,860k 10,908k 10,955k
Pension Credit 1,491k 1,489k 1,478k 1,459k 1,459k 1,457k 1,453k
Winter Fuel Payment 7,092k 7,011k 6,601k 6,517k 6,493k 6,381k 6,254k
Pension Age Winter Heating Payment (Scotland) 806k 807k 807k 805k 809k 812k 816k
Universal Credit 6,371k 6,379k 6,409k 6,420k 6,395k 6,387k 6,371k
Housing Benefit 1,254k 1,252k 1,254k 1,240k 1,245k 1,247k 1,249k
Council Tax Reduction 3,186k 3,211k 3,224k 3,245k 3,264k 3,280k 3,293k
Employment and Support Allowance (income-related) 187k 188k 188k 189k 190k 190k 191k
Employment and Support Allowance (contribution-based) 722k 724k 727k 730k 733k 737k 740k
Jobseeker's Allowance (income-based) 0k 0k 0k 0k 0k 0k 0k
Jobseeker's Allowance (contribution-based) 67k 67k 68k 68k 68k 69k 69k
Income Support 25k 0k 0k 0k 0k 0k 0k
Working Tax Credit 0k 0k 0k 0k 0k 0k 0k
Child Tax Credit 0k 0k 0k 0k 0k 0k 0k
Incapacity Benefit 0k 0k 0k 0k 0k 0k 0k
Personal Independence Payment 3,581k 3,595k 3,608k 3,623k 3,639k 3,655k 3,671k
Disability Living Allowance 1,296k 1,301k 1,306k 1,311k 1,317k 1,323k 1,329k
Attendance Allowance 1,701k 1,708k 1,714k 1,721k 1,729k 1,736k 1,744k
Carer's Allowance 1,038k 1,042k 1,046k 1,050k 1,055k 1,059k 1,064k
Carer Support Payment (Scotland) 71k 72k 72k 72k 73k 73k 73k
Carer's Allowance Supplement (Scotland) 0k 72k 72k 72k 73k 73k 73k
Severe Disablement Allowance 4k 4k 4k 4k 4k 4k 4k
Industrial Injuries Disablement Benefit 137k 138k 139k 139k 140k 140k 141k
Armed Forces Compensation Scheme 94k 94k 94k 95k 95k 95k 96k
War Widow's or Widower's Pension 0k 0k 0k 0k 0k 0k 0k
Child Benefit 8,136k 8,165k 8,185k 8,215k 8,249k 8,282k 8,314k
Scottish Child Payment 352k 354k 355k 356k 357k 358k 357k
Two Child Limit Payment (Scotland, counterfactual) 0k 0k 0k 0k 0k 0k 0k
Healthy Start vouchers 200k 201k 202k 203k 204k 204k 205k
Maternity Allowance 0k 0k 0k 0k 0k 0k 0k
Statutory Maternity Pay 334k 335k 336k 338k 339k 341k 342k
Statutory Paternity Pay 0k 0k 0k 0k 0k 0k 0k
Statutory Sick Pay 182k 183k 183k 184k 185k 186k 186k
Sure Start Maternity Grant 26k 26k 26k 27k 27k 27k 27k
Bereavement Support Payment 98k 98k 99k 99k 100k 100k 101k
Tax-Free Childcare 1,017k 1,028k 1,028k 1,033k 1,034k 1,038k 1,023k
Extended childcare entitlement 665k 671k 675k 677k 682k 686k 687k
Universal childcare entitlement 986k 989k 992k 997k 1,002k 1,013k 1,015k
Targeted childcare entitlement 119k 120k 120k 121k 121k 122k 121k
Care to Learn 0k 0k 0k 0k 0k 0k 0k
Childcare Grant 0k 0k 0k 0k 0k 0k 0k
Parents' Learning Allowance 98k 99k 99k 100k 100k 100k 101k
Adult Dependants' Grant 18k 18k 12k 13k 13k 13k 13k
Travel Grant 0k 0k 0k 0k 0k 0k 0k
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed
16 to 19 Bursary Fund 0k 0k 0k 0k 0k 0k 0k
Cost-of-living support payment 0k 0k 0k 0k 0k 0k 0k
Energy Bills Rebate 0k 0k 0k 0k 0k 0k 0k
Energy Price Guarantee subsidy 0k 0k 0k 0k 0k 0k 0k
Basic income 0k 0k 0k 0k 0k 0k 0k
Disability basic income 0k 0k 0k 0k 0k 0k 0k
Government balance, each component counted once: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Government receipts, each component once £899.38bn £939.24bn £976.18bn £1,009.38bn £1,045.66bn £1,082.60bn £1,123.48bn
Government spending £536.24bn † £550.45bn † £556.57bn † £563.61bn † £572.15bn † £581.38bn † £590.55bn †
Government balance, each receipt once £363.15bn † £388.79bn † £419.61bn † £445.77bn † £473.51bn † £501.23bn † £532.93bn †
Benefits in household_benefits but not in gov_spending £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Model totals: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
gov_tax £899.38bn £939.24bn £976.18bn £1,009.38bn £1,045.66bn £1,082.60bn £1,123.48bn
household_tax £493.03bn £519.53bn £545.32bn £567.51bn £589.72bn £614.17bn £640.87bn
pre_budget_change_household_tax £485.21bn £511.41bn £536.97bn £558.47bn £580.44bn £604.62bn £630.98bn
gov_spending £536.24bn † £550.45bn † £556.57bn † £563.61bn † £572.15bn † £581.38bn † £590.55bn †
household_benefits £536.24bn † £550.45bn † £556.57bn † £563.61bn † £572.15bn † £581.38bn † £590.55bn †
gov_balance £363.15bn † £388.79bn † £419.61bn † £445.77bn † £473.51bn † £501.23bn † £532.93bn †
Components the model counts twice: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
corporate_sdlt, counted again inside expected_sdlt n/a n/a n/a n/a n/a n/a n/a
Household income totals: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Household market income £1,657.06bn £1,719.25bn £1,771.68bn £1,821.99bn £1,872.88bn £1,930.99bn £2,001.98bn
Household net income £1,660.99bn † £1,709.41bn † £1,741.05bn † £1,775.15bn † £1,811.23bn † £1,852.86bn † £1,904.61bn †
Household net income (HBAI definition) £1,466.42bn £1,513.06bn £1,545.11bn £1,578.08bn £1,612.09bn £1,651.12bn £1,701.58bn
Population: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
People 69,514k 69,778k 70,036k 70,316k 70,626k 70,944k 71,249k
Benefit units 35,247k 35,381k 35,512k 35,654k 35,811k 35,972k 36,127k
Households 31,167k 31,285k 31,401k 31,526k 31,665k 31,808k 31,944k
Poverty rates: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone 15.9% 15.0% 15.5% 15.6% 15.7% 15.8% 15.8%
Absolute poverty, before housing costs: children 23.7% 20.9% 21.6% 21.4% 21.6% 21.8% 21.7%
Absolute poverty, before housing costs: working-age adults 13.8% 13.4% 14.0% 14.1% 14.2% 14.3% 14.3%
Absolute poverty, before housing costs: pensioners 13.7% 13.2% 13.3% 13.5% 13.6% 13.7% 13.7%
Absolute poverty, after housing costs: everyone 21.1% 20.6% 21.3% 21.5% 21.9% 22.2% 22.3%
Absolute poverty, after housing costs: children 32.1% 30.3% 30.9% 31.1% 31.7% 32.3% 32.5%
Absolute poverty, after housing costs: working-age adults 19.6% 19.4% 20.2% 20.4% 20.8% 21.0% 21.0%
Absolute poverty, after housing costs: pensioners 12.8% 12.6% 12.6% 13.1% 13.4% 13.4% 13.4%
Relative poverty, before housing costs: everyone 16.9% 16.4% 16.5% 16.6% 16.6% 16.7% 16.7%
Relative poverty, before housing costs: children 25.6% 23.5% 23.2% 23.2% 23.2% 23.2% 23.2%
Relative poverty, before housing costs: working-age adults 14.4% 14.4% 14.6% 14.8% 14.9% 15.0% 15.0%
Relative poverty, before housing costs: pensioners 15.0% 14.9% 14.4% 14.7% 14.3% 14.3% 14.6%
Relative poverty, after housing costs: everyone 21.7% 21.3% 21.4% 21.5% 21.6% 21.9% 22.0%
Relative poverty, after housing costs: children 33.0% 31.6% 31.0% 31.1% 31.3% 31.6% 32.0%
Relative poverty, after housing costs: working-age adults 20.0% 20.0% 20.3% 20.4% 20.6% 20.8% 20.9%
Relative poverty, after housing costs: pensioners 13.7% 13.1% 12.8% 13.0% 12.7% 12.9% 13.2%
People in poverty: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone 11,056k 10,435k 10,856k 10,960k 11,091k 11,220k 11,234k
Absolute poverty, before housing costs: children 3,560k 3,141k 3,261k 3,253k 3,298k 3,334k 3,335k
Absolute poverty, before housing costs: working-age adults 5,862k 5,735k 6,068k 6,164k 6,235k 6,314k 6,321k
Absolute poverty, before housing costs: pensioners 1,634k 1,559k 1,527k 1,543k 1,558k 1,572k 1,579k
Absolute poverty, after housing costs: everyone 14,663k 14,366k 14,907k 15,144k 15,491k 15,755k 15,874k
Absolute poverty, after housing costs: children 4,809k 4,556k 4,676k 4,719k 4,835k 4,939k 4,994k
Absolute poverty, after housing costs: working-age adults 8,333k 8,326k 8,775k 8,931k 9,122k 9,275k 9,329k
Absolute poverty, after housing costs: pensioners 1,521k 1,484k 1,456k 1,493k 1,533k 1,541k 1,551k
Relative poverty, before housing costs: everyone 11,780k 11,464k 11,523k 11,660k 11,708k 11,832k 11,879k
Relative poverty, before housing costs: children 3,840k 3,538k 3,506k 3,524k 3,542k 3,554k 3,565k
Relative poverty, before housing costs: working-age adults 6,154k 6,160k 6,356k 6,464k 6,530k 6,636k 6,628k
Relative poverty, before housing costs: pensioners 1,786k 1,766k 1,661k 1,673k 1,636k 1,643k 1,686k
Relative poverty, after housing costs: everyone 15,110k 14,866k 14,956k 15,109k 15,280k 15,513k 15,696k
Relative poverty, after housing costs: children 4,948k 4,756k 4,684k 4,715k 4,771k 4,840k 4,916k
Relative poverty, after housing costs: working-age adults 8,531k 8,560k 8,793k 8,917k 9,054k 9,187k 9,257k
Relative poverty, after housing costs: pensioners 1,631k 1,551k 1,479k 1,477k 1,455k 1,486k 1,523k
Inequality: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Gini coefficient, equivalised HBAI income before housing costs 0.3074 0.3052 0.3066 0.3072 0.3078 0.3084 0.3095
Mean household net income in each side's own deciles: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Decile 1: mean household_net_income per household £17,743 † £18,040 † £17,994 † £18,051 † £18,387 † £18,565 † £18,739 †
Decile 2: mean household_net_income per household £28,384 † £29,163 † £28,766 † £29,044 † £29,390 † £29,793 † £30,375 †
Decile 3: mean household_net_income per household £34,688 † £35,865 † £36,503 † £37,077 † £37,277 † £37,870 † £38,554 †
Decile 4: mean household_net_income per household £39,422 † £40,891 † £41,832 † £42,765 † £43,508 † £44,094 † £44,995 †
Decile 5: mean household_net_income per household £44,948 † £46,241 † £47,162 † £47,522 † £48,109 † £49,265 † £50,117 †
Decile 6: mean household_net_income per household £48,000 † £49,405 † £50,362 † £51,240 † £52,232 † £53,016 † £54,270 †
Decile 7: mean household_net_income per household £56,408 † £57,659 † £58,560 † £59,516 † £60,242 † £61,715 † £62,985 †
Decile 8: mean household_net_income per household £69,388 † £70,472 † £71,788 † £72,930 † £74,471 † £75,916 † £77,696 †
Decile 9: mean household_net_income per household £79,804 † £82,152 † £83,354 † £84,649 † £86,218 † £87,732 † £90,808 †
Decile 10: mean household_net_income per household £117,848 † £120,717 † £122,647 † £124,774 † £127,023 † £129,293 † £132,104 †
Standard reform costings (change in gov_balance): head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp £6.21bn £6.50bn £6.70bn £6.90bn £7.11bn £7.34bn £7.62bn
Raise higher rate by 1pp £3.54bn £3.82bn £4.05bn £4.27bn £4.49bn £4.76bn £4.96bn
Raise personal allowance by ~800GBP/year £-3.83bn £-3.96bn £-4.03bn £-4.10bn £-4.19bn £-4.29bn £-2.02bn
Raise child benefit by 25GBP/week per additional child £-2.00bn £-1.76bn £-1.64bn £-1.54bn £-1.44bn £-1.34bn £-1.24bn
Reduce Universal Credit taper rate to 20% £-20.54bn £-21.10bn £-21.45bn £-21.88bn £-21.95bn £-22.32bn £-22.79bn
Raise Class 1 main employee NICs rate to 10% £11.06bn £11.51bn £11.83bn £12.14bn £12.47bn £12.81bn £13.29bn
Raise VAT standard rate by 2pp £25.01bn £25.68bn £26.29bn £26.92bn £27.58bn £28.26bn £28.95bn
Raise additional rate by 3pp £2.83bn £3.07bn £3.27bn £3.47bn £3.67bn £3.91bn £4.23bn
Raise the Universal Credit standard allowance by 10% £-3.04bn £-3.17bn £-3.24bn £-3.32bn £-3.37bn £-3.42bn £-3.47bn
Raise the State Pension by 10% £-7.81bn £-8.07bn £-7.99bn £-8.11bn £-8.36bn £-8.66bn £-9.02bn
Standard reforms: change in each reform's target: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp: change in income_tax £6.36bn £6.65bn £6.86bn £7.07bn £7.28bn £7.52bn £7.80bn
Raise higher rate by 1pp: change in income_tax £3.55bn £3.83bn £4.06bn £4.28bn £4.50bn £4.77bn £4.97bn
Raise personal allowance by ~800GBP/year: change in income_tax £-3.96bn £-4.10bn £-4.19bn £-4.26bn £-4.36bn £-4.47bn £-1.77bn
Raise child benefit by 25GBP/week per additional child: change in child_benefit £2.34bn £2.15bn £2.03bn £1.92bn £1.82bn £1.71bn £1.59bn
Reduce Universal Credit taper rate to 20%: change in universal_credit £20.53bn £21.09bn £21.44bn £21.87bn £21.95bn £22.32bn £22.78bn
Raise Class 1 main employee NICs rate to 10%: change in national_insurance £11.33bn £11.79bn £12.13bn £12.44bn £12.78bn £13.13bn £13.62bn
Raise VAT standard rate by 2pp: change in vat £25.01bn £25.68bn £26.29bn £26.92bn £27.58bn £28.26bn £28.95bn
Raise additional rate by 3pp: change in income_tax £2.83bn £3.07bn £3.27bn £3.47bn £3.67bn £3.91bn £4.23bn
Raise the Universal Credit standard allowance by 10%: change in universal_credit £3.04bn £3.17bn £3.25bn £3.32bn £3.37bn £3.43bn £3.47bn
Raise the State Pension by 10%: change in state_pension £10.72bn £11.23bn £11.37bn £11.62bn £12.08bn £12.54bn £13.07bn

@MaxGhenis
MaxGhenis marked this pull request as ready for review October 22, 2026 06:10
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Hand-off from the UK hub's build job (stack-2235), at 8c1b54dd9.

What changed. I merged main at 6ac87fb04 (2f4021a29) and pushed once, as a fast-forward of 3ada49f23. One textual conflict and two semantic ones, all described in the body under "Main merged in":

  • fiscal_partition.yaml (both sides added it): this PR's tax side whole, main's spending side whole, and main's correction to the salary sacrifice note.
  • test_weighted_incidence.py (from main) abolished SDLT to isolate the purchase charge. Abolition now removes corporate SDLT too, so I dropped that line; the test still checks the £150 × shareholding allocation.
  • test_declared_reads_occur failed on the merged tree, because main's Impute UC deductions in constituency and local-authority runs #1905 gate skips the attendance imputation in situations. The trace now covers a situation and a data-built run of the same households, so the partition's private school reads are checked where they happen.

Main has since gained #2473 and #2474, which touch no file in this PR. They merge cleanly, and CI tests the merge ref.

Tests.

  • CI at 8c1b54dd9: all 16 checks pass (five Python shards, YAML, aggregate impact, fix evidence, lint). gh pr checks exits 0, and the PR is MERGEABLE and CLEAN. I marked it ready for review.
  • Local, without microsimulation tests (the host was saturated):
    • partition, SDLT property and aggregate impact tests: 280 passed and 1 failed, the trace case above; after the fix, 5 of 5 traced cases pass;
    • test_weighted_incidence.py: 19 passed;
    • the SDLT, council tax and tax-total YAML: 86 passed;
    • a stopped run of main's related property tests: 66 passed, none failed;
    • ruff format --check . is clean, and the fix-evidence checker passes.

Impact. The aggregate impact report passes: base main 9d81a5dfa8 against the merge 6d80d1afd1 on uk-data 1.58.1. gov_tax, household_tax, pre_budget_change_household_tax and gov_balance each fall by £3.13bn a year from 2025-26 to 2031-32, and household net income rises by the same. Each of 84 components passed the counted-once check, the base's declared corporate_sdlt double count is gone, and poverty and inequality don't change. The only check failing on both sides is negative VAT (uk-data#565).

Open.

Not merged by this job.

@MaxGhenis
MaxGhenis added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 0def167 Oct 22, 2026
18 of 19 checks passed
@MaxGhenis
MaxGhenis deleted the fix/corporate-sdlt-double-count branch October 22, 2026 13:16
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Merged by the UK hub (session local_8e19f9d5, Opus 5.5) on its merge gates. The hub owns this PR (LVT project hand-over, 13 Oct). Max lifted the LVT freeze for the Budget on 21 Oct. One merge-queue enqueue, pinned to head 8c1b54dd9.

🤖 Generated with Claude Code

MaxGhenis added a commit that referenced this pull request Oct 23, 2026
#2235 merged main and fixed its partition tests before landing. One
conflict, in the vat head's data note in fiscal_partition.yaml: keep
#2235's wording, which reports only the household counts. This PR's own
data notes on business_rates and sdlt_household are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 23, 2026
#2235 landed on main as 0def167, so this PR now targets main. No
conflicts. Main's changes since #2235's head touch no statistic, receipts
growth series or index this PR reads: the yoy_growth edits are to
consumer_price_index_ahc, mortgage_interest and social_rent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 23, 2026
test_weighted_incidence.py (new on main via #2235's merge) sets the four
business rates series so corporate incidence is £150 times shareholding.
This PR adds ENGLAND_CENTRAL_LIST and WALES_CENTRAL_LIST to the sum, so
they kept their real values (about £2.21bn in 2025) and five cases failed
with 2.2e7 against 1.5. Set both to zero with the others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 23, 2026
#2322 now carries #2235's final head and main (a45baf5). One conflict,
in the economic assumptions README's EFO refresh checklist: main added
step 6 (move PROJECTION_END_YEAR on) where this PR added step 6 (refresh
the receipts series). Keep both: receipts refresh as step 6, projection
horizon as step 7, then the importer example. The importer, its tests and
the yoy_growth.yaml comments merge without conflict; main has not touched
the importer or its tests since this PR branched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Corporate SDLT is counted twice in household and government tax totals

2 participants