You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
obr/esa ("Incapacity benefits") leaves out incapacity benefit, SDA and the incapacity part of income support #582
Corrected 2026-10-14: the premise below was wrong; see the correction comment. The remaining gap is incapacity benefit, SDA and the incapacity part of income support.
What's wrong
targets/sources/obr.py:538 (1.58.0 and 1.58.1) maps the OBR line "Incapacity benefits" to esa_income:
"esa": ("Incapacity benefits", "esa_income"),
The OBR "Incapacity benefits" line covers all ESA, contributory and income-related, plus Incapacity Benefit.
In policyengine-uk, esa_income is "ESA (income-based)" only. esa adds esa_contrib and esa_income, and incapacity_benefit is a separate variable.
So obr/esa (£7.21bn for 2025-26) is fitted to income-related ESA alone. It lands within 2% (estimate £7.34bn) only because calibration pushes income-related ESA up to meet a target that also covers contributory ESA and Incapacity Benefit. That inflates income-related ESA, and through it the legacy-benefit passports.
Found by the policyengine-model docs audit, the same kind of target-to-variable mismatch as #537. The UK hub confirmed the mapping and the variable definitions.
What to do
Score obr/esa against the variables the OBR line covers: esa (contributory + income-related) plus incapacity_benefit. Check the OBR table's notes for anything else on that line, such as Severe Disablement Allowance, and add it if the model has it.
Add a test that each OBR target's variable set matches the line's definition. Extend Stop calibrating OBR total NICs on ni_employee #537's two-targets-on-one-column check to a mapping table, with the OBR definition cited for each row.
Measure in the next batch build: income-related ESA, contributory ESA and IB totals and caseloads, and the legacy-benefit passports that read them.
Related: #537 (total NICs on ni_employee), #581 (engine skew).
changed the title [-]OBR "Incapacity benefits" target is scored against income-related ESA only (esa_income)[/-][+]obr/esa ("Incapacity benefits") leaves out incapacity benefit, SDA and the incapacity part of income support[/+]on Oct 14, 2026
Correction: the premise of this issue was wrong. I checked only the registry mapping when I filed it.
build_loss_matrix.py L413-L414 sends obr/esa to compute_esa, which returns esa_income + esa_contrib (compute/income.py L115-L119). That overrides the registry's esa_income, so the target is already scored against all ESA, not income-related ESA only. The docs audit session found the error, and an independent fact-check caught it.
What is left is narrower. Footnote 2 on OBR table 4.9 (storage/obr_efo/efo_expenditure.xlsx, cell B50) says the "Incapacity benefits" row includes incapacity benefit, employment and support allowance, severe disablement allowance, and income support (incapacity part), and excludes the health element of universal credit. The model side leaves out:
incapacity_benefit (exists in policyengine-uk as a reported amount);
sda (same);
the incapacity part of income support (no separate variable).
The OBR row is £12.41bn in 2024-25, £7.21bn in 2025-26 and £5.35bn in 2026-27. I have not measured how much of it these three benefits account for.
I have retitled the issue to this narrower gap. A fix would add incapacity_benefit and sda to compute_esa.
Activity
[-]OBR "Incapacity benefits" target is scored against income-related ESA only (esa_income)[/-][+]obr/esa ("Incapacity benefits") leaves out incapacity benefit, SDA and the incapacity part of income support[/+]MaxGhenis commentedon Oct 14, 2026
Correction: the premise of this issue was wrong. I checked only the registry mapping when I filed it.
build_loss_matrix.py L413-L414 sends
obr/esatocompute_esa, which returnsesa_income + esa_contrib(compute/income.py L115-L119). That overrides the registry'sesa_income, so the target is already scored against all ESA, not income-related ESA only. The docs audit session found the error, and an independent fact-check caught it.What is left is narrower. Footnote 2 on OBR table 4.9 (
storage/obr_efo/efo_expenditure.xlsx, cell B50) says the "Incapacity benefits" row includes incapacity benefit, employment and support allowance, severe disablement allowance, and income support (incapacity part), and excludes the health element of universal credit. The model side leaves out:incapacity_benefit(exists in policyengine-uk as a reported amount);sda(same);The OBR row is £12.41bn in 2024-25, £7.21bn in 2025-26 and £5.35bn in 2026-27. I have not measured how much of it these three benefits account for.
I have retitled the issue to this narrower gap. A fix would add
incapacity_benefitandsdatocompute_esa.