Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c820eed
Merge remote-tracking branch 'origin/main' into spc-qualifying-age-cl…
MaxGhenis Sep 30, 2026
aa45dd7
Use the State Pension Credit qualifying age, and start-of-year status…
MaxGhenis Sep 30, 2026
b9d8573
Address review: accurate benefit cap and CTR comments, date s.4(1A), …
MaxGhenis Sep 30, 2026
cae3131
Apply round-2 review nits: Class 4 wording and the cohort test bound
MaxGhenis Sep 30, 2026
0a03a13
Merge remote-tracking branch 'origin/main' into spc-qualifying-age-cl…
MaxGhenis Oct 1, 2026
09ec4bf
Take Class 4 out of ni_liable's description after merging main
MaxGhenis Oct 1, 2026
0408ef1
Rewrap the Class 4 paragraph in the State Pension docs
MaxGhenis Oct 1, 2026
c5124ae
Merge current main and reconcile statutory qualifying-age consumers
MaxGhenis Oct 3, 2026
6e9d3a7
Merge State Pension age dependency at 56316599f
MaxGhenis Oct 3, 2026
fcfcd41
Document Class 4 boundary and date Winter Fuel age tests
MaxGhenis Oct 3, 2026
739c7bd
Align qualifying-age property timing checks with dependency
MaxGhenis Oct 3, 2026
1c9f354
Route pension-age means tests through statutory scheme conditions
MaxGhenis Oct 3, 2026
8256ebc
Merge main and preserve HB legacy passports with pension regime routing
MaxGhenis Oct 3, 2026
b4a7c74
Merge current main at 5232f9afb
MaxGhenis Oct 3, 2026
1b51533
Merge updated State Pension age dependency at e51faaa43
MaxGhenis Oct 3, 2026
efca9d4
Pin non-pensioner allowances for Welsh mixed-age UC regression
MaxGhenis Oct 3, 2026
d0933a1
Merge current main into spc-qualifying-age-class-4-spa
MaxGhenis Oct 4, 2026
4906146
Choose each programme's premium schedule with its own regime test
MaxGhenis Oct 4, 2026
a4b9f73
Apply the Income Support age test to the claimant, not the whole family
MaxGhenis Oct 4, 2026
32a6c17
Require the Income Support claimant to meet both the age and category…
MaxGhenis Oct 4, 2026
94dad0c
Merge current main into spc-qualifying-age-class-4-spa
MaxGhenis Oct 4, 2026
43a52e2
Apply the savings-credit-only tariff exemption only under the pension…
MaxGhenis Oct 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Class 4 National Insurance now stops from the first tax year that begins on or after the day State Pension age is reached (Social Security (Contributions) Regulations 2001 reg 91(a)): a person over State Pension age on 6 April is excepted, and one who reaches it during the year pays Class 4 for that whole year. Before, anyone over State Pension age on 6 October was excepted.
1 change: 1 addition & 0 deletions changelog.d/spc-qualifying-age-class-4-spa.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added `state_pension_credit_qualifying_age` and `has_attained_state_pension_credit_qualifying_age`, the qualifying age for State Pension Credit from each person's date of birth, and `ni_class_4_liable`, Class 4 liability by age at the start of the tax year.
1 change: 1 addition & 0 deletions changelog.d/spc-qualifying-age-class-4-spa.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Winter Fuel Payment uses pensionable age from 2024-25 and the State Pension Credit qualifying age in earlier years, as the regulations in force in each year require.
1 change: 1 addition & 0 deletions changelog.d/spc-qualifying-age-class-4-spa.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pension Credit, Universal Credit, Housing Benefit, Council Tax Reduction, Income Support, the benefit cap (which reaches only working-age Housing Benefit and Universal Credit) and Winter Fuel Payment now use the qualifying age for State Pension Credit (State Pension Credit Act 2002 s.1(6)) instead of each person's own State Pension age. For a man born before 6 December 1953 that is the State Pension age of a woman born on the same day, not 65, so these programmes change only in 2018-19 and earlier. National Insurance and State Pension keep using the person's own State Pension age; Class 4 now reads it at the start of the tax year (see the Class 4 entry). Housing Benefit and Council Tax Reduction choose their pension-age or working-age allowances, means tests and premium schedules with their own statutory tests (HB(SPC) Regs 2006 reg 5 and the CTR pensioner tests), which exclude families on Universal Credit, Income Support, income-based Jobseeker's Allowance or income-related Employment and Support Allowance; the pension-age severe disability premium follows the qualifying age. Income Support uses its own working-age premiums, and its age test applies to the claimant, who must also be the one in a prescribed category such as carer, so a mixed-age couple can claim it through the younger partner unless the couple is on Pension Credit (SSCBA 1992 s.124(1)(aa), (e) and (g)).
29 changes: 29 additions & 0 deletions docs/book/programs/gov/dwp/state-pension.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,35 @@ extracts. The weighted share of each age over State Pension age then matches
the statute: three quarters of 66-year-olds in 2026-27, a quarter in 2027-28
and none from 2028-29.

