Repository navigation
Conversation
|
Composition note: #2015 (stacked on #2009 → #2006) deletes the two household flags this PR reads.
See the "National schemes and the exemption" section of #2015. (Corrected per this PR's author.) |
Cherry-picks #2007 (59c7082: HB reg 74 / SPC reg 55 bands, remunerative-work test, couple rule and exemptions; national CTR own scales and exemptions) onto the in-unit non-dependant change (#2014) and the #2006 rent shares, as agreed with #2007's author: - HB and national CTR aggregation: one deduction for a non-dependant couple (the claimant and partner of a non-dependant family, the higher amount; both for a Welsh working-age couple on UC), any other adult in that family counted separately, in-unit non-dependants pooled and apportioned by rent share (HB) or joint-liability share (CTR), and the claimant's exemption. - Joint income for the bands is the couple's only (reg 74(4), para 8(4)); another adult is banded on their own income. - The IS, income-based JSA, income-related ESA, Pension Credit and UC exemptions apply only to the award's claimant and partner. - The HB claimant exemption reads is_claimant_or_partner, not is_adult. Drops council_tax_reduction_pension_credit.yaml and the in_receipt_of_guarantee_credit output, which depend on #1909 (main only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cherry-picks #2007 (59c7082: HB reg 74 / SPC reg 55 bands, remunerative-work test, couple rule and exemptions; national CTR own scales and exemptions) onto the in-unit non-dependant change (#2014) and the #2006 rent shares, as agreed with #2007's author: - HB and national CTR aggregation: one deduction for a non-dependant couple (the claimant and partner of a non-dependant family, the higher amount; both for a Welsh working-age couple on UC), any other adult in that family counted separately, in-unit non-dependants pooled and apportioned by rent share (HB) or joint-liability share (CTR), and the claimant's exemption. - Joint income for the bands is the couple's only (reg 74(4), para 8(4)); another adult is banded on their own income. - The IS, income-based JSA, income-related ESA, Pension Credit and UC exemptions apply only to the award's claimant and partner. - The HB claimant exemption reads is_claimant_or_partner, not is_adult. Drops council_tax_reduction_pension_credit.yaml and the in_receipt_of_guarantee_credit output, which depend on #1909 (main only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Response to review r1 of #2007 (59c7082)The review asked for changes and was right on all five P1s. Each is fixed below with the law, the change, and a test that fails on 59c7082 and passes now.
Also from the review:
Not changed: the review's UNVERIFIED items on impact (exact zeros, decomposition, poverty causation). The impact is rerun on the new head after the host is free (the Axiom build has priority until about 10:00Z). The PR description's impact section is replaced with the rerun. |
Applies #2007 at 6257277 (59c7082 plus the r1 review commit) onto #2017 (in-unit non-dependants, #2006 rent shares): - One definition of claimant or partner: #1896's is_claimant_or_partner variable. #2007's proxy helper (benefit-unit head or any member who is not a Child Benefit child or QYP) is removed and its call sites read the variable. - HB and national CTR aggregation: another family's non-dependants per deduction_per_family (the couple's higher amount, both for a Welsh working-age UC couple, and each other member's own), counted once per family and apportioned by rent share (HB) or joint-liability share (CTR); a family's own in-unit non-dependants in full (LHA Guidance Manual 2.093; HBGM A5 5.622); the claimant exemptions. charged_to_other_families ("household minus own family") is no longer used and is removed. - #2007's property oracle reads is_claimant_or_partner; the in-unit property oracle counts a couple once and applies the claimant exemptions. - Drops council_tax_reduction_pension_credit.yaml and the in_receipt_of_guarantee_credit output (#1909, main only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Carries 2d54628 (review r2 F3-F5) onto the composition with #2007: - HB pools every non-dependant family amount, in-unit ones included, through #2007's deduction_per_family and apportions it by rent share; a boarder or lodger also bears its own in full; the claimant exemption still zeroes the claim. - National CTR pools every family's amount (one per couple, the higher, or both for a Welsh working-age UC couple), replaces the applicant's own family amount with its in-unit non-dependants only, and apportions by joint-liability share; the per-applicant exemption still zeroes the claim. - CTR eligibility includes a lodger's adult son; the local schemes stay neutral. The blind-sharer case now expects the non-exempt head to bear half of the sharer's son (para 8(5)). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Response to review r2 of #2007 (6257277)The review asked for changes again and was right on all five P1s. Findings 2-5 are fixed in the next commit, each with a YAML test that fails on 6257277 (
On the property tests, the review said the oracles repeat the implementation's classification. They now take the payee as the head (the generator reports no awards) and read the child benefit QYP flag from the model. After the #1896 rebase they read |
Codex review — changes requiredReviewed commit code-1 — [P1] Replace the QYP-complement helper with actual claimant/partner rolesThe current helper Executed illustration: a reported continuing HB award for an intended couple aged70/19, both parent-flagged, with the19-year-old in qualifying education and receiving standard PIP daily living, plus a separate40-year-old working non-dependant earning£30,000. The QYP complement excludes the young partner and sets the claimant exemption false. With £10,000 council rent and HB assessable income isolated at zero, the deduction is£6,232.20 and final HB£3,767.80. A control supplying the legally appropriate claimant/partner disability exemption gives deduction£0 and final HB£10,000. This snapshot lacks the canonical explicit claimant/partner input; the diagnostic's relationship is stated as the intended premise, while the code defect is the inability of this helper to honor that premise. Adopt the canonical relationship/role variable after the prerequisite lands, then add explicit young-partner and third-adult regression cases through final awards. Do not repeat the other four r2 findings: the current tree now includes statutory sick/maternity pay, employed pension deductions and MIF; the benefit-payee test; UC after the benefit cap; and CTR's adult Child Benefit QYP exemption. Confidence: high for the current unresolved helper/integration defect. Independent source review corroborates the actual-couple and claimant/partner conditions in HB regulation 74(3)–(6), HB interpretation and England CTR paragraph 8. The overlapping code and policy finding is counted once. The current tree addresses round-two findings 2–5; this review does not repeat those stale blockers. Current 2026 scale values were corroborated. The remaining confirmed blocker is adoption of the canonical claimant/partner roles and coverage of their downstream HB/CTR behavior. Outstanding evidence/decision:
Validation: 123 focused tests passed, including round-two regression tests. An executed controlled diagnostic isolates the missing partner disability exemption's final-HB effect. The intended relationship is an explicit scenario premise, and supplied benefits/HB assessable income isolate this path; the run does not establish any actual data record's demographics. Six official source originals were inspected and their cached bytes verified. 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:41:08.415704+00:00): same commit, UNSTABLE; 0 failed checks; 1 pending checks. |
|
Review pass (Claude Code, on Vahid's behalf) at Short version: the rules match the law I read, and the tests pass locally. Two things before merge: the claimant-or-partner helper still needs #1896's role variable (the Codex review's P1, which I agree with and won't repeat), and one new should-fix on the student exemption's age default in the household calculator. 1. Should-fix: with no education input, every 18- or 19-year-old non-dependant counts as a full-time student and is exempt.
On main this non-dependant is charged, so the PR introduces the gap for HB and the national CTR schemes (the English local schemes already had it through the same helper). Datasets are unaffected, since the Enhanced FRS stores 2. The claimant-or-partner helper (Codex P1). Checked and correct:
|
A person is on income-based JSA or income-related ESA on a day it "is payable to him" (reg 2(3), (3A)), and a person on income support is one "in receipt of" it (reg 2(1)). A couple's award is paid to the claimant, not the partner. is_on_income_related_esa, is_on_income_based_jsa and is_on_income_support now hold, of the claimant and partner, only for the payee: the one who reports the award, or the claimant where neither does (is_payee_of_couple_award). Another member's report never moves the payee. Anyone else is unchanged (their own report while the award is modelled as paid). Agreed with #2007, whose round-2 review raised the same point and which applies the same reading through its is_award_payee helper; the codebase now reads "who is on" one way. Effects: in the local working-age CTR schemes a non-dependant couple on one of these benefits pays the partner's deduction (one deduction per couple, the higher: Default Scheme Sch para 30(3)); the maintenance-loan ESA proxy follows the student's own award, not their partner's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e92b5d1 to
f5aae26
Compare
|
Composition note from #2078 (stacked on #2009), which makes the CTR means test assess the applicant and partner rather than the benefit unit's claimant and partner. #2078 changes When this PR's national exemption ( |
Housing Benefit (SI 2006/213 reg 74; SI 2006/214 reg 55): - bands include their lower edge, and only a non-dependant in remunerative work (16+ hours, reg 6(1)) is banded, on the couple's joint income; anyone else pays the reg 74(1)(b) amount; - one deduction per couple, the higher (reg 74(3)); - no deduction for full-time students, State Pension Credit recipients, or under-25s on IS, income-based JSA or UC without earned income (reg 74(7), (8), (10)), nor for any non-dependant when the claimant or partner is blind or on AA, DLA care, PIP daily living or AFIP (reg 74(6)). Council Tax Reduction (SI 2012/2885 Sch 1 para 8; WSI 2013/3029 Sch 1 para 3 and Sch 6 para 5; SSI 2012/319 reg 48; SSI 2012/303 reg 67 and SSI 2021/249 reg 90): - each national scheme's own weekly scale for 2013-14 to 2026-27, instead of the Housing Benefit amounts; - the same banding and couple rules, with Wales's working-age exception for couples on UC; - the schemes' any-age exemptions, the UC limb from the year each scheme added it, and the existing applicant exemption. Fixes #2004; the non-dependant half of #1934. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s, gross income - Identify the claimant or partner as the benefit unit's head or any member who is not an SSCBA s.142 child or qualifying young person (HB Regs 2006 regs 2(1) and 19; CTR regs 2(1)), replacing is_adult in the HB and CTR claimant exemptions. - Band a couple on the couple's joint income only, give the couple one deduction and any other adult in the family their own, and count benefit receipt (IS, JSA(IB), ESA(IR), SPC, UC) only for the award's claimant or partner. - Treat a non-dependant on IS, JSA(IB) or ESA(IR) as not in remunerative work for HB (reg 6(6)). - Take self-employed losses as nil in the UC no-earned-income test (UC reg 57(2)). - Add the family's UC (before the cap), tax credits and child benefit to gross income. - Tests: the review's counterexamples, a non-vacuous SPC exemption case, and property-test generators and oracles for dependent young people and losses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…A disregard - "No earned income" follows UC Regs 2013 regs 52-62: employment income plus SSP and SMP less relievable pension contributions (reg 55(4)-(5)), self-employed earnings with losses nil and the minimum income floor where the UC model applies it (regs 57(2), 62), and other paid work. - IS, JSA(IB), ESA(IR) and SPC count only for the person they are payable to (HB Regs 2006 reg 2(3)-(3A)): the member reporting the award, or the head; used for the exemptions and HB reg 6(6). UC still counts for both joint claimants. - Gross income uses UC after the benefit cap (UC reg 81), applying the cap to the capped benefits other than HB, which a non-dependant family does not receive. - CTR exempts an adult for whom another person is entitled to child benefit (LGFA 1992 Sch 1 para 3, via para 8(8)(b) and equivalents). - Tests: the review's counterexamples, and property oracles for the payee and the child benefit disregard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the local claimant-or-partner helper (benefit unit head, or anyone not a child benefit child or qualifying young person) with the is_claimant_or_partner variable: the SSCBA s.137 couple, at most two people. A partner at school is now a partner, and a third adult in a benefit unit is deducted separately. Adds the round-2 review cases: a blind 16-year-old partner (Wales), a non-dependant couple with a partner at school, and a 17-year-old partner's PIP in Merton. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The changelog and the property generator's comment now name is_claimant_or_partner instead of the SSCBA s.142 definitions, and is_award_payee says that both members of a joint-claim jobseeker's allowance couple are on it (HB reg 2(3)(c)), which the model cannot identify. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ap childcare, child benefit claims - Gross income adds statutory sick, maternity and paternity pay (earnings, HB reg 35(1)(i)) and Maternity Allowance to each person's taxable income, and the family's IS, JSA(IB), ESA(IR) and Pension Credit to a couple's. - Earned income for the UC limb adds statutory paternity pay (UC reg 55(4)(c)), and relievable pension contributions come off self-employed earnings when there are no employed earnings (reg 57(2), step 4). - Scotland's working-age scheme exempts a non-dependant whose partner is on IS, JSA(IB) or ESA(IR) and who is not on Universal Credit, from April 2022 (SSI 2021/249 reg 90(8)(a), reg 4(1)). - The after-cap UC in gross income keeps the cap's childcare protection (UC reg 81(1)-(2)). - The LGFA 1992 Sch 1 para 3 disregard needs a child benefit claim. - The property oracle derives the claimant and applicant exemptions from the generated inputs, and the generator varies statutory pay, pension contributions, the start-up period, the award's reporter and child benefit claims. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f5aae26 to
084e1f9
Compare
HB(SPC) Sch 3 para 6 has the working-age premium's conditions and para 12 its amounts, so the pension-age premium is severe_disability_premium for a family over State Pension age. A Pension Credit reform no longer moves pension-age HB or CTR. The schedule property keeps the Pension Credit addition as a cross-check. References add the CTR nomination rule and the other premium schedules; the conditions YAML notes the three income-rule defects its awards include (#1908, #2112, #2007). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Takes main's uv.lock, which drops an unintended one-line lock change from this branch's first commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Generated by Claude Code |
|
Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6JPH2P5XFEgwSLLAb1
|
Ready for hub review Head: Before starting: the last push to FindingsP3-1 (per-benefit-unit contract).
P3-2 (runs, mutants, invariant 14).
P3-3 (Axiom addendum).
P3-4. I added the review's sentence to the P3-5 (voice table).
Merge note. The body names #2784 at Text-only check
Tests (no survey data,
|
| Run | Head | Result |
|---|---|---|
test_non_dependant_cycle_contracts.py, test_non_dependant_deduction_properties.py, test_non_dependant_population_consistent_total.py, code_health/test_test_module_caches_released.py and test_parameter_descriptions.py together |
c2c55086e |
58 passed (14 + 10 + 5 + 5 + 24 by collection) |
test_non_dependant_deduction_properties.py, code_health/test_test_module_caches_released.py and test_parameter_descriptions.py together |
4ec0693f7 |
39 passed |
test_non_dependant_deduction_properties.py alone |
first amend of 4ec0693f7 (intermediate) |
10 passed |
YAML policy/baseline/gov/dwp/benefit_cap |
c2c55086e |
118 passed |
code_health/, with towncrier installed |
c2c55086e |
3,104 passed |
ruff@0.17.2 format --check ., check ., check --select F811,F821 policyengine_uk, git diff --check |
4ec0693f7 |
clean |
Mutation and revert checks
None. These commits change no formula, so there was nothing to revert. The review already reported the contract mutants (M1 and M2, 3 failures each), and the body now states them.
Skipped
- I didn't rerun the HB non-dependant and CTR YAML directories, the differential or the other property files, because these commits change no formula or YAML. CI covers them.
- I ran nothing that needs a survey dataset.
Judgment calls
- I pushed to
hub/2007-r5as well as to the session branch, since the brief allows a fast-forward there. - P3-4: of the review's two options, I took "add to the message".
- HB reg 74(1)-(2) at 2025: I marked it pending instead of rebuilding it from the 2026 text.
- I edited the posted body and addendum comments in place once to pin the final SHA. The first versions pinned
c2c55086e.
Generated by Claude Code
|
Ready for hub review Verdict: APPROVE WITH NITS at I checked out the head detached in a scratch worktree and ran FindingsNo P1 or P2 findings. P3-1.
|
| Finding | Status | Evidence |
|---|---|---|
| P3-1 per-benefit-unit contract | Closed | The message (uc_benefit_cap_welfare_benefits.py:26-39), its documentation (:50-55), benefit_cap_welfare_benefits.py:63-69, the changelog's last sentence, the body's "Universal Credit's cap" paragraph and invariant 15 all carry the review's row 1-4 and 7-8 text. The code agrees: the formula checks supplied_input(...) is not None for the whole population, and a supplied basket replaces the formula outright. My probe of two single-person benefit units, with the inputs set on u1 only: total alone gives ValueError; total plus HB £0 gives basket [20000, 0]; total plus basket £20,000 gives basket [20000, 0]. So the other unit reads nil, as the new text says. |
| P3-2 body runs, mutants, invariant 14 | Closed | The review's runs bullet and mutant paragraph are in, the false sentence is gone, and invariant 14 reads "At 95fbf3014 the same 60 families give arrays bit-identical to 02cc0896f's." |
| P3-3 Axiom 2025 law and pin | Partly closed | The header and first paragraph pin 4ec0693f7…. England's 2025 para 8(1)-(2) matches the review's quotation character for character (string compare: True). The 2025 HB reg 74(1)-(2) is filled in, but the summary sentence it was meant to replace is still there (P3-1 above). |
| P3-4 neutralized HB pre-cap | Closed | The message's last sentence and the body's reform bullet now name it. |
| P3-5 voice table | Closed | Rows 1-16 are applied where the hand-off says. Row 6 reads "The two couples match unless the inputs set is_uc_claimant." in both files, which is fine. Row 16's docstring drops the old one-input sentence, and its new last sentence ("Where they supply housing_benefit_pre_benefit_cap, Universal Credit reads that input without calculating Housing Benefit.") is accurate. |
Merge note, #2784 at 55e015e10 |
Closed | The body names 55e015e10. |
Judgment calls
- Fast-forwarding
hub/2007-r5is allowed by the brief.git ls-remoteshowshub/2007-r5andclaude/apply-2007-r5-nits-ogc2zeat4ec0693f7, andhb-ctr-non-dep-exemptionsstill at97f792542. - Of P3-4's two options, the author added the sentence to the message. That is reasonable and touches no logic.
- The author marked the 2025 reg 74 text pending rather than rebuilding it, which was right. The hub then filled it in (see below).
Text-only check (my own comparison). For each changed .py file at each commit, I blanked every string constant, dropped the constant parts of f-strings and compared ast.dump against the parent. All four files in c2c55086e and the one in 4ec0693f7 give True. The only other changed file is changelog.d/2004.fixed.md. git diff -w --word-diff=porcelain c2c55086e..4ec0693f7 shows no word changes, so the second commit only rewraps. The one executed string that changed is the ValueError message.
The three message-asserting tests still match. test_non_dependant_cycle_contracts.py:328, test_non_dependant_deduction_properties.py:1172 and test_non_dependant_population_consistent_total.py:103 all use match="housing_benefit_pre_benefit_cap", and the new message contains that name. A git grep for the old wording ("for the cap to subtract", "cap counts as nil") finds no other test.
The filled 2025-04-07 HB reg 74(1)-(2)
- Its figures (£126.65, £19.65; £183.00, £266.00, £348.00, £463.00, £577.00; £45.15, £62.00, £101.35, £115.45) equal the summary sentence and the
2025-04-01values inparameters/gov/dwp/housing_benefit/non_dep_deduction/amount.yaml. - With the figures masked, its wording is identical to the 2026-04-06 quotation.
- The companion holds: £18,753 / 52 = £360.6346…, which falls in (d)'s £348.00-£463.00 band, so £101.35 × 52 = £5,270.20. £18,032.75 / 52 = £346.7837… falls in (c)'s £266.00-£348.00 band, so £62.00 × 52 = £3,224. Both fall in England's £266.00-£463.00 band, so £10.20 × 52 = £530.40.
- The body's 2025-26 YAML figures (£100 / £183.02 / £349 / £578 giving 19.65 / 45.15 / 101.35 / 126.65) fit the same bands.
Runs at 4ec0693f7 (uv run pytest … -n 4; uv run policyengine-core test … -c policyengine_uk)
| Run | Result |
|---|---|
test_non_dependant_cycle_contracts.py, test_non_dependant_population_consistent_total.py, test_non_dependant_deduction_properties.py, code_health/test_test_module_caches_released.py, test_parameter_descriptions.py together |
58 passed in 238.62 s (14 + 5 + 10 + 5 + 24; the parameter-descriptions file collects 24) |
YAML policy/baseline/gov/dwp/benefit_cap |
118 passed |
YAML benefit_cap_by_scheme.yaml |
22 passed |
code_health/ (towncrier importable) |
3,104 passed in 289.87 s, matching the author's count at c2c55086e |
Mutant M2 in the scratch copy (replace raise ValueError(...) with return benunit("benefit_cap_welfare_benefits", period)), then test_non_dependant_cycle_contracts.py |
Killed: 3 failed (test_a_supplied_total_alone_raises[mixed], [single], test_model_values_supply_neither_input), 11 passed. I restored the file and the worktree is clean. |
ruff format --check ., ruff check ., ruff check --select F811,F821 policyengine_uk with ruff==0.17.2 (the version uv.lock pins) |
clean ("2174 files already formatted", "All checks passed!") |
git diff --check 2667976b8 4ec0693f7 |
clean |
Merge with current main. git merge-tree --write-tree origin/main 4ec0693f7, with main at 46a60678ff52d829253572393abdcc6a03ceb6a7 (17 commits past 2da212abc), is clean (exit 0).
Writing. I read every line of text this delta touched: the message, the two documentation strings, the benefit_cap.py docstring, the fixture comment, the invariant 12 docstring, the changelog, the body sections that changed and the Axiom additions. It has no passives and no fix history. Actors are DWP, the model, the formula or a caller. The rewrapped docstring is unchanged word for word.
What I couldn't check
- The 2025-04-07 HB reg 74(1)-(2) against the capture (
52cfed4d…7d61): legislation.gov.uk doesn't resolve from here. The filled text agrees with the summary, the parameters and the companion. Its wording is also the 2026 text with the 2025 figures in place, so these checks can't tell a faithful copy from a reconstruction. Only the capture can. - The previous round's logs and witnesses on the hub's machine (the 60-family differential, the probe, the CTR and HB non-dependant YAML directories). This delta changes no formula or YAML, so I didn't rerun those.
- CI and the aggregate-impact job at this head, which haven't run yet.
- The merges with Charge non-dependant deductions within the claimant's benefit unit #2017, Charge in-unit non-dependants in the local Council Tax Reduction schemes, and exclude a lodger personally only outside the head's family #2077, Give Scotland and Wales working-age CTR their own rules #1966, Universal Credit is paid to full-time students (WRA 2012 s. 4(1)(d); UC Regs 2013 regs. 12-14) #2346 and Count Maternity Allowance in the benefit cap #2784. I checked only main.
Generated by Claude Code
Conflicts: the Housing Benefit notebook's means-test sentence keeps #2007's non-dependant deduction sentences and main's applicable-income sentences; shard_durations.toml keeps both sides' timings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6HoH87XjnfRqcGiYmc
main's benefit_cap_reduction_applied.yaml supplies benefit_cap_welfare_benefits alone. Under this branch's contract a supplied total comes with the Housing Benefit in it, so each case supplies the nil the model calculates without rent; the outputs don't change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6HoH87XjnfRqcGiYmc
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6HoH87XjnfRqcGiYmc
Git stopped on one file, the documentation of benefit_cap_welfare_benefits. The merge keeps this PR's sentences on the two baskets and the supplied total, and #2811's sentences on Maternity Allowance and the other welfare benefits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With #2811 on main, DWP's cap counts the partner's 6,000 of Maternity Allowance, so the case's Universal Credit and both deductions move to the figures its comment worked out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
esa_income_abolition_reached moves a couple reporting income-related ESA to Universal Credit in 2026, and the award moves the working partner's band. These cases test how income-related ESA counts in the band, so the couples stay on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes #2004
Fixes #1934. Main already keeps people on IS, JSA(IB), ESA(IR) or Universal Credit out of the pensioner scheme (#1944). This PR adds the issue's non-dependant deductions. The model lacks inputs for assessment-phase ESA(IR) and a working student's summer vacation.
Summary
The model now calculates Housing Benefit and national Council Tax Reduction non-dependant deductions under each scheme's own rules. We use legislation.gov.uk's 7 April 2025 text and each year's CTR amending instruments.
Housing Benefit (SI 2006/213 reg 74). SI 2006/214 reg 55 sets pension-age HB deductions.
right=Trueputs £192.00 a week in the band belowCouncil Tax Reduction. We model three national schemes:
Changes
gov.benefit_uprating_cpi.council_tax_reduction_applicant_has_non_dep_exemption, which only the English local schemes read on main, to national CTR calculations.New variables:
housing_benefit_non_dep_deduction_exempt(Person),housing_benefit_non_dep_deductions_claimant_exempt(BenUnit),council_tax_reduction_non_dep_deduction_exempt(Person),uc_benefit_cap_welfare_benefits(BenUnit).New parameters: HB
income_related_benefit_age_limit(25); per CTR scheme,non_dep_deduction/{amount, exempt_universal_credit_without_earned_income}; Scotlandworking_age_exempt_partner_of_income_related_benefit_claimant(from 2022-04-01). HBage_threshold(18) now starts in 2006, when the 2006 Regulations took effect.Universal Credit's cap. The new
uc_benefit_cap_welfare_benefitsholds the welfare benefits the Universal Credit cap counts: those inbenefit_cap_welfare_benefits, for the same single person or couple, with Housing Benefit at nil (UC reg 80(2A)).uc_benefit_cap_reductionreads it where main read the combined total lesshousing_benefit_pre_benefit_cap. The Housing Benefit cap (HB reg 75C) keeps the combined total. A caller who suppliesbenefit_cap_welfare_benefits, a total that includes Housing Benefit, must also supplyhousing_benefit_pre_benefit_cap, which the new variable subtracts, oruc_benefit_cap_welfare_benefitsitself, with a value for every benefit unit. Otherwise the new variable raisesValueErrorand names both inputs, whether or not any household has a non-dependant. A value a scenario stores withset_model_valuesupplies neither. No baseline formula onuniversal_credit's route then calculates Housing Benefit, so the deductions can read the award itself.uc_benefit_cap_reduction_after_floorkeeps main's code. The baseline cap and award arrays match main (invariant 14).Gross income
DWP instructs councils to count "earnings, and any other income" as a non-dependant's gross weekly income (HB guidance A5.542), to add savings interest to earnings (A5.570), and to take no business expenses off a self-employed person's total income (A5.551). Reg 74(9) and its equivalents disregard specified disability, compensation and trust payments.
housing_benefit_non_dep_gross_income,council_tax_reduction_non_dep_gross_income): earnings, statutory sick, maternity and paternity pay, pensions, the taxable social security benefits, savings and dividend income, miscellaneous income, Maternity Allowance, IIDB, SDA, war widow's pension, and child and spousal maintenance. We add other investment income, ISA interest and ISA dividends, as main's local CTR schemes do.tax_free_savings_incomecounts ISA interest unless the inputs supply a total. The model holds self-employment and property profits rather than the receipts A5.551 describes, so we count each profit and treat a loss as nil.claimant_or_partner_jsa_income,claimant_or_partner_esa_income), Pension Credit, and Universal Credit where the award assesses either of them. It bands anyone else in the family on their own income, plus the Universal Credit whereis_uc_claimantmakes them its claimant instead.universal_credit, plusuc_deductionswhere the award is positive. DWP awards the maximum amount less the amounts for income (Welfare Reform Act 2012 s.8(1)). DWP then takes advances (SI 2013/383 reg 10), overpayments (SI 2013/384 regs 10-11) and third-party payments (SI 2013/380 Sch 6 para 2(1)) from the sum payable, so those deductions stay the family's income.universal_credit's formula reach the deduction throughuniversal_credititself.uc_benefit_cap_welfare_benefitsreads it throughCLAIMANT_OR_PARTNER_BENEFITS, so DWP's cut reaches the award the council counts. For a non-dependant family with £20,000 of Universal Credit before a £14,753 cap and £5,000 of Maternity Allowance, DWP pays £9,753 of Universal Credit, and the council counts that award.universal_creditwithout a cycle in any mix of households, andhousing_benefit_non_dep_deductionsneeds no early return. A supplied combined total comes with a suppliedhousing_benefit_pre_benefit_caporuc_benefit_cap_welfare_benefitsfor every benefit unit (invariant 15). A reform can add a read of calculated Housing Benefit to that route; the engine then raisesCycleErrorin the deduction, as it does inuniversal_credit.benefit_cap_welfare_benefitschanges the Housing Benefit cap alone. To change the benefits the Universal Credit cap counts, a reform replacesuc_benefit_cap_welfare_benefits. A reform that neutralizeshousing_benefit_pre_benefit_capdrops a supplied value, so a caller who supplies the total under it suppliesuc_benefit_cap_welfare_benefits; theValueErrormessage says so.Inputs and choices
is_on_income_support,is_on_income_based_jsa,is_on_income_related_esaandis_on_pension_credit, which ask whether DWP pays the award to that person (HB reg 2(1), (3), (3A)). Universal Credit counts for each claimant its award assesses (is_uc_assessed_claimant, the claimant and partner unlessis_uc_claimantnames others). For entitlement we read the award before the cap (universal_credit_pre_benefit_cap > 0): UC reg 80(2) uses "the amount to which the claimant is entitled before any reduction under regulation 81".current_education != NOT_IN_EDUCATIONorin_HE, the helper the local schemes use. With no input, the model gives an 18- or 19-year-old tertiary education, so it counts them as students.is_claimant_or_partner(Replace generic child and adult flags with each programme's legal definitions #1896), the benefit unit's claimant and at most one partner (SSCBA s.137).uc_individual_earned_income, so UC's deductions, company attribution, trading losses and conditional minimum income floor reach the exemption. DWP takes allowable employment expenses, tax, National Insurance and relievable pension contributions off earnings (UC reg 55(3), (5)). It adds trades' profits and losses together and attributes a company's income to its owner (reg 57(2), reg 77(3)(b)), and it applies the minimum income floor only where reg 62 does, a couple's floor included. The limb asks whether "the award is calculated on the basis that the non-dependant does not have any earned income", and DWP calculates a joint award on combined earnings under reg 22(1)(b). We test the non-dependant's own earned income; we found no DWP guidance on joint claims.Not modelled
esa_includes_support_componentmarks the support group only.is_apprenticehas no £195 earnings cap, so we don't read it.How this composes with main
housing_benefit_non_dep_deductions). For each family we sum each other family's amount (one per couple, the higher, plus one for each other member) over the non-dependants of the household head (Give sharers, boarders and lodgers their own rent, tenure and LHA category #2006). We treat a family that bears any share of the rent as a joint occupier, not a non-dependant (reg 3(2)(d)), even at nil rent. We then multiply the total by the family'sshare_of_household_rent(reg 74(5)) and zero it under the family's own claimant exemption.council_tax_reduction_non_dep_deductions). Each applicant family takes its deductions under its own scheme (council_tax_reduction_pensioner, Assess each Council Tax Reduction claim under its own family's scheme and exemption #2015). The person-level variables report the scheme of the household head's family, which Give Council Tax Reduction to the household head's family, not the oldest adult's #2009 makes the applicant; for a jointly liable applicant on the other scheme,_national_non_dependants.pyrecomputes the deductions under that scheme. We multiply the total bycouncil_tax_reduction_joint_liability_share(para 8(5)) and zero it under the family's owncouncil_tax_reduction_applicant_has_non_dep_exemption.Invariants
The property tests check these over generated populations (10 examples each, with explicit cases for rare combinations), the exhaustive edge test checks invariant 7, the fixture comparison invariant 8,
test_rent_of_sharers_boarders_and_lodgers_properties.pyinvariant 10, differential runs invariant 14, andtest_non_dependant_cycle_contracts.pyandtest_non_dependant_population_consistent_total.pyinvariant 15:is_uc_claimant, so another member's award as a single claimant appears.tests/fixtures/council_tax_reduction_non_dependant_deductions.yaml.housing_benefit_pre_benefit_cap. A reform can add a read of calculated Housing Benefit, and its cycle raisesCycleError. The Universal Credit in a non-dependant family's gross income equalsuniversal_creditplusuc_deductions. That sum equals the award before the cap less the cap reduction applied, under current law and under an 85% protected minimum floor, and the floor never lowers an award. Under a reform that scalesuniversal_credit, each household's HB and CTR deductions equal those of the same household with the reformed award supplied. The HB deduction equals the band of wages plus that award, so it moves when the award crosses a band.uc_individual_earned_incomeacross employment expenses, trading losses, company income, pension contributions and single and couple floors, and with the inputs wherever they settle it without the tax and National Insurance calculation.02cc0896f, under current law and under the 85% floor, main and that head gave bit-identicaluc_benefit_cap_reduction,uc_benefit_cap_reduction_after_floor,uc_deductionsanduniversal_creditarrays for 60 families on Universal Credit, and main's cap formulas and that head's gave identical arrays over 4,096 rows of inputs, with and without a supplied cap reduction and a protected floor. At95fbf3014the same 60 families give arrays bit-identical to02cc0896f's. Where a family supplies Housing Benefit alongside Universal Credit, which the model's Housing Benefit eligibility rules out when it calculates both, the basket differs from main's combined total less Housing Benefit by at most £0.004, one float32 step.benefit_cap_welfare_benefitsalso supplyhousing_benefit_pre_benefit_caporuc_benefit_cap_welfare_benefits; otherwise the model raisesValueErrorwhen it calculates Universal Credit's cap, with or without a non-dependant in the population. A value stored withset_model_valuesupplies neither, and a reform that gives the combined total a formula leaves Universal Credit's basket on its own sum. When the inputs give each benefit unit its own values, each household's Universal Credit, Housing Benefit and HB non-dependant deductions equal its results alone, for any mix of independent households and whichever result the first request asks for. A situation that sets either input for some benefit units stores nil for the rest.Tests
YAML (hand-worked expectations from the law):
Main's tests that change. Each move follows from the law:
household_benefits_individual_non_dep_deduction.yaml:housing_benefit_non_dep_remunerative_work.yaml(Split total income into programme-specific concepts #2620): for the nil-income non-worker the council deducts £20.40 × 52 = £1,060.80 (reg 74(1)(b)), not £0; the under-25 on Income Support now reaches £0 through the reg 74(8)(a) exemption, and the case computes eligibility instead of taking it as an input.council_tax_reduction_non_dep_remunerative_work.yaml(Split total income into programme-specific concepts #2620), 37 cases: each scheme's 2026-27 scale replaces the HB scale. For non-workers the councils deduct £270.40 (England), £288.60 (Scotland) or £348.40 (Wales) a year, and for £403.85 a week in work £551.20, £569.40 or £694.20. For a recipient of IS, JSA(IB) or ESA(IR) they deduct nothing (para 8(8)(a)), and for the nil-income non-worker England's £270.40. Each English case with a 30-year-old non-dependant now gives the household a separate 70-year-old applicant, and the model works out each family's scheme.council_tax_reduction_non_dep_gross_income.yaml(Split total income into programme-specific concepts #2620), 15 cases: £183.08 a week falls below every scheme's first band edge, so each scheme deducts its 2025-26 lowest amount (England £260, Scotland £278.20, Wales £325 a year) and the reduction comes to £4,000 less that.test_non_dependant_spousal_maintenance.py: the national CTR comparison moves to Wales, whose scheme covers working-age applicants: [£348.40, £348.40, £694.20, £348.40].housing_benefit_non_dep_deductions.yaml: for the non-worker with investment income the council deducts £19.65 × 52 = £1,021.80, where main'sright=Truegave £0.council_tax_reduction_individual_non_dep_deduction.yaml, on England's 2025-26 pensioner scale (SI 2025/39): for a non-worker with £556 a week of investment income the council deducts £5.00 × 52 = £260, and a worker's band counts it, £15.35 × 52 = £798.20.council_tax_reduction_pension_credit.yaml: for the son with no hours the council deducts England's £5.20 a week, so CTR is £1,729.60.claimant_family_scheme.yaml: for the 40-year-old adult child it deducts £5.20 × 52 = £270.40, so CTR is £1,529.60.housing_benefit_individual_non_dep_deduction_eligible.yaml: the 18-year-old "Eligible" case setscurrent_educationandwould_claim_uc: false; otherwise the age default makes them a student, and an income-free 18-year-old has Universal Credit without earnings.test_rent_of_sharers_boarders_and_lodgers_properties.py: the HB pool counts one deduction per couple, the higher, and only families without an exempt claimant bear it (invariant 10).benefit_cap_by_scheme.yaml, "UC reg 81(2) - no reduction where the childcare costs element exceeds the excess": the case supplies the combined total, so it now supplies the £0 of Housing Benefit the model calculates for it, and its outputs don't change. The other eight YAML cases that supply the total already supplyhousing_benefit_pre_benefit_cap. Before this change only one Python test supplied the total, the one intest_non_dependant_deduction_properties.pythat this PR rewrites.pension_age_severe_disability_conditions.yaml,claimant_household_head.yaml,housing_benefit_non_dep_gross_income.yamlandtest_housing_benefit_non_dep_history.pychange only in comments, apart from the new ISA case in the gross-income file.test_non_dependant_deduction_properties.py: Hypothesis populations for invariants 1-6, 9 and 11, which varyis_uc_claimant, with explicit examples for the rare Welsh-couple and under-25 cases; the exhaustive edge check (7); the fixture comparison (8); and the earned-income comparison (13). For invariant 12, one property compares the basket and the award under current law and an 85% floor with debt deduction rates; its explicit example takes £720.25 of debt and no cap reduction, so the award counts £20,000. Another scales the award by a reform, and its explicit example moves a non-dependant from the 348 band to the 266 band. A third traces Universal Credit, which reads no calculated Housing Benefit, and checks that a supplied total without Housing Benefit raisesValueError. The invariant 12 tests build core simulations on one tax-benefit system for the module.test_non_dependant_cycle_contracts.py(invariant 15) uses two independent households: a single Universal Credit claimant with £20,000 before a £14,753 cap and no rent, and a 70-year-old paying £6,000 rent with a non-dependant who earns £9,000 at 20 hours and claims no Universal Credit. For the second's non-dependant, the council deducts £19.65 × 52 = £1,021.80 (HB regs 70 and 74(2)(a), 2025-26), leaving £4,978.20 of Housing Benefit.ValueError, with or without the non-dependant.set_model_valuesupplies neither input, and a reform that gives the total a formula leaves Universal Credit's basket on its own sum.CycleError. With nothing supplied, a traced run shows Universal Credit reading only reported Housing Benefit, and the national and five local CTR schemes then read Universal Credit.test_non_dependant_population_consistent_total.pytakes each household's combined total and Housing Benefit from its own simulation with nothing supplied (£20,000 and £0; £4,978.20 and £4,978.20). Supplied together for the mixed population, they give each household its results alone for each first request, and the totals without the Housing Benefit raiseValueError.code_health/test_benefit_cap_lists_unique.pychecks that each name occurs once in the lists the two caps and a non-dependant family's income add up.Mutation testing. At
97f792542the tests killed the mutants of the earned-income limb, the Welsh couple rule, either exemption's earned-income test, the ISA income, the joint-occupier share and the partner's PIP. At86e86d3dbthey killed every other mutant of the rules except one that removes CTR's reg 10(6) work exclusion, which changes no result, because each scheme's para (8)(a) exemption already gives such a non-dependant no deduction. At02cc0896f, the tests killed nine of ten mutants of the award and the cap's basket:universal_credit, or counting Universal Credit before the cap;uc_benefit_cap_reductionreading the combined total with Housing Benefit; a supplied combined total never reaching the cap, or keeping its Housing Benefit; the basket leaving out income-based JSA and income-related ESA;housing_benefit_non_dep_deductionsreading income with no non-dependant, or returning nil for every household.The survivor adds debt deductions to a nil award. It changes no result under current law, where a positive deduction always leaves at least a penny of award. The basket leaving out child benefit and the cap ignoring the childcare costs element also failed their tests at
02cc0896f. This head deletes the early return that the no-non-dependant mutant changed.We also ran two mutants of the supplied-total contract. Restoring the calculated read, so that the basket subtracts
housing_benefit_pre_benefit_capfrom a supplied total whether or not the inputs supply it, makestest_a_supplied_total_alone_raises[mixed]and[single]raiseCycleErrorinstead ofValueError, andtest_model_values_supply_neither_inputstops raising. Dropping theValueError, so that a supplied total without Housing Benefit counts in full, makes all three stop raising.Differential against main. In 20 households with 40 people in five English councils (Merton, Kingston, Newham, Westminster and Oxford), each non-dependant earns £9,000 and has nothing else, £20,000 of other investment income, a £5,000 self-employment loss or a £5,000 property loss. At
86e86d3db, main2da212abcand the head gave identical arrays for all five local schemes' reductions, individual and family non-dependant deductions, and the shared eligibility, applicant-exemption, pensioner and joint-liability flags: 19 of 21 arrays. The two national gross-income arrays differed in the 15 investment and loss cases: £9,000 becomes £29,000 with investment income, and £4,000 becomes £9,000 with a loss.Runs, locally with no survey data, each file alone under a 4 GB memory cap (2 GB for mutants), at
95fbf3014unless stated.2667976b8then adds only a module-scoped fixture that clearsscaled_award_system's cache.gov/dwp/benefit_cap/118 passed, the HB non-dependant directory 139,gov/local_authorities/council_tax_reduction/376, andbenefit_cap_by_scheme.yaml22 at2667976b8.test_non_dependant_cycle_contracts.py14 passed,test_non_dependant_population_consistent_total.py5,test_non_dependant_deduction_properties.py10 (also at2667976b8),test_uc_deductions.py24,test_benefit_cap_uc_and_hb_properties.py1, the sharers properties 6 and the LHA scheme-split properties 7.code_health/withouttest_changelog_fragments.py: 2,999 passed and 2 failed.test_pytest_default_collection_confirms_function_and_class_namesfails only whenPYTEST_ADDOPTScarries-n 0into its nested pytest, and passes without it.test_every_test_module_cache_is_releasedfoundscaled_award_system's module-level cache, which2667976b8releases; at2667976b8that file reports 5 passed.test_changelog_fragments.py, run on its own with towncrier installed, reports 103 passed.uc_benefit_cap_reduction,uc_benefit_cap_reduction_after_floor,uc_deductionsanduniversal_creditarrays at95fbf3014and02cc0896f, under current law and under the 85% floor.ruff format --check,ruff check,ruff check --select F811,F821andgit diff --checkagainst main report nothing.4ec0693f7, whose two commits after2667976b8change only documentation strings, comments, the changelog and theValueErrormessage's text (no test asserts the changed wording; with every string literal blanked, each changed Python file parses to the same tree):test_non_dependant_cycle_contracts.py14 passed,test_non_dependant_population_consistent_total.py5 andgov/dwp/benefit_cap/YAML 118 atc2c55086e;test_non_dependant_deduction_properties.py10,code_health/test_test_module_caches_released.py5 andtest_parameter_descriptions.py24 at4ec0693f7;code_health/with towncrier installed 3,104 passed atc2c55086e;ruff format --check,ruff check,ruff check --select F811,F821andgit diff --checkreport nothing at4ec0693f7.Impact (Enhanced FRS 2024-25, certified uk-data 1.58.1)
CI's aggregate impact job (run 42049540193) compared main
e3765cb61witha00efbd699, its merge of this head into that main. It ran each fiscal year as a full microsimulation on both sides, on the certified dataset (sha256056e80fd8e91), broke no check and flagged no move for review.Tax receipts and population don't change in any year. We estimate that absolute poverty after housing costs falls by 2.2k to 7.2k people a year, and absolute poverty before housing costs rises by 47 to 1.3k. Relative poverty after housing costs falls in six years, by up to 7.1k (2026-27), and rises by 322 in 2031-32. The flat charge for non-workers and the wider gross-income rules leave some households worse off.
Merge with main
0198ce4c98b3ec37f8bf6d11a5c125c8cc8b7865mergesmainat5c7744144intofde435bd3with a merge commit. Git stopped on two files, and the merge keeps both sides in each:docs/book/programs/gov/dwp/housing-benefit.ipynb, step 3 ("Means test"). This PR adds the sentences on reg 74's bands, couples and exemptions after the reg 70 sentence.mainappends sentences on applicable income: income tax and National Insurance come off earnings, pensions and benefits, regulation 46(4) and the pension-age Schedule 5 paragraph 22 treat income from capital as capital, and the rent for letting part of the home counts less £20 a week per occupier. The merged sentence runs reg 70, this PR's sentences, the taper and Northern Ireland sentences, thenmain's.policyengine_uk/tests/shard_durations.toml: this PR's fourtest_band_edges_are_inclusivetimings andmain's seventest_person_isa_capital.pytimings with their comment, at the same place.Git merged every other file,
uc_benefit_cap_reduction.py,supplied_inputs.py,programs.yamlandcouncil_tax_reduction_pension_credit.yamlamong them, without a conflict. At the merge, this PR's 20 YAML test files report 339 passed, and its seven Python test files (test_benefit_cap_lists_unique.py,test_housing_benefit_non_dep_history.py,test_non_dependant_cycle_contracts.py,test_non_dependant_deduction_properties.py,test_non_dependant_population_consistent_total.py,test_non_dependant_spousal_maintenance.pyandtest_rent_of_sharers_boarders_and_lodgers_properties.py) report 48 passed, somainmoved none of this PR's results.maindid move one test of its own:benefit_cap_reduction_applied.yaml, new onmain, suppliesbenefit_cap_welfare_benefitsalone in seven cases, so at the merge each raised this PR'sValueError(invariant 15) andgov/dwpYAML reported 7 failed and 961 passed.6900b88b7supplies the nil Housing Benefit the model calculates for each case, which has no rent, as this PR did forbenefit_cap_by_scheme.yaml; the outputs don't change, and the file reports 8 passed.main's #2815 addsuc_receives_attendance_allowance, which this PR doesn't read: the HB and CTR claimant exemptions follow their own regulations and count armed forces independence payment separately.At
6900b88b7006fbc96690839ff297f16003459c23, locally with no survey data, each run under-n 4:policyengine-core testonfinance/benefit/family1,808 passed,gov/dwp968 passed andgov/local_authorities/council_tax_reduction391 passed, none failing;test_non_dependant_deduction_properties.py10,test_council_tax_reduction_claimant_properties.py3,test_household_head_agreement_properties.py3 andtest_uc_afip_housing_contribution_properties.py3 passed; the other files that readuc_non_dep_deductions,uc_receives_attendance_allowanceoruc_is_ineligible_partner:test_benefit_cap_lha_scheme_split_properties.py7,test_rent_of_sharers_boarders_and_lodgers_properties.py6,test_uc_legacy_closure_properties.py4,test_uc_non_dep_pension_credit.py3,test_uc_receiving_education_properties.py5,test_uc_single_claim_properties.py8 andtest_uc_work_related_groups_properties.py14 passed;policyengine_uk/tests/code_health3,168 passed;uvx ruff@0.17.2 format --check .,ruff check .andruff check --select F811,F821 policyengine_ukreport nothing;git diff --checkover this branch's new commits reports nothing;git merge-tree --write-tree --name-only HEAD origin/mainagainstmainat5c7744144reports no conflict;.github/check_fix_pr.pypasses on this title and body.7e239f148048fb4735154b2b167185659d8aaa35mergesmainat47a2817e2into6900b88b7, which brings in #2811. Git stopped on one file, the documentation ofbenefit_cap_welfare_benefits. The merge keeps this PR's sentences on the two baskets and the supplied total, and #2811's sentences on Maternity Allowance and the other welfare benefits.4f3962360f4e9f042ea705859ffda507ae9c4221moves the case "A non-dependant family's Universal Credit counts after the benefit cap" to the figures its comment worked out:universal_credit[£0, £10,890.20],housing_benefit_non_dep_deductions[£6,232.20, £0] andcouncil_tax_reduction_non_dep_deductions[£691.60, £0]. The local runs above read6900b88b7; CI tests this head.ce2aef8c6f393e87d973cfa069ba09cb5d4764a9mergesmainatfed9bcabeinto4f3962360, which brings in #2813, #2819 and #2826. Git stopped on one file, the comment aboveCLAIMANT_OR_PARTNER_BENEFITSinbenefit_cap_welfare_benefits.py. The merge keeps this PR's sentence onuc_benefit_cap_welfare_benefitsand #2813's sentences on a family receiving both awards. #2813's case inesa_income_abolition.yamlreadsbenefit_cap_welfare_benefitsanduc_benefit_cap_reductionas outputs, and this PR's basket gives its £2,442.20 reduction: £24,462.20 of benefits against the £22,020 cap.ae4721f2457622593bd1b0e64ad2980f6e83dfe1setswould_claim_uc_at_legacy_closure: falseon two cases innon_dependant_deduction_review_cases.yaml. #2813'sesa_income_abolition_reachedmoves a couple reporting income-related ESA to Universal Credit in 2026, and the award joins the band income: in the case "Income-related ESA is payable to the recipient, not the working partner", the partner moves from the £192 band to the £279 band, and the deductions rise from £2,436.20 to £3,346.20 for Housing Benefit and from £270.40 to £551.20 for Council Tax Reduction. These two cases test how income-related ESA counts in the band, so the couples stay on it. Their figures don't change.Merge order and overlaps
ae2be5fbecontains this head by merge. Give benefit-unit members aged 16 or over a bedroom under LHA rules #2010's head1bda5418dcontains Charge non-dependant deductions within the claimant's benefit unit #2017's by merge, and Charge non-dependant deductions within the claimant's benefit unit #2017 lands through Give benefit-unit members aged 16 or over a bedroom under LHA rules #2010 after this PR. Charge in-unit non-dependants in the local Council Tax Reduction schemes, and exclude a lodger personally only outside the head's family #2077 stacks on Charge non-dependant deductions within the claimant's benefit unit #2017 and conflicts with Charge non-dependant deductions within the claimant's benefit unit #2017's head in one file,council_tax_reduction_prescribed_benefits.yaml.housing_benefit_individual_non_dep_deduction_eligible.py, and whichever of the two lands second resolves it. Apply each scheme's own non-dependant test to the LHA shared accommodation rate #2030 and Count a non-dependant shared by joint tenants in each tenant's Housing Benefit size criteria #2035 conflict with this head in 21 and 16 files, and Give Scotland and Wales working-age CTR their own rules #1966 in one,programs.yaml; each owner resolves them when restacking.council_tax_reduction_non_dep_deductions, so it picks this up.supplied_inputs.py: this head registersbenefit_cap_welfare_benefitsandhousing_benefit_pre_benefit_capinSUPPLIED_INPUT_VARIABLES, since the new basket asks whether the inputs supply them. Git merges that file cleanly with Value means-tested capital less 10% sale expenses and secured debt #1969, Give UK simulations a working subsample #2265, Count only supplied inputs that are still stored in their tier #2308 and Carry unused Income Tax trading losses forward once #2661.uc_receiving_educationreads an explicitis_in_full_time_educationinput for Universal Credit's education condition. These exemptions keep the local schemes' helper, which infers full-time study fromcurrent_educationorin_HE.is_in_full_time_educationstays false until a user or dataset sets it, so reading it here would end the student exemption for anyone without that input.Axiom
axiom: TheAxiomFoundation/rulespec-uk#407 queued
rulespec-uk encodes none of HB reg 74, HB (SPC) reg 55, England's para 8 or Scotland's regs 48 and 90. Its Welsh Sch 1 para 3 and Sch 6 para 5 modules band a supplied gross income at 2026-27 amounts and defer the exemptions, the couple rule and apportionment. #407 holds the encoding brief, which binds the non-dependant's Universal Credit income to the award after the cap and before debt (
uc_pilot_award_amount); no separately approved billed signed-encoder run exists for it.Reproducer:
policyengine_uk/tests/test_non_dependant_deduction_properties.py::test_band_edges_are_inclusive,policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/non_dep_deduction/housing_benefit_non_dep_deduction_chain.yaml🤖 Generated with Claude Code