Repository navigation
Expand Savings Credit gate regression coverage and metadata - #2519
Conversation
Aggregate impact on certified data: passBase Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 0 (thresholds in Notes
Moves flagged for reviewNone. Spending by benefit and service
Caseloads
Household net income by decileNo household's net income changes in any year. No change in any year: receipts by tax head; government balance, each component counted once; model totals; components the model counts twice; household income totals; population; poverty rates; people in poverty; inequality; mean household net income in each side's own deciles; standard reform costings (change in gov_balance); standard reforms: change in each reform's target. Checks failing on both base and head (1)
Counted-once checkEach of 84 components was raised by £1 per unit in 2026-27, and every head of its totals was read household by household: its own head must rise by exactly £1, no other tax head may move, no other benefit may rise, and the model's own total must move by what its heads moved. A head that breaks a rule is measured again twice: with every other head held at its baseline value, and with every other head held at its value after the first £1 while the component rises again. It fails where either still shows the response. 0 failed; 0 were skipped.
Provenance
Dataset: Receipts by tax head: head levels
Spending by benefit and service: head levels
Caseloads: head levels
Government balance, each component counted once: head levels
Model totals: head levels
Components the model counts twice: head levels
Household income totals: head levels
Population: head levels
Poverty rates: head levels
People in poverty: head levels
Inequality: head levels
Mean household net income in each side's own deciles: head levels
Standard reform costings (change in gov_balance): head levels
Standard reforms: change in each reform's target: head levels
|
vahid-ahmadi
left a comment
There was a problem hiding this comment.
@juaristi22 first-round review of #2519 at 02076029, checked against #2458 (merged 19 Oct). One should, three nits. The test and metadata changes themselves look right; the should is about the PR body.
What I checked
- The formula,
defined_for = "is_pension_credit_eligible"gate and parameters are untouched; onlyreferenceanddocumentationchange insavings_credit.py. That matches the follow-up scope #2458 left. - New references: SPCA 2002 s.1, s.3 and s.4 resolve, and s.4(1A) is the mixed-age exclusion (in force 15 May 2019 via SI 2019/37 art.3). SI 2019/37 art.4 is the saving that disapplies s.4(1A) for a member entitled to SPC or HB as part of the couple on the day before, ending when they are entitled to neither. That fits the fixture's use of
has_mixed_age_couple_pension_credit_savingas an input contract. - YAML hand calculation (
savings_credit.yaml:30-67): DWP's 2026/27 rates give a couple standard minimum guarantee of £363.25 and a couple Savings Credit threshold of £329.75 a week, matching the repo parameters. With income £18,766: Amount A = min(0.6 × (18,889 - 17,147), 0.6 × (18,766 - 17,147)) = min(1,045.20, 971.40) = 971.40; no Amount B reduction because income is below the guarantee; GC = 123; total 1,094.40. All correct. test_savings_credit_eligibility.py: 6 passed. Pension Credit YAML directory: 219 passed. CI is green at head. The negative control fails as intended against the ungated formula, so the invariant can detect a lost gate.
Findings
-
should PR body,
axiom: needed. The PR template (.github/PULL_REQUEST_TEMPLATE.md:16) keepsneededfor external contributors who cannot do the Axiom work, so a maintainer PR should use one of the standard options. This PR changes no formula, gate or parameter, soaxiom: n/a: tests and documentation metadata only; the #2121 gate change and its Axiom follow-up are in #2458fits. If you think #2121 needs its own rulespec-uk issue rather than rulespec-uk#359 (which is about SPCA ss.4, 5 and 17, and is still open), open one and record it on #2458 or #2121. Either way, this PR's line should not beneeded. -
nit
savings_credit.yaml:32-33. The comment writes the tax as(20,000-12,570-1,260)*0.2. Marriage Allowance is a tax reducer of 20% of the transferred £1,260 (ITA 2007 s.55B(1)), not a deduction from taxable income. The number is the same, but(20,000-12,570)*0.2 - 0.2*1,260 = 1,234describes the mechanism correctly. -
nit
test_savings_credit_eligibility.py:281.test_savings_credit_generated_invariantstakes about 49 s locally (25 examples, up to 6 units each, two simulations per example). Fine to keep, butmax_examples=10ormax_size=4would cut that a lot without losing the four explicit examples. -
nit Merge order with #2092. That PR also edits
savings_credit.yaml, andgit merge-treereports a content conflict there. Whichever lands second needs a simple resolution. No conflict with #2363 or #2507.
🤖 Generated with Claude Code
|
Fixed item 1: the body now uses Nits 2 and 3 remain unchanged; the whichever-lands-second integration check with #2092 also remains open. All required and applicable checks pass, including Fix evidence run after the body edit. |
|
Merged by the UK hub (session local_8e19f9d5, Opus 5.5) on Max's explicit instruction to merge the team's ready PRs before the Budget (21 October, about 23:00Z: "go ahead and merge them. none of us has time to wait on each other"). One merge-queue enqueue, pinned to head
🤖 Generated with Claude Code |
Follow-up to #2458 for #2121.
savings_creditis the computed component before take-up is applied to total Pension Credit, and add specific references to its documentation metadata. Formula, eligibility gate and parameters are unchanged.Validation: 230 distinct local tests passed (11 Python and 219 Pension Credit YAML cases), with no skips. Towncrier discovered the fragment; format, lint and the trusted Fix-evidence check passed. The local evidence is bound to the reviewed commit and its base; hosted CI will test the PR’s combined state with current main. No private-data impact or fresh rate audit is claimed.
Reproducer: policyengine_uk/tests/test_savings_credit_eligibility.py::test_savings_credit_generated_invariants
axiom: n/a: tests and documentation metadata only; the #2121 production gate change is in #2458, whose Axiom-needed follow-up remains OPEN and unverified.
The original #2121/#2458 Axiom follow-up remains open, needed and unverified. The previously recorded TheAxiomFoundation/rulespec-uk#359 queue reference does not establish completed encoding or parity. This test and metadata follow-up does not close that obligation. No encoder ran.