Repository navigation
Conversation
…bedrooms in the LHA size criteria Universal Credit (UC Regs 2013 Sch 4 paras 9-12): the household head's non-dependants' children are in the extended benefit unit and share rooms with the renter's children; foster children are in no one's extended benefit unit; foster parents and adopters with a child placed (para 12(4)-(5)) and renters whose household includes someone with non-resident overnight care (para 12(A1), (3)) get one additional bedroom for each condition (12(9)). Foster parents are excepted from the shared accommodation rate (29(9A)), and armed forces independence payment counts in the para 29(5) exception. Housing Benefit (HB Regs 2006 and HB (SPC) Regs 2006 reg 13D): the children of non-dependants, boarders and lodgers are occupiers (13D(12)); a child placed with the claimant as a foster child or for adoption is not (reg 21(3)); a qualifying parent or carer and a person who requires overnight care give one additional bedroom each (13D(3A)-(3B)) and are not young individuals. New inputs: is_placed_for_adoption, is_approved_foster_parent_without_placement, has_non_resident_overnight_carer. Fixes #2011 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HB reg 21(3) names only children placed with the claimant or partner, but DWP treats foster children as not occupying the dwelling (LHA Guidance Manual para 2.033; HB circular A21/2013 para 22), as Universal Credit does (UC Sch 4 para 9(2)(g)). The household head's Housing Benefit size criteria and overnight-care bedroom now leave out a child placed with a non-dependant, boarder or lodger as a foster child or for adoption. Adds a YAML case and tightens the foster-child Hypothesis property to an exact effect on every family. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HB Regs 2006 reg 13D(3)(a) puts any occupier couple in "a couple" (one bedroom; LHA Guidance Manual para 2.012), so a non-dependant's, boarder's or lodger's couple adds one bedroom to the household head's HB size criteria, not two. Universal Credit is unchanged: each non-dependant who is not a child has a bedroom (UC Sch 4 para 10(1)(c); ADM F3112 note 1). Reported by the disabled-rooms session (chip task_cc724597). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Childcare Payments (Eligibility) Regs 2015 reg 4(2)(d): no one is responsible for a child placed for adoption by an adoption agency in the home of a person proposing to adopt them. The new is_placed_for_adoption input is documented for each scheme it touches: Universal Credit and Pension Credit treat the adopter as responsible (UC reg 4A(1)(c); SPC Sch IIA para 4(3)(c)); HB, the legacy schemes and English pensioner CTR do not count the child in the household; CTC's rule 4 case B depends on local authority payments and is not modelled. Changelog covers the HB occupier couple rule too. Found by the first review attempt's probes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt test predicates - HB occupier couple: count the half rooms only when both members are counted, so a benefit unit flagged as a couple without two adults no longer produces a fractional bedroom (and an enum error downstream). - UC: read "child" as under 18 for foster children throughout (is_lha_foster_child; parameter gov.dwp.LHA.foster_child_age_limit): a looked-after 16- or 17-year-old placed with the renter has no room of their own, and their overnight care counts under para 12(A1)(c). - Overnight care beyond the renter or HB claimant and partner applies from 1 April 2017 (SI 2017/213; parameter overnight_care_beyond_claimant). - youngest_child_age_for_legacy_benefits leaves out a child placed with the family (IS reg 16(4)). - Property tests derive the added person's status from the inputs (UC reg 5, Child Benefit QYP, looked after under 18) instead of the model, bias the generator towards looked-after young people, and give the added person overnight care in the reference property. - YAML: 13 new cases pinning the reviewer's surviving mutants and probes, a case with an inconsistent couple flag, and a 2016 date-gate case; the fostering-couple case now uses ages that detect counting the foster child; corrected citations. - Documentation: Scottish working-age CTR adoption gap, Scottish devolved disability benefits, HB 13D(3A)(a)(iii) reading, reg 21(3)(a) and s.22C, and the overnight-carer and adoption inputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follows #2016's reading of "foster child" (UC Sch 4 para 9(3), with the reg 2 foster parent definition) as a looked-after person under 18 placed with the renter (is_lha_foster_child), so a looked-after 16- or 17-year-old who is not a qualifying young person is excluded by para 9(2)(c) rather than counted as a non-dependant. The WRA 2012 s.40 reading (a child is under 16) would count them; the code records both. HB is unchanged: such a person is not a young person (reg 19), so reg 21(3) does not apply and they are a non-dependant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps #2016's paired couple weights and April 2017 overnight-care gate, routes the weights through housing_benefit_other_occupiers, and updates the #2016 independent reference so a non-dependant counts for every joint occupier by default (sharers included) and boarders and lodgers for the household head only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tering - is_looked_after_child: the looked-after flag applies only under 18 (Children Act 1989 ss.22(1), 105(1)). It replaces the raw flag in the UC, CTC and Pension Credit child tests and in the legacy placement test, so a flagged 18- or 19-year-old qualifying young person keeps their UC room and gives no HB carer room. The looked-after age limit moves to household.demographic.looked_after_child_age_limit. - HB occupier couples need is_couple as well as two counted claimant or partner members, so relation_type SINGLE is respected again. - Income Support Sch 1B para 2: a single claimant or lone parent with whom a child is placed by a local authority is a prescribed category. - YAML: a looked-after 17-year-old claimant (pins the claimant-guard mutant), a looked-after 18-year-old with a single renter of 30, a non-dependant pair entered as single, two IS para 2 cases. - Property predicates apply the under-18 limit and accept any non-tertiary education; P5 renamed to a reference count. The child-definition property reference applies the same under-18 limit. - Documentation: HB reg 19(2)(c) eligible children; looked-after flag under 18 only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follows #2016's reading of "foster child" (UC Sch 4 para 9(3), with the reg 2 foster parent definition) as a looked-after person under 18 placed with the renter (is_lha_foster_child), so a looked-after 16- or 17-year-old who is not a qualifying young person is excluded by para 9(2)(c) rather than counted as a non-dependant. The WRA 2012 s.40 reading (a child is under 16) would count them; the code records both. HB is unchanged: such a person is not a young person (reg 19), so reg 21(3) does not apply and they are a non-dependant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… deduction code Follows #2017 at 2d54628 (review r2 F3/F4): a non-dependant normally resides with each joint occupier whichever family they belong to (HB reg 3(1), (4); reg 74(5)), including a joint tenant's own adult son and a lodger's adult son (reg 3(2)(e)(i) excludes only the person liable to pay the claimant). A boarder or lodger keeps only their own family's. Both flags now count the same people the deduction formulas charge, so a deduction always implies a non-dependant, including for a family with no claimant or partner (review r1 finding 3). "Joint renter" in the UC docstring becomes "sharer of the rent" (in UC Sch 4 it means a joint claimant; review r1 finding 6). New YAML cases: a lodger's adult son (HB non-dependant of the householder and the lodger; UC counts him in the lodger's claim only, para 9(2)(f)), and a looked-after 16-year-old school leaver with a young single HB claimant (C, not A; #2016 review r2 N9). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follows #2016's reading of "foster child" (UC Sch 4 para 9(3), with the reg 2 foster parent definition) as a looked-after person under 18 placed with the renter (is_lha_foster_child), so a looked-after 16- or 17-year-old who is not a qualifying young person is excluded by para 9(2)(c) rather than counted as a non-dependant. The WRA 2012 s.40 reading (a child is under 16) would count them; the code records both. HB is unchanged: such a person is not a young person (reg 19), so reg 21(3) does not apply and they are a non-dependant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… deduction code Follows #2017 at 2d54628 (review r2 F3/F4): a non-dependant normally resides with each joint occupier whichever family they belong to (HB reg 3(1), (4); reg 74(5)), including a joint tenant's own adult son and a lodger's adult son (reg 3(2)(e)(i) excludes only the person liable to pay the claimant). A boarder or lodger keeps only their own family's. Both flags now count the same people the deduction formulas charge, so a deduction always implies a non-dependant, including for a family with no claimant or partner (review r1 finding 3). "Joint renter" in the UC docstring becomes "sharer of the rent" (in UC Sch 4 it means a joint claimant; review r1 finding 6). New YAML cases: a lodger's adult son (HB non-dependant of the householder and the lodger; UC counts him in the lodger's claim only, para 9(2)(f)), and a looked-after 16-year-old school leaver with a young single HB claimant (C, not A; #2016 review r2 N9). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… single case - Income Support Sch 1B para 2A: a single claimant or lone parent with whom a child is placed for adoption by an adoption agency is a prescribed category, so leaving the placed child out of the para 1 youngest-child test no longer removes eligibility. Two YAML cases. - The relation_type SINGLE YAML case now marks the parent and son's roles explicitly, so it asserts the legally correct [3, 2]; a separate case pins the is_couple guard on the renter's count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…euse placement test - Two Income Support cases that must be ineligible: a couple with a child placed for adoption, and a placement aged 16 (para 2A needs a single claimant or lone parent, and a child under 16). - The is_couple guard case asserts only the renter's bedrooms. - income_support_eligible reuses is_child_or_young_person_placed_with_family (under 16) instead of re-deriving it; renamed has_placed_child. - is_placed_for_adoption documentation mentions IS Sch 1B para 2A. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Coordination note from #2062 (issue #2059), which makes every programme read one household head. This PR's Whichever of the two PRs lands second needs these readers switched:
#2062 adds a test, |
…y the UC adopter definition HB reg 21(3) names only a placement with the claimant or partner, so a child placed with a non-dependant, boarder or lodger occupies the claimant's dwelling (13D(12)) and counts in the host's size criteria and under 13D(3A)(a)(iii). The carer's own claim still leaves the child out. UC Sch 4 para 12(4)(b) applies to an adopter as reg 89(3)(a) defines it, which excludes a foster parent or close relative of the child. The new child-level input adopter_is_foster_parent_or_close_relative feeds only the foster parent condition, and so para 29(9A). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6FYBy8zKExK1r9z9fW
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6FYBy8zKExK1r9z9fW
The CTR scheme-selection reference now stops looked-after status at 18, as is_looked_after_child does. The sharers' no-op bedroom check covers households with no child outside the head's family, since non-dependants' children now share the head's children's rooms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6FYBy8zKExK1r9z9fW
…count Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6FYBy8zKExK1r9z9fW
|
Generated by Claude Code |
|
Generated by Claude Code |
|
Generated by Claude Code |
|
Generated by Claude Code |
|
Ready for hub review Head: Commits:
Merge (12 conflicts)Resolved as the brief says. HB is rebuilt on Judgment call in the merge: #2010's HB couple test counted two claimant-or-partners as a couple. #2016's YAML case "An explicit single relationship stops the Housing Benefit couple rule" (review round 2) needs Other readers the merge broke:
I read the other legacy-flag readers: C1
New cases, each worked by hand in its comment:
UC for the review's family: foster Figures differ from the review. No BRMA in the model's tables for 2024-2028 has £228.70 or £273.09 as an HB C or D rate (I searched every BRMA). I used Maidstone 2026 with rent £300 a week and a working daughter (£20,000, 35 hours), so the non-dependant deduction is £105.20 a week. HB is £8,889.92 at 3 rooms against £5,359.64 at 2, £3,530.28 more. The review had £2,308.28. C2No code change was needed: the merge closes it. New cases in
The new property is invariant 7 in the CTR properties file. I read I updated the docstring of C3
Three YAML cases:
The property is invariant 7 in the LHA properties file. I updated Tests (at 9834880, or a04bc25 for the unchanged files)
DifferentialI generated 300 households (604 benefit units), Maidstone, 2025, with no placement, overnight-care or between-placements inputs and no children outside the head's family. Each household has a head family of 1-2 adults and up to 4 children aged 0-19, plus up to 2 adult-only sharer, boarder, lodger or non-dependant families. Both schemes' rooms match Mutations (scratch worktree at the head)All 8 were killed:
Skipped
Judgment calls
Hub documents are posted above: Generated by Claude Code |
juaristi22
left a comment
There was a problem hiding this comment.
Re-reviewed exact head 983488065231c5eaa10850196c9df25cfb17d2e2. C1, C2, C3 and A1 are resolved: the host's HB placement count, Scottish CTR responsibility and statutory UC adopter qualifier now have source-backed final-result checks, and the description correction has landed.
The actual description now reflects the adopted fixes and child-bound adopter input. The supplied extensions on rulespec-uk #406 and #411 were checked against the previously verified primary rules.
Review PARTIAL: 101 selected tests passed before the bounded runner timed out; 15 selected checks remain unfinished, and there are no hosted checks at this head. The close-relative control also passed through final UC and household net income.
This head still contains the older #2010 parent rather than its latest 2d362d2 fix. Approval remains withheld pending parent integration and required checks on the resulting head. The prior findings are closed; this does not approve a future integration tree.
juaristi22
left a comment
There was a problem hiding this comment.
Program review
Base repository: PolicyEngine/policyengine-uk
PR number: 2016
Reviewed head SHA: 9834880
Merge base SHA: d8c2249
Mode: incremental from 9834880
Scope: Unchanged raw head; reassess retargeted main integration and preserve prior finding/test dispositions. No new statutory-logic review.
Source manifest: /privatepr-2016-sweep20261109-1229-review-sources.json
Review status: PARTIAL
Source Documents
- 000-original-reuse-00-pr-2016-sweep20261102-1909-source-uc-sch4.xml —
cached original(retained review artifact). - 001-original-reuse-01-pr-2016-sweep20261102-1909-source-uc4.xml —
cached original(retained review artifact). - 002-original-reuse-02-pr-2016-sweep20261102-1909-source-hb21.xml —
cached original(retained review artifact). - 003-original-reuse-03-pr-2016-sweep20261102-1909-source-hb13D.xml —
cached original(retained review artifact). - 004-original-reuse-04-pr-2016-sweep20261102-1909-source-hb2.xml —
cached original(retained review artifact). - 005-original-reuse-05-pr-2016-sweep20261102-1909-source-hbspc13D.xml —
cached original(retained review artifact). - 006-original-reuse-06-pr-2016-sweep20261102-1909-source-uc4A.xml —
cached original(retained review artifact). - 007-original-reuse-07-pr-2016-sweep20261102-1909-source-uc2.xml —
cached original(retained review artifact). - 008-original-reuse-08-pr-2016-sweep20261102-1909-source-children22.xml —
cached original(retained review artifact). - 009-original-reuse-09-pr-2016-sweep20261102-1909-source-children105.xml —
cached original(retained review artifact). - 010-original-reuse-10-pr-2016-sweep20261102-1909-source-tfc4.xml —
cached original(retained review artifact). - 011-original-reuse-11-pr-2016-sweep20261102-1909-source-is-sch1B.xml —
cached original(retained review artifact). - 012-original-reuse-12-pr-2016-sweep20261102-1909-source-is16.xml —
cached original(retained review artifact). - 013-original-reuse-13-pr-2016-sweep20261102-1909-source-scot7.xml —
cached original(retained review artifact). - 014-original-reuse-14-pr-2016-sweep20261102-1909-source-wra40.xml —
cached original(retained review artifact). - 015-original-reuse-15-pr-2016-sweep20261102-1909-source-uc89.xml —
cached original(retained review artifact). - 016-original-reuse-16-pr-2016-sweep20261102-1909-source-overnight2017.xml —
cached original(retained review artifact). - 017-original-reuse-17-pr-2016-sweep20261102-1909-source-uc2018.xml —
cached original(retained review artifact). - 018-original-reuse-18-pr-2016-sweep20261102-1909-source-pc-schIIA4-alt.xml —
cached original(retained review artifact). - 019-original-reuse-19-pr-2016-sweep20261102-1909-source-ctc3-alt.html —
cached original(retained review artifact). - 020-original-reuse-20-pr-2016-sweep20261102-1909-source-adoption25.xml —
cached original(retained review artifact). - 021-original-reuse-21-pr-2016-sweep20261102-1909-source-lha-manual.pdf —
cached original(retained review artifact). - 022-original-reuse-22-pr-2016-sweep20261102-1909-source-uc2018-em.pdf —
cached original(retained review artifact). - 023-original-reuse-23-pr-2016-sweep20261102-1909-axiom-issue406.json —
cached original(retained review artifact). - 024-original-reuse-24-pr-2016-sweep20261102-1909-axiom-issue411.json —
cached original(retained review artifact). - 025-original-reuse-25-pr-2016-sweep20261102-1909-axiom-issue412.json —
cached original(retained review artifact). - 026-original-reuse-26-pr-2016-sweep20261102-1909-axiom-issue357.json —
cached original(retained review artifact). - 027-original-reuse-27-pr-2016-sweep20261102-1909-axiom-10.yaml.json —
cached original(retained review artifact). - 028-original-reuse-28-pr-2016-sweep20261102-1909-axiom-10.test.yaml.json —
cached original(retained review artifact). - 029-original-pr-current.json —
cached original(retained review artifact). - 030-original-issue406.json —
cached original(retained review artifact). - 031-original-issue406-comments.json —
cached original(retained review artifact). - 032-original-issue411.json —
cached original(retained review artifact). - 033-original-issue411-comments.json —
cached original(retained review artifact). - 034-original-issue357.json —
cached original(retained review artifact). - 035-original-issue357-comments.json —
cached original(retained review artifact). - 036-original-scot2012-reg8-made.xml —
cached original(retained review artifact). - 037-original-scot2012-reg10-made.xml —
cached original(retained review artifact). - 038-original-scot2012-reg11-made.xml —
cached original(retained review artifact). - 039-original-feedback-publication-pr-current.json —
cached original(retained review artifact). - 040-original-feedback-issue406.json —
cached original(retained review artifact). - 041-original-feedback-issue406-comments.json —
cached original(retained review artifact). - 042-original-feedback-issue411.json —
cached original(retained review artifact). - 043-original-feedback-issue411-comments.json —
cached original(retained review artifact).
Critical
C1 — Count a non-dependant's adoption placement in the host's HB rooms (RESOLVED)
Severity: CRITICAL (historical); Status: RESOLVED. housing_benefit_LHA_allowed_bedrooms now excludes a placement only from the applicant family's own occupiers and includes placements belonging to other non-rent-liable families in a liable claimant's occupiers. The own/other masks do not double-count the liable claimant's family, while the other family's own exclusion and carer room remain intact. The passing native YAML case has a private-renting head aged 60, a non-dependant daughter aged 32 earning £20,000, and her six-year-old adoption placement. It calculates host/daughter rooms [3,2] and final HB [£8,889.92,£0], with £15,600 Maidstone rent and the daughter's actual non-dependant deduction. The analogous foster case also passes. These use the present head's model amounts; they are not a claim that the prior counterexample's different earnings/rate context must retain its old award. The prior claimant-relative regulation 21(3)/13D source premise is unchanged and independently corroborated by the source role.
C2 — Preserve adopted-child responsibility in Scottish working-age CTR (RESOLVED)
Severity: CRITICAL (historical); Status: RESOLVED. The scheme-specific CTR child flag takes the UC responsibility branch for Scottish working-age claims from 2022, retaining a normally resident adoption-placement child while leaving the applicable old-scheme and pensioner exclusions separate. The paired 2025 actual-input cases (23-year-old adopter, child aged three, £11,000 earnings, £1,800 council tax, no UC) both retain lone-parent status and calculate final CTR £286.40, with applicable amount £4,786.60 and income £12,354.60. Both cases passed; the new adoption flag no longer causes the prior responsibility/allowance loss. The source role also confirms the pre-2022 exclusion under the earlier Scottish regulation, so this resolution does not backdate the 2021 rule. No certification of the shared route's entire allowance schedule is implied.
C3 — Apply the statutory adopter definition to the extra UC bedroom (RESOLVED)
Severity: CRITICAL (historical); Status: RESOLVED. The new Person-level adopter_is_foster_parent_or_close_relative input, supplied on the placed child, removes that placement from the UC adopter/foster-room route without changing general placement or child responsibility. Independent fostering/between-placement qualifications still work, and the input is inert without an adoption placement. Passing YAML includes unrelated-adopter, close-relative negative, under-35 and independently approved-foster-parent controls.
One uncovered final-money path was checked in a separate bounded native process: two actual 2026 private-renting adopter households, adult 40/child four, £18,000 earnings at 30 hours, £15,600 rent in Maidstone, no savings, UC claimed, and no independent foster/between-placement/overnight-care condition. Matched agency placement is supplied under the placement input's contract; only the actual close-relative qualification differs. There is no eligibility, room, cap or award input override. Both claims are eligible and paid, with no benefit-cap reduction. The unrelated adopter receives three rooms, UC housing £14,400 and final UC £16,900.50/HNI £35,718.50; the statutorily excluded close-relative adopter receives two rooms, housing £10,860 and UC £13,360.50/HNI £32,178.50. The £3,540 consequence follows only the lawful additional-room distinction; the child remains the adopter's responsibility in both. Inputs/outputs (retained review artifact), diagnostic (retained review artifact), log (retained review artifact). This diagnostic passed in 3.80 seconds, exit 0.
Should Address
A1 — Refresh the description to match the adopted placement fixes (RESOLVED)
Severity: SHOULD ADDRESS. Status: RESOLVED. The actual new publication-guard body remains bound to head 9834880 and now describes the claimant-relative HB occupier/overnight-care mask, the Scottish working-age adoption responsibility branch from 2022, and the statutory UC adopter exclusion. It lists adopter_is_foster_parent_or_close_relative as a child-level input and removes the old statements that those fixes are unimplemented. Current test figures are labelled by head, and old population estimates are explicitly historical with no new run claimed. The new axiomatic line links actual406/411 extension comments. The original clarity issue is resolved; author test or impact claims are not substituted for independent validation.
Suggestions
None.
Evidence Gaps
- MAIN_INTEGRATION: No reviewed integration with captured main0520d96467724adf6b71b700fb099f94e5ee8049 exists. Read-only merge-tree reports four content conflicts; an actual conflict-resolved child head and affected checks are required before assessing the combined behavior.
- LOCAL_REGRESSION_COMPLETION: The prior same-raw-head campaign completed101 of116 selected outcomes before its540-second timeout;15 named outcomes remain uncompleted. Current onlyFix-evidence success is not full-suite or Test/Result evidence.
Notes
- Raw head unchanged; incremental code diff empty. Prior C1/C2/C3/A1 resolutions remain valid for that raw head, and do not certify eventual integration.
- Parents #2007 and #2010 are merged. Captured main0520contains2010head4bb/mergefdc; child983containsneither. FourLHAparameter/formula/property conflicts require a new integrated child head and affected checks.
- Retarget-only scope: no new policy/source interpretation.44cached original sources andderivatives werehashvalidated;0fresh acquisition orrendering.
- Historical101passes of116outcomes and2householdnativewitnesses remainhistorical;15unfinishedoutcomes remaingaps. No new tests/models/install/sync/commits/PRmerges.
- PR API baseRefOidfdc differs from liveGitmain0520; live-ref guard independently confirmed the captured base and is repeated before publication. This named identity resolution is included in consolidation time.
Validation Summary
Read-only merge-tree of child983488 and main0520d964 exited1 with4contentconflicts; no tracked/index/branch/commit changes. CurrentexactheadCIonlyFixevidence success129148741266, nofullTest/Result. Historical101/116selectedoutcomes+2householdnativeproof retained;15unfinishednodes explicitlylisted inreview-validation.json.1codereviewer,40technicalmembers,44cachedoriginalsources,0freshsources/renders/tests/models.
Timing
setup seconds: 322.12s; parallel review seconds: 226.29s; policy role seconds: 0.00s; code role seconds: 226.29s; adjudication seconds: 85.70s; consolidation cleanup seconds: 238.14s; elapsed seconds: 786.87s
Review Severity
COMMENT. Open findings: 0 critical, 0 should address, 0 suggestions.
Merges main at 117e674. Four files conflicted: - shared_accommodation_exception_benefits.yaml takes main's version. Main's list reads uc_receives_attendance_allowance, which counts armed forces independence payment, and its description names the Scottish heads of para 29(5): the two changes this branch made to the file. - lha_renter_has_non_dependant.py takes main's description of other families' non-dependants and keeps this branch's sentence on children placed as foster children or for adoption. The formula merged without conflict. - LHA_allowed_bedrooms.py keeps this branch's bedrooms_for_children. A new helper, other_family_non_dependants, holds main's count of other families' non-dependants: main's is_uc_non_dependant_of_household_head and main's in-unit non-dependants of a family that makes no Universal Credit claim of its own. The family's own non-dependants are main's is_benefit_unit_non_dependant_for_universal_credit less this branch's foster children. - test_lha_bedroom_young_people_properties.py numbers the invariants 1 to 9: this branch's seven, then main's invariants on contributions and on coding as 8 and 9. The exact-effect and reference tests take in main's in-unit non-dependant whose own family makes no claim. The next commit brings this branch's foster children and LHA_additional_bedrooms into line with main's Universal Credit non-dependants. Until then the test's in_unit_non_dependants check fails for a fostered person aged 16 or 17 who is not a qualifying young person, whom main's is_benefit_unit_non_dependant_for_universal_credit marks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The merge of main brought is_benefit_unit_non_dependant_for_universal_credit, which gives an in-unit non-dependant's bedroom and housing cost contribution one definition, and is_uc_non_dependant_of_household_head, which leaves a boarder's or lodger's children out of the renter's extended benefit unit (UC Regs 2013 Sch 4 para 9(2)(g)). This commit brings this branch's foster children and additional bedrooms into line with them. - is_benefit_unit_non_dependant_for_universal_credit leaves out the claimant's or partner's foster child (is_lha_foster_child; para 9(2)(c) and (3)), so LHA_allowed_bedrooms reads it as main does. - other_family_non_dependants passes a foster child aged 16 or 17 who is not a qualifying young person to the claim that counts the household's non-dependants, unless that claim is the foster family's. Para 9(2)(c) takes them out of their foster parent's extended benefit unit only. Being under 21, they owe no housing cost contribution (para 16(2)(a)). - LHA_additional_bedrooms reads other_family_non_dependants. It read is_non_dependant_of_household_head, which since main's change also marks a boarder's or lodger's children, and so gave the counting claim an overnight care room for them. - is_non_dependant_of_household_head's description no longer says that the flag covers every member of a family: main's formula leaves out a boarder's or lodger's payer and partner. - The property tests expect the foster child's bedroom, and the overnight care room of anyone passed on, in the claim that counts the household's non-dependants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main changed two results that this branch's YAML cases expected, and the merge kept the old expectations. - In LHA_other_families_children_and_additional_bedrooms.yaml, is_non_dependant_of_household_head now marks a lodger's child who pays nothing. The lodger pays the householder on a commercial basis, so HB Regs 2006 reg 3(2)(e)(i) leaves the lodger out of the householder's non-dependants, but no exception in reg 3(2) covers the lodger's child. The case now expects true for the child, and it adds is_uc_non_dependant_of_household_head, which leaves the child out (UC Regs 2013 Sch 4 para 9(2)(g)). The case's other outputs stand. - In council_tax_reduction_young_person.yaml, Cases 11 and 12 now take Scotland's working-age route. A lone parent's personal allowance and child premium at the 2025-26 rates give an applicable amount of (92.05 + 105.85) * 52 = 10,290.80. The £25 a week earnings disregard leaves income of 11,000 - 25 * 52 = 9,700, and income below the applicable amount gives the whole £1,800 of council tax. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Invariant 3 of test_claimant_not_own_child_properties.py restates the CTC and Pension Credit child tests, which leave out a child whom a local authority looks after. This branch's is_looked_after_child reads the flag only for a person under 18, since a local authority can look after only a child (Children Act 1989 s.105(1)), and both child tests read it. The restatement still read the raw flag, so it expected CTC to leave out an 18-year-old with the flag in approved training, whom the model counts as a qualifying young person. The restatement now reads the flag only under 18, and the test adds that 18-year-old as a fixed example. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Invariant 9 of test_lha_bedroom_young_people_properties.py says that moving a non-claiming adult aged 20 or over out of their family's benefit unit changes no claim. That fails where the family makes its own claim and another family's claim counts the household's non-dependants. In the family, the adult is the family's non-dependant, and the family's claim bears their bedroom and contribution (invariant 8). In a benefit unit of their own, the adult is a non-dependant of the household, and the counting claim bears them. For example, where a sharer's family claims beside the household head's, moving an adult out of the sharer's family moves a bedroom and a housing cost contribution from the sharer's claim to the head's. Main's model gives the same results for that case, so main's version of the invariant fails on it too. The invariant now expects that one bedroom to move, from the family's claim to the counting claim, and every other claim to keep its bedrooms, contribution and award. The test adds the sharer case as a fixed example. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juaristi22
left a comment
There was a problem hiding this comment.
Review status: PARTIAL
Reviewed head: 2f42ce1afeadb1d320a8db61d03931c60dc497c0
C4 — Include the new other-family non-dependants in the shared-accommodation-rate exception. lha_renter_has_non_dependant.py:51–58 still uses the narrower household-head flag. The new room-count helper can count a sharer’s fostered 16/17-year-old non-QYP for the renter while that flag remains false. Under UC Schedule 4, paragraphs 9 and 27–28, a legal non-dependant rules out the shared rate.
The executed 2026 case has a single 30-year-old private renter in Maidstone, a rent-liable 40-year-old foster-parent sharer earning £60,000 and not claiming UC, and their looked-after 17-year-old non-QYP who pays no rent and makes no claim. Only the head claims UC. The model gives the head two rooms but category A/shared, housing £5,337.96 and final UC £10,436.76. A diagnostic control that only reuses the new other-family helper in the shared-rate flag gives category C, housing £10,860 and final UC £14,753. The final UC loss is £4,316.24; the benefit cap explains why this is smaller than the housing-element difference. No eligibility or benefit amount was forced. Please align the non-dependant definitions and cover this route through the final award. This control diagnoses the cause; it is not a tracked fix or certification of every award component.
Prior C1–C3 and A1 remain resolved. The merged head resolves the previous four-conflict topology, and the fresh adopter pair passes through final UC and household net income. The source review is complete using 48 validated originals and 39 extracts, with no new acquisition. Queued RuleSpec work remains queued, rather than executed parity.
Remaining validation gap: the single 420-second repository campaign passed five Python tests with no failed assertion, then timed out. Seventy of 75 collected tests remain unfinished, including ten of the previous fifteen checkpoint selections; the named ledger is retained in the full report. Historical 101 passes are not presented as current integration evidence. Hosted exact-head CI is still pending. Changes are requested for confirmed C4; the incomplete regression evidence also prevents a complete review or approval.
Aggregate impact on certified data: passBase Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 0 (thresholds in Notes
Moves flagged for reviewNone. Spending by benefit and service
Caseloads
Government balance, each component counted once
Model totals
Household income totals
Poverty rates
People in poverty
Inequality
Mean household net income in each side's own deciles
Standard reform costings (change in gov_balance)
Standard reforms: change in each reform's target
Household net income by decileMean change in household net income per household, and as a share of the decile's base income; households stay in the base run's deciles.
No change in any year: receipts by tax head; population. Checks failing on both base and head (1)
Counted-once checkThe check raised each of 92 components by £1 per unit in 2026-27 and read every head of its totals household by household: its own head must rise by exactly £1, no other tax head may move, no other benefit may rise, and the model's own total must move by what its heads moved. A response that is not finite breaks every rule. The check measures a head that breaks a rule twice more: once holding every other head at its baseline value, and once holding every other head at its value after the first £1 while the component rises again. The head fails where either measurement still shows the response. The check cannot hold a head at a value that is not finite. In each unit where another head is not finite after the first £1, it holds that head at its baseline value, and the second measurement judges no household the unit belongs to. There a head fails wherever it first broke a rule, or wherever the check could not confirm whether its response contains the component. 0 failed and the check skipped 0.
Provenance
Dataset: Receipts by tax head: head levels
Spending by benefit and service: head levels
Caseloads: head levels
Government balance, each component counted once: head levels
Model totals: head levels
Household income totals: head levels
Population: head levels
Poverty rates: head levels
People in poverty: head levels
Inequality: head levels
Mean household net income in each side's own deciles: head levels
Standard reform costings (change in gov_balance): head levels
Standard reforms: change in each reform's target: head levels
|
Finding C4. Under UC Regs 2013 Sch 4 para 28(4), a renter with a non-dependant is not a specified renter, so para 27's shared accommodation rate does not apply. LHA_allowed_bedrooms gives the claim that counts the household's non-dependants a bedroom for each person in other_family_non_dependants, but lha_renter_has_non_dependant read only is_uc_non_dependant_of_household_head. It missed two groups the bedroom count includes: main's in-unit non-dependants of a family that neither claims nor counts the household's non-dependants, and this PR's foster child aged 16 or 17 who is not a qualifying young person. So a single renter under 35 could get a non-dependant's bedroom, and on main bear their housing cost contribution, while keeping the shared rate. In the C4 case, a non-claiming sharer fosters a looked-after 17-year-old not in education, and the renter of 30 in Maidstone gets category A: a housing costs element of 5,337.96 and Universal Credit of 10,436.76 in 2026. Main gives the same category and amounts. The flag's other-family part now reads other_family_non_dependants, so the flag and the bedroom count name the same people. That case now gets category C: a housing costs element of 10,860 and Universal Credit of 14,753 after the benefit cap. A non-claiming sharer's son of 22 in the sharer's benefit unit moves the same way, from category A to C. The flag's in-family part keeps its rules (#2030 splits it by scheme). Tests: both cases through final Universal Credit, in LHA_other_families_children_and_additional_bedrooms.yaml and LHA_young_person_bedroom.yaml, and property 2 of test_lha_bedroom_young_people_properties.py now also checks that a counting claim that gains a bedroom from another family's person has a non-dependant on the flag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Property 2's new check, that a counting claim which gains a bedroom from another family's person has a non-dependant on lha_renter_has_non_dependant, also passed with the flag as it stood at 2f42ce1: its 25 derandomized examples never reached either route. Two explicit examples now cover them: a claiming sharer of 40 with a looked-after 17-year-old not in education, and a sharer of 70, who makes no Universal Credit claim, with a 19-year-old not in education. In each, the head's claim gains the bedroom. With the flag at 2f42ce1, both examples fail the check; at this commit, both pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juaristi22
left a comment
There was a problem hiding this comment.
Review status: PARTIAL
Reviewed head: b460cf65bfb3020f9ad4a17c44fe307041d1fc17
C4 is resolved. The shared-rate flag now uses the same other-family non-dependant helper as the room count. The exact original review household now gives category C, housing £10,860, final UC £14,753 and household net income £58,230.40, without eligibility/award amount inputs or a diagnostic reform. C1–C3 remain resolved; no new code blocker was found.
This head advanced from e2f368 during review. Its only delta adds two explicit examples to the property test; all production, parameters, dependency lock and PR body are identical. The changed property passed again at this head in93.30seconds. Current evidence is61retained unchanged passing tests plus1updated passing test, covering the same62nodes—not63. The preceding focused62-test campaign passed in137.90seconds.
A1 is reopened (nonblocking): the description still calls 2f42 “this head” and describes the adopted SAR correction as a future follow-up. Please distinguish current behavior from historical validation.
The focused checks close45of the previous70unfinished outcomes.25remain, including9of the earlier10checkpoint selections; these remain a material validation gap. Hosted CI for this head is pending. The old90-minute cancellation belongs to 2f42, not this head. Policy/source checks remain complete with49validated originals and40extracts, with no new acquisition. Approval remains withheld for A1 and incomplete validation.
|
Thanks, @juaristi22. A1: I've posted the updated description, which I'd held while the tests ran.
On the remaining validation gap, the hosted run at b460cf6 covers the full YAML suite and all eight Python shards. I'll post its counts here when it finishes. |
juaristi22
left a comment
There was a problem hiding this comment.
Review status: PARTIAL
Reviewed head: b460cf65bfb3020f9ad4a17c44fe307041d1fc17
A1 is resolved. The updated description and author reply now describe the adopted shared-rate fix, remove the future-follow-up statement, and distinguish current-head testing from earlier commits. C1–C4 remain resolved. There are no remaining code, policy or description findings.
The code head is unchanged, so the completed code/native/test evidence remains applicable. I validated the retained49source originals and40extracts without new acquisition, model calculations or test executions. The new differential-grid figures and additional local-test counts remain attributed author claims; I did not independently rerun that grid or add those counts to verified coverage.
The review remains PARTIAL:25previously selected outcomes, including9checkpoint selections, still lack independent completion evidence in this review, and the current hosted suite remains pending. Approval is withheld until the material validation gaps are closed and the applicable required checks pass at this head.
|
The hosted run at b460cf6 has finished. Every job in
The Python count exceeds 2f42ce1's because main's seven commits since that run's base added tests; this PR's later commits add no test functions. I've put these counts in the description's Tests section in place of the pending line. |
juaristi22
left a comment
There was a problem hiding this comment.
Review status: COMPLETE — approved at b460cf65bfb3020f9ad4a17c44fe307041d1fc17.
All prior findings C1–C4 and A1 are resolved, with no open findings or material evidence gaps. The retained policy/source, code and native final-result evidence remains applicable to this unchanged reviewed head.
The successful official CI run now closes both remaining validation gaps: all 25 previously unfinished outcomes and all 9 checkpoint selections pass. The full suite reports 6,659 YAML passes and 13,394 Python passes, with 61 allowlisted skips and 2 allowlisted expected failures. Every one of the 13,457 collected Python cases has exactly one recorded outcome; no failures, unexpected passes, missing outcomes or collection errors remain. All 21 current-head check contexts pass.
The official execution used synthetic merge 92fdb9b9ab33b9332dbd647170989af8fb6aa78d of this head into 3cf10f8c73275090fd2c86465d7b396c64b66702. Relevant test definitions match the reviewed versions; the frozen lock differs only in the local package release version, with dependency versions unchanged. The latest CI-only description update and author reply match these official results.
This follow-up uses the official outcomes and retained review evidence; it does not claim new local test execution or recertify historical population results. No further changes requested.
Fixes #2011
Reproducer: policyengine_uk/tests/policy/baseline/finance/benefit/family/LHA_other_families_children_and_additional_bedrooms.yaml::A non-dependant's foster child raises the renter's final Housing Benefit
axiom: uk/regulations/uksi/2013/376/schedule/4/paragraph/10 (UC Sch 4 para 10(1)(d)-(f), (3)(b)) encoded-correct, companion cases in TheAxiomFoundation/rulespec-uk#412 | UC Sch 4 para 9(2)(c), (g) (non-dependants' children, foster children): TheAxiomFoundation/rulespec-uk#406 queued (addendum: TheAxiomFoundation/rulespec-uk#406 (comment); extension: TheAxiomFoundation/rulespec-uk#406 (comment)) | UC Sch 4 paras 12 and 29(5), (9A), with reg 2 and reg 89(3)(a) "adopter": TheAxiomFoundation/rulespec-uk#411 queued (extension: TheAxiomFoundation/rulespec-uk#411 (comment)) | HB Regs 2006 / HB (SPC) Regs 2006 regs 2(1), 13D(3)(c)-(e), (3A)-(3B), (12), 21(3): TheAxiomFoundation/rulespec-uk#406 and #357 queued (addenda: TheAxiomFoundation/rulespec-uk#406 (comment), TheAxiomFoundation/rulespec-uk#357 (comment); extension: TheAxiomFoundation/rulespec-uk#406 (comment))
Problem
The model's LHA size criteria had four gaps:
bedrooms_for_childrencounted only the claimant's own benefit unit, so a grandchild living with their parent in the renter's home never had a room. Under Housing Benefit, neither did a boarder's or lodger's child.lha_renter_has_non_dependantalso counted a foster child under 16 as a non-dependant, which took a single foster parent under 35 out of the shared accommodation rate for the wrong reason.lha_renter_has_non_dependantdidn't count that person, so a single renter under 35 kept the shared accommodation rate, which UC Sch 4 para 28(4) rules out for a renter with a non-dependant.The law, and how DWP applies it
We read the provisions on legislation.gov.uk on 2026-10-01, and reg 2 and reg 89(3)(a) of the UC Regs 2013 and HB reg 21(3) again on 2026-11-02.
Universal Credit (UC Regs 2013 Sch 4):
Housing Benefit (HB Regs 2006 and HB (SPC) Regs 2006, reg 13D):
Change
LHA_allowed_bedrooms)housing_benefit_LHA_allowed_bedrooms)uc_non_dependants_counted)lha_renter_meets_foster_parent_condition)is_housing_benefit_qualifying_parent_or_carer)New variables:
LHA_additional_bedrooms,housing_benefit_LHA_additional_bedrooms.meets_lha_overnight_care_condition,lha_renter_meets_foster_parent_condition,is_housing_benefit_qualifying_parent_or_carer.is_child_or_young_person_placed_with_family: the reg 21(3) placement test.is_child_or_young_person_for_legacy_benefitsnow uses it, so children placed for adoption also leave the legacy household (IS reg 16(4), JSA reg 78(4), ESA reg 156(5), HB reg 21(3)).housing_benefit_has_non_dependantand the HB severe disability premium's non-dependant test read the placement test too, so a child placed with the claimant does not become a non-dependant (HB reg 3(2)(c)).tax_free_childcare_qualifying_childexcludes a child placed for adoption (Childcare Payments (Eligibility) Regs 2015 reg 4(2)(d)). An adoption placement has a different effect in each scheme:youngest_child_age_for_legacy_benefits, which drives Income Support lone-parent eligibility, reads the legacy flag and so leaves out a child placed with the family (IS reg 16(4)).New inputs, all default false:
is_placed_for_adoption;adopter_is_foster_parent_or_close_relative, set on the child: the person the child lives with on an adoption placement is a foster parent or close relative of the child (UC reg 2, reg 89(3)(a)). Onlylha_renter_meets_foster_parent_conditionreads it;is_approved_foster_parent_without_placement;has_non_resident_overnight_carer.A user marks a foster child as a household member with the existing
is_looked_after_by_local_authority, whose documentation now describes that use.New parameters:
gov.dwp.LHA.overnight_care_benefitslists the qualifying benefits: attendance allowance, AFIP, DLA care at the middle or highest rate, and the PIP daily living component. The Scottish devolved equivalents (child disability payment, adult disability payment, Scottish adult DLA, pension age disability payment) also qualify under the law. The model has no variables for those, so they count only where the data records them as the DWP benefits. The same holds for the para 29(5) list.household.demographic.looked_after_child_age_limit(18).gov.dwp.LHA.overnight_care_beyond_claimant: false before 1 April 2017, true from then (SI 2017/213). Before that date only the renter, or the HB claimant and partner, could meet the overnight care condition.New variables:
is_looked_after_child:is_looked_after_by_local_authorityand under 18. A local authority can look after only a child, a person under 18 (Children Act 1989 ss.22(1) and 105(1)), so the flag has no effect at 18 or over.is_child_or_young_person_placed_with_family.is_lha_foster_child: a looked-after child placed with the renter (see judgment call 5).income_support_eligiblenow includes Income Support Sch 1B paras 2 and 2A: "a single claimant or a lone parent with whom a child is placed" by a local authority, or placed for adoption by an adoption agency. Without them, leaving placed children out of the youngest-child test would have taken eligibility from a lone parent whose only child under 5 is a foster or adoptive placement.bedrooms_for_childrentakes masks for the family's own children and other families' children, and a mask of the families that count the others; #2010'schild_bedroomsdoes the arithmetic for both schemes.Main's Universal Credit non-dependants
Main gives an in-unit non-dependant's bedroom and housing cost contribution one definition (
is_benefit_unit_non_dependant_for_universal_credit), and leaves a boarder's or lodger's children out of the renter's extended benefit unit (is_uc_non_dependant_of_household_head, para 9(2)(g)). This PR fits its foster children and additional bedrooms to them:is_benefit_unit_non_dependant_for_universal_creditleaves out the claimant's or partner's foster child (is_lha_foster_child; para 9(2)(c) and (3)).LHA_allowed_bedrooms, a new helper,other_family_non_dependants, holds main's count of other families' non-dependants:is_uc_non_dependant_of_household_head, and the in-unit non-dependants of a family that makes no Universal Credit claim of its own. It adds a foster child aged 16 or 17 who is not a qualifying young person, and gives them to the claim that counts the household's non-dependants unless that claim is the foster family's. Para 9(2)(c) takes them out of their foster parent's extended benefit unit only. Being under 21, they owe no housing cost contribution (para 16(2)(a)).LHA_additional_bedroomsreads the same helper. Main'sis_non_dependant_of_household_headnow also marks a boarder's or lodger's children, so reading it would give the counting claim an overnight care room for them.lha_renter_has_non_dependantreads the same helper for people from other families, so the shared accommodation rate's flag and the bedroom count name the same people (para 28(4)). It readis_uc_non_dependant_of_household_headalone, which misses both groups the helper adds. The in-family part keeps its rules; Apply each scheme's own non-dependant test to the LHA shared accommodation rate #2030 splits it by scheme.Judgment calls
adopter_is_foster_parent_or_close_relativeon the child. Such a person still meets the condition as a foster parent of another child, or within 12 months after their last placement ended or after approval (para 12(4)(a), (5)). In reg 4A(1)(c), the Secretary of State writes of the child being "placed for adoption", without the defined term, so the child still counts. In HB reg 21(3) and the HB definition of a qualifying parent or carer, the Secretary of State doesn't use the term either, so HB doesn't change.num_bedrooms, and the data lacks it), so it assumes the dwelling has one.is_lha_foster_child). A looked-after 16- or 17-year-old placed with the renter therefore counts as a foster child: they have no room of their own, the renter has the foster room, and their overnight care counts.lha_renter_has_non_dependantstill counts a looked-after 17-year-old not in education as a non-dependant. Its separate age-16 rule catches a 16-year-old. HB treats them the same way; on this reading, UC doesn't. Apply each scheme's own non-dependant test to the LHA shared accommodation rate #2030 splits that variable into UC and HB versions and excludesis_lha_foster_childfrom the UC one.govparameters at 30 April of each year (its fiscal-year convention), so the extension applies from model year 2017 (2017-18).Invariants
test_lha_bedroom_young_people_properties.pyholds 9 Hypothesis properties, with 25 derandomized examples each, plus explicit examples. Properties 1 to 7 come from this PR; 8 and 9 come from main.Monotonicity. Adding a person aged 16 to 19 never lowers any family's UC or HB bedrooms. This holds with the claimant and partner supplied or inferred.
Exact effect of a person aged 16 to 19. This extends Give benefit-unit members aged 16 or over a bedroom under LHA rules #2010's property:
lha_renter_has_non_dependant, so its renter gets no shared accommodation rate (para 28(4)).Children. Adding a child under 16 who is neither fostered nor placed for adoption raises each family's bedrooms by 0 or 1, under each scheme.
Placed children. Adding a child under 16 placed with a family as a foster child or for adoption gives that family one more bedroom under each scheme if it did not already meet the foster condition, and none otherwise. If that family is a non-dependant's, boarder's or lodger's, each family liable for the rent gains 0 or 1 HB bedrooms. A foster child changes no other family's UC bedrooms; a child placed for adoption adds 0 or 1 to the adopter's family and to the claim counting a non-dependant adopter's household. No joint tenant's bedrooms change.
Reference count. Each family's bedrooms and additional bedrooms equal the test's own count.
child_bedroomsagainst the optimum.In-unit non-dependants (Give benefit-unit members aged 16 or over a bedroom under LHA rules #2010's property). Every benefit-unit member aged 16 or over who is not the claimant or partner, a UC qualifying young person, the household head or the family's foster child has a UC bedroom of their own, and making them qualifying young persons the renter is responsible for leaves every family's UC bedrooms unchanged.
The close-relative input. Setting
adopter_is_foster_parent_or_close_relativeon every member takes awaylha_renter_meets_foster_parent_conditionwhere, and only where, an adoption placement was the family's only route to it, lowers that family's UC bedrooms by one, and leaves UC responsibility, the HB placement test, the qualifying parent or carer and every family's HB bedrooms unchanged.Rooms and contributions (main's property). No one owes a housing cost contribution without being a non-dependant (para 13). An in-unit non-dependant aged 16 to 64, not in education, owes one unless under 21 or on Attendance Allowance (para 16(2)). The claim that bears them gains that contribution, unless its renter is exempt (para 15), and one bedroom: their own family's claim if it makes one, otherwise the claim that counts the household's non-dependants.
Coding (main's property). Moving a non-claiming adult aged 20 or over between a family and a benefit unit of their own changes no claim's UC bedrooms, contributions or award, with one exception. Where the adult's family makes its own claim and doesn't count the household's non-dependants, the family's claim bears them while they belong to it (property 8), and the counting claim bears them in a benefit unit of their own. Their bedroom then moves between those two claims, and no other claim changes. Main's own model gives the same result, so main's version of the property also failed on this case (see Known gaps).
test_council_tax_reduction_young_person_properties.pyadds:Before the merge of main, on 300 generated households (604 benefit units) in Maidstone in 2025, with no placement, overnight-care or between-placements inputs and no children outside the head's family,
LHA_allowed_bedroomsandhousing_benefit_LHA_allowed_bedroomsagree with #2010's d8c2249 for every benefit unit. Each household has a head family of 1-2 adults aged 20-85 and up to 4 children aged 0-19 (those aged 16 or over with random education and benefits), and up to 2 adult-only sharer, boarder, lodger or non-dependant families.We ran each mutation as one change to a copy of the branch, against the named tests.
At 1f3ce21 (the earlier head), each made at least one property fail:
At 1f3ce21, YAML cases also killed four more mutations: "placed" without the Child Benefit young-person test; a non-dependant's foster child's overnight care counting under UC; reverting (A1)(c) for a looked-after qualifying young person; and a looked-after claimant giving the foster room (a case with a 17-year-old looked-after claimant pins it; the property generator supplies claimant roles, so the properties cannot reach it).
At 9834880:
LHA_other_families_…,LHA_young_person_bedroom,council_tax_reduction_young_person)othersdrops placed children againownkeeps placed children~placedback inhousing_benefit_LHA_additional_bedroomsadopter_is_foster_parent_or_close_relativeis_child_or_qualifying_young_person_for_universal_credithousing_benefit_has_non_dependantCommits after 9834880
mainat 117e674. Four files conflicted:shared_accommodation_exception_benefits.yamltakes main's version;lha_renter_has_non_dependant.pyandLHA_allowed_bedrooms.pycombine both sides; and the property test numbers its properties 1 to 9.lha_renter_has_non_dependantreadother_family_non_dependants(see Main's Universal Credit non-dependants), with two YAML cases through final Universal Credit and a new check in property 2. b460cf6 adds an explicit example for each route to that check.Tests
At b460cf6 (this head):
pr_code_changes.yamlpassed (run 42936378851), and all 21 checks on this head pass. The run tests this head merged with main at 3cf10f8. YAML: 6,659 passed, two more than at 2f42ce1: the two new cases. Python, 8 shards: 13,394 passed, 61 skipped, 2 xfailed, with no failures; all three property modules below ran (9, 7 and 3 tests). The Python count exceeds 2f42ce1's because main's seven commits since that run's base added tests; this PR's later commits add no test functions.policyengine-core test … -c policyengine_uk:LHA_other_families_children_and_additional_bedrooms.yaml45 passed;LHA_young_person_bedroom.yaml15;benefit_unit_non_dependants.yaml45;claims_as_single_person.yaml33;rent_of_sharers_boarders_and_lodgers.yaml19;LHA_claimant_composition.yaml17;boarders_and_lodgers_non_dependants.yaml16;resolved_household_head.yaml9. That covers every YAML file that nameslha_renter_has_non_dependant, plusbenefit_unit_non_dependants.yamlfor in-unit non-dependants.pytest:test_lha_bedroom_young_people_properties.py9 passed;test_benefit_cap_lha_scheme_split_properties.py7;test_household_head_agreement_properties.py3.@examplecases fail property 2's check. With the fix, all pass. Property 2's 25 derandomized examples alone never reached either route, so b460cf6 pins both with@example: a claiming sharer of 40 with a looked-after 17-year-old not in education, and a sharer of 70, who makes no Universal Credit claim, with a 19-year-old not in education.At 2f42ce1:
pr_code_changes.yamlon a branch at this commit (run 42897383483): every job passed. YAML: 6,657 passed. Python, 8 shards: 13,333 passed, 61 skipped, 2 xfailed, including both property modules below.LHA_other_families_children_and_additional_bedrooms.yaml44 passed;council_tax_reduction_young_person.yaml13 passed.LHA_other_families_children_and_additional_bedrooms.yaml, a lodger's child who pays nothing counts as the householder's HB non-dependant, since HB reg 3(2)(e)(i) excepts only the paying lodger, and not as a UC one (para 9(2)(g)).council_tax_reduction_young_person.yaml, Cases 11 and 12 take Scotland's working-age route. The lone parent's applicable amount comes to (92.05 + 105.85) × 52 = £10,290.80; the £25 a week earnings disregard leaves income of £11,000 − £25 × 52 = £9,700, so CTR covers the whole £1,800 of council tax, with and without the adoption placement.@example:test_claimant_not_own_child_properties.py(main's file), property 3: an 18-year-old with the looked-after flag in approved training. Its restatement of the CTC and Pension Credit child tests now reads the flag only under 18, asis_looked_after_childdoes.test_lha_bedroom_young_people_properties.py, property 9: a sharer's family that claims beside the household head's.ruff format --checkandruff check(0.16.7) pass on the changed Python files.At 9834880 (before the merge of main):
policyengine-core test … -c policyengine_uk: 97 passed.LHA_other_families_children_and_additional_bedrooms.yaml: 44 cases, including a renter of 60 whose non-dependant daughter has a child placed with her, as a foster child and for adoption (HB[3, 2]; UC[2, 2]and[3, 3]), both through final Housing Benefit, a looked-after young person of 17 placed with a non-dependant, a child placed with a lodger, a child placed with a joint tenant, a non-dependant's placed child who needs overnight care (HB[4, 3]), three close-relative adopter cases, and a placed child who is not an HB non-dependant.LHA_young_person_bedroom.yaml: 11. The case of a looked-after qualifying young person in a non-dependant's family now expects the carer's foster room:[2, 2], categories[C, C].LHA_claimant_composition.yaml: 17.income_support.yaml: 7.tax_free_childcare_qualifying_child.yaml: 5.council_tax_reduction_young_person.yaml: 13, including Cases 11-13: in Scotland's working-age scheme, an adopter of 23 with a child of 3 has the same lone-parent status, applicable amount (£4,786.60) and final CTR (£286.40) with and without the adoption placement, and under Scotland's pension-age scheme the child placed for adoption drops out.pytest … -n 4:test_lha_bedroom_young_people_properties.py: 7 passed.test_child_and_adult_definitions_properties.py: 18 passed.test_means_test_income_properties.py: 2 passed.test_rent_of_sharers_boarders_and_lodgers_properties.py: 6 passed. Its no-op bedroom check now covers households with no child outside the head's family.test_council_tax_reduction_young_person_properties.py: 7 passed. Its scheme-selection reference now stops looked-after status at 18.test_household_head_agreement_properties.py: 3 passed, with the two additional-bedroom variables added to its outputs.policyengine_uk/tests/code_health: 3,102 passed.ruff format --check,ruff checkandruff check --select F811,F821 policyengine_uk(0.17.2): all pass.Differential grid
We ran 23 hand-built households in Maidstone in 2026, each once with Universal Credit claims and once with Housing Benefit claims (46 runs). We ran them at seven commits:
mainat 3cf10f8 and at 117e674,mainimmediately before (e050200) and after (fdc0c78) #2010 landed, #2016's earlier head 9834880, 2f42ce1, and e2f368d, whose model code this head keeps. Twenty households pay a private rent of £200 a week. Three sharer households with a head of 30 pay £500 a week in the South East, so each family's half exceeds the shared accommodation rate. For every benefit unit or person, we comparedLHA_allowed_bedrooms,LHA_category,housing_benefit_LHA_allowed_bedrooms,uc_non_dep_deductions,universal_credit,housing_benefit,lha_renter_has_non_dependant,is_non_dependant_of_household_head,is_uc_non_dependant_of_household_headandis_benefit_unit_non_dependant_for_universal_credit. No run raised an error.The previous version of this grid set the claim inputs on some benefit units only, which left the others at the default of no claim. This version sets them on every benefit unit, and sets the roles of every person in the three households with a head of 30.
mainat 3cf10f8 and at 117e674 give identical results on every case.This head against
maingives 35 differences, all from this PR. At 2f42ce1 there are 27:lha_renter_has_non_dependant1 to 0, renters aged 30 and 40, under both schemes). The bedrooms stay at 2, as the foster room replaces the child's room.is_benefit_unit_non_dependant_for_universal_credit1 to 0). Where the foster parent rents alone, the foster room replaces their own room, so the total stays at 2. Where a sharer who claims fosters them, the head's claim, which counts the household's non-dependants, takes their bedroom from the sharer's claim: with the head's own child of 8, it goes from 2 bedrooms to 3 and category C to D, and the sharer keeps 2 with the foster room. Where the sharer makes no claim, the head's claim already had their bedroom onmainand keeps it.mainhas nois_placed_for_adoptioninput, so there the child counts as the renter's own.e2f368d adds 8, all from the flag:
Between 9834880 and 2f42ce1, 92 differences are variables that
mainadded after 9834880's base. Of the 25 value changes, 23 come frommain:is_non_dependant_of_household_head): 4.The other 2 are this PR's: the 17-year-old a sharer fosters gives the head's claim its third bedroom (1f24fca).
The final-HB cases use Maidstone in 2026, where the rent of £300 a week exceeds the D rate: the renter's HB at three bedrooms, £8,889.92, exceeds the HB at two, £5,359.64, by £3,530.28.
Impact (real microsimulation)
We ran these on #2010's earlier head and this PR's earlier head: base 49866c2, branch 500424e (084664c and 9311e4e give identical aggregates). We haven't rerun them at this head; a rerun needs the dataset. They use the enhanced FRS 2024-25 as released (policyengine-uk-data 1.57.4,
enhanced_frs_2024_25.h5, sha25603fe15e4…), for 2026.We identify a survey household by its rent and its members' ages, which every enhanced-FRS record shares with its FRS 2024-25 source household. We suppress cells built from fewer than 10 survey households, and suppress sub-cells together when any one of them falls short, so no one can recover a hidden cell by subtraction.
At 500424e against 49866c2, we estimate:
LHA_cap, which the model computes for every private renter whether or not they claim) rises by £14.7m net.Figures this head can move, pending a rerun:
mainchanged since 49866c2, which this head merges at 117e674: Give benefit-unit members aged 16 or over a bedroom under LHA rules #2010's household head and non-dependant counting (uc_non_dependants_counted,is_resolved_household_head) and HB occupiers for sharers' claims, and main's later UC non-dependant rules.uc_non_dependants_countedrather than the household head's family, so a household whose head does not claim UC can give them to a sharer's claim.is_couple) as well as having two claimants or partners.Known gaps (not changed here)
lha-disabled-cannot-share-roomsadds them.hb-joint-tenant-shared-non-dependant(Count a non-dependant shared by joint tenants in each tenant's Housing Benefit size criteria #2029) addresses apportionment.is_resolved_household_head), even if a lodger.Documentation
The variables'
documentationfields describe the rules. No docs notebook covers the size criteria.🤖 Generated with Claude Code