Other programmes test State Pension age in two ways:

- **The qualifying age for State Pension Credit** (State Pension Credit Act
2002 s.1(6)) is a woman's State Pension age, and for a man the State
Pension age of a woman born on the same day. `state_pension_credit_qualifying_age`
applies the timetable without rule (1), and
`has_attained_state_pension_credit_qualifying_age` is whether it is reached
by 6 October. Pension Credit, Universal Credit (Welfare Reform Act 2012
s.4(1)(b)), Housing Benefit (Housing Benefit Regulations 2006 reg 5 in both
sets), Council Tax Reduction's pension-age schemes, Income Support
(SSCBA 1992 s.124(1)(aa)), the benefit cap (which reaches only
working-age Housing Benefit and Universal Credit) and Winter Fuel Payment
(to September 2024) use it. It differs from
`is_SP_age` only for men born before 6 December 1953, so only in 2018-19
and earlier: a man born on 6 April 1952 reached it on 6 May 2014, nearly
three years before his State Pension age of 65.
- **Class 4 National Insurance** stops from the first tax year that begins on
or after the day State Pension age is reached: a person over it at the
beginning of the tax year (6 April) is excepted (Social Security
(Contributions) Regulations 2001 reg 91(a)), so `ni_class_4_liable` needs
`months_since_state_pension_age` below 6. Someone who reaches it on 6 April
itself is read as over it at the beginning of that year. With default
whole-number ages in a household situation, the inferred birthday is
6 April. Entering an integer State Pension age therefore makes this
boundary reading determine the Class 4 result; fractional ages and explicit
birthday-month inputs can place the birthday on another day. Class 1 employee
contributions stop at State Pension age itself (SSCBA 1992 s.6(3)), which
the annual model reads as `is_SP_age`.

