Repository navigation
Apply the Carer Support Payment earnings limit - #2473
Conversation
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Fine once the clash with #2474 is settled.
@juaristi22, the law and the numbers check out. One process point and a few nits.
- should:
policyengine_uk/variables/gov/social_security_scotland/carer_support_payment_pre_overlap.py:50-57conflicts textually with #2474, which adds the CSP minimum-age condition to the sameeligibleexpression. I merged the two heads locally and git reports a content conflict in this file. Whichever lands second needs a rebase that keeps bothmeets_earningsandmeets_age_condition. A combined YAML case (for example a 15-year-old below the earnings limit, and a 16-year-old above it, both getting £0) would show both gates survive the merge. - nit: the same file computes the earnings test inline with a dtype cast and an
earnings_rounding_precisionparameter. Carer's Allowance does the same job inis_gainfully_employed_for_carers_allowance.pywithnp.floor(weekly * 100 + 1e-6) / 100 > limit. A matching boolean variable for CSP would keep the two tests symmetric and make the condition visible to downstream users. A penny is a unit, not a policy value, soearnings_rounding_precision.yamlis arguably not needed as a parameter. Either way the result is right. - nit:
carer_support_payment_pre_overlap.py:33-34now returns early whencsp_in_effectis false, socsp_in_effectin theeligibleexpression below is redundant. - nit: #2444 changes
carers_allowance_earnings, which this PR now reads for CSP. That is the intended sharing, but the CSP expectations here should be rerun once either lands.
On the law:
- Reg. 14 values match legislation.gov.uk point-in-time text: £139 as made (in force 19 Nov 2023), £151 from 7 Apr 2024 (SSI 2024/105 reg. 7(2)), £196 from 6 Apr 2025 (SSI 2025/100 reg. 13(2)), £204 from 5 Apr 2026 (SSI 2026/170 reg. 12(2)).
- Sch. 2 para. 4 treats a fraction of a penny as a penny only when that helps the individual, otherwise it is disregarded. For an earnings test that means rounding down, so "excluded iff weekly earnings are at least £204.01" is right.
- Reg. 4A(c) (from 15 Mar 2026) makes reg. 14 an entitlement condition, so the reported-CA route should also be barred. It is.
- UC carer element is unaffected (
is_carer_for_benefitsstays true), which is right as UC has no earnings condition on it. The Scottish Carer Supplement falls to £0 with CSP, also right.
Hand checks: £204 × 52 = £10,608 passes; £10,608.26 / 52 = £204.005 rounds down to £204.00 and passes; £10,608.52 / 52 = £204.01 fails. £11,000 less half of £1,000 pension contributions = £10,500, below £10,608, so it passes. Award 2026: £86.45 × 52 = £4,495.40; 2025: £83.30 × 52 = £4,331.60.
What I checked
- Read the PR body, issue #2345 and the full diff. Fetched reg. 4, 4A, 14 (as made, 2024-04-07, 2025-04-06, current) and sch. 2 para. 4 from legislation.gov.uk.
policyengine-core teston the new YAML: 13 passed. With the formula reverted to main: 6 failed, 7 passed, as the PR says.pytest policyengine_uk/tests/test_carer_support_payment.py: 10 passed.- All Social Security Scotland YAML tests plus the two Carer's Allowance YAML files: 125 passed.
ruff checkandruff format --checkon the changed Python files: clean.- Hosted CI is green on the current head. Changelog fragment is
fixed; Reproducer and axiom lines are present. - Merged with #2474 locally: content conflict. No overlap with the other open PRs I checked.
- Not checked: the docs page build, and any population-level effect.
🤖 Generated with Claude Code
Aggregate impact on certified data: passBase Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 13 (thresholds in Notes
Moves flagged for review
Receipts by tax head
Spending by benefit and service
Caseloads
Government balance, each component counted once
Model totals
Household income totals
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
Household net income by decileMean change in household net income per household, and as a share of the decile's base income; households stay in the base run's deciles.
No change in any year: components the model counts twice; population. 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
|
|
The published parent integrates the post-#2444 age-conditioned NI reader and retains the CSP earnings/penny condition. Published child #2474 ( |
|
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 |
policyengine-uk 2.146.1 applies Carer Support Payment's earnings limit (PolicyEngine/policyengine-uk#2473), so the Carer's Allowance take-up stage's reason for leaving Scotland closed (the engine did not apply the limit) no longer holds. The stage still leaves Scotland closed, as before; its text says the engine applies the limit and that opening Scotland is a follow-up (microcosm#1319). The engine test now pins the limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes #2345.
Fixes #2548.
Carer Support Payment now applies its earnings condition before the overlapping-benefit calculation. A Scottish carer with £40,000 of annual pay and 40 hours of weekly care receives £0 CSP, rather than £4,495.40. Reported Carer's Allowance receipt does not bypass the condition. The shared annual earnings reader retains the age-conditioned NI deductions from merged #2444; care/take-up conditions, rates, overlap and supplement formulas remain unchanged.
The CSP-specific weekly limits are £139 from 19 November 2023, £151 from 7 April 2024, £196 from 6 April 2025 and £204 from 5 April 2026. Regulation 14 and schedule 2 paragraph 4 supply the limit and favorable fractional-penny rule. Equality passes; £204.005 counts as £204.00, while £204.01 exceeds the limit. The comparison uses the first excluded annual penny level represented in the earnings reader's dtype, with no additional epsilon or annual-earnings rounding.
The model spreads annual net earnings over 52 weeks. It cannot reproduce varying award-week earnings, including the switch to the preceding award week from 16 November 2025. Existing standard-code PAYE and unrepresented care-charge/disregard approximations remain. Raw legal dates and annual April30 sampling are distinguished; the model's CSP coverage still starts in 2025. Age, education, caree-benefit and full claim-status gaps are outside this earnings-limit repair.
Reproducer: policyengine_uk/tests/policy/baseline/gov/social_security_scotland/carer_support_payment_earnings_limit.yaml::Scottish carer with forty thousand pounds of pay gets no CSP
Historical validation at f9f43d5:67 unique accepted checks: 18 new and 49 unchanged CSP, CA, overlap and Scottish CTR controls. The first affected batch had 66 passes and one new raw-parameter test API failure; only that corrected node was rerun and passed. Its policy/date oracles stayed fixed, with all other module AST and production bytes unchanged. Initial batch: 20.85s pytest/24.44s CLI; corrected node: 2.80s pytest/5.05s CLI. Unchanged production first reproduced six genuine final-cash failures and passed seven controls. Actual-holder tests cover the source penny cases, encoded float32 boundary and adjacent levels, CSP/CA parameter independence, and person/family/request-order isolation. All five existing CSP test functions and 2,968 protected tracked files remain unchanged.
Historical documentation build at f9f43d5 passed in 7.53s; existing builder/Node warnings are retained. Seven official XML originals and seven extracts support the source packet. That historical local validation used Python 3.13.14/Core3.32.27/Hypothesis6.168.2 versus locked Core3.33.2/Hypothesis6.169.0, with exact worktree imports, offline/no-sync and external caches. No private population estimate, full-suite pass, encoder or parity result is claimed. Hosted CI and human review remain pending.
Current integration: main42c01db9 includes merged #2444. Four natural-income dependency cases now pass: Class2/Class4 pension-age exemptions and the distinct Class4 SPA-reaching-year rule; the two pension-age cases failed numerically on untouched production. The focused current tree passed 21 Python checks and 74 successful raw YAML checks (95 raw checks), retaining original settings and oracles. Runtime is private/offline/no-sync Python3.13.14, UK2.141.1, Core3.33.2 and Hypothesis6.169.0 with actual-worktree imports. Independent captured-head review is complete for this exact commit; publication still requires fresh guards and new-head hosted CI.
Landing order remains #2473 then #2474. The reviewed parent commit d7f1a43 contains the earnings condition and the post-#2444 NI reader. The reviewed child commit 315e374 retains BOTH the age and earnings conditions. The proposed child publication base is the existing parent branch
fix-2345-csp-earnings-limit. Only after #2473 actually merges should #2474 retarget main and rerun the combined cash checks against that integration before merging. Queue admission or passing local tests does not establish that landing. Fresh public head/base/CI guards remain required.Captured current-main check: separate local test projections of the reviewed heads with main c281c2e passed 17 CSP earnings/NI/pension-age YAML checks for #2473 and 21 age/earnings/DLA YAML checks for #2474. These projections used UK2.141.2/Core3.33.2. The checks overlap earlier validation; the counts are not added across heads or batches. They do not replace new-head hosted CI or establish that either PR has landed.
Pension reform scope remains open. Captured main c281c2e reads
gov.dwp.carers_allowance.pension_contribution_deduction_rate, whose default is 0.5, through the shared CA earnings reader. Changing only that CA-labelled share from 0.5 to 0 changed a Scottish carer's earnings from £10,500 to £11,000 and CSP from £4,495.40 to £0 in the 2026 natural-input check (£11,000 pay, £1,000 employee pension contributions, age 45 and 40 weekly care hours). CSP schedule 2 paragraphs 9 and 12 separately specify half the individual's pension contributions. The shared reader has no independent CSP pension-share reform control. The default checks passed; no default-law defect, independent CA-only reform behavior or encoded parity is claimed. A proposed shared pre-floor calculation with programme-specific pension shares and locality tests remains an unimplemented follow-up.axiom: needed