Repository navigation
Read the State Pension Credit qualifying age for UC's no work-related requirements group (reg 89(1)(a)) - #2160
Merged
Merged
Conversation
UC Regs 2013 reg 89(1)(a) puts a claimant who "has reached the qualifying age for state pension credit" in WRA 2012 s.19 (no work-related requirements). That is SPCA 2002 s.1(6), the meaning the phrase has in WRA 2012 s.4(4), carried into the regulations by Interpretation Act 1978 s.11. uc_work_related_group_apart_from_earnings read is_SP_age; it now reads has_attained_state_pension_credit_qualifying_age (#1907). The two differ only for men born before 6 December 1953, in 2018-19 and earlier. Adds 6 YAML cases from Pensions Act 1995 Sch 4 para 1 (as at 6 October 2016), a statute differential over a birth grid against test_state_pension_age.reference_attainment_day, a check that the routes differ only before 2019-20, and a Hypothesis differential against the State Pension age route. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 6, 2026
A man born on 6 November 1953 reaches the qualifying age on his 65th birthday, so the comments now say "before, or on the same day if born on 6 November 1953". Women born before 6 April 1950 reach pensionable age at 60 (Pensions Act 1995 Sch. 4 para. 1 rule (2)), so the YAML comment no longer says every man takes the table 1 day. Comments only: both Python files are AST-equal to the previous head and the YAML parses identically. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 6, 2026
#2160 reads the State Pension Credit qualifying age for UC reg 89(1)(a) in uc_work_related_group_apart_from_earnings and extends test_uc_work_related_groups_properties.py. No conflicts; it touches none of this PR's files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2161
Follow-up to #2081 and #1907.
Summary
UC Regs 2013 reg 89(1)(a) puts a claimant in the group with no work-related requirements (Welfare Reform Act 2012 s.19) if "the claimant has reached the qualifying age for state pension credit". #2081 encoded that route with
is_SP_ageuntil #1907 added the qualifying age. This PR switches it tohas_attained_state_pension_credit_qualifying_age.uc_work_related_group_apart_from_earnings, plus a reference to SPCA 2002 s.1(6). No other UC rule readis_SP_agefor this test.Tests
YAML, in
uc_work_related_group_apart_from_earnings.yaml(6 new cases). Each case is a couple with a partner aged 40 (41 in case 3, a year on). Every expected day comes from Pensions Act 1995 Sch 4 para 1 as it stood on 6 October 2016, read on legislation.gov.uk:uc_mif_appliesis false (was true)On the base commit (
3b7c1f9fe, main after #2081 and #1907), the new YAML file fails exactly cases 1, 3 and 6, each onuc_work_related_group_apart_from_earnings(ALL_REQUIREMENTSwhere the statute givesNO_REQUIREMENTS). Cases 2, 4 and 5 pass on both commits. A direct run of case 6 on the base givesuc_mif_applies[true, false], so "was true" holds: 3 failed, 28 passed on the base, 31 passed on this branch.Property and statute tests, added to
test_uc_work_related_groups_properties.py(invariant 8):test_state_pension_age.reference_attainment_day, which shares no code with the model. The partner stays in s.22.is_SP_ageas the qualifying-age status: only claimants past the qualifying age and under State Pension age change group, all into s.19. A fixed example (case 1's man) makes every run exercise the change.Run locally:
All on
00536b934, one at a time (the head before the review's comment fixes; see below for84a1a1ce3):uv run --frozen --extra dev policyengine-core test policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit -c policyengine_uk: 376 passed (uc_work_related_group_apart_from_earnings.yaml: 31).uv run --frozen --extra dev pytest -q -p no:cacheprovider policyengine_uk/tests/test_uc_work_related_groups_properties.py: 14 passed (the 7 existing tests, plus 5 years of the statute differential, the before-2019 check and the Hypothesis differential), 2,035 s. The host was heavily loaded, and this file, unlike the repo's other property files, builds a new model for everySimulation. So the run added an out-of-tree pytest plugin that applies the repo's owncloned_uk_tax_benefit_systemconftest fixture to every test. Nothing in the repo changed. CI runs the file as committed.uv run --frozen --extra dev ruff format --check policyengine_uk: 1,264 files already formatted.84a1a1ce3changes comments only, from the review's nits. Both changed Python files have an AST identical to00536b934's (ast.dump), and the YAML file parses to the same 31 cases. On84a1a1ce3,policyengine-core teston the WRR YAML file: 31 passed;ruff format --check policyengine_uk: 1,264 files already formatted.Microsimulation impact
Real
Microsimulationruns on the Enhanced FRS 2024-25 (private copy, SHA-256e433e532b17bd8ce…), one at a time: base3b7c1f9fe9aa0db7809c6b9ba1ed3b26d905e6da(main after #2081 and #1907) against this branch at00536b934e8e2f25aeffcf994fef0ee404eaa9ac, both with a clean tree, for 2025-26 to 2030-31. Each run saves 17 arrays a year: per person, the weight, id,is_SP_age,has_attained_state_pension_credit_qualifying_age, the work-related group,uc_mif_applies,uc_minimum_income_floor_gross,uc_individual_earned_incomeand the BHC and AHC poverty flags; per benefit unit, the weight, id,universal_credit,universal_credit_pre_benefit_capanduc_earned_income; per household,household_net_incomeand the weight. The comparison is exact (no tolerance).The runs used
00536b934. Head84a1a1ce3changes only comments (AST-identical code), so the result holds for it unchanged.Exactly zero. No array differs in any year, and no person in the data has qualifying-age status different from State Pension age status. That follows from the years: the simulated years are 2025-26 onward, and the two statuses have agreed for everyone since 2019-20 (men born 5 December 1953, the last cohort with a male pensionable age of 65, turned 65 on 5 December 2018). The change matters for 2018-19 and earlier, which the YAML and property tests cover.
Invariants
Caveats
git grep -n is_SP_age -- policyengine_uk/variables/gov/dwp policyengine_uk/utilson this head findsadditional_state_pensionandstate_pension_type(the State Pension itself, where pensionable age is the right test),winter_fuel_allowance(reads the qualifying age before 2024-25 andis_SP_agefrom 2024-25, where its comment cites SI 2024/869's "has reached pensionable age") and comments inutils. No rule whose law says "qualifying age for state pension credit" still readsis_SP_age. The benefit-cap readers (is_benefit_cap_exempt_health_disability,is_benefit_cap_exempt_earnings) no longer readis_SP_ageorhas_pensioner. Readers outsidegov/dwpandutils(National Insurance, HBAI, the Scottish Pension Age Winter Heating Payment, a contrib basic income) were not checked against their law here.has_attained_state_pension_credit_qualifying_age(from Use the State Pension Credit qualifying age, and start-of-year status for Class 4 NI #1907) says men born before 6 December 1953 "reach it before" their State Pension age; for a birth on 6 November 1953 the two days coincide. The formula is unaffected. Tracked in Follow-ups from #2160: qualifying-age docstring, UC work-related groups property-file speed, changelog fragment example #2162.test_uc_work_related_groups_properties.pydoes not usepytestmark = pytest.mark.usefixtures("cloned_uk_tax_benefit_system"), which the repo's other property files use, so it loads the model again for everySimulation. Tracked in Follow-ups from #2160: qualifying-age docstring, UC work-related groups property-file speed, changelog fragment example #2162.Axiom parity
On rulespec-uk
main(ac0a151),uk/regulations/uksi/2013/376/89.yamldoes not exist, so reg 89 stays queued in #396. That issue already carries reg 89's module, law, outputs and tests (from #2081). The comment for this PR adds the qualifying-age companion cases and thereview_findingsentence for (1)(a). SPCA 2002 s.1 is encoded and its man/woman-same-birthday case passes. Computing the qualifying age from a date of birth needs Pensions Act 1995 Sch 4 para 1, which is queued in #369.Review
00536b934(Subfleet20261006-001159-uc-wrr-spcqa-review, GPT-6.1 Sol, task review): APPROVE, nothing blocking or should-fix. It re-derived the six cases from Sch 4's 2016 text, confirmed the law chain, the non-vacuity of invariant 8 (165, 116, 61, 6 and 0 men moved in 2015-16 to 2019-20 on the grid), the byte-identical impact archives and the Axiom comments. Its five nits, and what was done about them:84a1a1ce3).Fixes #2161added.-on the changelog fragment: not taken. Towncrier adds the bullet, and fragments that start with-render as- -inCHANGELOG.md(2.122.2, 2.121.0). This fragment matches Apply the UC minimum income floor only to claimants subject to all work-related requirements #2081's.84a1a1ce3(Subfleet20261006-022129-uc-wrr-spcqa-delta, Opus 5.5 on claude-9, task review): APPROVE, nothing blocking or should-fix. It confirmed the delta is comments only (AST, comment-stripped token stream and parsed YAML all equal) and checked the new comments against Sch 4's 2016 XML. Across every birth from 1 January 1880 to 5 December 1953, a man's qualifying day is never after his 65th birthday and falls on it only for 6 November 1953. It also agreed with declining the changelog nit, and re-ran the WRR YAML file (31 passed) and the format check. Its three nits: test 2's year range (fixed above in Locality), and two follow-ups outside this PR (the Use the State Pension Credit qualifying age, and start-of-year status for Class 4 NI #1907 docstring and the changelog example indocs/engineering/skills/github-prs.md), filed with the test-speed item as Follow-ups from #2160: qualifying-age docstring, UC work-related groups property-file speed, changelog fragment example #2162.🤖 Generated with Claude Code