Repository navigation
Include other investment income in total income - #2184
Conversation
Review of #2184 — Include other investment income in total incomeBase repository: PolicyEngine/policyengine-uk Source DocumentsCriticalC1 — Gate Housing Benefit deduction bands on remunerative work (STILL OPEN)Severity: CRITICAL (Must Fix) Adding other_investment_income correctly fixes tax/post-tax income, but now feeds investment-only nonworking adults into Housing Benefit's earnings-linked non-dependant bands. The new test explicitly accepts the highest band for £28,912 investment income and no work inputs. Housing Benefit Regulations 2006 regulation 74(1)(b) and (2) place adult non-dependants who are not in remunerative work in the minimum deduction category; the higher gross-income bands are expressly conditional on remunerative work. The downstream deduction formula checks total_income without this work gate. Retain the income inclusion and protect that consumer's category selection, with separate working/nonworking tests. Executed trigger: model year 2025, 40-year-old existing Housing Benefit claimant in council housing with annual rent £15,000 and reported HB £5,000; separate benefit unit for a 25-year-old adult child with £28,912 other investment income, zero earnings, self-employment income and hours, OTHER_INACTIVE status and no education. The claimant is explicitly a continuing unmigrated HB recipient whose notice/deadline has not ended entitlement, with would_claim_uc=False. That variable is a supplied take-up preference with no formula, not an overridden eligibility result. No eligibility or intermediate deduction is forced. The model computes HB eligibilitytrue for the claimant, identifies the adult child as a non-dependant, and computes zero JSA, ESA, Income Support and Pension Credit for them. Observed: deduction £124.55/week (£6,476.60/year) and final claimant HB £8,523.40. The source-backed expected category is the minimum, regardless of this nonworker's investment-income level. A named in-memory minimum-category control using the captured model's stored £19.30/week lower tier gives deduction £1,003.60/year and final HB £13,996.40: the current code removes £5,473/year more than its own minimum-category implementation. The model's £19.30 is used only to quantify this conditional modeled difference; the exact statutory 2025 amount was not independently corroborated, and this is not a finding about that rate. Claim-history/migration timing is not encoded, so the reproduction's continuing-award premise is explicit. The material wrong category is established independently by regulation 74. Reproduction: script ( Should AddressNone. SuggestionsNone. Evidence GapsNo material gaps reported. Notes
Validation SummaryReused exact-head validation (not rerun in this batch): 240 tests passed (pr-2184-code-tests.log); final2025working-age nonworking-investment-only HBdiagnostic exit0,4.63s, claimantHB8523.40 vs13996.40 named minimum-categorycontrol; pr-2184-code-hb-diagnostic.py/.log. Snapshot import confirmed. Reused exact-head validation (not rerun in this batch): Three official originals/extracts; reg74work-status rule corroborated. Code final2025case eligibility True, HB£8,523.40 vs minimum-category modelcontrol£13,996.40 (exit0,4.63s). Cache helper passed; source manifest canonical. CI at c8cda39: Install + smoke-import (py3.11)=SUCCESS, Install + smoke-import (py3.12)=SUCCESS, Install + smoke-import (py3.13)=SUCCESS, Install + smoke-import (py3.14)=SUCCESS, Lint=SUCCESS, Test=SUCCESS. Detailed code, policy, source and reproduction artifacts were retained locally. Timingelapsed seconds: 1151.70s; setup seconds: 269.92s Review SeverityREQUEST_CHANGES. Open findings: 1 critical, 0 should address, 0 suggestions. |
Addresses María's finding C1 on #2184. Counting other investment income in total_income pushed non-working non-dependants with investment income into the Housing Benefit gross-income bands. HB Regs 2006 reg 74(2) (SPC Regs reg 55(2)) applies those bands only to a non-dependant "in remunerative work"; anyone else aged 18 or over takes the reg 74(1)(b) minimum. Reg 6(1) defines remunerative work as at least 16 paid hours a week. - Add gov.dwp.housing_benefit.non_dep_deduction.remunerative_work_hours (16) and band income only when weekly_hours >= 16; otherwise, and for a worker below the first threshold, deduct the first-bracket (reg 74(1)(b)) amount. - The minimum now also reaches zero-income non-dependants, who previously got 0 because calc(0, right=True) fell below the first bracket. That exposed the missing reg 74(6) / SPC reg 55(6) exemption (claimant or partner blind or on AA, DLA care, PIP daily living or AFIP), so add housing_benefit_non_dep_deduction_exempt and apply it in housing_benefit_non_dep_deductions. The two pension-age severe disability tests pass with their original expected values. - Fix the investment-only test to expect the minimum; add hours to the band tests; add non-worker, worker, 16-hour boundary, zero-income and AA exemption tests. UC's non-dependant housing cost contribution is a flat amount and is unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks, María. You were right on C1, and it's fixed in 291a01c. What the regulation says
What changed
A knock-on fix Before this change, a non-dependant with zero income got a £0 deduction rather than the minimum, because I added Evidence
Unchanged and out of scope
🤖 Generated with Claude Code |
Addresses María's finding C1 on #2184. Counting other investment income in total_income pushed non-working non-dependants with investment income into the Housing Benefit gross-income bands. HB Regs 2006 reg 74(2) (SPC Regs reg 55(2)) applies those bands only to a non-dependant "in remunerative work"; anyone else aged 18 or over takes the reg 74(1)(b) minimum. Reg 6(1) defines remunerative work as at least 16 paid hours a week. - Add gov.dwp.housing_benefit.non_dep_deduction.remunerative_work_hours (16) and band income only when weekly_hours >= 16; otherwise, and for a worker below the first threshold, deduct the first-bracket (reg 74(1)(b)) amount. - The minimum now also reaches zero-income non-dependants, who previously got 0 because calc(0, right=True) fell below the first bracket. That exposed the missing reg 74(6) / SPC reg 55(6) exemption (claimant or partner blind or on AA, DLA care, PIP daily living or AFIP), so add housing_benefit_non_dep_deduction_exempt and apply it in housing_benefit_non_dep_deductions. The two pension-age severe disability tests pass with their original expected values. - Fix the investment-only test to expect the minimum; add hours to the band tests; add non-worker, worker, 16-hour boundary, zero-income and AA exemption tests. UC's non-dependant housing cost contribution is a flat amount and is unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
291a01c to
21bb4dd
Compare
|
Suggested The check isn't required yet (decision d1368); it fails fix PRs whose description names no reproducer. 🤖 Generated with Claude Code |
|
Independent review (GPT-6.1 Sol, UK hub, 2026-10-12): REQUEST_CHANGES at @vahid-ahmadi: the central change, adding
Full review below. Would you like to fix these yourself, or have the hub push the fixes as new commits on your branch? Say which here. Note that #2007 and #2017 (open drafts) overlap six of the same HB files; finding 6 suggests how to compose them. VERDICT: REQUEST_CHANGES
The central income addition is correct under ITA 2007 s 23 Step 1. The only explicit iterator over The YAML expectations are hand-derived. They cover mixed interest, allowance tapering, post-tax income, the 16-hour boundary and Attendance Allowance, but miss the regressions above. No test is weakened, skipped or xfailed by this diff. No property test covers the new accounting or deduction invariants; the existing Winter Fuel property oracle repeats the strict comparison and omits £35,000. Required invariants include counting investment income once, unchanged tax/ANI between definitions, and the corresponding post-tax-income increase. Total income should cover charged income in the supported nonnegative domain; a universal assertion would currently fail because statutory pay is omitted and some negative components differ from floored taxable bases. Statutory exemption and one-deduction-per-couple invariants also need coverage. Other open overlaps are #2002 ( Compressor usage was 21.1 GiB before testing. Serial pytest with the PolicyEngine YAML collector passed 35 changed-file cases plus 11 HB net-earnings cases. |
juaristi22
left a comment
There was a problem hiding this comment.
Reviewed 21bb4dd0649f2190af085c3f3a5be3e8100480fb. I found no model-code defect. The 49 focused tests pass, and current-head CI is 10/10 green.
Please update the PR description before merge: (1) it says only households with other_investment_income change, but the new Housing Benefit remunerative-work gate and claimant disability exemption also affect households without that income; (2) its 2025–26 non-dependant deduction examples use stale £124.55/£19.30 values, while current parameters and tests give £115.45/£19.65; (3) axiom: n/a: aggregation... covers income aggregation only, while the diff also implements Housing Benefit regulation 74(2),(6) and State Pension Credit regulation 55 rules. Please state the corresponding RuleSpec parity outcome, or a specific reason those additional rules are inapplicable. These are description and traceability corrections, so I am leaving a comment rather than requesting code changes.
|
@MaxGhenis thanks, I'll fix these myself on this branch today. |
ITA 2007 s. 23 Step 1 sums all income charged to income tax, and the model charges other_investment_income through taxable_savings_interest_income. total_income left it out, so post_tax_income subtracted tax on income it never added, and the Winter Fuel taxable-income test and HB/CTR non-dependant bands missed it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Addresses María's finding C1 on #2184. Counting other investment income in total_income pushed non-working non-dependants with investment income into the Housing Benefit gross-income bands. HB Regs 2006 reg 74(2) (SPC Regs reg 55(2)) applies those bands only to a non-dependant "in remunerative work"; anyone else aged 18 or over takes the reg 74(1)(b) minimum. Reg 6(1) defines remunerative work as at least 16 paid hours a week. - Add gov.dwp.housing_benefit.non_dep_deduction.remunerative_work_hours (16) and band income only when weekly_hours >= 16; otherwise, and for a worker below the first threshold, deduct the first-bracket (reg 74(1)(b)) amount. - The minimum now also reaches zero-income non-dependants, who previously got 0 because calc(0, right=True) fell below the first bracket. That exposed the missing reg 74(6) / SPC reg 55(6) exemption (claimant or partner blind or on AA, DLA care, PIP daily living or AFIP), so add housing_benefit_non_dep_deduction_exempt and apply it in housing_benefit_non_dep_deductions. The two pension-age severe disability tests pass with their original expected values. - Fix the investment-only test to expect the minimum; add hours to the band tests; add non-worker, worker, 16-hour boundary, zero-income and AA exemption tests. UC's non-dependant housing cost contribution is a flat amount and is unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main now uses the SI 2025/295 bands and amounts (minimum £19.65, £463-576.99 band £115.45), so the remunerative-work cases expect those. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… at £35,000 Review of 21bb4dd (hub findings 1-3): the remunerative-work gate gave the reg 74(1)(b) minimum to non-dependants the regulations exempt (full-time students, reg 74(7)(c)-(e) / SPC reg 55(7)(e)) and charged a non-dependant couple twice (reg 74(3)-(4)). Doing that properly is #2007's work, so this drops the gate, the minimum and the claimant exemption from this PR. Housing Benefit and national CTR non-dependant deductions now band on total_income less other_investment_income, so they are unchanged from main for every household until #2007 models the remunerative-work test. That also stops the national CTR deduction banding a non-worker whose only income is investment income (hub finding 3, review C1). Winter Fuel Payment (hub finding 4): ITEPA 2003 s.681I(1)(b) charges only total income that "exceeds £35,000", so the income test is now inclusive. The property-test oracle and the 2024 reform case are updated to match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
21bb4dd to
8c222fa
Compare
|
Thanks both. Pushed 8c222fa, rebased onto main (e01f2f5). I've narrowed the PR: the remunerative-work gate, the new minimum deduction and the claimant exemption are gone, and the core Why narrow. I reproduced findings 1 to 3 at 21bb4dd, and the law backs all three (HB reg 74(3), (4), (7) and (8); SPC reg 55(3), (4) and (7); SI 2012/2885 Sch 1 para 8). Fixing them properly means student and benefit exemptions, couple aggregation and CTR scheme rates. That is #2007's job almost file for file. Keeping only the 16-hour gate without the minimum would give part-time earners a new wrong result, so I dropped the whole HB expansion rather than half of it. Max's review
The double-counting analysis and the María's description points
Reproducer. Added, listing the tests in the final diff. Tests
This should be squash-merged. @juaristi22 @MaxGhenis could you re-review? |
juaristi22
left a comment
There was a problem hiding this comment.
Re-reviewed 8c222fa6602915f94c379287aca576235beb7ff5. The narrowed scope resolves the earlier blockers, and I am approving.
other_investment_income enters total income once, while tax and adjusted net income retain their independent taxable-component paths. Both non-dependant band readers subtract the new component, preserving previous HB/CTR inputs; the proposed work gate, minimum deduction and claimant exemption are removed. The underlying HB/CTR gaps remain for #2007. Actual-household controls confirm unchanged final HB/CTR, tax and adjusted net income, with post-tax income increasing by the added investment income.
The Winter Fuel boundary is now inclusive at £35,000, matching ITEPA section681I, which charges only income exceeding that amount. The scope description, examples, Reproducer and axiom status are corrected.
Validation:81 changed/regression cases pass, including the Winter Fuel Hypothesis properties, and the corrected final-accounting diagnostic passes separately (82 distinct passing checks). Two setup errors in my review-only diagnostic were corrected; no PR test failed. Seven official sources checked; captured latest hosted CI passes. Private population tables were not independently rerun.
Fixes #2174.
What was wrong
total_incomecites ITA 2007 s. 23, whose Step 1 sums all income charged to income tax. It added eight components but notother_investment_income(National Savings, securities and trust interest). Income tax does charge that income:taxable_savings_interest_incomeadds it tosavings_interest_income, soincome_taxandadjusted_net_incomeinclude it.For anyone with other investment income,
total_incomewas lower than the income the model taxes. Sopost_tax_incomesubtracted the tax on that income without adding the income, and the Winter Fuel Payment income test missed it.Separately, the Winter Fuel Payment income test took the payment away at exactly £35,000. The winter fuel payment charge it stands in for applies only where total income "exceeds £35,000" (ITEPA 2003 s.681I(1)(b), inserted by Finance Act 2026 Sch 10).
Fix
other_investment_incometototal_income.adds. It isn't double counted:savings_interest_incomeis an input that excludes it, and the two are summed only intaxable_savings_interest_income, which doesn't readtotal_income.housing_benefit_net_earningsloops overtotal_income.adds, so it picks up the new component without a code change. The denominator of its earnings share now includes the income that the tax being apportioned is charged on.total_incomelessother_investment_income, so they are exactly as onmain. Their bands apply only to a non-dependant in remunerative work (HB Regs 2006 reg 74(2), SPC Regs reg 55(2), SI 2012/2885 Sch 1 para 8(2)), and the model doesn't yet test that. Counting the new income there would band non-workers whose only income is investment income. Apply Housing Benefit and national Council Tax Reduction non-dependant deductions as legislated #2007 implements reg 74 in full (work test, exemptions, couples) and can then readtotal_incomedirectly.<=the limit, not<.employment_benefits), the related gap noted in the issue, is left for a separate change.housing_benefit_net_earningsadds it on top oftotal_income, so including it here would need that formula changed too.Who's affected
Two groups change: people with
other_investment_incomeabove zero, and pensioners not on a relevant benefit whose total income is exactly the £35,000 limit. Nobody else's results move.post_tax_incomewinter_fuel_payment_eligiblehousing_benefit_net_earningsbi_individual_phaseout,bi_household_phaseoutmainfor every household (guard tests below).Unchanged:
income_taxandadjusted_net_income, so the personal allowance taper and the High Income Child Benefit Charge.Datasets that calibrate to HMRC SPI total-income bands (for example Microcosm UK's 47
total_incometargets) now band these records by the income they're taxed on.Microsimulation, 2026,
main(e01f2f5) against this branchSame pinned file and weights for both runs, values mapped to households.
e433e532…): no change to any output. The dataset carries noother_investment_income, and no pensioner's Winter Fuel Payment moves.aa31bdf6…), which does carry it (£2.78bn over 2,305 sample households, 227k weighted):mainincome_taxadjusted_net_incometotal_incomepost_tax_incomehousing_benefitcouncil_tax_reductionwinter_fuel_allowancepost_tax_incomerises by exactly each household's other investment income (within float rounding). Every Winter Fuel Payment change is in a household with other investment income that now takes a pensioner over £35,000. Workers, non-workers and zero-income households see no Housing Benefit or CTR change, because the non-dependant deductions are unchanged, and no household's HB moved through the net-earnings apportionment either.Tests
gov/hmrc/income_tax/total_income.yaml: other investment income only; with savings interest, not double counted; above the £100k taper, wheretotal_incomeequalsadjusted_net_incomeand the personal allowance is £7,570.household/post_tax_income_other_investment.yaml: £20,000 of other investment income in 2025-26 gives tax of £286 and post-tax income of £19,714.main. The non-dependant guards and the £35,000 cases fail on the previous head (21bb4dd, rebased onto main) and pass here; the guards also pass onmain, which is what they pin.tests/policy: 5,393 passed, 100 skipped, 2 xfailed.ruff formatandruff checkare clean..github/check_fix_pr.pypasses on this description.Reproducer:
policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/total_income.yaml,policyengine_uk/tests/policy/baseline/household/post_tax_income_other_investment.yaml,policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/non_dep_deduction/household_benefits_individual_non_dep_deduction.yaml::Other investment income does not band a non-worker,policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/non_dep_deduction/housing_benefit_non_dep_deductions.yaml::A non-dependant's investment income does not raise the Housing Benefit deduction,policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_individual_non_dep_deduction.yaml,policyengine_uk/tests/policy/baseline/gov/dwp/winter_fuel_allowance.yaml::Pensioner with total income of exactly £35,000 keeps WFP,policyengine_uk/tests/policy/reforms/parametric/winter_fuel_allowance/taxable_income_test.yaml::Enable income test - other investment income counts towards taxable incomeaxiom: uk:statutes/ukpga/2007/3/23 encoded-correct (Step 1 sums every income component charged to income tax, so other investment income counts with no special case; companion case
23.test.yaml::taxpayer_liability_after_reliefs_allowances_reductions_and_added_tax); ITEPA 2003 s.681I (the £35,000 "exceeds" boundary) is TheAxiomFoundation/rulespec-uk#420 queuedThis PR no longer changes HB Regs 2006 reg 74 or HB (SPC) Regs 2006 reg 55, so it makes no parity claim for them; that work and its parity line belong to #2007.
Should be squash-merged.
🤖 Generated with Claude Code