Skip to content

Apply the Pension Credit earnings disregards (SPC Regs 2002 Sch VI) - #2019

Open
MaxGhenis wants to merge 6 commits into
mainfrom
pc-earnings-disregard
Open

MaxGhenis wants to merge 6 commits into
mainfrom
pc-earnings-disregard

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #1954 (its bullet "pension_credit_income applies no Sch VI earnings disregards").

Waits on Max's ruling d1424 on how an employee's income tax is attributed to their earnings (below). It implements option (a).

The law

SPC Regs 2002 reg 17(9) disregards the sums in Schedule VI from the claimant's earnings (legislation.gov.uk, current and as-made texts, read 2026-10-01):

Para Who Weekly
1 lone parent £20
3 claimant or partner is a carer satisfying Sch I para 4 £20
4(1)(a) claimant or partner receives long-term IB, SDA, AA, DLA, ESA, PIP, AFIP (or a Scottish equivalent, WTC disability element, war pensions mobility supplement) £20
4(1)(b) claimant or partner certified severely sight impaired or blind £20
4A £20 is the most, however many conditions are met
5 otherwise: single / couple with earnings £5 / £10

The amounts have not changed since 6 October 2003. ESA was added to para 4(1)(a) on 27 October 2008 (SI 2008/1554), and PIP and AFIP on 8 April 2013 (SI 2013/388, SI 2013/591).

The earnings the sums come off are net (texts read 2026-10-11):

  • Employed earners: reg 17(10) disregards "any amount payable by way of tax" and NI deducted; reg 17A(4A) disregards half of pension contributions.
  • Self-employed earners: reg 17(11) and 17B apply the Computation of Earnings Regulations 1996 regs 13 and 14, which deduct a notional tax and notional contributions in place of those actually payable:
    • income tax at the basic rate (the Scottish basic rate for a Scottish taxpayer) on the profit less only the personal reliefs of ITA 2007 Part 3 Chapters 2, 3 and 3A (CER reg 14(1));
    • Class 4 at the main rate between the lower and upper profits limits (reg 14(2)(b)), and Class 2 until reg 14(2)(a) was omitted on 6 April 2024;
    • half of pension premiums (reg 13(4)(c)).
  • Losses: a loss in one employment is not set against earnings in another (CER reg 13(12)).

