Skip to content

Use the State Pension Credit qualifying age, and start-of-year status for Class 4 NI - #1907

Merged
MaxGhenis merged 22 commits into
mainfrom
spc-qualifying-age-class-4-spa
Oct 4, 2026
Merged

MaxGhenis merged 22 commits into
mainfrom
spc-qualifying-age-class-4-spa

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #1906

#1899 (State Pension age by date of birth), which this PR builds on, has merged. This branch merges main 2105816c (after #1945 and #2079), so its diff against main is its own change.

Summary

Two statutory age tests read the wrong State Pension age status. The statutes below were all read on legislation.gov.uk for this PR.

1. The qualifying age for State Pension Credit

State Pension Credit Act 2002 s.1(6): "the qualifying age" means "(a) in the case of a woman, pensionable age; or (b) in the case of a man, the age which is pensionable age in the case of a woman born on the same day as the man." A man born before 6 December 1953 has a pensionable age of 65 (Pensions Act 1995 Sch 4 para 1 rule (1)). His qualifying age is earlier: the day table 1 gives a woman with his date of birth. The model used his own pensionable age (is_SP_age) wherever the law uses the qualifying age.

  • New variables.
  • Refactor. The timetable logic moves from state_pension_age into policyengine_uk/utils/state_pension_age.py, so both ages share one implementation, including Set State Pension age from date of birth, including the rise to 67 #1899's month arithmetic, fractional-age precedence and six-month birthday default. Set State Pension age from date of birth, including the rise to 67 #1899's tests are unchanged.
  • Who changes. Whether someone has attained the qualifying age differs from whether they have reached their own State Pension age only for men born before 6 December 1953, and only in 2018-19 and earlier (their qualifying age stays below 65, but by 2019-20 they are over both). Example: a man born 6 April 1952 reached the qualifying age on 6 May 2014, nearly three years before 65. In 2016-17 the model had him eligible for Universal Credit and not Pension Credit; now it is the reverse.
