Background
After PR #1618 fixed state_pension_type (BASIC vs NEW classification), the model's state pension aggregate is £127.5 bn vs the OBR 2025 target of ~£140 bn — still a -£12 bn gap, identified in tracking issue #1621 as the largest residual benefit aggregate misalignment.
Diagnosis
Two related pipeline limitations combine to understate the total:
1. new_state_pension pays flat max amount to every NEW-type retiree
Current formula in policyengine_uk/variables/gov/dwp/new_state_pension.py:
def formula(person, period, parameters):
type = person("state_pension_type", period)
eligible = type == type.possible_values.NEW
p = parameters(period).gov.dwp.state_pension.new_state_pension
return eligible * p.amount * WEEKS_IN_YEAR # full amount for everyone
This ignores the reported amount entirely. In reality:
- Under 35 NI years → pro-rated full amount
- Over full rate (Protected Payment from pre-2016 SERPS/S2P) → higher than flat amount
The flat-max assumption over-states for partial-NI-record retirees and under-states Protected Payment for those with substantial pre-2016 SERPS contributions. The net effect on aggregate is ambiguous without data.
2. additional_state_pension only captures reported amounts exceeding max basic, for BASIC type
Current ASP formula in policyengine_uk/variables/gov/dwp/additional_state_pension.py:
reported = person("state_pension_reported", data_year) / WEEKS_IN_YEAR
type = person("state_pension_type", data_year)
# ...
amount_in_data_year = where(
type == type.possible_values.BASIC,
max_(reported - max_sp_data_year, 0), # only BASIC
0,
)
For BASIC-type retirees reporting exactly the max basic amount (£169/wk in 2024), this yields ASP = 0 — but many of those retirees in reality also received SERPS/S2P top-ups. FRS state_pension_reported is derived from SRP (the single weekly benefit value), which aggregates basic + ASP; if SRP is capped or rounded at the max basic, ASP is under-imputed.
Additionally, there's no Protected Payment component for NEW-type retirees anywhere in the pipeline.
Proposed fixes
Two options, both non-trivial:
-
Formula-side — change new_state_pension to use state_pension_reported directly (with data-year uprating, matching the basic_state_pension / additional_state_pension pattern). This captures Protected Payment organically for NEW-type retirees who reported more than the flat max. Risk: reduces aggregate for partial-NI-record retirees whose reported is < max.
-
Data-side — impute an ASP component on BASIC-type rows whose reported matches the max basic exactly. This requires breaking out SERPS/S2P coverage from an external source (ONS National Pensioners Survey or DWP administrative caseload by pension type).
Either approach needs empirical validation against OBR/DWP outturn for FY 2024-25. Filing for follow-up; too scoped to land in the current PR sweep.
References
Background
After PR #1618 fixed
state_pension_type(BASIC vs NEW classification), the model's state pension aggregate is £127.5 bn vs the OBR 2025 target of ~£140 bn — still a -£12 bn gap, identified in tracking issue #1621 as the largest residual benefit aggregate misalignment.Diagnosis
Two related pipeline limitations combine to understate the total:
1.
new_state_pensionpays flat max amount to every NEW-type retireeCurrent formula in
policyengine_uk/variables/gov/dwp/new_state_pension.py:This ignores the reported amount entirely. In reality:
The flat-max assumption over-states for partial-NI-record retirees and under-states Protected Payment for those with substantial pre-2016 SERPS contributions. The net effect on aggregate is ambiguous without data.
2.
additional_state_pensiononly captures reported amounts exceeding max basic, for BASIC typeCurrent ASP formula in
policyengine_uk/variables/gov/dwp/additional_state_pension.py:For BASIC-type retirees reporting exactly the max basic amount (£169/wk in 2024), this yields ASP = 0 — but many of those retirees in reality also received SERPS/S2P top-ups. FRS
state_pension_reportedis derived from SRP (the single weekly benefit value), which aggregates basic + ASP; if SRP is capped or rounded at the max basic, ASP is under-imputed.Additionally, there's no Protected Payment component for NEW-type retirees anywhere in the pipeline.
Proposed fixes
Two options, both non-trivial:
Formula-side — change
new_state_pensionto usestate_pension_reporteddirectly (with data-year uprating, matching thebasic_state_pension/additional_state_pensionpattern). This captures Protected Payment organically for NEW-type retirees who reported more than the flat max. Risk: reduces aggregate for partial-NI-record retirees whose reported is < max.Data-side — impute an ASP component on BASIC-type rows whose reported matches the max basic exactly. This requires breaking out SERPS/S2P coverage from an external source (ONS National Pensioners Survey or DWP administrative caseload by pension type).
Either approach needs empirical validation against OBR/DWP outturn for FY 2024-25. Filing for follow-up; too scoped to land in the current PR sweep.
References