Repository navigation
Gate Savings Credit on Pension Credit eligibility - #2458
Conversation
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Looks right, fine to approve. Note the knock-on for #2092.
@juaristi22, gating savings_credit with defined_for = "is_pension_credit_eligible" matches guarantee_credit and pension_credit_entitlement. It also follows SPCA 2002 s1, read with s3: Savings Credit is an element of Pension Credit, so it needs the same entitlement conditions. is_pension_credit_eligible reads is_savings_credit_eligible, not savings_credit, so there is no cycle.
- should,
policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/savings_credit/savings_credit.yaml: #2092 (open) adds three cases to this file. They setis_savings_credit_eligible: truebut noage, and expect a positivesavings_credit. After this PR those cases return 0. I ran #2092's Case 3 inputs on this branch and got 0 where #2092 expects 413.976. Git may merge the two cleanly, so this would only show up as a test failure. Whichever merges second needsage: 80on those cases, as you did for cases 1 and 2. A comment on #2092 would help its author.
What I checked
- Read the issue, the PR body and the full diff (including
test_savings_credit_eligibility.py), plusis_pension_credit_eligible,is_savings_credit_eligibleand the consumers (pension_credit_entitlement,in_receipt_of_savings_credit_only). - Worked the both-over-80 couple by hand: Savings Credit 0.6 x (18,000 - 329.75 x 52) = £511.80; Guarantee Credit 18,889 - 18,000 = £889; total £1,400.80. This matches.
- Ran
policyengine-core test policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit: 208 passed.pytest test_savings_credit_eligibility.py: 4 passed. With the formula file reverted: 3 failed, 1 passed. ruff checkandruff format --checkon both changed Python files: clean.- Hosted CI on 287cd8b is green.
- Process: the changelog fragment is
.fixed.md; the Reproducer and axiom lines are present; the Fix evidence check is green. - Not checked: the microsimulation check the issue asks for (that
pension_creditandpension_credit_entitlementtotals are unchanged). It needs the private data.
🤖 Generated with Claude Code
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Approving, per my review above. The shoulds and nits can follow.
|
UK hub: an independent review at Confirmed:
Nits:
The impact (none) and the 🤖 Generated with Claude Code |
|
UK hub audit (session local_8e19f9d5, Opus 5.5), for Max's d1728 (2026-10-19), under which the hub merges #2458, #2497 and #2147 on its gates, after correcting each body's
🤖 Generated with Claude Code |
Fixes #2121
Computed
savings_creditnow usesdefined_for = "is_pension_credit_eligible", matching Guarantee Credit and Pension Credit entitlement. The existing amount formula, local Savings Credit conditions, mixed-age savings and legacy migration helpers are unchanged. Explicit amount inputs retain their existing override behavior.A 2026 couple aged 80/60 with £20,000 State Pension and no protected claim history previously had £971.40 raw Savings Credit despite being ineligible for Pension Credit. The existing default marriage/Marriage Allowance assumptions give income tax £1,234, net income £18,766 and
0.6 × (18,766 − 329.75 × 52) = 971.40. The component is now 0; Pension Credit entitlement/payment and Housing Benefit were already 0 and remain so. Clearly eligible older-pensioner controls retain their independently calculated Pension Credit and Housing Benefit amounts.Reproducer: policyengine_uk/tests/test_savings_credit_eligibility.py::test_shared_gate_preserves_final_pension_credit_and_consumers
The entitlement basis is State Pension Credit Act 2002 s 1, read with s3 and s4. The conditional mixed-age saving in SI 2019/37 art 4 is preserved. This does not certify every 2016 Savings Credit continuity condition, inherited history proxy or Northern Ireland means-test detail; the positive controls avoid relying on protected mixed-age continuity.
Validation: 286 passed (4 new and 282 existing), covering Pension Credit age/eligibility/amounts, final Pension Credit/Housing Benefit/Council Tax Reduction invariance, childcare regressions, receipt/freeze/rate reforms and legacy routes. Both calculation orders and a direct Savings Credit input are covered. Two existing isolated formula tests gain age 80 as their Pension Credit eligibility precondition, with their numeric expectations unchanged.
make format, Ruff andgit diff --checkpassed. The initial RED exposed the gate and an old-amount oracle that omitted the default Marriage Allowance; corrected RED reproduced 3 gate failures/1 control pass on unchanged production.Local validation used Python 3.13.14/Core 3.32.27; the locked Core 3.33.2 environment and full hosted CI remain to be checked. No full-suite/docs/private population run or aggregate effect measurement was performed. Eligible and off-route synthetic final awards were checked; the issue's requested representative microsimulation invariance measurement remains unrun. Existing 2026 rates supplied the numeric regression premises; this PR does not update or freshly audit them.
Impact (UK hub, 2026-10-19): none.
e2ea32893with main merged with this head (ab4358193), on certified policyengine-uk-data 1.58.1, fiscal years 2025-26 to 2031-32.savings_credit(pension_credit_entitlement,in_receipt_of_savings_credit_only) already require Pension Credit eligibility. Only thesavings_creditcomponent itself changes, and it isn't a reported aggregate.axiom: TheAxiomFoundation/rulespec-uk#359 queued