Skip to content

Add overseas and other real estate as property components, and count UK land once in household land - #2688

Draft
MaxGhenis wants to merge 27 commits into
mainfrom
property-wealth-overseas-other
Draft

MaxGhenis wants to merge 27 commits into
mainfrom
property-wealth-overseas-other

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2577

Adds the WAS household stock inputs overseas_property_value and other_property_value, with GDP-per-capita uprating. Worldwide gross property_wealth sums the six saved components and passes them into total wealth once. UK household land directly sums residential, non-residential and unclassified other property before applying regional intensity, then adds directly owned UK land at full value. Identified overseas property contributes no UK household land; direct summation avoids float32 cancellation below the directly owned land value.

Both new categories receive the existing real-property sale-expense treatment across six means tests. UC routes them through uc_overseas_property_capital and uc_other_property_capital into the separate property pool. A financial-only benunit_reported_capital report retains counted property, including when the report is zero. A complete uc_reported_capital override still replaces ordinary capital before the existing company substitution. Property shares remain allocated across all claimant/partner adults; complete-override units consume their shares. Sale expenses and identified secured debt apply once. No new secured-debt inputs are inferred for the two new categories.

Pension Credit now combines reported financial capital with separately valued land and property in its final assessment, without an intermediate float32 total. Its complete programme override defaults to -1, retaining explicit overrides' precedence and year-specific expiry. Housing Benefit's savings-credit-only route inherits this correction. Ordinary HB, IS, income-based JSA and income-related ESA do not replace their capital source pools with financial-only reports and need no routing changes. share_like_capital, HOLDINGS_SOURCE, and #1969's sale-expense, secured-debt, zero-floor and penny-rounding behavior are preserved.

Merged origin/main at b9f55f84b5cf without conflicts, including #2690's six Python CI shards. Updated the company-owner conservation test's oracle to reproduce stored-input precision, holdings-budget scaling and penny rounding at the same per-person, pool and per-unit steps as the formulas, under UC regulation 6(1), without widening its tolerance. #1969 will require this same oracle correction when it merges current main.

This draft remains stacked on #1969, whose history is preserved and which must merge first. Companion data #543 follows data #501; the model and component data release must land together with a compatible dependency pin. A saved property_wealth input still overrides that aggregate's formula; household land reads domestic components directly. No licensed-source reconciliation, production rebuild, recalibration or population/LVT estimate is claimed.

The component contract and consumer audit documents stock/transaction routing, geographic assumptions, uprating, allocation and data-release limits. Main residence/private pension exclusions and UC's existing omission of direct land are retained. Unclassified real estate continues to use the regional UK-land approximation until its geography can be classified.

Validation

  • Before/after UC, PC/HB, land and C2 witnesses: all assertions passed.
  • YAML files, run individually with policyengine-core test <file> -c policyengine_uk: uc_assessable_capital.yaml 23 passed; pension_credit_reported_capital.yaml 31 passed; benunit_reported_capital.yaml 6 passed; household_land_value.yaml 15 passed.
  • Python files, each run in its own python -m pytest <file> -p no:randomly -q -x command: test_property_wealth_components.py 41 passed; test_capital_valuation_properties.py 8 passed; test_uc_property_capital_mock.py 26 passed; test_projection_horizon.py 14 passed; test_benunit_reported_capital_properties.py 7 passed (the last uses -n 2).
  • test_uc_company_owner_properties.py: 7 passed with -n 2 after the initial rounding correction. After the subsequent conservation-only scale correction, its final focused node passed, including both regression pins and generated cases; the other six nodes and global helpers were unchanged. The original oracle and the simplified scale oracle were each observed failing first.
  • Mutation: reinstating the three old UC routing lists produced the intended failure, assert 0.0 >= 18000.0. All three files were restored byte for byte with matching SHA-256 digests; both restored property parameterizations then passed (2 passed, 39 deselected).
  • make format: passed before every fix commit.

CI at 798491cb7: all six Python shards, lint, documentation builds, Python smoke builds, aggregate impact, changelog and fix-evidence checks passed. Both YAML attempts printed 5,217 passed, but the Core CLI remained alive until the 30-minute limit cancelled the job. Test / Result failed with YAML: cancelled; Python: success. This shutdown issue remains the CI blocker.

Each test command passes one touched file, with OMP_NUM_THREADS=2 and at most two pytest workers. The existing Python 3.13 environment is reused with the lockfile's Core 3.33.12 installed as a workspace-local overlay. No caller environment was modified and no virtual environment was created. Whole-suite/folder runs and licensed-data work are omitted under the shared-host constraint; the heavy-run lock is not bypassed. The documentation build is omitted because this updates a durable engineering page without changing generated documentation.

Reproducer: policyengine_uk/tests/test_property_wealth_components.py::test_financial_reports_preserve_separately_valued_property; policyengine_uk/tests/test_property_wealth_components.py::test_household_land_value_is_at_least_direct_uk_land; policyengine_uk/tests/test_uc_company_owner_properties.py::test_household_capital_is_allocated_and_conserved_across_benefit_units

axiom: needed

🤖 Generated with Claude Code

MaxGhenis and others added 22 commits September 30, 2026 17:28
UC Regs 2013 reg. 49(1) and its legacy equivalents (HB Regs 2006 reg. 47,
HB (SPC) Regs 2006 reg. 45, IS Regs 1987 reg. 49, JSA Regs 1996 reg. 111,
ESA Regs 2008 reg. 113, SPC Regs 2002 reg. 19) calculate capital at market
or surrender value less 10% where a sale would incur expenses and less any
encumbrance secured on it. The model summed every capital source at full
value.

Each programme gets a capital.sale_expenses node (rate 0.1 and the sources
whose sale incurs expenses: land, property and corporate_wealth, not cash
savings). A shared helper applies the 10% before the encumbrance and never
values an encumbered asset below nil. New household inputs carry debt
secured on other residential property, non-residential property and land;
the Enhanced FRS has none, so they default to zero.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Each programme's sale-expense parameters now cite its GB and NI
  regulations, the guidance paragraph that orders the 10% before the
  encumbrance, and per-asset guidance with exact PDF page anchors (DMG ch 52
  for ESA, HBGM Annex F for HB savings, H1656/H1665/H1673-H1675 for UC).
- The source-list descriptions and changelog say plainly that
  corporate_wealth also holds unit trusts, ISAs, employee share options and,
  in datasets built before the pension split, non-DB pension wealth.
- The helper and secured-debt docs say debts net within a source category.
- The property-test oracle fixes the sale-expense assets and the 10% itself
  instead of reading the parameters, checks pension-age HB, and runs on
  larger populations. New hand-computed cases cover HB second homes and
  premises, per-source flooring between two encumbered sources, pension-age
  HB, and a monthly secured debt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HBGM W1.430 states only the general 10% rule; the rule that real property
always has costs of sale comes from R(IS) 21/93, as DMG 29622 applies it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolve the capital variables onto main's claimant/partner allocation and
person-level sources, valuing household sources through valued_capital.
Update the let-property tests #1950 added: £10,000 of property is now £9,000
of capital under reg. 49(1), so 12 tariff steps, not 16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two tests main added after this branch's earlier base assumed full-value
capital:

- The CTR savings-credit-only case holds savings 10,000 and a 7,000 second
  property: capital is 10,000 + 90% of 7,000 = 16,300 (SPC Regs 2002 reg.
  19(a)), still over the 16,000 limit, so CTR stays nil. Deemed income is 13
  steps x 52 = 676, Pension Credit income 13,314 + 676 = 13,990, and savings
  credit 60% of (12,376 - 208.07 x 52) less 40% of (13,990 - 12,376) =
  288.22.
- The reported-capital property test's proxy oracle now values land,
  property and shares at 90% and savings at face value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep main's recorded benefit-unit capital (benunit_reported_capital), which