A person attains an age at the start of the anniversary of their birth
(Family Law Reform Act 1969 s.9(1)), and an age of "N years and M months" on
the same day of the month, or the month's last day where that day does not
Expand Down
2 changes: 1 addition & 1 deletion docs/book/programs/gov/hmrc/national-insurance.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "## How PolicyEngine computes National Insurance liability\n\nFor each person, PolicyEngine computes NI contributions class-by-class:\n\n- **Class 1 employee** (`ni_class_1_employee`): the sum of `ni_class_1_employee_primary` (main rate on earnings between the Primary Threshold and the Upper Earnings Limit) and `ni_class_1_employee_additional` (additional rate on earnings above the UEL). These primary contributions are due from age 16 until state pension age (`ni_liable`): SSCBA 1992 s.6(3) ends them at pensionable age.\n- **Class 1 employer** (`ni_class_1_employer`): paid on earnings above the Secondary Threshold; surfaced through the `ni_employer` variable. These secondary contributions are due on earners over 16 with no upper age limit (`ni_class_1_secondary_liable`), so employers keep paying them for employees over state pension age (SSCBA 1992 s.6(1)(b) and s.6(3)).\n- **Class 2** (`ni_class_2`): a flat weekly rate paid by the self-employed with profits above the Small Profits Threshold.\n- **Class 3** (`ni_class_3`): a voluntary flat weekly rate; the variable is exposed but defaults to zero unless explicitly set.\n- **Class 4** (`ni_class_4`): main rate between the Lower and Upper Profits Limits plus additional rate above the UPL, charged on `ni_class_4_profits`. Those are the trade profits chargeable to income tax under ITTOIA 2005 Part 2 Chapter 2 (`ni_class_4_profits_before_losses`: self-employment profit after capital allowances and the trading allowance), less trading losses as SSCBA 1992 Schedule 2 paragraph 3 allows (`ni_class_4_loss_relief`). A loss reduces only trade profits for Class 4: each year's losses (those brought forward, then the year's own loss, `ni_class_4_trading_loss`) are set against that year's trade profits, and the rest is carried forward until used (`ni_class_4_losses_brought_forward`, `ni_class_4_losses_carried_forward`). A year's own loss is the `trading_loss` entered for that year, so a loss entered once is relieved once: it is not counted again in the later years that `trading_loss` carries into. Carry-back claims and the paragraph 3(5) deductions for trade interest and royalties are not modelled. Where the person also pays primary Class 1 contributions (or, before 6 April 2024, Class 2 contributions), liability is capped at the annual maximum in regulation 100 of the Social Security (Contributions) Regulations 2001 (`ni_class_4_maximum`).\n\nThe individual total `national_insurance` sums the four employee and self-employed components directly — `ni_class_1_employee + ni_class_2 + ni_class_3 + ni_class_4` — so voluntary Class 3 contributions are included in the household-side liability. The convenience aggregates `ni_employee` (Class 1 employee only) and `ni_self_employed` (Class 2 + Class 4) are also exposed for reporting. The Class 1 *employer* charge (`ni_class_1_employer`, surfaced as `ni_employer`) is an employer-side cost rather than part of the individual's `national_insurance`, so it is tracked separately and feeds the government revenue aggregates on its own.\n\nParameters live in `policyengine_uk/parameters/gov/hmrc/national_insurance/` and the per-class formulas in `policyengine_uk/variables/gov/hmrc/national_insurance/`."
"source": "## How PolicyEngine computes National Insurance liability\n\nFor each person, PolicyEngine computes NI contributions class-by-class:\n\n- **Class 1 employee** (`ni_class_1_employee`): the sum of `ni_class_1_employee_primary` (main rate on earnings between the Primary Threshold and the Upper Earnings Limit) and `ni_class_1_employee_additional` (additional rate on earnings above the UEL). These primary contributions are due from age 16 until state pension age (`ni_liable`): SSCBA 1992 s.6(3) ends them at pensionable age.\n- **Class 1 employer** (`ni_class_1_employer`): paid on earnings above the Secondary Threshold; surfaced through the `ni_employer` variable. These secondary contributions are due on earners over 16 with no upper age limit (`ni_class_1_secondary_liable`), so employers keep paying them for employees over state pension age (SSCBA 1992 s.6(1)(b) and s.6(3)).\n- **Class 2** (`ni_class_2`): a flat weekly rate paid by the self-employed with profits above the Small Profits Threshold.\n- **Class 3** (`ni_class_3`): a voluntary flat weekly rate; the variable is exposed but defaults to zero unless explicitly set.\n- **Class 4** (`ni_class_4`): main rate between the Lower and Upper Profits Limits plus additional rate above the UPL, charged on `ni_class_4_profits`. Those are the trade profits chargeable to income tax under ITTOIA 2005 Part 2 Chapter 2 (`ni_class_4_profits_before_losses`: self-employment profit after capital allowances and the trading allowance), less trading losses as SSCBA 1992 Schedule 2 paragraph 3 allows (`ni_class_4_loss_relief`). A loss reduces only trade profits for Class 4: each year's losses (those brought forward, then the year's own loss, `ni_class_4_trading_loss`) are set against that year's trade profits, and the rest is carried forward until used (`ni_class_4_losses_brought_forward`, `ni_class_4_losses_carried_forward`). A year's own loss is the `trading_loss` entered for that year, so a loss entered once is relieved once: it is not counted again in the later years that `trading_loss` carries into. Carry-back claims and the paragraph 3(5) deductions for trade interest and royalties are not modelled. Where the person also pays primary Class 1 contributions (or, before 6 April 2024, Class 2 contributions), liability is capped at the annual maximum in regulation 100 of the Social Security (Contributions) Regulations 2001 (`ni_class_4_maximum`). Class 4 is due from age 16 until the first tax year that begins on or after the day the person reaches state pension age (`ni_class_4_liable`): regulation 91(a) excepts anyone over pensionable age at the beginning of the tax year, so a person who reaches it during a year pays for that whole year.\n\nThe individual total `national_insurance` sums the four employee and self-employed components directly \u2014 `ni_class_1_employee + ni_class_2 + ni_class_3 + ni_class_4` \u2014 so voluntary Class 3 contributions are included in the household-side liability. The convenience aggregates `ni_employee` (Class 1 employee only) and `ni_self_employed` (Class 2 + Class 4) are also exposed for reporting. The Class 1 *employer* charge (`ni_class_1_employer`, surfaced as `ni_employer`) is an employer-side cost rather than part of the individual's `national_insurance`, so it is tracked separately and feeds the government revenue aggregates on its own.\n\nParameters live in `policyengine_uk/parameters/gov/hmrc/national_insurance/` and the per-class formulas in `policyengine_uk/variables/gov/hmrc/national_insurance/`."
},
{
"cell_type": "markdown",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@
output:
severe_disability_minimum_guarantee_addition: 86.05 * 52

- name: The pension-age premium is zero below State Pension age
- name: The pension-age premium is zero below the State Pension Credit qualifying age
period: 2026
absolute_error_margin: 0.01
input:
Expand All @@ -277,3 +277,37 @@
country: {2026: ENGLAND}
output:
pension_age_severe_disability_premium: 0

- name: A mixed-age couple on Universal Credit uses the working-age premium schedule
# HB(SPC) Regs 2006 reg 5 and the CTR pensioner tests exclude a couple on
# Universal Credit, so the working-age allowance and premiums apply even
# though one partner is over State Pension age.
period: 2026
absolute_error_margin: 0.01
input:
people:
claimant:
age: {2026: 50}
is_disabled_for_benefits: {2026: true}
partner:
age: {2026: 70}
state_pension: {2026: 3_000}
benunits:
benunit:
members: [claimant, partner]
households:
household:
members: [claimant, partner]
country: {2026: ENGLAND}
tenure_type: {2026: RENT_FROM_COUNCIL}
rent: {2026: 6_240}
council_tax: {2026: 2_000}
output:
is_uc_entitled: true
housing_benefit_pension_age_regulations_apply: false
council_tax_reduction_pensioner: false
pension_age_severe_disability_premium: 0
# Legacy disability premium (couple) 64.00 * 52 = 3,328.
benefits_premiums: 64.00 * 52
# Working-age couple allowance 150.15 * 52 = 7,807.80, plus the premium.
council_tax_reduction_applicable_amount: (150.15 + 64.00) * 52
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# HB Regs 2006 reg 5 and HB (SPC) Regs 2006 reg 5 route a claimant on
# income-based JSA to the working-age regulations even after the qualifying
# age. CTR SI 2012/2885 reg 3 applies the same exclusion to its pensioner test.
# These tests preserve the model's existing historical allowance parameters:
# 73.10 * 52 = 3,801.20 and 181 * 52 = 9,412, without asserting that the
# shared pension-age allowance parameter reproduces every statutory age band.

- name: Qualifying-age claimant on income-based JSA uses working-age HB and CTR allowances
period: 2017
absolute_error_margin: 0.01
input:
people:
claimant:
age: 64
months_since_last_birthday: 4
is_male: true
benunits:
benunit:
members: [claimant]
jsa_income: 100
income_support: 0
esa_income: 0
guarantee_credit: 0
households:
household:
members: [claimant]
rent: 6_240
tenure_type: RENT_FROM_COUNCIL
output:
has_attained_state_pension_credit_qualifying_age: true
is_SP_age: false
housing_benefit_eligible: true
housing_benefit_pension_age_regulations_apply: false
council_tax_reduction_pensioner: false
benefits_premiums: 0
housing_benefit_applicable_amount: 3_801.20
council_tax_reduction_applicable_amount: 3_801.20

- name: Qualifying-age claimant without excluded benefits retains pension-age HB and CTR allowances
period: 2017
absolute_error_margin: 0.01
input:
people:
claimant:
age: 64
months_since_last_birthday: 4
is_male: true
benunits:
benunit:
members: [claimant]
jsa_income: 0
income_support: 0
esa_income: 0
guarantee_credit: 0
households:
household:
members: [claimant]
rent: 6_240
tenure_type: RENT_FROM_COUNCIL
output:
has_attained_state_pension_credit_qualifying_age: true
is_SP_age: false
housing_benefit_eligible: true
housing_benefit_pension_age_regulations_apply: true
council_tax_reduction_pensioner: true
benefits_premiums: 0
housing_benefit_applicable_amount: 9_412
council_tax_reduction_applicable_amount: 9_412

- name: Synthetic component routing does not apply the pension-age guarantee-credit passport under working-age flags
# This fixes the scheme flags and income components to test their consumers;
# it does not assert lawful receipt of these benefits together. HB (SPC)
# reg 26 disregards all income and capital only within that scheme. Working
# HB reg 52 gives (12,000 - 6,000) / 250 * 52 = 1,248 tariff income here.
# The separate working-age capital passports are outside this component test.
period: 2017
absolute_error_margin: 0.01
input:
people:
claimant:
age: 64
months_since_last_birthday: 4
is_male: true
employment_income: 1_000
income_tax: 0
national_insurance: 0
pension_contributions: 0
benunits:
benunit:
members: [claimant]
housing_benefit_eligible: true
housing_benefit_pension_age_regulations_apply: false
council_tax_reduction_pensioner: false
guarantee_credit: 1_000
income_support: 0
jsa_income: 0
esa_income: 0
tax_credits: 0
benefits_premiums: 0
housing_benefit_applicable_income_disregard: 0
housing_benefit_applicable_income_childcare_element: 0
households:
household:
members: [claimant]
savings: 12_000
output:
has_attained_state_pension_credit_qualifying_age: true
housing_benefit_applicable_amount: 3_801.20
council_tax_reduction_applicable_amount: 3_801.20
housing_benefit_assessable_capital: 12_000
housing_benefit_tariff_income: 1_248
housing_benefit_applicable_income: 2_248

- name: Synthetic component routing applies the guarantee-credit passport under pension-age flags
# The same controlled components now fall under the pension-age scheme.
# HB (SPC) reg 26: "the whole of his capital and income shall be disregarded".
period: 2017
absolute_error_margin: 0.01
input:
people:
claimant:
age: 64
months_since_last_birthday: 4
is_male: true
employment_income: 1_000
income_tax: 0
national_insurance: 0
pension_contributions: 0
benunits:
benunit:
members: [claimant]
housing_benefit_eligible: true
housing_benefit_pension_age_regulations_apply: true
council_tax_reduction_pensioner: true
guarantee_credit: 1_000
income_support: 0
jsa_income: 0
esa_income: 0
tax_credits: 0
benefits_premiums: 0
housing_benefit_applicable_income_disregard: 0
housing_benefit_applicable_income_childcare_element: 0
households:
household:
members: [claimant]
savings: 12_000
output:
has_attained_state_pension_credit_qualifying_age: true
housing_benefit_applicable_amount: 9_412
council_tax_reduction_applicable_amount: 9_412
housing_benefit_assessable_capital: 0
housing_benefit_tariff_income: 0
housing_benefit_applicable_income: 0

- name: Synthetic component routing keeps the working-age tariff income for savings-credit-only status under working-age flags
# This fixes the scheme flags and savings-credit-only status to test their
# consumer; it does not assert a lawful award. HB (SPC) reg 27(5) lifts the
# tariff income rule only within the pension-age regulations. Working HB
# reg 52 gives (12,000 - 6,000) / 250 * 52 = 1,248 tariff income here.
period: 2017
absolute_error_margin: 0.01
input:
people:
claimant:
age: 64
months_since_last_birthday: 4
is_male: true
benunits:
benunit:
members: [claimant]
housing_benefit_pension_age_regulations_apply: false
in_receipt_of_savings_credit_only: true
guarantee_credit: 0
households:
household:
members: [claimant]
savings: 12_000
output:
housing_benefit_assessable_capital: 12_000
housing_benefit_tariff_income: 1_248
Loading
Loading