Consumer Statutory test Now uses
meets_pension_credit_age_conditions (Pension Credit, new-claim Housing Benefit and Universal Credit read it), pension_credit_assessable_capital, is_mixed_age_couple, both age checks in has_mixed_age_couple_pension_credit_saving SPCA 2002 s.1(2)(b) "has attained the qualifying age"; s.4(1A) (other member "has not attained the qualifying age"); SI 2019/37 arts 2 and 4 qualifying age, with main's claimant and partner roles and the SI 2019/37 saving kept
is_uc_eligible WRA 2012 s.4(1)(b) "has not reached the qualifying age for state pension credit"; s.4(4) points to SPCA s.1(6); UC Regs 2013 reg 3(2)(a) qualifying age
housing_benefit_pension_age_regulations_apply (which HB regulations apply) HB Regs 2006 reg 5 and HB (SPC) Regs 2006 reg 5: "has attained the qualifying age for state pension credit", with the Universal Credit and legacy-benefit exclusions qualifying age, with main's exclusions (#1944) kept
HB allowance, tariff income, capital limit, the Guarantee Credit income and capital passports and the savings-credit-only rule (housing_benefit_applicable_amount, _tariff_income, _assessable_capital, _applicable_income), and the HB premium schedule (benefits_premiums) the separate working-age and pension-age Schedule 3 tables (HB Regs 2006 reg 22; HB (SPC) Regs 2006 reg 22); working reg 52 against pension reg 29(2); working reg 43 and pension reg 43; pension regs 26 and 27 the regulations switch above, so a family the exclusions keep under the working-age regulations gets working-age amounts and premiums. Main's legacy-benefit income and capital passports (#2000) and savings-credit-only rule (#1945) are kept
council_tax_reduction_pensioner, and through it the CTR allowance and premium schedule (council_tax_reduction_applicable_amount) SI 2012/2885 reg 3(1)(a)(i) (England), SI 2013/3029 reg 3(1)(a)(i) (Wales), SSI 2012/319 reg 12(1) (Scotland), each with its benefit exclusions qualifying age, with main's exclusions kept
income_support_eligible, and the Income Support premiums SSCBA 1992 s.124(1)(aa) "he has not attained the qualifying age for state pension credit"; s.124(1)(g) "the other member of the couple is not entitled to state pension credit"; IS Regs 1987 Sch 2 qualifying age of the claimant, who must also be the one in a prescribed category (a carer, or the lone parent of a young child; s.124(1)(e), Sch 1B paras 1 and 4): either member of a couple can claim, so a mixed-age couple can claim through a younger partner who is a carer (main barred the family if any member was over State Pension age, and counted a carer anywhere in the benefit unit). The couple is barred where it is on Pension Credit; reading the Pension Credit amount there would be circular, so the model treats a couple that meets the Pension Credit age conditions and would claim it as on Pension Credit. Income Support always uses its own (working-age) premium schedule
pension_age_severe_disability_premium HB (SPC) Regs 2006 Sch 3 para 6 paid where a claimant or partner has attained the qualifying age; HB and CTR then choose the schedule with their own switch
is_benefit_cap_exempt_other no age exception in UC Regs 2013 regs 79-83 or HB Regs 2006 Part 8A; the cap reaches only working-age HB (reg 5) and Universal Credit reads the HB regulations switch (main's #1944), now on the qualifying age
winter_fuel_allowance SI 2000/729 reg 2(1)(b) (in force to 15 September 2024): "has attained the qualifying age for state pension credit"; SI 2024/869 reg 2(1)(a) and SI 2025/969 reg 2(a): "has reached pensionable age" qualifying age before 2024-25, pensionable age from 2024-25
ni_liable (Class 1 employee, Class 2), state_pension_type, additional_state_pension, meets_savings_credit_age_requirement (SPCA s.3(1)(a): "has attained pensionable age before 6 April 2016"), Scottish pawhp (SSI 2024/351 reg 6: "has reached pensionable age"), HBAI pensioner status pensionable age unchanged

The unused has_pensioner reads of is_SP_age in is_benefit_cap_exempt_earnings and is_benefit_cap_exempt_health_disability are removed.

Premium schedules. Main's #1938 chose the pension-age premium schedule for HB, CTR and Income Support whenever any member of the family was over State Pension age, while the allowances above follow each programme's own regulations switch. Combined, a mixed-age couple on Universal Credit got the working-age CTR allowance with the pension-age premiums. Each programme now chooses its premium schedule with the test that chooses its allowance (490614677), and a new YAML case pins that couple.

2. Class 4 National Insurance at the start of the tax year

SI 2001/1004 reg 91 excepts "any earner who (a) at the beginning of a year of assessment is over pensionable age". ni_class_4 and ni_class_4_main used defined_for = "ni_liable", which is status on 6 October, so they excepted anyone who reached State Pension age between 6 April and 6 October. HMRC NIM24510: "A person who attains State pension age during the course of the year of assessment remains liable for Class 4 NICs for the whole of that year."

  • New variable. ni_class_4_liable = over_16 and not (months_since_state_pension_age ≥ 6), since 6 April is six months before 6 October (MONTHS_FROM_TAX_YEAR_START_TO_MID_YEAR). Class 4 now uses it in place of ni_liable.
  • 6 April itself. The model reads a person who attains pensionable age on 6 April as over it at the beginning of that year: pensionable age is attained at the commencement of a day, and the enabling power (SSCBA 1992 s.17(2)(b)) is "to a person having attained pensionable age". In a household simulation with whole-number ages the inferred birthday is 6 April, so anyone entered at exactly State Pension age is decided by this reading. ni_class_4_liable's documentation and the State Pension docs say so; explicit birthday-month inputs and fractional ages place the birthday elsewhere.
  • ni_liable now covers primary Class 1 and Class 2 only; its label and documentation say so, and the National Insurance docs page states the Class 4 age rule. Employee Class 1 stays on ni_liable: SSCBA 1992 s.6(3) stops primary Class 1 on earnings paid "after he attains pensionable age".
  • Under-16s. The existing over_16 condition is kept. Reg 93's under-16 exception applies only on application for a certificate.

Invariants (stated and tested)

  1. Qualifying age = statute, day by day. test_state_pension_credit_qualifying_age.py reuses Set State Pension age from date of birth, including the rise to 67 #1899's differential population: births every third day from 1945 to 1984 plus both sides of every statutory boundary, both sexes, 13 fiscal years. Set State Pension age from date of birth, including the rise to 67 #1899's statute-text reference (reference_attainment_day) shares no code with the model. For every person, the model's qualifying day equals that reference's day for a woman born the same day, and status on 6 October follows it.
  2. Class 4 = statute, day by day. On the same population, ni_class_4_liable equals "attains pensionable age after 6 April" (reference day vs 6 April), for every person and year.
  3. Ordering. Qualifying age ≤ pensionable age for everyone. They are equal for women and for men born on or after 6 December 1953. has_attained_state_pension_credit_qualifying_age ⊇ is_SP_age, with equality in every year from 2019-20. A companion test checks that 2015-16 to 2018-19 do contain people where the two differ, all of them men born before 6 December 1953, so the checks are not vacuous.
  4. Consumers follow the qualifying age (Hypothesis). For any set of birth dates, either sex and any year from 2015 to 2030, single people with no income or capital: Pension Credit eligibility, CTR pensioner status and the benefit cap's pension-age exemption equal the statutory qualifying-age status, Universal Credit eligibility is its negation, the pension-age CTR personal allowance applies exactly when it holds, and Winter Fuel Payment follows it through 2023-24. A second property test samples the cohort where the two ages can differ (men born 6 April 1950 to 6 December 1953, in 2015-16 to 2018-19); not every example has differing statuses (a man born 6 April 1950 is over both in 2018-19).
  5. Premium schedules. Over the qualifying age, the pension-age severe disability premium is 0, 1 or 2 weekly rates and equals severe_disability_premium; below it, nil. The HB premiums follow the pension-age schedule exactly when the pension-age HB regulations apply, which needs the qualifying age.
  6. Class 4 properties (Hypothesis). Liability never resumes (liable next year implies liable this year); liability ⇔ months_since_state_pension_age < 6; anyone under State Pension age on 6 October is liable; Class 4 is positive exactly when liable (profits of £60,000).

YAML tests: state_pension_credit_qualifying_age.yaml (26 cases, including men born 1950-1953 in 2015-16 to 2018-19, the 6 December 1953 boundary, a woman born the same day, and a couple both born 6 June 1953 who are not a mixed-age couple; every expected day comes from Sch 4 para 1 table 1); ni_class_4_liable.yaml (9 cases, including the issue's example: born 6 June 1960, State Pension age 6 September 2026, pays (30,000 − 12,570) × 6% = £1,045.80 for 2026-27 and nothing for 2027-28, and exactly on 6 April 2025); new cases for the HB regime routing (housing_benefit_pension_age_means_test.yaml), the CTR pensioner test including the Welsh mixed-age couple on Universal Credit, Winter Fuel Payment's two dated tests, the mixed-age couple on Universal Credit in pension_age_premiums.yaml, and six mixed-age Income Support cases (Cases 21-26 in state_pension_credit_qualifying_age.yaml: the 2017 cohort couple with and without a Pension Credit claim, a couple in 2026, a couple where only the older partner is a carer, and a pair showing that the Pension Credit bar applies to a couple whose income is too high for Pension Credit, where Income Support is nil anyway).

Tests run locally: on 43a52e25, all 2,245 YAML cases under policyengine_uk/tests/policy; on 94dad0c1, the same YAML (2,244) under policyengine_uk/tests/policy, and 1,984 pytest (one existing xfail) across the qualifying-age, State Pension age, severe disability premium and addition, pension-age HB, HB savings-credit-only, benefit cap and CTR, mixed-age couple, UC State Pension, means-test income and HB passport property files and the code-health tests. CI runs the full suite.

Microsimulation impact

Real Microsimulation runs on the Enhanced FRS 2024-25 (policyengine-uk-data 1.57.4, SHA-256 03fe15e4…68d4): main 2105816c against this branch at 43a52e25. 94dad0c1, and earlier heads against main 6ae9c5ee, gave identical totals. Changes, this branch minus main:

2025-26 2026-27 2027-28 2028-29
National Insurance (£m) +35.4 +4.4 +5.2 +1.3
Household net income (£m) −35.4 −4.4 −5.2 −1.3
Households with lower net income (thousands) 11.4 3.9 4.2 3.8
  • No household gains. Income tax, Universal Credit, Housing Benefit, Council Tax Reduction, Pension Credit, Income Support, Winter Fuel Payment and poverty do not change in any of these years.
  • The National Insurance change is Class 4: people who reach State Pension age between 6 April and 6 October now pay for that year. It is smaller from 2026-27. From then State Pension age rises from 66 to 67, one month per month of birth for people born from 6 April 1960 (Pensions Act 2014 s.26), so fewer people reach it in any one year.
  • The qualifying-age change touches only 2018-19 and earlier. This run uses the Enhanced FRS 2024-25, and a simulation extends a dataset forward from its year, not back, so those years cannot be run from it.

Review

vahid-ahmadi's review of 1 October:

  1. Set State Pension age from date of birth, including the rise to 67 #1899 first. Set State Pension age from date of birth, including the rise to 67 #1899 has merged and this branch merges main after it; Set State Pension age from date of birth, including the rise to 67 #1899's state-pension-age-67-phase-in* changelog fragments are no longer in this PR's diff.
  2. Semantic merge with Date the mixed-age couple Pension Credit exclusion and model the SI 2019/37 saving #1940 and Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944. The qualifying-age test is now in meets_pension_credit_age_conditions, is_mixed_age_couple, housing_benefit_pension_age_regulations_apply and council_tax_reduction_pensioner, and both age checks in the SI 2019/37 saving inference. Main's claimant and partner roles, the saving, and Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944's Universal Credit and legacy-benefit exclusions are kept. The HB and CTR means tests now read those switches too (table above), and the consumer property tests pass.
  3. 6 April boundary. Documented in ni_class_4_liable and the State Pension docs (see Class 4 above).
  4. Survey-record counts. The description no longer gives any.

An independent review of 490614677 (Subfleet, GPT-6.1 Sol) found the law-to-code mapping, the semantic merges and every impact figure correct, and asked for three changes: Income Support's age test applied to the whole family rather than the claimant (fixed in a4b9f73a, with the s.124(1)(g) Pension Credit bar and three YAML cases); the description's claim about the earliest dataset (narrowed above); and two wordings (the change in who has attained the qualifying age, and what the cohort property samples), both fixed. Its review of a4b9f73a found that the age and carer conditions could be met by different members of a couple; 32a6c175 requires the same claimant to meet both (Cases 24-26). 94dad0c1 merges main after #1945 (HB(SPC) reg 27, savings credit only): its rule is kept next to this branch's Guarantee Credit passport routing and applies only where the pension-age regulations do. The review of 94dad0c1 found the tariff income part of that rule (reg 27(5)) still ungated after the automatic merge; 43a52e25 gates it, with a routing case that fails without the gate.

Earlier rounds: three independent Opus 5.5 reviews (Subfleet) approved aa45dd76, b9d8573d and cae31319/09ec4bf0; their findings were addressed in those commits.

Caveats and follow-ups

  • Pension-age personal allowances. The pension-age HB and CTR tables split at 65 until 2016 (e.g. HB (SPC) Regs Sch 3 para 1 in 2016: £155.60 under 65, £168.70 at 65 or over) and now split by whether pensionable age was reached before 1 April 2021. The model has one aged rate (£181 a week for 2015-16 to 2020-21). Not changed here.
  • Mixed-age couples before 15 May 2019. The SI 2019/37 saving infers past entitlement and continuity from current reports and a birth-year cutoff, and the model handles the May 2019 transition on annual periods. Kept from main.
  • Tax credit migrants. The HB regulations switch counts a Universal Credit award only where a claimant or partner is under the qualifying age, as main does. Tax credit migrants who can hold an award after both reach it (SI 2014/1230 reg 60A) are not modelled; modelling them would need HB reg 5 and the benefit-cap exemption (reg 60C) to be treated separately.
  • Welsh CTR for Universal Credit claimants. WSI 2013/3029 Sch 6 paras 3 and 9 prescribe a separate applicable amount and income calculation for Universal Credit claimants, which the model does not implement; the Welsh mixed-age test asserts the non-pensioner status and the shared working-age allowance only.
  • HB income of dependants. HB applicable income still includes programme-defined children's and young persons' own income, which HB Regs 2006 reg 25(3) excludes. Not changed here.

Axiom parity

axiom: uk/statute/ukpga/2002/16/1 encoded-correct (uk/statutes/ukpga/2002/16/1.test.yaml case man_uses_woman_same_birthday_age: a man's qualifying age is a woman's pensionable age for the same birthday)
axiom: uk/statute/ukpga/2012/5/4 encoded-correct (uk/statutes/ukpga/2012/5/4.test.yaml case person_does_not_meet_basic_conditions_after_reaching_state_pension_credit_qualifying_age_without_exception; the qualifying age is a leaf input)
axiom: uk/statute/ukpga/1995/26/schedule/4/paragraph/1 TheAxiomFoundation/rulespec-uk#369 queued (computing pensionable age, and so the qualifying age, from date of birth)
axiom: uk/regulation/uksi/2006/213/5 TheAxiomFoundation/rulespec-uk#370 queued (which Housing Benefit regulations apply, and new claims)
axiom: uk/regulation/uksi/2001/1004/91 TheAxiomFoundation/rulespec-uk#373 queued

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits September 30, 2026 06:39
… for Class 4

State Pension Credit Act 2002 s.1(6) sets the qualifying age as a woman's
pensionable age, and for a man that of a woman born on the same day. Pension
Credit, Universal Credit (WRA 2012 s.4(1)(b), (4)), Housing Benefit (reg 5 of
SI 2006/213 and 2006/214; SI 2014/1230 reg 6A(4)), Council Tax Reduction
pension-age schemes, Income Support (SSCBA 1992 s.124(1)(aa)), the benefit
cap's pensioner exception and Winter Fuel Payment (SI 2000/729 reg 2(1)(b))
now use it instead of the person's own pensionable age. They differ only for
men born before 6 December 1953, so only in 2018-19 and earlier.

Class 4 NI (SI 2001/1004 reg 91(a)) now excepts only people over State
Pension age at the beginning of the tax year (6 April), not on 6 October.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits September 30, 2026 08:21
…more tests

- is_benefit_cap_exempt_other: say the cap has no age exception and that
  exempting any unit with a member over the qualifying age misses Universal
  Credit mixed-age couples (UC Regs 2013 reg 3(2)(a)); behaviour unchanged.
- council_tax_reduction_household_has_pensioner: note the unmodelled
  "not on UC, IS, JSA(IB) or ESA(IR)" limb of SI 2012/2885 reg 3(1)(a)(ii).
- is_pension_credit_eligible and YAML case 13: s.4(1A) is in force from 15 May
  2019 (SI 2019/37 art. 3); the model applies it in every year.
- ni_class_4_liable: label the 6 April reading as an interpretation; name the
  six-month offset MONTHS_FROM_TAX_YEAR_START_TO_MID_YEAR (also used by the
  Savings Credit age test).
- Changelog and docs: describe the benefit cap as reaching only working-age
  HB and UC, and point the qualifying-age entry to the Class 4 entry.
- Tests: YAML cases 14-20 pin the HB and CTR applicable amounts, HB tariff
  income and capital, the guarantee credit route and Pension Credit capital
  (4 of the 7 fail on the parent commit; 3 are controls). A property test
  now samples only the cohort where the two ages differ (men born 6 April
  1950 to 6 December 1953, 2015-16 to 2018-19) and also checks the
  pension-age CTR allowance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Class 4 "stops from the first tax year that begins on or after the day State
Pension age is reached", matching the 6 April reading. The cohort property
test samples births up to 5 December 1953, the last day rule (1) covers.

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

Copy link
Copy Markdown
Collaborator Author

Overlap with #1940 (mixed-age couples, SI 2019/37). #1940 routes is_pension_credit_eligible, new-claim housing_benefit_eligible and is_uc_eligible through one variable, meets_pension_credit_age_conditions. It also dates this PR's 'the model applies s.4(1A) in every year' exclusion from 15 May 2019, with the art. 4 saving. Whichever merges second should read has_attained_state_pension_credit_qualifying_age in is_mixed_age_couple and meets_pension_credit_age_conditions in place of is_SP_age, and drop the local all-adults test in the three eligibility files in favour of the shared variable.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Coordination with #1944 (mixed-age couples on UC: benefit cap and CTR pensioner status). #1944 rewrites the two is_SP_age lines this PR changes:

  • is_benefit_cap_exempt_other now reads a new housing_benefit_pension_age_regulations_apply (HB Regs 2006 reg 5).
  • council_tax_reduction_household_has_pensioner now reads a new council_tax_reduction_pensioner (SI 2012/2885 reg 3). It includes the UC and legacy-benefit condition that this PR's comment calls "not modelled".

Whichever lands second should:

  1. Move the qualifying-age switch into those two new variables. Both use is_SP_age on is_uc_claimant members, for the attained test and for the working-age-claimant test on the UC award. Keep is_uc_claimant.
  2. Drop this PR's "not modelled" comment.

A review agent merged the two branches in a scratch clone and took #1944's side of the two conflicting files. #1907's consumer assertion then failed for men born 1951-53 in 2017, because the new variables still read is_SP_age. Step 1 is needed, not just a clean textual merge.

🤖 Generated with Claude Code

MaxGhenis and others added 3 commits September 30, 2026 22:47
#1895 described ni_liable as covering primary Class 1, Class 2 and Class 4.
Class 4 now uses ni_class_4_liable (status at 6 April, SI 2001/1004 reg
91(a)), so ni_liable covers primary Class 1 and Class 2 only. The National
Insurance docs page states the Class 4 age rule.

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

Copy link
Copy Markdown
Collaborator

Reviewed: not ready.

The law is right. SPCA 2002 s.1(6) gives men born before 6 December 1953 a qualifying age earlier than their own pensionable age. Reg 91(a) makes Class 4 depend on status at 6 April, and months_since_state_pension_age >= 6 encodes exactly that.

  1. Blocking: this depends on Set State Pension age from date of birth, including the rise to 67 #1899. Rebase after Set State Pension age from date of birth, including the rise to 67 #1899 merges: the branch lacks Set State Pension age from date of birth, including the rise to 67 #1899's latest main merge, and it carries Set State Pension age from date of birth, including the rise to 67 #1899's three state-pension-age-67-phase-in.* changelog fragments.
  2. Blocking: as your own comments say, Date the mixed-age couple Pension Credit exclusion and model the SI 2019/37 saving #1940 and Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944 need a semantic merge, not just a textual one. Agree the order first. Then move the qualifying-age test into meets_pension_credit_age_conditions, is_mixed_age_couple, housing_benefit_pension_age_regulations_apply and council_tax_reduction_pensioner, and rerun the consumer property test.
  3. Nit: ni_class_4_liable.py:33: treating someone who reaches State Pension age on 6 April as excepted is defensible. But in a household simulation, anyone exactly at State Pension age (66 in 2020-21 to 2025-26, 67 from 2028-29) has a 6 April birthday, so this reading decides every such result. State it in the docs.
  4. Nit: consider dropping the unweighted survey-record counts from the Class 4 table in the description.

Verified: I read SPCA s.1(6), SI 2001/1004 reg 91, SSCBA s.17(2)(b) and NIM24510. SSCBA Sch 2 para 6 is about interest; the age exception is reg 91(a). I checked Class 4 case 1 by hand: (30,000 − 12,570) × 6% = £1,045.80. The new and #1899 YAML tests passed (69/69). The new Python tests and test_state_pension_age.py passed (67/67). Zero effect from the qualifying-age change in the data is expected, because it only changes years up to 2018-19. CI is green.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Composition note: #2015 (stacked on #2009 → #2006) deletes council_tax_reduction_household_has_pensioner in favour of a per-family council_tax_reduction_pensioner (BenUnit). Whichever lands second should move this PR's has_attained_state_pension_credit_qualifying_age test into council_tax_reduction_pensioner.py.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Coordination with #2076, stacked on #2027.

#2076 removes the unused benefit sums from is_benefit_cap_exempt_other.py and is_benefit_cap_exempt_earnings.py. It also moves the afcs and ESA terms out of is_benefit_cap_exempt_other into is_benefit_cap_exempt_health_disability, limited to the claimant and partner. Before, any member's AFCS or contributory ESA lifted the cap.

Whichever lands second: keep this PR's age or earnings test, and drop the afcs and esa_support_component terms and the dead QUAL_* lists from _other and _earnings.

MaxGhenis and others added 8 commits October 3, 2026 08:49
Preserve claimant and partner routing, mixed-age couple savings, and shared Housing Benefit and Council Tax Reduction switches while using the State Pension Credit qualifying age.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Retain the shared timetable refactor with upstream month arithmetic, fractional age precedence, birthday defaults, and unchanged dependency tests. Dependency changelog fragments remain identical to the dependency head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Make Winter Fuel Payment follow qualifying age before September 2024 and pensionable age afterwards, including reforms that separate those ages. Assert the historical couple is not mixed-age and reuse the loaded country model in qualifying-age properties without changing expectations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preserve all assertions, strategies and example counts while suppressing the slow-generation health check already handled by the State Pension age dependency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use the shared Housing Benefit regime for applicable allowances, tariff, guarantee-credit passports and capital-limit selection, and the per-family CTR pensioner predicate for applicable allowances. Preserve rates and claimant/partner structure, add focused historical and component regressions, and clarify public metadata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep legacy income and capital passports from main alongside the pension-regime guarantee-credit condition, and correct the independent carer overlap reference at the strict 6 April 2016 State Pension cutoff.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Retain main earnings disregards and module-release follow-up alongside the qualifying-age changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Incorporate the dependency clean merge of main without rewriting the existing qualifying-age commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits October 4, 2026 07:14
Welsh regulation 3 excludes UC recipients from pensioner status. Assert the corrected shared-model allowance explicitly and retain the documented, separate UC-specific calculation gap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One textual conflict, in the National Insurance notebook: main's Class 4
profits and losses text (#1919) is kept, followed by this branch's
sentence on Class 4 liability ending at State Pension age.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's #1938 picked the pension-age premium schedule for HB, CTR and
Income Support when any member was over State Pension age, while this
branch moves the HB and CTR allowances to their own statutory tests
(HB(SPC) Regs reg 5; the CTR pensioner tests). A mixed-age couple on
Universal Credit then got the working-age allowance with pension-age
premiums. Each programme now chooses the schedule with the test that
chooses its allowance; Income Support, whose Schedule 2 is a
working-age schedule, uses the working-age premiums; and the
pension-age severe disability premium follows the qualifying age of a
claimant or partner.

Also folds the build's changelog fragments into this PR's own.

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

Copy link
Copy Markdown
Collaborator Author

@vahid-ahmadi, thanks. All four items are addressed at 49061467:

  1. Set State Pension age from date of birth, including the rise to 67 #1899 first. Set State Pension age from date of birth, including the rise to 67 #1899 has merged, and this branch merges main after it, so Set State Pension age from date of birth, including the rise to 67 #1899's state-pension-age-67-phase-in* fragments are no longer in this PR's diff.
  2. Semantic merge with Date the mixed-age couple Pension Credit exclusion and model the SI 2019/37 saving #1940 and Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944. The qualifying-age test is now inside meets_pension_credit_age_conditions, is_mixed_age_couple, housing_benefit_pension_age_regulations_apply, council_tax_reduction_pensioner and both age checks in the SI 2019/37 saving inference. Main's claimant and partner roles, the saving, and Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944's Universal Credit and legacy-benefit exclusions are kept. The HB and CTR means tests (allowances, tariff income, capital limit, Guarantee Credit passports, premium schedules) now read those switches too. The consumer property tests pass.
  3. 6 April. ni_class_4_liable's documentation and the State Pension docs now say that a whole-number household age implies a 6 April birthday, so this reading decides every such case.
  4. Survey-record counts. Removed. The description's impact table is a fresh run against current main.

Merging current main also exposed one interaction with #1938. Its premium switch (any member over State Pension age) disagreed with the HB and CTR allowance switches, so a mixed-age couple on Universal Credit got working-age CTR allowances with pension-age premiums. Each programme now picks its premium schedule with its own regulations' test (490614677), and a new YAML case pins that couple. Details are in the updated description.

🤖 Generated with Claude Code

MaxGhenis and others added 4 commits October 4, 2026 08:16
SSCBA 1992 s.124(1)(aa) requires that the claimant has not attained the
qualifying age for State Pension Credit, and either member of a couple
can claim, so a mixed-age couple can claim through the younger partner.
The test barred the family if any member had attained the qualifying
age. s.124(1)(g) separately bars Income Support where the other member
is entitled to State Pension Credit; reading the Pension Credit amount
would be circular, so the couple is taken to be on it where it meets
the Pension Credit age conditions and would claim it.

Adds three YAML cases: the 2017 cohort couple with and without a
Pension Credit claim, and a mixed-age couple in 2026.

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

The age test and the carer test could be met by different members of a
couple: the younger partner under the qualifying age and the older one a
carer. SSCBA 1992 s.124(1)(aa) and (e) and IS Regs 1987 Sch 1B require
the same claimant to meet both, so the formula now finds a claimant or
partner who is under the qualifying age and a carer (or the lone parent
of a young child). Carers who are neither claimant nor partner no longer
count.

Adds Case 24 (only the older partner is a carer: ineligible) and Cases
25-26, which show the Pension Credit proxy barring Income Support for a
couple whose income is too high for Pension Credit, and that Income
Support is nil for that couple anyway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's #1945 adds HB(SPC) Regs reg 27 (savings-credit-only awards) next
to the Guarantee Credit passport in housing_benefit_applicable_income
and housing_benefit_assessable_capital. Both files keep #1945's reg 27
branch and this branch's routing of the passport through the HB
regulations switch; reg 27 also applies only where the pension-age
regulations do.

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

HB(SPC) Regs 2006 reg 27(5) lifts the tariff income rule for a
savings-credit-only award, within the pension-age regulations. The main
merge gated #1945's income and capital branches on
housing_benefit_pension_age_regulations_apply, but the tariff branch
merged automatically without it. Adds a component routing case that
fails without the gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 4, 2026 13:03
@MaxGhenis
MaxGhenis merged commit e0da550 into main Oct 4, 2026
7 checks passed
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Merged under decision d751 (merge after #1899 once CI is green on the head, an independent review approves it and the impact is stated) and Max's PE-UK merge-on-gates rule.

@MaxGhenis
MaxGhenis deleted the spc-qualifying-age-class-4-spa branch October 4, 2026 13:39
MaxGhenis added a commit that referenced this pull request Oct 4, 2026
One conflict, in income_support_eligible.py. Main's #1907 rewrote the
Income Support conditions: the carer limb now needs a claimant or partner
who is under the qualifying age for State Pension Credit and a carer
(SSCBA 1992 s.124(1)(aa) and (e), IS Regs 1987 Sch 1B para 4). That
already contains this branch's rule (a claimant or partner carer, not any
member), so the formula and its comments are main's. The reference tuple
is the union of both sides: Sch 1B, reg 4ZA, s.124 and Claims and
Payments Regs 1987 reg 4.

Main also brought in a fix for the read-only cache test fixture with
policyengine-core 3.32.16 (#2125), which failed this branch's last CI run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 4, 2026
After merging main, income_support_eligible's formula is main's (#1907),
which already opens the carer route only through a claimant or partner,
who must also be under the qualifying age for State Pension Credit. Main's
changelog records that, so this branch no longer claims it. The branch
keeps its Income Support route tests and two extra references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 4, 2026
Main (#1907) split Class 4 out of ni_liable into ni_class_4_liable:
Class 4 is due for the whole tax year from anyone not over State
Pension age on 6 April (SI 2001/1004 reg. 91(a)). The floor's notional
NI still multiplied Class 4 by ni_liable, so a claimant who reaches
State Pension age between 7 April and 6 October paid Class 4 on their
actual profits but had none deducted from the threshold. In 2026 that
is everyone aged 66 with the default birthday: notional NI 0 against
633.73, a floor 633.73 too high.

Class 1 and Class 2 keep ni_liable; Class 4 uses ni_class_4_liable,
matching the model's actual contributions. An exhaustive check over
ages 16-80, birthday months 0-11, 2020, 2026 and 2027 and both NI bases
finds no difference from ni_class_2 + ni_class_4 or ni_class_1_employee
on the threshold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 4, 2026
is_uc_eligible tests has_attained_state_pension_credit_qualifying_age since
#1907, not State Pension age.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 4, 2026
Main (255 commits) moved State Pension age into utils/state_pension_age
and added the State Pension Credit qualifying age (#1907), each deriving
the birth from age and months_since_last_birthday. Resolved so every
date-of-birth rule shares utils.dates.birth_instant (date_of_birth where
given, 0 = not given, invalid input rejected):
- state_pension_age and state_pension_credit_qualifying_age take the
  instant from birth_instant;
- months_since_attaining now takes the birth instant and year, and
  months_since_state_pension_age and
  has_attained_state_pension_credit_qualifying_age pass it;
- meets_savings_credit_age_requirement's "attained 65" uses it too;
- utils.state_pension_age.date_of_birth reuses birth_instant_from_age;
- the mixed-age saving keeps main's SPC qualifying age condition with
  this branch's 5 February 1954 date cutoff.
Without a date_of_birth input every result is main's. Also narrows the
UC born_before reference title (Sol review nit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 5, 2026
Brings in #1896, #2001 and #1907 among others. Two conflicts:

- income_support_eligible.py: keeps this branch's rule (the award holder
  is the claimant or partner who reports Income Support, and must be in a
  covered prescribed category, under the qualifying age and without
  contributory ESA; income-related ESA read for the claimant and partner
  only; capital test unchanged). Takes main's age test
  (has_attained_state_pension_credit_qualifying_age instead of is_SP_age)
  and main's s.124(1)(g) bar (meets_pension_credit_age_conditions and
  would_claim_pc), with its comment, and says so in the documentation.
- income_support_carer_route.yaml: keeps main's para 4(a)/(b) header and
  its new para 4(a) case, and this branch's award-holder wording and the
  partner case with the award on the caring partner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 5, 2026
Brings in #2009, #2006, #1944, #1907, #2033 and the rest of main since
4b84ea0. Each claim's scheme and non-dependant exemption still follow its
own family's council_tax_reduction_pensioner and
council_tax_reduction_applicant_has_non_dep_exemption, read on
is_council_tax_reduction_applicant_or_partner, for every claim.

- council_tax_reduction_pensioner: keeps #1944's reg 3 test (#1907's
  qualifying age, the IS/JSA/ESA and Universal Credit conditions) on this
  PR's applicant-and-partner members.
- #2006's joint-claims-only machinery is replaced by the per-family rule it
  anticipated: council_tax_reduction_claim_pensioner,
  council_tax_reduction_claim_scheme_supported and
  _legacy.single_claim_is_pensioner are removed, and nothing reads
  council_tax_reduction_claims_are_joint for a scheme or an exemption.
  council_tax_benefit keeps this PR's reconciliation.
- council_tax_reduction_household_has_pensioner is deleted again.
- simulated_council_tax_reduction_benunit keeps main's
  council_tax_reduction_assessable_capital.
- Tests on main that read the deleted flags now read the per-family ones:
  council_tax_reduction_pensioner.yaml, joint_liability.yaml,
  state_pension_credit_qualifying_age.yaml and four property tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use the State Pension Credit qualifying age, and Class 4 status at the start of the tax year

2 participants