Repository navigation
Conversation
Codex review — changes requiredReviewed commit code-1 — [P1] Cap the disregard against earnings after statutory deductionsThe new cap at 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. |
|
Review pass (Claude Code, on Vahid's behalf) at 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.
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 Checked and correct:
|
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>
2c87cee to
3d4f12b
Compare
…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>
|
Composition note from #2259 (Pension Credit: a loss on one source counts as nil), found by its GPT-6.1 Sol review. #2259 makes Here, Suggested fix, whichever lands second: sum the individually floored person-level sources, for example 🤖 Generated with Claude Code |
|
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
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 Both requested |
- 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>
|
The last description update dropped this PR's 🤖 Generated with Claude Code |
vahid-ahmadi
left a comment
There was a problem hiding this comment.
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_2is 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 usesis_claimant_or_partner.
-
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 inDECISIONwith the decision and its date, so the docs don't describe a choice that is still open. -
nit (carried over from my 2 Oct comment),
pension_credit_earnings_disregard.pydocumentation: 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. -
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 inutils, would makepension_credit_employment_income_taxeasier to find. -
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.
-
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.pyandtest_pension_credit_income_losses.py: 9 passed.
- the Pension Credit YAML directory and
- 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 checkandruff format --checkon 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
Part of #1954 (its bullet "
pension_credit_incomeapplies 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):
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):
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).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, oris_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 byrelation_type.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, followingmarginal_tax_rate: computed values are dropped from the branch, then employment income is set to nil.Notional self-employed deductions (
pension_credit_self_employment_deductions, person): CER reg 14 as above.pension_credit_incomenow 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: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:
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:
housing_benefit_net_earningsdoes now.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):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:Updated expectations, with the arithmetic in comments (each was written before Pension Credit had an earnings disregard):
pension_credit_income.yaml: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: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):
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 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_incomededucting 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