What changes

  • New parameters gov.dwp.pension_credit.earnings_disregard:

    • standard (SINGLE £5, COUPLE £10);
    • higher.amount (£20);
    • higher.disability_benefits, a dated person-level list: IB, SDA, AA, DLA; contributory ESA from 2008-10-27; PIP and AFIP from 2013-04-08;
    • higher.disability_benefit_unit_benefits: income-related ESA, held on the benefit unit, from 2008-10-27.
  • pension_credit_earnings_disregard (benefit unit) = min(net earnings, 52 × weekly amount).

    • The weekly amount is £20 if the unit is a lone-parent family, or a claimant or partner (is_claimant_or_partner) is entitled to carer's allowance (is_entitled_to_carer_benefit, the carer addition's own Sch I para 4 test), is on a listed benefit, or is_blind, or the unit receives working tax credit with its disability or severe disability element (para 4(1)(a)(vi), from 6 October 2003). Otherwise it is £5 or £10 by relation_type.
    • Net earnings are each person's own employment and self-employment income, each floored at nil, less their primary Class 1, their notional self-employed deductions and half their pension contributions, floored at nil; summed over the claimant and partner, less the income tax on their employed earnings.
  • Income tax on employed earnings (pension_credit_employment_income_tax, benefit unit) is the fall in the claimant's and partner's income tax when nobody has employment income. A branch of the simulation measures it, following marginal_tax_rate: computed values are dropped from the branch, then employment income is set to nil.

    • It includes the tax earnings add on savings (a lost starting-rate band or personal savings allowance) and the effect of one partner's earnings on the other's tax (marriage allowance).
    • Result: while the disregard covers the net earnings, Pension Credit income does not change with either partner's earnings, so earning more never raises Pension Credit.
  • Notional self-employed deductions (pension_credit_self_employment_deductions, person): CER reg 14 as above.

    • The Scottish basic rate is read from the basic band itself, since the scale at an instant leaves out the starter band before 2018-19.
    • The reliefs are the personal allowance, blind person's allowance and marriage allowance (as the model deducts it from income), with the married couple's allowance as a reduction.
  • pension_credit_income now takes self-employed earnings net of the notional deductions rather than the tax and contributions actually payable on the profit (reg 17(11)). It deducts the actual tax on the profit (pension_credit_self_employment_income_tax, the further fall in income tax with nobody's self-employment income either) and actual Class 2 and 4, and deducts the notional amounts instead. It then subtracts the disregard.

  • housing_benefit_savings_credit_only_income (HB(SPC) Regs 2006 reg 27): the Secretary of State's figure is Pension Credit income, which is now after the Sch VI disregards. So only the higher amounts reg 27(4)(c)(i) and (d) allow come off:

    • a lone parent's £25 over the amount disregarded for Pension Credit;
    • the additional £17.10.

    Before, it deducted the whole Housing Benefit disregard, because Pension Credit income had none. The CTR savings-credit-only route already took the Pension Credit figure as it stands, so it is now after the disregards as the CTR schemes require.

  • Not modelled, as stated in the variable and parameter documentation:

    • the para 2-2B employments (part-time firefighters, coastguards, lifeboat crew, reserve forces), for which there is no data;
    • the para 4(2)-(4) transitional protections;
    • continued carer qualification under Sch I para 4 after carer's allowance stops (no record of when it stopped);
    • pension age disability payment, adult disability payment and Scottish adult DLA, which have no variables of their own;
    • the war pensions mobility supplement, which has no variable.

Methodology choice for Max (d1424)

The regulations do not say which part of a person's income tax is payable on their earnings, and the model has no PAYE codes. The options:

  • (a) Top slice (this PR): the extra tax the earnings cause, above pensions, savings and self-employment. It is the only option under which Pension Credit income never changes with earnings inside the disregard.
  • (b) Income share: the person's tax split by the earnings' share of total income, as housing_benefit_net_earnings does now.
  • (c) All of it: all of the person's income tax, capped at the earnings, as PAYE codes usually collect the tax on State Pension through the job.

HB reg 36 raises the same question.

Dependency. The carer test reads is_entitled_to_carer_benefit, so the Carer's Allowance earnings limit reaches it once #2312 lands. Until then, a carer who earns above the limit keeps entitlement in the model and gets the £20 disregard.

Invariants

Stated here and executed in tests/test_pension_credit_earnings_disregard_properties.py (Hypothesis):

  1. Statute. The disregard equals min(net earnings, 52 × w). The test recomputes net earnings from the inputs and from independent re-simulations without anyone's employment, and without anyone's earnings. This is a differential check of the branch.
  2. Bounds. 0 ≤ disregard ≤ min(gross earnings, £20 × 52).
  3. Differential. Pension Credit income equals the sources less tax, NI and half of pension contributions, with the actual self-employed tax and contributions replaced by the notional ones, less the disregard.
  4. Guarantee credit is never below its value without the disregard (units entirely over State Pension age).
  5. Monotonicity. Earning more, employed or self-employed, by either partner (+£1 to +£5,000), never raises Pension Credit.
  6. Flatness. Under the disregard, Pension Credit income does not change with a rise in either partner's employed or self-employed earnings. 23 of 25 generated cases exercise it.
  7. Dated lists. ESA appears from 2008-10-27, PIP and AFIP from 2013-04-08.
  8. Scottish basic rate. The notional tax reads 20% in every year from 2016.

Known exception (floors, by construction): where a person's pension contributions exceed their earnings, their net earnings floor at nil. Pension Credit income still deducts the contributions, so it rises with the earnings. That raises income, so it never raises Pension Credit.

Tests

pension_credit_earnings_disregard.yaml, with new regression cases:

  • Savings. £12k State Pension, £12k savings interest and AA, with and without £1,040 of wages: Pension Credit income £10,914 both ways. Tax on the earnings is £208, including tax they add on the savings.
  • Pension contributions. £15k pension and £300 of contributions, with and without £400 of wages. Tax on the earnings is £20: £80 of tax less the £60 of relief the wages unlock. The disregard is £230.
  • Losses. £400 wages and an £8,000 self-employment loss: the disregard is £260 (CER reg 13(12)).
  • Self-employed profit under the personal allowance: no notional tax, and the £486 of tax it actually causes is not deducted.
  • Trading allowance. Profit within it is tax-free and fully disregarded.
  • Working tax credit: with its disability element in payment the disregard is £20; with the element but no WTC paid, £5.
  • Notional deductions:
    • Scottish profit: 20% notional tax, not the 19%/20%/21% bands, plus main-rate Class 4 under State Pension age;
    • 2023-24: Class 2 included;
    • blind person's allowance deducted.

Updated expectations, with the arithmetic in comments (each was written before Pension Credit had an earnings disregard):

  • pension_credit_income.yaml:
    • "All income sources are included" (343 → 214);
    • main's self-employment-loss case (Pension Credit income 10,000 → 9,740 with the £5 disregard; Pension Credit 2,376 → 2,636).
  • claimant_partner_income_and_carers.yaml: PC income 8,579 → 7,539.
  • tests/test_pension_credit_income_losses.py: the A property loss reduces Pension Credit income, paying the full guarantee credit to someone with a £20,000 pension #2255 trading-loss reproducer (the same £260).
  • housing_benefit_savings_credit_only.yaml:
    • case 3 (the non-dependant's Pension Credit income less £260);
    • case 4 (savings credit on the lower income: 718.62 → 822.62; HB 7,760.60 → 7,693.00);
    • case 5 (State Pension raised to £12,500 to keep the award savings-credit-only: £1,040 lone-parent disregard; £260 higher amount plus £889.20 additional);
    • new case 5a (the original inputs: the disregard brings £140.96 of guarantee credit and its passport).

Local runs: the benefit, local authority, DWP (including Pension Credit), Scotland, household, DfE, DCMS, winter fuel and integration YAML suites (2,170 cases) pass. So do the Pension Credit, HB and CTR property tests. CI runs the full suite.

Measured impact (real runs)

The PolicyEngine/policyengine-uk-data#510 build D Enhanced FRS (2024-25), calibrated weights, GB, against main 3f174d0 (this branch's merge base):

2025-26 2026-27
benefit units entitled to Pension Credit +2.3k +2.6k
benefit units receiving it +1.7k +2.0k
Pension Credit spending +£0.5m +£0.6m
household net income (UK) +£0.8m +£1.0m
Housing Benefit, CTR (UK) +£0.0m +£0.0m
pensioner poverty unchanged to 0.01pp unchanged

It does not change which FRS Pension Credit reporters are entitled; the reporter gap comes from imputed capital (#2018, merged, and PolicyEngine/policyengine-uk-data#513). Cost: the two branches that measure tax on earnings added about 1 second (35.3s against 34.1s) and 0.14 GB of peak memory to a two-year aggregates run on the full dataset.

Review

Earlier reviews (an Opus 5.5 review of the first head and GPT-6.1 Sol delta reviews) found the following, all fixed here:

  • the gross-earnings cap;
  • caring hours qualifying on their own;
  • the WTC rationale in the parameter description (the elements are now read, so it is gone);
  • Scottish band crossing;
  • the tax-on-earnings attribution ignoring savings interactions (+£1,040 of wages raised Pension Credit by £114 in the reviewer's case);
  • self-employment taxed as an employee's;
  • a loss offset against wages.

The reviewer suggested labelling as intended the case where more self-employed profit raises Pension Credit. I did not: the statute does not produce it. It came from pension_credit_income deducting the actual tax on the profit while the earnings used the notional tax. Reg 17(11) replaces both, and with that fix the property tests show earning more never raises Pension Credit.

axiom: TheAxiomFoundation/rulespec-uk#414 queued (SPC Regs 2002 Sch VI; the corpus cannot yet ingest a Roman-numeral schedule)

🤖 Generated with Claude Code

Reproducer: policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/housing_benefit_savings_credit_only.yaml, policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/claimant_partner_income_and_carers.yaml::Pension Credit counts both partners' income deductions and carer additions, policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_earnings_disregard.yaml, policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml::All income sources are included., policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml::A self-employment loss does not reduce Pension Credit income from wages., policyengine_uk/tests/test_pension_credit_earnings_disregard_properties.py::test_statute_bounds_differential_and_monotonicity

@juaristi22

Copy link
Copy Markdown
Collaborator

Codex review — changes required

Reviewed commit 2c87ceebfb0dccddb0aa8d9cc73881cf14634b2e. COMPLETE; 1 confirmed blocking finding(s). Independent code/test and policy/source reviews were consolidated for the changed behavior and affected dependencies.

code-1 — [P1] Cap the disregard against earnings after statutory deductions

The new cap at pension_credit_earnings_disregard.py:54–55 uses gross pension_credit_earnings, whereas pension_credit_income.py:19–25 separately subtracts tax, National Insurance and half pension contributions before this disregard. Therefore the cap still allows the disregard to consume pension income. For a single person aged 70 in 2024, £400 employment earnings, £400 reported employee pension contributions, £9,000 State Pension and no savings, the current head produces £260 disregard, £8,940 assessable income and £2,403.80 final Pension Credit. Half the contribution leaves only £200 earnings before the Schedule VI disregard; capping to £200 leaves £9,000 assessable income and £2,343.80 Pension Credit, a £60 annual overpayment in the PR. This follows the independently checked regulation 17A(4A) earnings calculation and regulation 17(9)/Schedule VI ordering.

Cap using the nonnegative net earnings available at this stage and add a low-earnings/pension-contribution regression that asserts the final award. The property tests currently construct gross-only earnings and so do not challenge this deduction ordering. Confidence: high; current-head code, source rule and final award reproduction agree.

Policy/source review independently confirms the ordering in regulation 17A(4A), regulation 17(9) and Schedule VI. The code and policy reports describe the same defect, counted once.

The standard/higher disregard amounts and category conditions were corroborated. The required correction is the cap's placement after statutory deductions.

Validation: 43 focused tests passed. A separate executed household diagnostic reproduced the £60 final Pension Credit overpayment described above. Three official source originals were inspected and their cached bytes verified. Existing passing tests do not cover the failing net-earnings ordering. No material review gaps remain within this scope.

Focused tests used an existing cached Python 3.13 environment (Core 3.32.9, NumPy 2.1.3, pandas 2.3.1, microdf-python 1.2.1, Hypothesis 6.168.2, pytest 8.4.2) with this PR’s isolated source snapshot. No dependencies were installed; this was not a freshly synced lock environment or a full-suite/population run. This is a review comment, not a formal GitHub review vote.

Live check before posting (2026-10-02T10:35:18.903311+00:00): same commit, CLEAN; all reported CI checks pass.

@vahid-ahmadi

Copy link
Copy Markdown
Collaborator

Review pass (Claude Code, on Vahid's behalf) at 2c87ceeb

Short version: the Schedule VI amounts, categories and dating are right, but the cap needs to move. I agree with the Codex review's blocking finding and reproduced it independently. Everything else is small.

1. Blocking: cap the disregard at net earnings, not gross. pension_credit_earnings_disregard.py:54-55 caps at pension_credit_earnings. But pension_credit_income.py:22-25 subtracts tax, NI and half the pension contributions before the disregard. Reg 17(9) applies Schedule VI to earnings as calculated under reg 17A, and reg 17A(4A) takes net earnings after income tax, Class 1 NI and half of any pension contribution. So the disregard can currently eat into non-earned income.

  • Reproduced at this head (2024): single person aged 70, £400 earnings, £400 employee pension contributions, £9,000 State Pension. The disregard is £260, Pension Credit income £8,940 and Pension Credit £2,403.80. Capped at the £200 of net earnings, Pension Credit income is £9,000 and Pension Credit £2,343.80, so this head overpays by £60.
  • Fix: cap at max(0, earnings − NI − 0.5 × pension contributions − income tax on earnings). pension_credit_income deducts income tax on all income (State Pension included), so for the cap you need only the share that falls on earnings. Apportioning by earnings' share of taxable income is a reasonable approximation; say so in the docstring.
  • Test: add a YAML case that asserts the final award for the case above. The property tests only generate gross earnings with no deductions, so they can't catch this. A strategy with pension contributions, or taxable earnings, would.

2. Nit: Sch VI para 6 isn't mentioned. Earnings from an employment that ended before the claimant first became entitled to Pension Credit are disregarded in full (other than reg 17(9)(b) amounts). The model can't see when an employment ended, so listing para 6 under "Not modelled" next to paras 2-2B would be enough.

3. Nit: coordination with #1896. The claimant-or-partner test reads is_uc_claimant (line 32). #1896 introduces is_claimant_or_partner for exactly this, and #1946 uses it. Whichever lands second should switch, so a Pension Credit rule doesn't depend on a UC-named flag.

Checked and correct:

  • Read against the current Sch VI text:
    • £20 for a lone parent (para 1), a carer (para 3, via the Sch I para 4 addition), or a claimant or partner on a listed benefit or blind (para 4(1)).
    • £5 single and £10 where the claimant has a partner (para 5).
    • £20 at most however many conditions apply (para 4A).
  • The dated lists add ESA from 27 October 2008, and PIP and AFIP from 8 April 2013. Treating incapacity_benefit as long-term IB is documented.
  • Probes on this head behave as expected otherwise:
    • single with £200 earnings: £200 disregarded, the earnings cap;
    • couple with £200 earnings: £200, under the £520 couple amount;
    • self-employment of £3,000 with AA: £1,040, the £20 rate, and AA stays outside Pension Credit income.
  • Tests: the Pension Credit YAML directory (63) and the property file pass locally; CI 6/6 green.

MaxGhenis and others added 2 commits October 2, 2026 09:54
20 pounds a week for a lone parent (para 1), a carer satisfying Sch I para 4
(para 3), or a claimant or partner on a listed disability benefit or
certified blind (para 4(1)); otherwise 5 pounds single and 10 pounds couple
(para 5); at most 20 pounds (para 4A), never more than the earnings.

Refs #1954.

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

Reg 17(9) disregards the Sch VI sums in calculating the claimant's earnings,
which are net of income tax and NI (reg 17(10)) and of half of pension
contributions (reg 17A(4A)). Capping at gross earnings let a taxpayer's
first pounds of earnings raise Pension Credit. Income tax on earnings is the
lesser of the person's income tax and the basic rate on their earnings.

Also: the carer condition reads the claimant's or partner's
is_carer_for_benefits (Sch I para 4), not the carer addition, which counts
dependants; is_claimant_or_partner after #1896; property tests compute net
earnings independently, include dependants' DLA and caring, and add that
earning more never raises Pension Credit; parameter description and test
comment fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the pc-earnings-disregard branch from 2c87cee to 3d4f12b Compare October 2, 2026 14:08
MaxGhenis and others added 2 commits October 3, 2026 18:47
…ment (review of #2019)

- Income tax on earnings is now the tax on them as the top slice of taxable
  non-savings income on the person's own Scottish or rest-of-UK schedule,
  capped at their income tax. The 20% cap let earnings crossing Scottish
  bands raise Pension Credit (reviewer's couple: +2.89).
- The para 3 carer condition reads is_entitled_to_carer_benefit, the carer
  addition's own Sch I para 4 test; caring hours alone no longer qualify
  (reviewer's case overpaid 780 a year).
- Tests: Scottish couple pair (income flat with and without earnings),
  hours-only vs entitled carer cases; the property test adds Scottish
  households, carer entitlement, care hours and pension contributions, and
  measures tax on earnings independently by rerunning without them.

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

Copy link
Copy Markdown
Collaborator Author

Composition note from #2259 (Pension Credit: a loss on one source counts as nil), found by its GPT-6.1 Sol review.

#2259 makes pension_credit_earnings floor each person's employment_income and self_employment_income at zero before adding them: Computation of Earnings Regulations 1996 reg. 13(12), applied by SPC Regulations 2002 reg. 17B(5)(b), bars setting a loss in one employment against earnings in another.

Here, pension_credit_earnings_disregard.py recomputes gross earnings as max_(0, add(person, period, pc.guarantee_credit.earnings_sources)), which nets the sources before flooring. With £10,000 of wages and a £10,000 self-employment loss, #2259 counts £10,000 of earnings but this formula gives gross earnings of £0, so the disregard ceiling is £0 instead of £260 (£5 a week). That happens in whichever order the two PRs merge.

Suggested fix, whichever lands second: sum the individually floored person-level sources, for example sum(max_(0, person(source, period)) for source in pc.guarantee_credit.earnings_sources), or read pension_credit_earnings once #2259 is on main, and add a combined case (wages £10,000, self-employment −£10,000: disregard £260).

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Independent review (GPT-6.1 Sol, UK hub sweep, 2026-10-12): REQUEST_CHANGES at the head below. The hub is routing it to this PR's owner session. Methodology readings the source leaves open go to Max as a decision before they're picked.

VERDICT: REQUEST_CHANGES
Head reviewed: 816a4e1

  1. [blocker] The tax cap violates the stated invariants. At pension_credit_earnings_disregard.py:87, tax attribution excludes savings interactions. Reproduced in England, 2024: age 70, £12,000 State Pension, £12,000 savings interest and £3,000 Attendance Allowance. Adding £1,040 wages raises Pension Credit from £4,653.26 to £4,767.26, an increase of £114. A second reproduced case—£15,000 pension income, £400 wages and £300 pension contributions—produces a £170 disregard versus £230 under the property test’s counterfactual oracle. Fix: reconcile tax attribution with the income deduction and agreed methodology; add deterministic regressions and generate savings income and earnings-dependent relief cases.

  2. [blocker] Caring hours still establish purported entitlement. pension_credit_earnings_disregard.py:61 calls a helper whose Carer’s Allowance calculation checks caring hours and a claim flag, without the earnings limit or qualifying care recipient. Thus £12,000 annual wages and 40 caring hours can qualify for the higher disregard despite exceeding the earnings limit. The new YAML test bypasses this inference by supplying entitlement as false. Fix: use a predicate satisfying the actual entitlement conditions, preserving underlying entitlement after overlapping-benefit adjustments; test ordinary inputs without overriding that predicate. Official eligibility requirements.

  3. [blocker] Self-employed earnings use the wrong tax calculation. pension_credit_earnings_disregard.py:72 combines wages and self-employment profits before applying the full marginal tax schedule. Pension Credit instead applies a notional self-employment calculation; CER regulation 14 specifies basic-rate tax and prescribed personal reliefs. Fix: calculate employed and self-employed net earnings separately before aggregation and the disregard cap, with mixed pension/self-employment tests. DWP guidance, regulation 14 amendment.

  4. [blocker] Employed-tax allocation requires Max’s methodology decision. pension_credit_earnings_disregard.py:22 attributes pension-first, marginal-tax allocation to DMG 86038–86039. Those paragraphs specify employer-deducted tax, without establishing that approximation. HMRC says employers usually collect pension tax through wages; pension providers can also collect it. Fix: obtain Max’s decision, document the chosen annual approximation accurately, and test its consequences before merging. DMG 86038–86039, HMRC collection guidance.

  5. [blocker] Current main introduces a semantic conflict despite a clean merge. pension_credit_earnings_disregard.py:72 floors earnings after summing. Main’s Count a loss on one source as nil in Pension Credit income and earnings #2259 floors each source separately because losses cannot offset another employment’s earnings. After merging, £400 wages plus an £8,000 self-employment loss would count £400 earnings but receive zero disregard instead of £260. Fix: floor each source separately, add this regression, and update main’s affected income-test expectations when integrating it.

  6. [should-fix] Carer continuation is an undocumented omission. pension_credit_earnings_disregard.py:61 tests current entitlement only, whereas Schedule VI incorporates Schedule I’s continued carer qualification. Fix: cover the continuation conditions, or explicitly document and agree their deferral. DWP continuation guidance.

  7. [should-fix] The WTC omission rationale is inaccurate. disability_benefits.yaml:12 assumes WTC disability elements necessarily follow positive DLA/PIP receipt. The model’s disability flag is independently supplied in calculator situations. Fix: support qualifying WTC element receipt for historical years, or correct the claimed equivalence and explicitly document the historical coverage gap. Official qualifying-benefit list.

Verification: 35 targeted YAML tests passed serially; changed Python files passed lint and formatting checks. Property-test execution was blocked by missing Hypothesis/pytest-xdist and sandbox temporary-file restrictions. Invariants are stated; no existing tests were removed, skipped, xfailed or weakened.

The required merge-tree check found no textual conflicts against local origin/main 3f174d0, but finding 5 remains. No protected files or workflows changed.

Both requested gh commands failed to connect. PR-body mechanism claims and enhanced-FRS impact provenance remain unverified; I cannot establish whether impact is missing. ESA/PIP amendment dates were corroborated through official consolidated annotations, but their direct amendment pages could not be fetched.

MaxGhenis and others added 2 commits October 11, 2026 21:25
- Employed earnings (SPC Regs 2002 regs 17(10), 17A): less the income tax
  they add for the claimant and partner, measured on a branch with nobody's
  employment income (marginal attribution; methodology ruling d1424), and
  primary Class 1.
- Self-employed earnings (regs 17(11), 17B; CER 1996 regs 13(4), 14): less
  notional basic-rate tax on profit over personal reliefs, main-rate Class 4
  and (before April 2024) Class 2. Pension Credit income replaces the tax and
  contributions actually payable on the profit with these.
- Each source floored at nil (CER reg 13(12)).
- Sch VI para 4(1)(a)(vi): working tax credit with a disability element.
- HB savings-credit-only route (HB(SPC) Regs reg 27(4)): deduct only the
  higher HB disregards, since Pension Credit income is now after Sch VI.
- Regression cases for savings interactions, pension relief, losses,
  notional deductions; property tests for statute, flatness under the
  disregard and monotonicity in either partner's earnings.

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

Copy link
Copy Markdown
Collaborator Author

The last description update dropped this PR's Reproducer: line, so the Fix evidence check failed. I've added it back. Please keep it in the description file you edit from, or narrow it to the test that reproduces the bug:

Reproducer: `policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/housing_benefit_savings_credit_only.yaml`, `policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/claimant_partner_income_and_carers.yaml::Pension Credit counts both partners' income deductions and carer additions`, `policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_earnings_disregard.yaml`, `policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml::All income sources are included.`, `policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml::A self-employment loss does not reduce Pension Credit income from wages.`, `policyengine_uk/tests/test_pension_credit_earnings_disregard_properties.py::test_statute_bounds_differential_and_monotonicity`

🤖 Generated with Claude Code

@vahid-ahmadi vahid-ahmadi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine once the d1424 tax-attribution ruling is recorded. The code matches Schedule VI and the earlier blocking findings are fixed.

@MaxGhenis this is a delta review since my comment at 2c87cee (2 Oct). It also covers the 12 Oct review at 816a4e1 and the #2259 composition note.

Earlier findings, re-checked on the current head merged locally with main 714b143:

  • Cap at net earnings (2 Oct, blocking): fixed. £400 of wages, £400 of pension contributions and a £9,000 State Pension (2024): disregard £200, Pension Credit income £9,000, Pension Credit £2,343.80, as hand-computed (£218.15 × 52 − £9,000).
  • Earnings raising Pension Credit through savings tax (12 Oct, finding 1): fixed. £12,000 State Pension, £12,000 interest and Attendance Allowance: Pension Credit is £4,667.80 with or without £1,040 of wages. The £832 disregard exactly offsets the wages net of the tax they add.
  • Carer by caring hours alone (finding 2): fixed now that #2312 is on main. With £12,000 of wages and 40 caring hours, the disregard is the £5 standard amount, not £20.
  • Self-employed notional tax (finding 3): fixed. CER reg 14 is applied as written: basic or Scottish basic rate, Chapter 2, 3 and 3A reliefs only, and main-rate Class 4 between the limits. Class 2 is included only while ni_class_2 is non-zero; it is £0 from 2024-25, which matches the omission of reg 14(2)(a).
  • Loss netting (#2259 note, finding 5): fixed. £400 of wages and an £8,000 self-employment loss give the £260 disregard.
  • WTC (finding 7): fixed. Para 4(1)(a)(vi) is read from the elements and WTC in payment.
  • is_uc_claimant (my nit 3): fixed. The formula now uses is_claimant_or_partner.
  1. should, pension_credit_earnings_income_tax.py:3-8: the top-slice attribution is still marked provisional, pending the d1424 ruling, and the PR body says it waits on that. Nothing in the code needs to change if option (a) stands. Once the ruling is made, please replace the "provisional" wording in DECISION with the decision and its date, so the docs don't describe a choice that is still open.

  2. nit (carried over from my 2 Oct comment), pension_credit_earnings_disregard.py documentation: Sch VI para 6 (earnings from an employment that ended before first entitlement are disregarded in full) is still not in the "Not modelled" list. One clause would do.

  3. nit, pension_credit_earnings_income_tax.py: the file holds four variables, and none is named after the file. The repo keeps one variable per file, named for it. Splitting it, with the shared helper in utils, would make pension_credit_employment_income_tax easier to find.

  4. nit, PR body: the "Dependency" paragraph says carers above the earnings limit keep the £20 "until #2312 lands". #2312 merged on 12 Oct, so after the next merge from main that sentence is out of date.

  5. nit, overlaps: draft #2066 (winter fuel charge) conflicts with this PR in pension_credit_income.py. #2092, #1913 and #1969 merge cleanly with it. None of Vahid's own open PRs touch these files.

What I checked

  • Read the full diff, the PR body and all the earlier review threads. Read SPC Regs 2002 Sch VI (paras 1 to 7, including 4A(2)'s couple limit) and CER 1996 reg 14 on legislation.gov.uk.
    • The amounts (£20, £5, £10, unchanged since 6 October 2003), the para 4(1)(a) list and its dated additions, and the para 3 link to Sch I para 4 all match.
    • The disregard sits at benefit-unit level with one weekly amount, which is right for para 4A(2).
  • On the head (d91b322):
    • the Pension Credit YAML directory and housing_benefit_savings_credit_only.yaml: 251 passed;
    • test_pension_credit_earnings_disregard_properties.py and test_pension_credit_income_losses.py: 9 passed.
  • On a local merge with main (not pushed):
    • the Pension Credit and Housing Benefit YAML directories: 485 passed;
    • the Carer's Allowance earnings-limit, overlapping-benefits and pension-age HB means-test files: 47 passed;
    • the property and loss tests: 9 passed;
    • the probes above.
  • ruff check and ruff format --check on the changed Python files: pass.
  • CI was green at d91b322.
  • Not run: the national impact table. It needs the Enhanced FRS build, which I did not download. I did not time the branch simulations either.

🤖 Generated with Claude Code

This branch has not been deployed

No deployments
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.

3 participants