replaces the valued household sources as recorded, and register the
secured-debt inputs beside main's uprating entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
£20,000 of shares is £18,000 of Pension Credit capital (SPC Regs 2002
reg. 19(a)), still over the CTR limit: deemed income 16 x 52 = 832,
Pension Credit income 14,146, savings credit 933.816 - 0.4 x 1,770 =
225.82.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's Housing Benefit passport (#1927 and the Universal Credit limb) gives a
family on a passporting benefit nil HB capital, so the property's
independent reg 47 valuation applies only to non-passported families.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of 54ed063: half the generated units now decline Universal Credit,
so the Housing Benefit passport cannot remove every working-age unit from the
reg 47 differential, and a passported unit's HB capital is asserted to be nil
rather than skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Delta review of b541677 (F1): coverage of the HB passport-nil assertion and
the working-age reg 47 differential depended on Hypothesis draws. The checks
move into check_valuation(), which counts the branches it ran, and a fixed
test asserts both run: a UC claimant with £5,000 of savings (passported, nil
HB capital) and a non-claimant with a mortgaged second home (valued under
reg 47).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Savings 12,000 plus a 5,000 property is 12,000 + 4,500 = 16,500 of Pension
Credit capital (SPC Regs 2002 reg. 19(a)), still over the 16,000 CTR limit.
Deemed income is 13 a week, so the savings credit is 0.6 x 29.93 - 0.4 x 15
= 11.958 a week (621.82).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main now values Universal Credit property on its own path (#2439:
property_sources, secured debt, a 10% property_sale_cost_rate) and carries
regulation 77 company substitution (#1965). Reconcile:

- One UC rate: property_sale_cost_rate becomes capital.sale_expenses.rate,
  used by the property path and the financial pool; UC sale_expenses.sources
  lists the financial source with costs of sale, corporate_wealth.
- The financial pool is valued with valued_capital, so shares count at 90%.
- As the second of #1965 and #1969 to land, value reg. 77 holdings where they
  leave capital: at 90% from the pool (household_uc_pool_company_holdings),
  in the override floor (household_uc_reported_financial_capital) and from a
  complete override, which is a countable figure; in full from a recorded
  financial total, which is used unvalued. A shared counted_share helper.
- Keep main's secured-debt inputs, documenting the legacy equivalents, and
  add owned_land_secured_debt in the same shape.
- Tests main added that assumed full-value shares, rewritten from the law:
  the reg. 77 company cases, the property-capital and mock suites, the
  company-override conservation identities and the savings-credit-only cases.

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

From the GPT-6.1 Sol review of a7d8988:

- A recorded benunit_reported_capital total holds its owner's reg. 77
  holding at full value, while the pool counts that holding at 90%. The
  report now consumes its known holding part at the counted 90%
  (household_uc_reported_financial_capital), so it can no longer eat another
  unit's savings; the owner's own assessment still takes the full holding off
  the report. The company-override conservation oracle consumes the same way,
  and a YAML regression pins the reviewer's case: £16,500 of savings and a
  £10,000 report that is all holding give [0, 16,500].
- valued_capital rounds the 90% value down to the penny in the claimant's
  favour (ADM H1665), in float64 with a guard against binary noise. A YAML
  regression puts £1,000 of savings and £16,666.67 of shares at exactly
  £16,000.00, which passes the limit (WRA 2012 s. 5(1)(a), UC reg. 18(1)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inputs are float32, so 90% of £16,001 came to £14,400.8994 and the
penny floor gave £14,400.89 (the HB £16,001 case failed). less_sale_expenses
takes the value to the penny in float64 before the 10% deduction and
rounds down to the penny (ADM H1665). The UC property path now uses it
too, so every reg. 49(1)(a) valuation rounds the same way.

Adds a Hypothesis property checking 90% of every whole-penny float32
input up to £131,071.99 against integer pence, and a UC YAML case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol review v4b found that rounding the input to the penny first could
round up (the ADM H1665 example gave 930.94, not 930.93), that nothing
was rounded at the last stage, and that UC rounds to the nearest penny.

- capital.round_down per programme: false for UC (UC Regs 2013 reg 6(1);
  NI reg 7(1)) and HB (HB Regs 2006 reg 80; HB (SPC) reg 61(6); NI 78(8),
  59(7)); true for IS (reg 27), JSA (reg 92), ESA (reg 3(a)) and Pension
  Credit (reg 24A), which count a fraction only to the claimant's
  advantage.
- exact_amount removes float32 storage error only where a value is the
  stored form of a whole penny; other values are kept exactly.
- Each valuation, each UC holding and property share, and each
  programme's assessed capital (the last stage) is rounded by that rule.
- A recorded financial total below its owner's holding now consumes the
  holding at its counted value, as an override does, so no part of the
  holding is left for another unit.

Tests: the H1665 example (930.93 / 930.94), whole-penny properties for
both rules, a never-wrong-way bound for any float32 input, UC half-penny,
16,000.00 after a holding, a three-way split, IS shared-capital rounding,
and reports below the holding in the reg 77 conservation grid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol review v5 at b3f6f60:
- exact_amount raised an underflow warning on zero inputs, failing
  test_warning_filters. Errors are now ignored inside np.errstate, and
  twice the gap is compared with the spacing.
- IS, JSA and ESA read household values through benunit.max, which is
  float64, so exact_amount used float64 spacing and never removed float32
  storage error: 16,000.01 of savings floored to 16,000.00, at the limit.
  A value equal to its float32 is now judged at float32 spacing.
- From 131,072 float32 cannot hold every penny, so no penny is identified
  and the stored value is kept; rounding down then never goes against
  the claimant.
- The Lifetime ISA's 75% and UC company capital are worked in float64
  from the stored amounts; company capital is rounded under reg. 6(1).
- test_uc_capital_allocation expected exact conservation; each share is
  now its own nearest-penny amount (1.00 three ways is 0.33 each).
- Docstrings: the guard's intended tolerance; no report leaves a holding
  in the pool.

Tests: a model-level property that every programme counts whole-penny
savings, shares and Lifetime ISA balances to the penny; widened-input
and above-131,072 helper checks; YAML for 16,000.01 of savings under IS,
JSA and ESA and a 1,000.04 Lifetime ISA.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge the capital sale-expense prerequisite without rewriting its history, preserve share-component routing, and include worldwide property while counting UK land once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep UK wrapper integration coverage for dataset loading, uprating, monthly stocks, purchases and LVT while avoiding repeated setup for formula-only draws.

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

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Aggregate impact on certified data: pass

Base b9f55f84b5 against head f075271ca7, 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: 196 (thresholds in report_spec.yaml; a flag does not fail the job).

Workflow run and full report

Notes

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

Moves flagged for review

Measure Year Base Head Change
Universal Credit 2030-31 £86.87bn £88.35bn +£1.48bn
Universal Credit 2029-30 £85.58bn £86.90bn +£1.32bn
Universal Credit 2031-32 £87.97bn £89.04bn +£1.07bn
Universal Credit 2028-29 £84.23bn £85.19bn +£957.2m
Decile 2: mean household_net_income per household 2029-30 £29,096 £29,371 +£275
Decile 6: mean household_net_income per household 2030-31 £53,174 £53,631 +£457
Decile 8: mean household_net_income per household 2031-32 £77,427 £76,878 -£549
Decile 7: mean household_net_income per household 2031-32 £61,765 £62,200 +£434
Decile 5: mean household_net_income per household 2031-32 £49,710 £50,019 +£309
Decile 7: mean household_net_income per household 2026-27 £57,224 £56,883 -£341
Decile 8: mean household_net_income per household 2026-27 £70,533 £70,927 +£394
Universal Credit 2027-28 £82.93bn £83.48bn +£555.0m
Decile 7: mean household_net_income per household 2030-31 £60,061 £59,743 -£318
Decile 6: mean household_net_income per household 2026-27 £49,525 £49,783 +£257
Decile 2: mean household_net_income per household 2028-29 £28,906 £29,055 +£149
Decile 3: mean household_net_income per household 2026-27 £35,463 £35,644 +£181
Decile 5: mean household_net_income per household 2029-30 £47,327 £47,565 +£238
Decile 3: mean household_net_income per household 2029-30 £36,851 £37,028 +£177
Decile 8: mean household_net_income per household 2030-31 £75,540 £75,184 -£356
Decile 9: mean household_net_income per household 2026-27 £81,421 £81,039 -£381
Relative poverty, after housing costs: children 2029-30 31.0% 30.5% -0.46pp
Decile 3: mean household_net_income per household 2030-31 £37,338 £37,502 +£164
Decile 4: mean household_net_income per household 2030-31 £43,906 £44,096 +£190
Absolute poverty, before housing costs: children 2029-30 21.5% 21.1% -0.40pp
Decile 6: mean household_net_income per household 2029-30 £52,203 £52,408 +£205
Decile 9: mean household_net_income per household 2027-28 £82,828 £82,504 -£323
Decile 8: mean household_net_income per household 2028-29 £73,075 £72,793 -£282
Absolute poverty, after housing costs: children 2027-28 31.1% 30.7% -0.38pp
Relative poverty, after housing costs: children 2027-28 30.8% 30.4% -0.38pp
Decile 8: mean household_net_income per household 2029-30 £74,092 £73,814 -£278
Relative poverty, before housing costs: children 2027-28 23.4% 23.0% -0.37pp
Absolute poverty, before housing costs: children 2029-30 3,261k 3,201k -60.5k
Absolute poverty, after housing costs: children 2029-30 31.4% 31.1% -0.36pp
Decile 8: mean household_net_income per household 2027-28 £71,800 £72,036 +£236
Decile 1: mean household_net_income per household 2029-30 £18,142 £18,083 -£59
Tax-Free Childcare 2027-28 1,024k 1,007k -16.8k
Universal Credit 2026-27 £80.38bn £80.71bn +£326.3m
Tax-Free Childcare 2026-27 1,024k 1,007k -16.7k
Decile 5: mean household_net_income per household 2028-29 £46,288 £46,439 +£151
Absolute poverty, after housing costs: children 2030-31 31.7% 31.4% -0.32pp

156 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
Income tax -£6,015 0 0 0 0 0 0
VAT on private school fees 0 0 -£2.0m -£0.4m -£56.5m -£51,689 0
TV licence fee -£0.2m -£0.2m -£0.2m -£0.3m -£0.2m -£0.3m -£0.1m

Spending by benefit and service

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Pension Credit +£1.0m +£1.1m +£1.1m +£0.9m +£1.0m +£0.8m +£0.7m
Universal Credit +£219.4m +£326.3m +£555.0m +£957.2m +£1.32bn +£1.48bn +£1.07bn
Housing Benefit +£0.9m +£0.9m +£0.4m +£2.7m +£0.6m +£31.1m +£26.8m
Council Tax Reduction +£0.8m +£0.2m +£0.3m +£0.3m +£1.0m -£20,579 -£51,629
Employment and Support Allowance (income-related) +£0.4m +£0.3m +£0.3m +£2.5m +£0.4m +£0.4m +£0.5m
Jobseeker's Allowance (income-based) +£13,636 0 0 0 0 0 0
Income Support +£58,309 0 0 0 0 0 0
Scottish Child Payment 0 0 0 0 +£5.9m +£6.1m +£23.8m
Tax-Free Childcare -£0.7m -£1.3m -£1.3m 0 -£0.9m -£10.8m -£10.4m
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
Pension Credit +971 +1.1k +2.4k +2.8k +968 +1.5k +570
Universal Credit +29.5k +44.9k +50.6k +79.0k +97.2k +93.6k +74.5k
Housing Benefit +94 +86 0 +197 0 +3.0k +3.3k
Council Tax Reduction +514 -76 -45 -46 +552 0 -53
Employment and Support Allowance (income-related) 0 0 0 +189 0 0 0
Scottish Child Payment 0 0 0 0 +3.8k +3.8k +14.5k
Tax-Free Childcare -685 -16.7k -16.8k 0 -3.8k -12.5k -11.2k
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 -£0.2m -£0.2m -£2.2m -£0.7m -£56.6m -£0.3m -£0.1m
Government spending +£221.7m † +£327.6m † +£555.8m † +£963.7m † +£1.33bn † +£1.50bn † +£1.11bn †
Government balance, each receipt once -£221.8m † -£327.8m † -£558.0m † -£964.4m † -£1.39bn † -£1.50bn † -£1.11bn †

Model totals

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
gov_tax -£0.2m -£0.2m -£2.2m -£0.7m -£56.6m -£0.3m -£0.1m
household_tax -£0.2m -£0.2m -£0.2m -£0.3m -£0.2m -£0.3m -£0.1m
pre_budget_change_household_tax -£0.2m -£0.2m -£0.2m -£0.3m -£0.2m -£0.3m -£0.1m
gov_spending +£221.7m † +£327.6m † +£555.8m † +£963.7m † +£1.33bn † +£1.50bn † +£1.11bn †
household_benefits +£221.7m † +£327.6m † +£555.8m † +£963.7m † +£1.33bn † +£1.50bn † +£1.11bn †
gov_balance -£221.8m † -£327.8m † -£558.0m † -£964.4m † -£1.39bn † -£1.50bn † -£1.11bn †

Household income totals

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Household net income +£221.8m † +£327.8m † +£556.0m † +£963.9m † +£1.33bn † +£1.50bn † +£1.11bn †
Household net income (HBAI definition) +£225.3m +£331.7m +£560.3m +£965.8m +£1.34bn +£1.51bn +£1.11bn

Poverty rates

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone -0.01pp -0.03pp -0.08pp -0.10pp -0.15pp -0.08pp -0.07pp
Absolute poverty, before housing costs: children -0.01pp -0.09pp -0.23pp -0.25pp -0.40pp -0.20pp -0.13pp
Absolute poverty, before housing costs: working-age adults -0.01pp -0.02pp -0.06pp -0.07pp -0.10pp -0.05pp -0.05pp
Absolute poverty, before housing costs: pensioners -0.00pp 0 0 0 0 -0.02pp -0.02pp
Absolute poverty, after housing costs: everyone -0.00pp -0.07pp -0.15pp -0.14pp -0.19pp -0.17pp -0.12pp
Absolute poverty, after housing costs: children -0.01pp -0.19pp -0.38pp -0.24pp -0.36pp -0.32pp -0.16pp
Absolute poverty, after housing costs: working-age adults -0.01pp -0.05pp -0.11pp -0.14pp -0.17pp -0.16pp -0.13pp
Absolute poverty, after housing costs: pensioners -0.00pp -0.00pp 0 -0.00pp -0.01pp -0.02pp -0.03pp
Relative poverty, before housing costs: everyone -0.01pp -0.07pp -0.14pp -0.10pp -0.02pp +0.06pp +0.08pp
Relative poverty, before housing costs: children -0.00pp -0.19pp -0.37pp -0.26pp -0.11pp +0.19pp +0.23pp
Relative poverty, before housing costs: working-age adults -0.01pp -0.05pp -0.09pp -0.07pp -0.01pp +0.03pp +0.05pp
Relative poverty, before housing costs: pensioners -0.00pp 0 0 -0.00pp +0.08pp +0.03pp -0.01pp
Relative poverty, after housing costs: everyone -0.01pp -0.11pp -0.14pp -0.08pp -0.22pp -0.17pp -0.07pp
Relative poverty, after housing costs: children -0.01pp -0.30pp -0.38pp -0.07pp -0.46pp -0.29pp -0.06pp
Relative poverty, after housing costs: working-age adults -0.01pp -0.08pp -0.10pp -0.11pp -0.19pp -0.16pp -0.08pp
Relative poverty, after housing costs: pensioners -0.00pp -0.00pp +0.00pp +0.05pp +0.01pp -0.03pp -0.03pp

People in poverty

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone -4.6k -20.6k -58.8k -66.4k -105.6k -55.6k -46.0k
Absolute poverty, before housing costs: children -2.0k -12.8k -34.9k -37.2k -60.5k -29.8k -20.4k
Absolute poverty, before housing costs: working-age adults -2.6k -7.9k -23.9k -29.2k -45.1k -23.8k -23.6k
Absolute poverty, before housing costs: pensioners -8 0 0 0 0 -2.0k -2.0k
Absolute poverty, after housing costs: everyone -3.3k -52.0k -103.1k -99.3k -130.8k -122.7k -83.6k
Absolute poverty, after housing costs: children -985 -29.0k -56.6k -36.7k -54.3k -48.7k -23.9k
Absolute poverty, after housing costs: working-age adults -2.2k -22.9k -46.5k -62.6k -75.2k -71.6k -56.1k
Absolute poverty, after housing costs: pensioners -94 -86 0 -8 -1.3k -2.4k -3.7k
Relative poverty, before housing costs: everyone -4.4k -50.9k -95.8k -69.9k -12.1k +44.9k +57.3k
Relative poverty, before housing costs: children -509 -28.5k -56.1k -39.1k -16.7k +28.8k +34.3k
Relative poverty, before housing costs: working-age adults -3.9k -22.3k -39.7k -30.8k -4.3k +12.4k +24.1k
Relative poverty, before housing costs: pensioners -8 0 0 -19 +8.9k +3.6k -1.1k
Relative poverty, after housing costs: everyone -3.6k -77.4k -100.1k -54.7k -152.8k -116.4k -48.3k
Relative poverty, after housing costs: children -977 -45.0k -56.6k -10.8k -70.0k -44.0k -8.5k
Relative poverty, after housing costs: working-age adults -2.2k -32.3k -44.1k -49.3k -84.4k -69.1k -36.6k
Relative poverty, after housing costs: pensioners -477 -86 +520 +5.4k +1.6k -3.3k -3.1k

Inequality

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Gini coefficient, equivalised HBAI income before housing costs -0.0001 -0.0002 -0.0004 -0.0004 -0.0007 -0.0007 -0.0003

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 +£11 † -£26 † +£14 † +£4.27 † -£59 † +£15 † +£25 †
Decile 2: mean household_net_income per household +£29 † -£85 † +£44 † +£149 † +£275 † +£16 † +£70 †
Decile 3: mean household_net_income per household +£29 † +£181 † +£71 † +£115 † +£177 † +£164 † -£21 †
Decile 4: mean household_net_income per household -£23 † +£28 † +£114 † +£5.91 † +£30 † +£190 † +£64 †
Decile 5: mean household_net_income per household -£8.00 † -£2.51 † -£55 † +£151 † +£238 † +£146 † +£309 †
Decile 6: mean household_net_income per household +£31 † +£257 † -£25 † +£105 † +£205 † +£457 † -£53 †
Decile 7: mean household_net_income per household -£14 † -£341 † +£116 † -£46 † -£109 † -£318 † +£434 †
Decile 8: mean household_net_income per household -£4.57 † +£394 † +£236 † -£282 † -£278 † -£356 † -£549 †
Decile 9: mean household_net_income per household +£1.66 † -£381 † -£323 † +£2.98 † -£0.51 † -£0.52 † -£3.91 †
Decile 10: mean household_net_income per household +£0.31 † +£0.16 † +£0.31 † +£0.31 † +£0.31 † +£0.33 † +£1.34 †

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 -£2.1m -£3.3m -£0.9m -£3.7m -£4.3m -£4.8m -£4.4m
Raise higher rate by 1pp +£91 +£0 -£0.1m +£0.3m +£55.9m -£58.5m -£34,315
Raise personal allowance by ~800GBP/year +£6.3m +£2.2m +£2.7m +£2.5m +£4.6m +£2.5m +£3.7m
Raise child benefit by 25GBP/week per additional child +£0.5m +£7,636 +£2.1m +£0.5m +£0.4m +£1.3m +£58,121
Reduce Universal Credit taper rate to 20% -£177.3m -£450.2m -£518.4m -£648.0m -£585.7m -£472.6m -£459.0m
Raise Class 1 main employee NICs rate to 10% -£3.0m -£4.9m -£5.2m -£10.8m +£40.7m -£10.2m -£11.9m
Raise VAT standard rate by 2pp -£77 -£41 -£0.2m -£44,080 -£5.6m -£5,191 -£0
Raise additional rate by 3pp -£0 -£0 0 -£0 -£91,895 suppressed suppressed
Raise the Universal Credit standard allowance by 10% -£8.7m -£22.8m -£32.9m -£48.7m -£64.7m -£45.8m -£35.7m
Raise the State Pension by 10% -£4.5m +£0.9m +£2.0m +£1.5m +£58.3m +£0.7m +£3.3m

Standard reforms: change in each reform's target

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp: change in income_tax +£6,015 0 0 0 0 0 0
Raise higher rate by 1pp: change in income_tax +£6,015 0 0 0 0 0 0
Reduce Universal Credit taper rate to 20%: change in universal_credit +£174.5m +£448.0m +£519.5m +£629.7m +£641.1m +£472.0m +£459.0m
Raise additional rate by 3pp: change in income_tax 0 0 0 0 0 suppressed suppressed
Raise the Universal Credit standard allowance by 10%: change in universal_credit +£8.1m +£22.6m +£35.0m +£49.2m +£66.3m +£54.9m +£45.7m

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 +£24 (+0.1%) +£17 (+0.1%) +£64 (+0.4%) +£104 (+0.6%) +£166 (+0.9%) +£169 (+0.9%) +£76 (+0.4%)
Decile 2 +£7 (+0.0%) +£49 (+0.2%) +£50 (+0.2%) +£9 (+0.0%) +£41 (+0.1%) +£46 (+0.2%) +£34 (+0.1%)
Decile 3 +£12 (+0.0%) +£9 (+0.0%) +£18 (+0.0%) +£9 (+0.0%) +£10 (+0.0%) +£13 (+0.0%) +£19 (+0.1%)
Decile 4 +£6 (+0.0%) +£7 (+0.0%) +£7 (+0.0%) +£8 (+0.0%) +£14 (+0.0%) +£68 (+0.2%) +£67 (+0.2%)
Decile 5 +£5 (+0.0%) +£4 (+0.0%) +£11 (+0.0%) +£154 (+0.3%) +£153 (+0.3%) +£145 (+0.3%) +£144 (+0.3%)
Decile 6 +£5 (+0.0%) +£5 (+0.0%) +£3 (+0.0%) +£2 (+0.0%) +£13 (+0.0%) +£13 (+0.0%) +£6 (+0.0%)
Decile 7 +£4 (+0.0%) +£4 (+0.0%) +£5 (+0.0%) +£5 (+0.0%) +£2 (+0.0%) +£2 (+0.0%) +£2 (+0.0%)
Decile 8 +£2 (+0.0%) +£5 (+0.0%) +£5 (+0.0%) +£3 (+0.0%) +£3 (+0.0%) +£2 (+0.0%) +£1 (+0.0%)
Decile 9 +£4 (+0.0%) +£4 (+0.0%) +£3 (+0.0%) +£4 (+0.0%) fewer than 10 households change fewer than 10 households change fewer than 10 households change
Decile 10 fewer than 10 households change fewer than 10 households change fewer than 10 households change fewer than 10 households change fewer than 10 households change fewer than 10 households change fewer than 10 households change
all +£7 (+0.0%) +£11 (+0.0%) +£18 (+0.0%) +£31 (+0.1%) +£42 (+0.1%) +£48 (+0.1%) +£35 (+0.1%)
Year People gaining over £1 People losing over £1
2025-26 3.7% 0.0%
2026-27 3.6% 0.0%
2027-28 3.8% 0.0%
2028-29 3.8% 0.0%
2029-30 3.8% 0.0%
2030-31 3.7% 0.0%
2031-32 3.5% 0.0%

No change in any year: population.

Checks failing on both base and head (1)
  • VAT excluding private school fees is never negative (sign:vat): 2025-26: 76 units below zero, a weighted £-53,889,156 in total; 2026-27: 76 units below zero, a weighted £-55,420,387 in total; 2027-28: 76 units below zero, a weighted £-56,618,038 in total
Counted-once check

Each of 91 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.

  • widowed_parents_allowance: pension_credit responds only through other heads in fewer than 10 households (other heads that moved there: carers_allowance; gov_spending; not a failure)
  • widowed_parents_allowance: pension_credit responds only through other heads in fewer than 10 households (other heads that moved there: carers_allowance; household_benefits; not a failure)
Provenance
Side Commit Runtime Environment hash Partition hash Time
base main b9f55f84b5 uk 2.162.12 (files 31952b344b07), core 3.33.12, py 3.13.18 aarch64 cad278205035 4f86ac4248d9 1858.28s
head #2688 merged into main f075271ca7 uk 2.162.12 (files 512532d01732), core 3.33.12, py 3.13.18 aarch64 cad278205035 4f86ac4248d9 1902.04s

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
Final charge on cash interest in non-cash ISAs £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Lifetime ISA withdrawal charge £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Income tax £298.70bn £318.31bn £335.60bn £350.52bn £365.79bn £383.53bn £401.03bn
National Insurance (employee and self-employed) £52.37bn £54.71bn £56.48bn £58.15bn £60.22bn £62.11bn £64.44bn
National Insurance (employer) £150.59bn £156.99bn £161.74bn £166.13bn £173.24bn £178.59bn £185.29bn
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.61bn £13.05bn £13.53bn £14.02bn £14.52bn £15.05bn £15.58bn
Student loan repayments £7.91bn £8.21bn £8.43bn £8.63bn £8.85bn £9.10bn £9.42bn
VAT excluding private school fees £249.37bn £255.28bn £261.81bn £267.87bn £274.12bn £280.56bn £286.81bn
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 £1.95bn £2.00bn £2.05bn £2.10bn £2.16bn £2.21bn £2.31bn
Change in private school VAT from its baseline £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
Betting and gaming duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
TV licence fee £4.26bn £4.41bn £4.42bn £4.44bn £4.45bn £4.47bn £4.48bn
Council tax £49.21bn £51.88bn £54.97bn £58.29bn £61.55bn £64.92bn £68.49bn
High value council tax surcharge £0.00bn £0.00bn £0.00bn £0.48bn £0.49bn £0.50bn £0.51bn
Northern Ireland domestic rates £0.55bn £0.58bn £0.60bn £0.63bn £0.66bn £0.69bn £0.72bn
Business rates £34.68bn £38.04bn £38.88bn £39.76bn £43.07bn £43.13bn £44.57bn
Stamp duty land tax on the household's own purchases £6.90bn £7.39bn £7.81bn £8.21bn £8.62bn £9.02bn £9.42bn
Stamp duty land tax paid by companies £4.81bn £5.98bn £6.73bn £7.46bn £8.21bn £8.87bn £9.16bn
Land transaction tax (Wales) £0.07bn £0.08bn £0.09bn £0.09bn £0.10bn £0.10bn £0.11bn
Land and buildings transaction tax (Scotland) £0.31bn £0.32bn £0.34bn £0.35bn £0.37bn £0.38bn £0.40bn
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
Lifetime ISA bonus £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
State Pension £121.64bn £126.07bn £127.08bn £128.87bn £132.52bn £136.31bn £140.08bn
Pension Credit £6.66bn £7.04bn £7.32bn £7.46bn £7.60bn £7.77bn £7.94bn
Winter Fuel Payment £1.86bn £1.86bn £1.80bn £1.78bn £1.79bn £1.79bn £1.80bn
Pension Age Winter Heating Payment (Scotland) £0.19bn £0.20bn £0.20bn £0.21bn £0.21bn £0.22bn £0.22bn
Universal Credit £75.43bn £80.71bn £83.48bn £85.19bn £86.90bn £88.35bn £89.04bn
Housing Benefit £8.56bn £8.89bn £9.17bn £9.31bn £9.58bn £9.87bn £10.12bn
Council Tax Reduction £2.07bn £2.18bn £2.32bn £2.46bn £2.60bn £2.74bn £2.89bn
Employment and Support Allowance (income-related) £0.79bn £0.81bn £0.83bn £0.85bn £0.87bn £0.89bn £0.91bn
Employment and Support Allowance (contribution-based) £5.20bn £5.34bn £5.46bn £5.59bn £5.72bn £5.85bn £5.99bn
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.32bn £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 £26.94bn £28.06bn £29.13bn £29.83bn £30.54bn £31.26bn £31.96bn
Disability Living Allowance £7.49bn £7.80bn £8.10bn £8.29bn £8.49bn £8.69bn £8.88bn
Attendance Allowance £8.68bn £9.04bn £9.38bn £9.61bn £9.83bn £10.07bn £10.29bn
Carer's Allowance £4.48bn £4.67bn £4.84bn £4.96bn £5.08bn £5.19bn £5.31bn
Carer Support Payment (Scotland) £0.31bn £0.32bn £0.33bn £0.34bn £0.35bn £0.36bn £0.37bn
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.50bn £0.52bn £0.53bn £0.54bn £0.55bn £0.57bn £0.58bn
Armed Forces Compensation Scheme £0.61bn £0.62bn £0.64bn £0.65bn £0.67bn £0.68bn £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.16bn £16.83bn £17.43bn £17.85bn £18.26bn £18.69bn £19.10bn
Scottish Child Payment £0.49bn £0.52bn £0.54bn £0.55bn £0.57bn £0.58bn £0.59bn
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.30bn £3.39bn £3.47bn £3.55bn £3.63bn £3.72bn £3.80bn
Statutory Paternity Pay £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Statutory Sick Pay £1.12bn £1.15bn £1.18bn £1.21bn £1.24bn £1.27bn £1.29bn
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.73bn £0.75bn £0.77bn
Widowed Parent's Allowance £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Tax-Free Childcare £0.55bn £0.56bn £0.57bn £0.58bn £0.59bn £0.60bn £0.57bn
Extended childcare entitlement £2.99bn £3.50bn £3.60bn £3.67bn £3.77bn £3.85bn £3.94bn
Universal childcare entitlement £2.05bn £2.23bn £2.28bn £2.34bn £2.40bn £2.47bn £2.52bn
Targeted childcare entitlement £0.50bn £0.51bn £0.52bn £0.53bn £0.54bn £0.56bn £0.52bn
Childcare Offer for Wales £0.26bn £0.28bn £0.28bn £0.29bn £0.30bn £0.30bn £0.31bn
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 £203.83bn £204.54bn £205.13bn £205.79bn £206.49bn £207.23bn £207.73bn
State education spending £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn
Transport subsidy spending £25.05bn £25.13bn £25.21bn £25.29bn £25.37bn £25.46bn £25.53bn
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
Lifetime ISA bonus 0k 0k 0k 0k 0k 0k 0k
State Pension 11,261k 11,158k 10,849k 10,746k 10,783k 10,822k 10,848k
Pension Credit 1,486k 1,484k 1,483k 1,464k 1,463k 1,466k 1,461k
Winter Fuel Payment 7,842k 7,793k 7,494k 7,407k 7,432k 7,459k 7,477k
Pension Age Winter Heating Payment (Scotland) 803k 803k 803k 800k 803k 806k 808k
Universal Credit 6,364k 6,386k 6,417k 6,426k 6,442k 6,427k 6,372k
Housing Benefit 1,249k 1,247k 1,250k 1,235k 1,238k 1,243k 1,243k
Council Tax Reduction 3,175k 3,198k 3,209k 3,229k 3,245k 3,257k 3,264k
Employment and Support Allowance (income-related) 71k 71k 71k 71k 71k 72k 72k
Employment and Support Allowance (contribution-based) 719k 721k 723k 726k 728k 731k 732k
Jobseeker's Allowance (income-based) 0k 0k 0k 0k 0k 0k 0k
Jobseeker's Allowance (contribution-based) 67k 67k 67k 68k 68k 68k 68k
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,566k 3,579k 3,589k 3,601k 3,613k 3,626k 3,635k
Disability Living Allowance 1,291k 1,295k 1,299k 1,303k 1,308k 1,312k 1,316k
Attendance Allowance 1,694k 1,700k 1,705k 1,711k 1,716k 1,723k 1,727k
Carer's Allowance 1,034k 1,038k 1,041k 1,044k 1,048k 1,051k 1,053k
Carer Support Payment (Scotland) 71k 71k 72k 72k 72k 72k 73k
Carer's Allowance Supplement (Scotland) 0k 71k 72k 72k 72k 72k 73k
Severe Disablement Allowance 4k 4k 4k 4k 4k 4k 4k
Industrial Injuries Disablement Benefit 137k 137k 138k 138k 139k 139k 140k
Armed Forces Compensation Scheme 93k 93k 94k 94k 94k 95k 95k
War Widow's or Widower's Pension 0k 0k 0k 0k 0k 0k 0k
Child Benefit 8,102k 8,128k 8,142k 8,165k 8,191k 8,216k 8,232k
Scottish Child Payment 350k 352k 353k 357k 358k 359k 356k
Two Child Limit Payment (Scotland, counterfactual) 0k 0k 0k 0k 0k 0k 0k
Healthy Start vouchers 199k 200k 201k 201k 202k 203k 203k
Maternity Allowance 0k 0k 0k 0k 0k 0k 0k
Statutory Maternity Pay 332k 334k 335k 336k 337k 338k 339k
Statutory Paternity Pay 0k 0k 0k 0k 0k 0k 0k
Statutory Sick Pay 181k 182k 182k 183k 183k 184k 185k
Sure Start Maternity Grant 26k 26k 26k 26k 26k 27k 27k
Bereavement Support Payment 98k 98k 98k 99k 99k 99k 100k
Widowed Parent's Allowance 0k 0k 0k 0k 0k 0k 0k
Tax-Free Childcare 1,013k 1,007k 1,007k 1,027k 1,023k 1,018k 1,002k
Extended childcare entitlement 796k 801k 806k 809k 815k 819k 820k
Universal childcare entitlement 1,071k 1,074k 1,077k 1,080k 1,086k 1,096k 1,097k
Targeted childcare entitlement 165k 156k 154k 155k 155k 156k 144k
Childcare Offer for Wales 39k 39k 39k 39k 39k 39k 39k
Care to Learn 0k 0k 0k 0k 0k 0k 0k
Childcare Grant 0k 0k 0k 0k 0k 0k 0k
Parents' Learning Allowance 98k 98k 99k 99k 99k 100k 100k
Adult Dependants' Grant 18k 18k 12k 12k 12k 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 £898.82bn £941.86bn £980.11bn £1,013.84bn £1,052.84bn £1,089.01bn £1,129.10bn
Government spending £529.18bn † £544.16bn † £552.23bn † £559.02bn † £567.90bn † £576.81bn † £584.49bn †
Government balance, each receipt once £369.64bn † £397.70bn † £427.87bn † £454.81bn † £484.93bn † £512.20bn † £544.61bn †
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 £898.82bn £941.86bn £980.11bn £1,013.84bn £1,052.84bn £1,089.01bn £1,129.10bn
household_tax £496.91bn £527.60bn £554.51bn £577.74bn £603.32bn £627.65bn £654.69bn
pre_budget_change_household_tax £489.00bn £519.39bn £546.08bn £568.63bn £593.98bn £618.05bn £644.75bn
gov_spending £529.18bn † £544.16bn † £552.23bn † £559.02bn † £567.90bn † £576.81bn † £584.49bn †
household_benefits £529.18bn † £544.16bn † £552.23bn † £559.02bn † £567.90bn † £576.81bn † £584.49bn †
gov_balance £369.64bn † £397.70bn † £427.87bn † £454.81bn † £484.93bn † £512.20bn † £544.61bn †
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,651.49bn £1,713.03bn £1,764.05bn £1,812.97bn £1,862.19bn £1,918.39bn £1,985.28bn
Household net income £1,644.66bn † £1,689.02bn † £1,720.10bn † £1,751.58bn † £1,783.01bn † £1,822.58bn † £1,868.50bn †
Household net income (HBAI definition) £1,457.52bn £1,504.82bn £1,538.14bn £1,570.32bn £1,604.00bn £1,641.99bn £1,688.15bn
Population: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
People 69,224k 69,466k 69,668k 69,891k 70,128k 70,381k 70,550k
Benefit units 35,100k 35,223k 35,325k 35,438k 35,558k 35,686k 35,772k
Households 31,037k 31,145k 31,236k 31,336k 31,442k 31,555k 31,631k
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 16.0% 15.0% 15.3% 15.4% 15.5% 15.6% 15.6%
Absolute poverty, before housing costs: children 23.9% 21.1% 21.1% 21.1% 21.1% 21.6% 21.7%
Absolute poverty, before housing costs: working-age adults 13.8% 13.4% 13.9% 14.0% 14.0% 14.1% 14.1%
Absolute poverty, before housing costs: pensioners 13.7% 13.2% 13.1% 13.4% 13.5% 13.5% 13.5%
Absolute poverty, after housing costs: everyone 21.4% 20.7% 21.1% 21.3% 21.5% 21.7% 22.0%
Absolute poverty, after housing costs: children 33.0% 30.5% 30.7% 30.8% 31.1% 31.4% 32.1%
Absolute poverty, after housing costs: working-age adults 19.8% 19.5% 20.1% 20.3% 20.5% 20.7% 20.9%
Absolute poverty, after housing costs: pensioners 12.7% 12.4% 12.3% 12.5% 12.8% 12.9% 13.0%
Relative poverty, before housing costs: everyone 17.2% 16.3% 16.3% 16.3% 16.2% 16.4% 16.6%
Relative poverty, before housing costs: children 26.2% 23.3% 23.0% 22.9% 22.6% 23.0% 23.3%
Relative poverty, before housing costs: working-age adults 14.6% 14.3% 14.6% 14.6% 14.6% 14.7% 14.9%
Relative poverty, before housing costs: pensioners 15.0% 14.8% 14.1% 14.1% 14.1% 14.0% 14.2%
Relative poverty, after housing costs: everyone 21.6% 20.9% 21.0% 21.1% 21.1% 21.2% 21.7%
Relative poverty, after housing costs: children 33.3% 30.9% 30.4% 30.7% 30.5% 30.7% 31.4%
Relative poverty, after housing costs: working-age adults 19.9% 19.7% 20.0% 20.2% 20.2% 20.3% 20.6%
Relative poverty, after housing costs: pensioners 12.9% 12.5% 12.1% 11.9% 11.9% 11.8% 12.8%
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,045k 10,445k 10,678k 10,793k 10,854k 10,998k 11,035k
Absolute poverty, before housing costs: children 3,578k 3,158k 3,176k 3,183k 3,201k 3,276k 3,297k
Absolute poverty, before housing costs: working-age adults 5,842k 5,738k 5,998k 6,094k 6,124k 6,186k 6,195k
Absolute poverty, before housing costs: pensioners 1,625k 1,550k 1,504k 1,517k 1,530k 1,537k 1,543k
Absolute poverty, after housing costs: everyone 14,843k 14,370k 14,705k 14,895k 15,111k 15,280k 15,554k
Absolute poverty, after housing costs: children 4,936k 4,580k 4,615k 4,649k 4,703k 4,765k 4,888k
Absolute poverty, after housing costs: working-age adults 8,404k 8,337k 8,686k 8,835k 8,949k 9,042k 9,184k
Absolute poverty, after housing costs: pensioners 1,503k 1,454k 1,404k 1,411k 1,459k 1,472k 1,482k
Relative poverty, before housing costs: everyone 11,892k 11,352k 11,372k 11,417k 11,379k 11,513k 11,709k
Relative poverty, before housing costs: children 3,918k 3,495k 3,463k 3,452k 3,418k 3,487k 3,551k
Relative poverty, before housing costs: working-age adults 6,198k 6,113k 6,298k 6,369k 6,364k 6,428k 6,539k
Relative poverty, before housing costs: pensioners 1,776k 1,744k 1,611k 1,597k 1,597k 1,599k 1,620k
Relative poverty, after housing costs: everyone 14,953k 14,520k 14,598k 14,771k 14,799k 14,926k 15,303k
Relative poverty, after housing costs: children 4,976k 4,632k 4,573k 4,624k 4,620k 4,668k 4,786k
Relative poverty, after housing costs: working-age adults 8,441k 8,423k 8,636k 8,797k 8,832k 8,907k 9,056k
Relative poverty, after housing costs: pensioners 1,536k 1,465k 1,388k 1,350k 1,347k 1,351k 1,461k
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.3084 0.3057 0.3061 0.3067 0.3068 0.3074 0.3091
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,792 † £17,880 † £17,846 † £17,909 † £18,083 † £18,354 † £18,507 †
Decile 2: mean household_net_income per household £27,991 † £28,832 † £28,698 † £29,055 † £29,371 † £29,662 † £30,304 †
Decile 3: mean household_net_income per household £34,410 † £35,644 † £36,135 † £36,624 † £37,028 † £37,502 † £38,022 †
Decile 4: mean household_net_income per household £38,762 † £40,741 † £41,987 † £42,419 † £43,174 † £44,096 † £44,231 †
Decile 5: mean household_net_income per household £43,780 † £44,623 † £45,551 † £46,439 † £47,565 † £48,432 † £50,019 †
Decile 6: mean household_net_income per household £48,241 † £49,783 † £50,711 † £52,018 † £52,408 † £53,631 † £54,150 †
Decile 7: mean household_net_income per household £56,205 † £56,883 † £57,881 † £57,964 † £58,931 † £59,743 † £62,200 †
Decile 8: mean household_net_income per household £69,146 † £70,927 † £72,036 † £72,793 † £73,814 † £75,184 † £76,878 †
Decile 9: mean household_net_income per household £79,492 † £81,039 † £82,504 † £84,138 † £85,538 † £87,053 † £89,940 †
Decile 10: mean household_net_income per household £117,582 † £120,296 † £121,934 † £124,163 † £126,045 † £128,342 † £131,112 †
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.47bn £6.76bn £6.67bn £6.86bn £7.06bn £7.34bn £7.54bn
Raise higher rate by 1pp £3.69bn £3.98bn £4.03bn £4.29bn £4.51bn £4.73bn £4.91bn
Raise personal allowance by ~800GBP/year £-3.81bn £-3.94bn £-4.01bn £-4.09bn £-4.17bn £-4.18bn £-2.00bn
Raise child benefit by 25GBP/week per additional child £-1.99bn £-1.75bn £-1.56bn £-1.46bn £-1.35bn £-1.23bn £-1.12bn
Reduce Universal Credit taper rate to 20% £-20.57bn £-21.41bn £-21.90bn £-22.26bn £-22.46bn £-22.64bn £-23.06bn
Raise Class 1 main employee NICs rate to 10% £11.02bn £11.41bn £11.77bn £12.06bn £12.41bn £12.74bn £13.05bn
Raise VAT standard rate by 2pp £24.89bn £25.55bn £26.14bn £26.75bn £27.38bn £28.03bn £28.66bn
Raise additional rate by 3pp £2.96bn £3.21bn £3.26bn £3.46bn £3.65bn suppressed suppressed
Raise the Universal Credit standard allowance by 10% £-3.06bn £-3.20bn £-3.33bn £-3.38bn £-3.44bn £-3.46bn £-3.51bn
Raise the State Pension by 10% £-7.79bn £-8.02bn £-8.01bn £-8.12bn £-8.37bn £-8.54bn £-8.87bn
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.61bn £6.91bn £6.83bn £7.03bn £7.24bn £7.47bn £7.73bn
Raise higher rate by 1pp: change in income_tax £3.69bn £3.99bn £4.04bn £4.25bn £4.47bn £4.74bn £4.93bn
Raise personal allowance by ~800GBP/year: change in income_tax £-3.95bn £-4.08bn £-4.17bn £-4.24bn £-4.34bn £-4.41bn £-1.76bn
Raise child benefit by 25GBP/week per additional child: change in child_benefit £2.33bn £2.14bn £1.95bn £1.84bn £1.73bn £1.62bn £1.50bn
Reduce Universal Credit taper rate to 20%: change in universal_credit £20.57bn £21.39bn £21.89bn £22.25bn £22.51bn £22.69bn £23.07bn
Raise Class 1 main employee NICs rate to 10%: change in national_insurance £11.28bn £11.74bn £12.06bn £12.37bn £12.69bn £13.03bn £13.49bn
Raise VAT standard rate by 2pp: change in vat £24.69bn £25.35bn £25.94bn £26.54bn £27.17bn £27.81bn £28.43bn
Raise additional rate by 3pp: change in income_tax £2.96bn £3.21bn £3.26bn £3.46bn £3.66bn suppressed suppressed
Raise the Universal Credit standard allowance by 10%: change in universal_credit £3.06bn £3.20bn £3.33bn £3.41bn £3.49bn £3.53bn £3.56bn
Raise the State Pension by 10%: change in state_pension £10.68bn £11.18bn £11.31bn £11.55bn £12.00bn £12.44bn £12.94bn

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

@juaristi22 juaristi22 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Program review

Base repository: PolicyEngine/policyengine-uk
PR number: 2688
Reviewed head SHA: 442f033
Merge base SHA: 5b94537
Mode: full
Scope: All77 changed property-accounting/capital-valuation paths and affected six-benefit/land/wealth/override dependencies, including composed1969prerequisite; no separate1969review or privateproducer audit
Source manifest: /private/tmp/policyengine-command-runs/881387a1b745/pr2688-hb1241-review-20261027-review-sources.json
Review status: PARTIAL

Source Documents

Critical

C1 — Preserve non-financial property when a financial-only total is reported (critical) (OPEN)

Location: policyengine_uk/parameters/gov/dwp/universal_credit/means_test/capital/sources.yaml:59–60, the new placement of overseas/other property in the financial replacement pool. Affected calculation: uc_assessable_capital.py:63–65,77–112.

benunit_reported_capital.py:9–25 explicitly defines a financial observation that excludes property, with zero meaning no financial capital. It also identifies the separate uc_reported_capital input for a complete countable-capital override. The new source-list entries put real property in a pool that is replaced when this financial-only report is nonnegative. uc_assessable_capital.py:99–103 then selects the financial report, losing the new property; lines104–112 add only the separate existing domestic-property valuation.

A consistent direct-input case is a single otherwise eligible claimant who owns an ordinary, freely transferable overseas investment property worth£20,000, has no secured debt or relevant statutory disregard, and reports£0financial capital. Set overseas_property_value=20000, benunit_reported_capital=0, no domestic countable property, no company holdings, no complete UC override (default−1), and zero other financial sources. These inputs are consistent: property ownership does not contradict a zero cash/investment report. The new code source trace gives assessable capital£0; without that financial report the same new property is valued at£18,000. A financial-only report does not extinguish an owned property.

UC regulation49(1),(2) requires valuation of owned overseas assets, with the sale-cost deduction and secured encumbrances taken into account. Official ADM H1601–H1608 explains that non-disregarded capital is included, foreign assets are valued, and real property incurs sale costs. Schedule10 provides actual disregards; the case above deliberately satisfies none. The correct countable amount for the supplied debt-free asset is£18,000. This is material to the implemented benefit: is_UC_eligible.py:31–32,67 compares assessable capital with the captured£16,000 limit, so the source-traced£0 permits the capital condition while£18,000fails it. No executed award or population prevalence is claimed.

The PR body explicitly requests placement in the financial pool. That records design intent but does not reconcile this existing financial-only input contract with the legal treatment of non-financial property. Merely documenting the replacement does not make the consistent case a complete-capital override. Keep these new property values separately counted when a financial-only total is present, or introduce and consistently apply a properly distinct total-capital observation contract; retain the existing complete-override semantics. Add a discriminating property-plus-zero-financial-report final-eligibility regression rather than pinning the loss as an expected accounting identity.

Primary evidence: UC regulation49 (source27; NIequivalent source28), UC Schedule10 (source31), and the official ADM H1 full PDF source32, physical43–45. Source27SHA5391166a8aebcf520fb05d2898ff4632d56ecb572be6da4996f0e59361480d60; its exact full original and derivative are bound in the manifest. The primary/source/code scenario joins are recorded in /private/tmp/policyengine-command-runs/881387a1b745/pr2688-hb1241-review-20261027-policy-evidence.json. This is a confirmed source-derived case, NOT RUN. CODE independently corroborated the input and branch semantics and does not duplicate this finding.

Coordinator assessment: CODE independently confirms the financial-only report and complete-override distinction and the replacement branch. Its complementary £100,000/£90,000 trace is the same defect; the £20,000/£18,000 policy witness directly crosses the £16,000 capital limit. Counted once. All amounts here are source-derived, NOT RUN.

C2 — Current-head required Python and result checks are failing (OPEN)

At captured head 442f0330c8c99ff9965dd76eebfc539dd6f93bc1, the complete 20-row status connection reports 18 SUCCESS and 2 FAILURE. Both failed checks are in CheckSuite 109486082318, whose commit.oid is this exact head:

  • Test / Python 1/5, check ID 121824890358, completed 2026-10-26T21:33:19Z: FAILURE.
  • Test / Result, check ID 121862213237, completed 2026-10-26T21:35:00Z: FAILURE.

The repository's current docs/engineering/skills/testing.md requires the Python shards and Test / Result: the result job rejects incomplete, duplicated or unaccepted test outcomes. A successful YAML job, the other four Python shards or Aggregate impact does not clear these failed required checks. Resolve the failing required checks and establish a passing current-head result before treating this PR as merge ready.

Only check metadata was inspected. No logs, artifacts, rerun or test execution was accessed. The cause is unproved; this finding does not attribute the failure to the new component code or to the composed prerequisite, and does not claim a particular failed test, error, count or official attempt history. The raw capture is the evidence, not the author's focused-pass/mutation report.

Should Address

None.

Suggestions

None.

Evidence Gaps

  • POLICY-G1: Full composed six-programme foreign/historical qualification remains incomplete: complete currency/transfer rules, property-specific disregards and historical applicability at all newly parameterised starting dates are not fully traced across all six programmes. UC C1 ordinary sole-owned property case is primary-source supported; this gap does not convert remaining mappings into confirmed defects.
  • Role checks incomplete: pr2688-hb1241-review-20261027-review-policy.md; see recovered report.

Notes

  • C1 is introduced by the new overseas/other entries in the financial replacement pool, despite disclosed author design intent. Existing financial-only input semantics exclude property, while a distinct complete UC override remains available. Do not replace the legal/value issue with a documentation-only fix.
  • Worldwide gross-property identity, component geography, directland count-once algebra, sale-cost/debt ordering and broad rounding rules have supported static results. Unclassified otherproperty geography, within-category debt pooling, missing new debt inputs, private beneficial ownership/disregards and data501/543 release/reconciliation/calibration are disclosed limits, not verified population or adoption certificates.
  • The captured API baseRefOid is cc31bd3; fetched public main is bfe4b5b and actual mergebase is 5b94537. These distinct observations remain recorded; drift cause is unproved. POLICY opening text calls the fetched SHA a captured base; this note distinguishes it from API metadata.
  • Scope marker92.894844s aftercapture misses60s aim, including dispatch/coordinator overhead; no retiming. Exactfirstdispatch timestamp was not separately sealed, so parallel_review_seconds is omitted rather than manufactured. Actual role/start/finish and canonical whole elapsed remain.
  • Generic partial-role aliases added by the assembler refer to the single specific POLICY-G1 check, not another primary evidence gap. Old1969reviewreservation and source/native/private/timing histories remain; no duplicate1969review or takeover.

Validation Summary

Local country/Core imports, collection, model and tests NOT RUN. CODE inventoried77paths, parsed33changedPythonASTs, checked12capital/sale lists and traced finalbenefit consumers. Exacthead20checks=18SUCCESS2FAILURE: Python1/5 and Test/Result; no logs/artifacts/cause/rerun acquired. POLICY acquired32officialpublic originals (30HTML,1WASpublicXLSX,1DWP PDF), no originalreuses; sourcewindow233.686691/300s CLOSED/checker0, relevantPDFtext read/physical45rendered+visuallyinspected, XLSX inertZIP/XML. BothrolesDONE and all ownnativesclosed; exactsnapshotHEAD/tree/clean verified then normallyremoved/no force, hubretained. Author180passes/8mutations/publicbotimpact are not independent execution or population certificates.

Timing

setup seconds: 12.61s; scope seconds: 92.89s; code role seconds: 499.38s; policy role seconds: 455.41s; adjudication seconds: 0.00s; consolidation cleanup seconds: 131.12s; elapsed seconds: 681.06s; source acquisition window seconds: 233.69s

Review Severity

REQUEST_CHANGES. Open findings: 2 critical, 0 should address, 0 suggestions.

MaxGhenis and others added 4 commits October 27, 2026 07:34
Merge main at b9f55f8, including the six Python CI shards. No merge conflicts; preserve the stacked UC sale-expense changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model stored-input precision, holdings scaling and regulation 6(1) penny
rounding at each valuation and benefit-unit allocation step. Pin the CI
counterexample and the holdings-budget precision boundary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Route overseas and other property through UC's separate property pool.
Keep Pension Credit property in the final assessment when a financial-only
report replaces financial proxies, including HB's savings-credit route.
Preserve complete overrides and the existing valuation and company rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Avoid subtracting components from rounded worldwide property wealth.
Pin the float32 cancellation witness and enforce the exact direct-land
lower bound.

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

Copy link
Copy Markdown
Collaborator

Review at 6c5cbc83b.

Verdict: the component accounting and ITTOIA scope are sound, and today's commit closes María's C1 for UC. Before this merges, though, the land change and the new Pension Credit contract both act on the current certified data, and neither is measured or stated. The PR also stays blocked on #1969 and data #501/#543.

Findings

  1. must: the Pension Credit half of the C1 fix doesn't reach the certified data, and it relabels a stored column.

    • pension_credit_reported_capital.py:9-29 now defines the variable as a complete countable-capital override and drops its formula, so property is retained only through benunit_reported_capital.
    • uk-data stores pension_credit_reported_capital directly (frs.py:1872), as FRS TOTCAPB4, "the adults' savings and investments". That is a financial-only total, and it does not store benunit_reported_capital.
    • On enhanced_frs_2024_25.h5 (uk-data 1.58.1), 37,916 of 61,214 benefit units carry a non-negative value. 3,602 of them (3.3m weighted) live in a household with owned_land, other residential or non-residential property. For those units Pension Credit still drops the property, which is the case C1 describes, under SPC Regs 2002 reg. 19.
    • Either the data release moves TOTCAPB4 to benunit_reported_capital in lockstep with this, or the model keeps reading the stored column as financial-only. The docstring shouldn't call the stored survey figure "complete" either way.
  2. should: the household land change acts on current data, and the body says "unmeasured".

    • On main, household_land_value.py computes property_wealth × intensity + owned_land. The saved property_wealth is WAS DVPropertyR8 (uk-data wealth.py:66), which already includes DVLUKValR8_sum, so UK land is counted twice. This PR fixes that (household_land_value.py:63-64), and the fix applies to today's release, not only after Add high-income households #543.
    • On the certified file at data-year values, it moves household land from about £5,112bn to £4,911bn: −£201bn, or 3.9%, across the 758 households with owned_land. This uses the YAML intensities, at 0.57 for UNKNOWN.
    • The aggregate report has no land or LVT measure, so CI can't show this, and the LVT contrib reform and uk-data's MHCLG land targets (targets/sources/mhclg_regional_land.py) both read this variable.
    • Please put the number in the body and changelog. Also check whether the land calibration targets need re-fitting in the same release.
    • A smaller point: property_wealth and its components were imputed independently on this release. The residential components alone sum to more than the saved total (£8,913bn vs £8,006bn weighted), and 12 households have owned_land above property_wealth. For them, household_land_value comes out below direct land. test_household_land_value_is_at_least_direct_uk_land holds only for component-derived totals.
  3. should: the body's effect statement and the UC move. The bot's +£219m to +£1.48bn UC (26 Oct, head 97c986e96) is Value means-tested capital less 10% sale expenses and secured debt (UC reg 49 and legacy equivalents) #1969's change; its own report shows +£226m to +£1.49bn. 2028-29 doesn't match: +£957m here vs +£517m on Value means-tested capital less 10% sale expenses and secured debt (UC reg 49 and legacy equivalents) #1969, on different bases. Once Value means-tested capital less 10% sale expenses and secured debt (UC reg 49 and legacy equivalents) #1969 merges, please re-run against it so the body can state this PR's increment. Pension Credit and HB will move too after 6c5cbc8, which now retains property alongside financial-only reports for both programmes.

  4. nit: the changelog fragment undersells today's commit. 2688-review-capital.fixed.md says "overseas and other property". For Pension Credit, property_sources.yaml (new) also retains owned_land, other residential and non-residential property alongside a financial report, which changes behaviour for existing categories too.

Checked, no finding

  • ITTOIA 2005 Part 3. The PR adds wealth stocks only and touches no income variable. property_income and property_rental_income already cover "UK and overseas property businesses" (s.264 and s.265). The property allowance is one £1,000 (s.783BD) over the relievable receipts of all the individual's relevant property businesses (s.783BB-783BC), so treating them jointly is right.
  • Settle property allowance elections without the charge where it cannot change them #2695. It changes uses_property_allowance and the winter fuel charge ceiling. No file overlaps with this PR's 88, so the two don't interact.
  • Mapping. This is WAS round 8, not the FRS or SPI. The seven-term table in docs/engineering/property-wealth-components.md matches the UKDS DV_Spec_Property_R8 definition of DVPropertyR8. uk-data Add high-income households #543 maps DVLOSValR8_sum to overseas_property_value, where current uk-data names it non_uk_land, and stops saving property_wealth.
  • María's C1 for UC. The new categories now sit in property_sources (uc_overseas_property_capital, uc_other_property_capital) and are out of the financial pool. C2 is now a fresh six-shard run, still pending at the time of writing.

What I ran: a fresh worktree and uv venv (uv sync --frozen --extra dev), one process at a time.

  • At 1193614a6: test_property_wealth_components.py and test_capital_valuation_properties.py, 47 passed; four wealth/UC/capital YAML files, 63 passed.
  • At 6c5cbc83b: those two files plus test_benunit_reported_capital_properties.py, test_uc_property_capital_mock.py and test_pension_credit_reported_capital_properties.py, 86 passed; the wealth directory, uc_assessable_capital.yaml, capital_valuation.yaml and the Pension Credit YAML directory, 419 passed.
  • I read the certified h5 directly, with no microsimulation, for the land and reported-capital figures.

What I didn't do: review #1969's own changes (the six legacy programmes' sale-expense and debt rules), run the full suite, or run the licensed WAS reconciliation.

🤖 Generated with Claude Code

@vahid-ahmadi

Copy link
Copy Markdown
Collaborator

Addendum at 798491cb7. This commit landed while I was posting the review above, so here is finding 2 again for the new formula. Findings 1, 3 and 4 are unchanged.

household_land_value.py now applies intensity to residential_property_value + non_residential_property_value + other_property_value rather than to the saved property_wealth. That does keep land at or above owned_land, which closes the 12-household point. On today's certified file, though, the components and the saved total were imputed independently: £8,913bn of components against £8,006bn saved, weighted. So the move on current data now goes the other way. Household land rises from about £5,113bn to £5,521bn, +£408bn or +8.0%. 12,353 households change: 3,785 rise and 8,568 fall. These are data-year values with the YAML intensities.

That is a larger shift than the double-count fix alone (−£201bn at 6c5cbc83b). It comes from swapping the saved WAS total for its separately imputed components, which is what #543 will do on purpose. I'd still ask for the figure in the body and changelog, and a check of the MHCLG land targets in the same release. The new fragment (2688-review-land.fixed.md) only mentions the lower bound.

🤖 Generated with Claude Code

@juaristi22 juaristi22 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Program review

Base repository: PolicyEngine/policyengine-uk
PR number: 2688
Reviewed head SHA: 798491c
Merge base SHA: b9f55f8
Mode: incremental from1193614a6436560a443714b7873e7ff26a328e6c
Scope: Our originalC1UCfinancial-only/propertyretention fix and C2currentvalidation, with necessarydependencies. OtherreviewerPC/land/privateimpactfindings notadjudicated; no wholeprogrammeaudit or separate1969review.
Source manifest: /private/tmp/policyengine-command-runs/881387a1b745/pr2688-hb1811-review-20261027-review-sources.json
Review status: PARTIAL

Source Documents

Critical

C1 — RESOLVED (RESOLVED)

capital/sources.yaml and capital/sale_expenses/sources.yaml no longer contain overseas or unclassified other property. capital/property_sources.yaml:26–30 adds their separately valued variables exactly once, alongside the existing domestic property valuations. Each new household YEAR/STOCK formula calls less_sale_expenses once on the nonnegative assessment-year property value. The existing uc_property_capital then sums these net sources and allocates the household property pool independently of financial reports.

The decisive original case is now source-traced correctly: ordinary freely transferable overseas investment property£20,000, no secured debt/disregard, no other capital, financial-only benunit_reported_capital=0, no complete override. The property's value is£18,000 and remains in uc_property_capital; uc_assessable_capital.py:98–110 adds it after selecting the£0 financial report. The unchanged£16,000 capital limit therefore fails in is_uc_eligible, rather than the prior incorrect£0 assessment. This is a source-derived static result, not an executed award or dataset impact.

The expectation is independently supported by UC regulation49(1)–(2), cached original27 SHA5391166a8aebcf520fb05d2898ff4632d56ecb572be6da4996f0e59361480d60, plus official ADM H1601–H1608 in cached original32, physical44–45: count non-disregarded capital, use the foreign market value where transferable, deduct sale costs for real property, then secured encumbrances. UC6(1)'s penny rule is preserved. These sources and the explicit no-disregard/no-debt premises support this narrow witness; they do not certify every broad property record.

Coordinator assessment: CODE independently corroborates distinct financial/property source lists, unchanged assessment/override branches, debt/saleonce and finaleligibility. Exactordinary£20k/report0case now source-traces to£18k, not£0; tests/modelNOTRUN. This resolves our originalUCfinding only; no private/currentdata/wholeprogrammecertificate.

C2 — Current-head clearance UNVERIFIED (prior critical history retained) (UNVERIFIED)

The supplied exact798 capture has20 terminal observed raw CheckRuns: 11 SUCCESS,8 IN_PROGRESS,1 CANCELLED, rollupFAILURE. Every CheckSuite.commit.oid equals798. Cancellation Fix evidence122362230628/run40553212940 completed17:44:33Z is preserved together with a later successful Fix evidence122363000203/run40553270847 completed17:45:50Z. Neither row is discarded; no official-attempt, rerun, effective-status or cause determination is made, and cancellation alone is not a newly confirmed defect.

Aggregate122362487333, YAML122362858228 and Python1/6–6/6 remain in progress in the capture; Test / Result is not observed. The current tests and required checks are therefore not cleared. Old442/281 failures,119 pending contexts and author/Vahid reports do not certify798. C2 remains UNVERIFIED for current-head clearance, rather than confirmed failed or RESOLVED.

Coordinator assessment: Both rawcancelledFix122362230628 and laterSUCCESSFix122363000203 remain; no newfindingfromcancellationalone or officialattempt/rerun/cause inference. Actual currentPython/YAML/Aggregate stillpending and Resultabsent at capture; oldheadfailures nottransferred.

Should Address

None.

Suggestions

None.

Evidence Gaps

  • POLICY-G1: Full composed six-programme foreign/historical qualification remains incomplete: complete currency/transfer rules, property-specific disregards and historical applicability at all newly parameterised starting dates are not fully traced across all six programmes. UC C1 ordinary sole-owned property case is primary-source supported; this gap does not convert remaining mappings into confirmed defects.
  • CODE-CI: Exact798requiredYAML/sixPython/Result/Aggregate completion notestablished atcaptured18:12metadata.20raw=11SUCCESS8IN_PROGRESS1CANCELLED, including separate laterSUCCESSFix; localmodel/import/collection/testsNOTRUN.
  • Role checks incomplete: pr2688-hb1811-review-20261027-review-code.md; see recovered report.
  • C2 remains unverified; its prior severity is retained.

Notes

  • BothrolesindependentlyresolveC1bysource/control-flow;0newfindings. Newfinal-eligibilityYAMLusesgenuineproperty/report/ageinputs and source-derivedamounts; not executedlocalRED/GREEN or privateimpactevidence.
  • 32cachedofficial originals/derivatives validatedreuse/checker0/0rejected0discarded/sourcebudget0/0GETsearchrender/newwindow. OnlyC1UCnecessarysources newlyinterpreted; G1carriedunchanged, not a32-source or six-programme re-audit. Original233.686691/300closedsourcewindow retained.
  • Vahid571comments6449451323/6449462413arecurrentPCstoredsurveycontract/landcalibration/impactreviews. Those findings/privatecounts remain externalreports/ownership, not newRootcriticalfindings, sourcecertificates or adoptedmetrics. Data501-543release/licensedreconciliation/adoption and1969reservation remain; no rawprivate/.job/sourceguess/takeover.
  • PriorpublicREQUEST_CHANGES5667352937anditsclaimremainconsumed/preserved; thiscanonicalCOMMENTis a materialC1resolutionfollowup, not APPROVE/dismissal/READY/merge. Publicationrequiresseparatefreshguards/oneclaim/readback.
  • Sandboxcaptureeda69aDNSfailureclosed beforeauthorized8b2b73exactclean798capture. Firstdispatch-to-brief/parallelinterval notseparatelyclocksealed; scopebrief18:17:06isactualpostdispatch, no inventedtiming. Rolefirstmarkersinclskillsetup remain actual.
  • Consolidation/cleanup duration is measuredfromlastroleseal; anyover120saim is retained asMISS, includingruntime delivery/coordinatorwork, withoutretiming.

Validation Summary

IndependentCODE/POLICYsource/AST/decimal checksresolveC1; no model/Core/country imports, collection or tests. Current798exactbranch/latestcommit/all20CheckSuitejoins; 11SUCCESS8IN_PROGRESS1CANCELLED withlaterFixSUCCESS; Resultunobserved atcapture. Source32reuse/checker0/newsource0. BothrolesDONE/owncommandsclosed; exactsnapshotnormalcleanup below. No private/sourceadoption/performance/cause/wholeCIcertificate.

Timing

setup seconds: 219.37s; code role seconds: 226.51s; policy role seconds: 239.49s; adjudication seconds: 0.00s; consolidation cleanup seconds: 91.51s; elapsed seconds: 603.43s; source acquisition window seconds: 0.00s

Review Severity

COMMENT. Open findings: 1 critical, 0 should address, 0 suggestions.

Fresh pre-publication CI observation

At 2026-10-27T18:23:11.732387+00:00, the same reviewed commit has 20 observed raw checks: 11 SUCCESS, 7 IN_PROGRESS and 2 CANCELLED. Test / YAML 122362858228 completed CANCELLED at 18:14:48Z; Test / Result is not yet observed. The earlier cancelled Fix evidence row remains alongside its separate later SUCCESS. This updates the time-stamped CI observation above; C2 clearance remains unestablished and this follow-up remains PARTIAL/COMMENT. No logs, rerun, cancellation cause or official-attempt classification were acquired.

@MaxGhenis

MaxGhenis commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

@juaristi22, addressed C1 and C2, including the two Sol findings.

Merged current origin/main cleanly in 28164b2, including #2690's six Python shards. No conflicts. Main's JSA/ESA changes read the existing capital assessments without changing capital sources or financial-report replacement. This PR remains draft and still follows #1969.

C1 — financial reports erasing property (María and Sol). 6c5cbc8 moves both new categories out of UC's financial pool and into the existing separately valued property route. Financial-only reports retain property; a complete uc_reported_capital override still replaces ordinary capital. Sale expenses and available secured debt are deducted once. #1969's HOLDINGS_SOURCE, share-like valuation and regulation 77 company substitution remain intact.

Audit of all six programmes:

Programme Result and code
UC Fixed: separately valued uc_property_capital.py:29; financial report and complete override remain distinct in uc_assessable_capital.py:98.
Pension Credit Fixed: financial reports add separately valued land/property, including existing domestic categories, directly in pension_credit_assessable_capital.py:81. Its independent complete override defaults to -1.
HB Ordinary route unaffected: no financial-report replacement in housing_benefit_assessable_capital.py:53. Savings-credit-only assessments inherit the PC fix at line 85.
IS Not affected: retains valued sources, with no financial-report replacement; income_support_assessable_capital.py:42.
JSA Not affected: reported benefit awards affect allocation, not capital replacement; jsa_income_assessable_capital.py:37.
ESA Not affected: same distinction; esa_income_assessable_capital.py:37.

Witnesses use 2026, one claimant, £20,000 of the named property, and no debt/disregards. UC claimant age is 40; PC/HB claimant age is 75. Each row applies separately to both overseas_property_value and other_property_value.

Witness Before After
UC, no financial report £18,000; capital limit failed £18,000; capital limit failed
UC, financial report £0 £0; capital limit passed £18,000; capital limit failed
UC, financial report £0 + complete override £4,000 £4,000 £4,000
PC and savings-credit-only HB, financial report £0 £0 £18,000

Replaced the YAML expectations that encoded property loss. Added both-category witnesses, complete overrides, secured-debt checks, PC/HB inheritance and large-value PC rounding regressions. The Hypothesis property checks that a nonnegative financial report never reduces counted property, and equals the report plus separately valued property net of disregards. Reinstating the old routing makes it fail: assert 0.0 >= 18000.0 for the explicit £20,000 overseas-property / £0 report example (1 failed, 39 deselected). Restoration was byte-for-byte: sources.yaml SHA-256 05263b2c2be8817c9835db62e3af4f27ce277ebdac7b7745802fa0a6ce226dc0; sale_expenses/sources.yaml SHA-256 3685ca48b2d5e6b998e75fdf5cda9de546d6cba3e6ed4f101e647fea84fb7006; property_sources.yaml SHA-256 f76c51a9d6f9ea285193706d8e49937ecd33c64c9f5567228078b2a48f4a8fa3; the restored property passes.

Sol — float32 land lower bound. 798491c sums residential, non-residential and unclassified other property directly before applying intensity (household_land_value.py:22). This preserves the formula in exact arithmetic and avoids subtracting rounded aggregates. The London witness with direct land £20,000.50 and overseas property £8,388,608 changes from £20,000.07421875 to exactly £20,000.50. Added a zero-tolerance YAML regression and tightened the generated lower-bound assertion to land >= owned_land exactly.

C2 — penny-rounding oracle. Reproduced the original oracle failure with the exact CI example pinned: python -m pytest policyengine_uk/tests/test_uc_company_owner_properties.py::test_household_capital_is_allocated_and_conserved_across_benefit_units -p no:randomly -x -vv (Core 3.33.12, setup-only clone fixture). It failed with actual £50.56 versus expected £50.5480013972151. CI printed no seed, only a Hypothesis 6.169.0 reproduction blob; the compact explicit example reproduces the same numeric failure in the reused 6.168.5 environment.

1193614 models stored-input precision, the raw float32 holdings-budget scale, separately penny-rounded share/holding valuations, each owner's company capital and each unit's final capital under UC regulation 6(1). Household expectations sum rounded units. For the CI case: £5,753.58 − £5,703.03 = £50.55; each £25.275 half rounds to £25.28, giving £50.56. Production results and tolerances are unchanged.

The full file passed 7 tests after the initial correction. An additional pin (shares £0.65, two holdings £0.40 each) exposed a scale-precision oracle error: actual £0.02 versus simplified oracle £0. After the conservation-only scale correction, the final focused node passed both new pins and generated cases; the other six nodes and global helpers were unchanged. All seven C2 nodes also passed in final-head CI. #1969 will encounter the original failure when it merges main's claimant/partner-role change and needs this same oracle correction.

Validation (one touched file per command):

  • Before/after UC, PC/HB, land and C2 witnesses: all assertions passed.
  • YAML files, run individually with policyengine-core test <file> -c policyengine_uk: uc_assessable_capital.yaml 23 passed; pension_credit_reported_capital.yaml 31 passed; benunit_reported_capital.yaml 6 passed; household_land_value.yaml 15 passed.
  • Python files, each run in its own python -m pytest <file> -p no:randomly -q -x command: test_property_wealth_components.py 41 passed; test_capital_valuation_properties.py 8 passed; test_uc_property_capital_mock.py 26 passed; test_projection_horizon.py 14 passed; test_benunit_reported_capital_properties.py 7 passed (the last uses -n 2).
  • test_uc_company_owner_properties.py: 7 passed with -n 2 after the initial rounding correction. After the subsequent conservation-only scale correction, its final focused node passed, including both regression pins and generated cases; the other six nodes and global helpers were unchanged. The original oracle and the simplified scale oracle were each observed failing first.
  • Mutation: reinstating the three old UC routing lists produced the intended failure, assert 0.0 >= 18000.0. All three files were restored byte for byte with matching SHA-256 digests; both restored property parameterizations then passed (2 passed, 39 deselected).
  • make format: passed before every fix commit.

CI at 798491c: BLOCKED: 18 checks passed, including all six Python shards, but Test / YAML was cancelled twice at its 30-minute limit after printing 5,217 passed. The Core CLI did not exit after the success summary. Test / Result failed with YAML: cancelled; Python: success. The YAML-only retry was attempted; both dropped watch connections were retried. YAML retry log, Result log.

🤖 Generated with Claude Code

@MaxGhenis
MaxGhenis requested a review from juaristi22 October 27, 2026 18:42

This branch has not been deployed

No deployments
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.

Add overseas and other real estate components and correct household land accounting

3 participants