Repository navigation
Lift the benefit cap only for the support component and the people HB reg 75F and UC reg 83 name, and cap only the family's benefits - #2076
Conversation
HB Regs 2006 reg 75F(1)(a) and UC Regs 2013 reg 83(1)(a) lift the cap where "the claimant or the claimant's partner is receiving an employment and support allowance ... which includes a support component". The model lifted it for any income-related ESA of the claimant or partner and for any member's contributory ESA, in both is_benefit_cap_exempt_health_disability and is_benefit_cap_exempt_other. Add has_own_esa_award (Person): the person claims ESA themselves (a reported contributory or income-related award, or a directly entered income-related award attributed to the claimant who heads the benefit unit). Add esa_includes_support_component (Person): whether that ESA includes the support component (WRA 2007 ss.2(2), 4(4)). Datasets or users can supply it; otherwise it is assumed for anyone with an ESA award of their own, as for about nine in ten ESA recipients in the Family Resources Survey 2024-25. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HB Regs 2006 reg 75F(1) and UC Regs 2013 reg 83(1) name, for each benefit, whose receipt lifts the cap. is_benefit_cap_exempt_health_disability summed every benefit-unit member's attendance allowance, DLA, PIP, industrial injuries benefit, Carer's Allowance and Carer Support Payment, and is_benefit_cap_exempt_other exempted any member's armed forces compensation. Any member with the LCWRA flag or caring responsibilities also lifted it. Now: - the claimant or partner only: attendance allowance, industrial injuries benefit and armed forces compensation (75F(1)(b)-(d); 83(1)(b)-(e)); - also a child or young person they are responsible for: DLA (75F(1)(e); 83(1)(f)); - also a young person: PIP, Carer's Allowance and Carer Support Payment (75F(1)(ea), (h), (ha); 83(1)(g), (i), (ia)); armed forces independence payment for a Housing Benefit young person (75F(1)(ea); UC reg 2 counts it as attendance allowance); - the UC LCWRA and carer elements: a claimant with limited capability or caring responsibilities (83(1)(a), (j); regs 27(1), 29(1)), or an element entered directly. The cap serves both schemes, so a child or young person under either scheme's definition counts. A 16-year-old who receives benefits in their own right or is looked after counts for neither (UC regs 4(6), 5(5); HB reg 19(2)). Datasets flag every ESA recipient as disabled, so the LCWRA exception lifted the cap for every ESA recipient whatever their ESA group. Universal Credit takes the ESA assessment (UC Regs 2013 reg 40(1)(a)(ii)), so for a person with an ESA award of their own uc_limited_capability_for_WRA is now inferred from the support component. The work allowance and the reduced minimum age need only limited capability for work (regs 8(1)(a), 22, 39), which an ESA award carries, so they read the new uc_limited_capability_for_work. is_benefit_cap_exempt_earnings and is_benefit_cap_exempt_other lose their unused benefit sums and keep their results. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inferring limited capability for work-related activity from the ESA support component in both directions gave a non-dependant's own ESA an LCWRA element in the family's Universal Credit, because uc_LCWRA_element and the work allowance still read every member of the benefit unit (#2027's legacy-award invariance test caught it). Now a person whose own ESA lacks the support component is taken not to have LCWRA (UC Regs 2013 reg 40(1)(a)(ii)), and otherwise uc_limited_capability_for_WRA keeps its is_disabled_for_benefits default. uc_limited_capability_for_work is LCWRA or the disability flag, so the work allowance and reduced minimum age are as before for every input that does not set the new variables. The cap property's family-rate reference now counts any 16-year-old, as the family-rate helper does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ut record The Universal Credit reform hook calculates uc_LCWRA_element while the simulation is being built, and uc_limited_capability_for_WRA now reads has_own_esa_award. That went through claimant_or_partner_esa_income and so entered_directly, which read Simulation._user_input_keys before any input had created it (test_child_and_adult_definitions_properties builds its situations without inputs). has_own_esa_award now takes an income-related award with no member's report behind it as entered for the family, and entered_directly treats a simulation with no recorded inputs as having none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efit-cap-75f-claimant-partner #2027 now leaves the benefit cap to this branch and deletes utils/inputs.py (entered_directly), deciding a directly entered award by value. Conflicts: - is_benefit_cap_exempt_health_disability.py: keep this branch's version; an entered UC LCWRA or carer element is now recognised by value (positive although no member's circumstances give it) instead of entered_directly. - passports.yaml: keep this branch's support-component cap cases. - utils/inputs.py: deleted, as on #2027. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UC Regs 2013 reg 80(1) caps "the amount to which the single person or couple is entitled", and HB Regs 2006 reg 75A the welfare benefits to which the claimant or couple is entitled. benefit_cap_reduction summed every benefit-unit member's contributory ESA and JSA, incapacity benefit and SDA, and the whole unit's income-related ESA and income-based JSA, so another member's own award reduced the family's Universal Credit or Housing Benefit: with UC of 20,000 before the cap, a non-dependent adult's 5,000 of ESA cut the family's UC from 14,753 to 9,753 (#2027 review r2). The capped total now takes the claimant's and partner's person-level awards, claimant_or_partner_esa_income, claimant_or_partner_jsa_income, and the family's Child Benefit, CTC, Income Support, UC and Housing Benefit. Household income keeps the full awards. YAML tests check UC and Housing Benefit amounts; the non-dependant invariance property now also covers benefit_cap_reduction and universal_credit, with JSA, incapacity benefit and SDA among the circumstances. #2027's legacy-award invariance reads the benefit cap exemption again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The non-dependent adult's support component cannot lift the family's cap, so the two cases do not need the input and now also run on the base package, where they fail on value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efit-cap-75f-claimant-partner #2027 makes "on" a legacy award payee-only: of the claimant and partner, only the one the award is payable to (who reports it, or the claimant who heads the family when it is entered directly) is on it (HB Regs 2006 reg 2(1), (3), (3A)). The cap's ESA head reads is_on_income_related_esa for receipt, so a partner who does not hold the couple's award no longer receives it. Two YAML cases now expect the payee only, and the property reference counts an income-related award as received by its reporter. The direct-entry attribution in has_own_esa_award already picks the same person. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efit-cap-75f-claimant-partner #2027 now puts a member outside the couple on an income-related award only when the award on their own report alone is positive. The cap's ESA head reads is_on_income_related_esa only for the claimant and partner, so the exemption is unchanged; the cap YAML and the single-head table pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Coordination with #2084 (UC claim by a member of a couple as a single person, UC Regs 2013 reg 3(3)). This PR counts That PR edits main's versions of Whichever PR lands second should make the claimant set in the rewritten file A separate point from that PR's review, not caused by either PR: |
|
Coordination with #2088, which models the UC childcare work condition's partner exceptions (UC Regs 2013 reg 32(1)(b)). Limb (i) is "has limited capability for work". On main the only LCW proxy is What changes once both merge. Under this PR, an ESA award without the support component removes LCWRA but not LCW. So whichever of the two merges second should switch limb (i) in If this PR merges first, I'll make the switch in #2088. If #2088 merges first, please switch it here when you merge main. Tests to add with the switch. A working claimant whose partner has
🤖 Generated with Claude Code |
|
Coordination with #2089 (each scheme its own benefit cap and LHA shared-accommodation rules), which is stacked on #2084. #2089 deletes the shared exception files this PR rewrites,
Porting this PR onto the split (whichever of the two merges second):
I will push a pre-resolved composition of the two branches, |
…late example cases From the independent review of 17b9b8a (no P1s; two P2s, two P3s): - P2: the shared-rules gate read only claims_legacy_benefits, so a family that reports Housing Benefit but is calculated on Universal Credit (would_claim_uc) lost the UC rules in the LHA category, the UC housing costs element and the cap. The gate is now stays_on_legacy_benefits = claims_legacy_benefits & ~would_claim_uc, the route housing_benefit_eligible gives a continuing working-age HB award. YAML pairs: reports HB but claims UC (single cap, no exception for the partner's PIP, shared rate) and stays on legacy (couple rate, partner's PIP lifts the cap per HB reg 75F(1)(ea), no shared rate). - P2: the examples gave LCWRA and caring to the same person and asserted a carer element, against reg 29(4). LCWRA and caring are now in separate example families. - P3: AFCS and contributory ESA examples isolated, with positive joint and claimant controls on both cap exceptions; the capital property is now a differential against each member calculated alone; docstring notes the model's ESA-amount proxy for the support component and the under-16 scope of the cap-rate oracle. - P3: the changelog no longer says every cap exception is gone for the other member (an older partner still lifts it, pre-existing; #2076). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The pre-resolved composition of this PR with #2089 is pushed: branch
Checked on this branch, one process at a time:
Whichever of #2076 and #2089 merges second can take these files as they are. |
|
#2088 has merged to main (99d0448), ahead of this PR. As my earlier comment said, the switch now falls to this PR: when you merge main, change limb (i) in The test to add with the switch: a working claimant whose partner has 🤖 Generated with Claude Code |
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Thanks Max. The scoping is right, and the tests support it. I reviewed head e648b2db5 against #2027 (b8b4d7b50).
What I checked:
- Law. I pulled HB Regs 2006 regs 75A, 75E and 75F, UC Regs 2013 regs 39, 40, 79, 80, 80A and 83, and WRA 2007 s.2(2) from legislation.gov.uk. Your quotes match the current text. The person scopes match the 75F/83 wording head by head, including AFIP: UC treats it as attendance allowance (claimant only), and HB 75F(1)(ea) also covers a young person.
- Tests. All passed:
- YAML (303):
gov/dwp/benefit_cap/,benefit_cap.yaml,legacy_award_readers/andfinance/benefit/family/universal_credit/. test_benefit_cap_specified_benefits_properties.py: 6 passed.test_legacy_award_readers_properties.py: 10 passed.
- YAML (303):
- Probes (2025, North East), main / #2027 base / this PR:
- A non-dependant with £5,000 of income-related ESA, and UC of £20,000 before the cap: UC goes from £20,000 (exempt) to £14,753, a reduction of £5,247. That matches the PR body.
- The claimant's own contributory ESA without the support component, flagged disabled, rent £9,000, earnings £3,000: no LCWRA element, the £4,932 work allowance is kept, and UC is capped at £9,753. With the support component, the LCWRA element is £5,079.24 and the family is exempt.
- Cases that are exempt on all three: the claimant's LCWRA flag without ESA, a 10-year-old's DLA, and the claimant's attendance allowance on HB only.
- A 17-year-old in FE with PIP: capped on main and the base (reduction £4,334.60), exempt here. That is a real fix.
- Breaking-change check. A single ESA claimant entered as
esa_contrib_reported+is_disabled_for_benefitswith no support-component input gives the same result here as on the base: UC £18,880.92, LCWRA element kept, exempt. Calculator users who don't set the new variables keep the LCWRA element.
Findings:
-
Should fix.
uc_limited_capability_for_work.py:29-30changes results for inputs that set none of the new variables. The body says the opposite ("results are as before for every input that does not set the new variables"). Take someone withuc_limited_capability_for_WRA: falseset explicitly,is_disabled_for_benefits: trueand £6,000 of earnings, rent £9,000. They now get the work allowance: £0 → £4,932, and UC goes from £10,501.68 to £13,214.28. Before, setting LCWRA to false removed the work allowance. Fix: only add back what the ESA inference took away, e.g.uc_limited_capability_for_WRA | (is_disabled_for_benefits & has_own_esa_award & ~esa_includes_support_component)(reg 39(1)(a): ESA's own LCW determination). Then add a YAML case for the explicit-false input. If you'd rather keep the wider rule, say so in the changelog. -
Should fix (when you resolve against main). Main has changed all three cap files since this branch's base:
- The carer test reads
is_entitled_to_carer_benefit(378a248, 607a815). benefit_cap_reductionsums overis_uc_assessed_claimant(de51949, c8f3902).is_benefit_cap_exempt_otheris the pension-age HB / reg 60C test (a2bd3c4, efd9dd7).
The body's "Review of the other exceptions" and "Coordination" sections still describe #1994 and #1944 as pending. When you resolve:
is_benefit_cap_exempt_health_disability.py:29-31should listis_entitled_to_carer_benefit, not thecarers_allowance/carer_support_paymentamounts. Otherwise a claimant whose Carer's Allowance is overlapped to nil stops lifting the cap again, a regression against main. Add a YAML case for it.benefit_cap_reduction.py:46should combine your claimant-or-partner lists withis_uc_assessed_claimant.- Keep main's age test and drop only the
afcs/esa_contribterms.
Please also refresh those two body sections.
- The carer test reads
-
Should fix (PR body). The Enhanced FRS section describes a cell of fewer than 10 records together with its members' characteristics. Please change it to "fewer than 10", as #2082 does. The other counts are ≥10 and are aggregates.
-
Nit.
is_benefit_cap_exempt_health_disability.py:138-141: take a non-dependant flagged disabled. They still add the £5,079.24 LCWRA element to the family's UC, becauseuc_LCWRA_elementreads every member, but the family is now capped (UC £18,880.92 → £14,753). Capping is the right direction in law. Until #1989 makes the element claimant-only, though, the award "includes the LCWRA element" (reg 83(1)(a)) and is capped at the same time. A one-line note in the docstring would help, or a YAML case pinning it as a known limitation. -
Nit.
benefit_cap_reduction.py:22cites UC reg 80 while countinghousing_benefit_pre_benefit_cap. Reg 80(2A) counts HB as nil for the UC cap, and HB reg 75F(1)(g) switches the HB cap off when the claimant gets UC. This is pre-existing and belongs in your "split the exceptions by scheme" follow-up. It would be worth naming 80(2A) there.
Mergeability: the branch merges cleanly into #2027's current head (fc1ff55d1, one commit ahead of the version merged here). As part of the stack it conflicts with main in the cap files above. Other open PRs editing the same files: #2089, #2084, #1989, #1820, #1999, #1965, #2066, #2085.
The previous commit put this PR's set_input override beside delete_arrays expecting git to conflict with #2076's override there. It does not: git merges the two (`git merge-tree` exits 0), and the class then defines set_input twice. The later definition, this PR's, replaces #2076's, so its forget_model_value call would be lost without an error. CI checks formatting only, not `ruff check`, whose F811 reports this. This code-health test fails when Simulation or Microsimulation defines a method more than once (property setters, deleters and overload stubs aside). It fails on the tree merged with #2076, so whichever of the two lands second must combine the overrides into one: call core's set_input, then forget_model_value, then hold_identifiers_in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merge hazard with #2354 (UK hub, 2026-10-11 21:05Z): this PR and #2354 ("Fix PE-UK identifiers for inputs set before the data year", stacked on #2349) both override #2354 adds super().set_input(variable_name, period, value)
forget_model_value(self, variable_name, period)
hold_identifiers_in(self, variable_name, period)Then re-run its CI after the first one merges. A run from before that merge won't see the duplicate. Edited 2026-10-11 22:40Z: corrected the recipe. Since #2354's d2f48c8, |
|
PE-UK main fix landed (UK hub, 2026-10-11 21:42Z): #2349 merged as |
…f-claimant-partner Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… for its period `Simulation.set_input` forgot every model value whose period contained, or was contained in, the period passed, whether or not the call stored anything there. An input for `year:2026:2` (stored under its own key) or a month consistent with the year (which stores nothing) then left the rebalancing's 2026-2029 element in place but read it as an entry, so a non-claimant's limited capability lifted the cap in those years (r6). The override now compares, for each model value of the variable on the branch, policyengine-core's entry for the stored input (`Holder._user_input_storage`) before and after the call. Core replaces that entry each time it stores an input for the period, even an equal value, so only a period the call stored into is forgotten. It is forgotten even if the call then raises. Tests: r6's five periods and three controls as a parametrized test over 2026-2029, an inconsistent month (core's error, record kept), the engine's own array stored back as an entry route, and longer-period and month inputs in the Hypothesis sequence property. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Thanks Max. Reviewed at d4984fb34, against main 3381500f4.
The law reading still holds, and the resolutions in the main merges are right. Below: two body corrections and two notes on merging with other PRs. Nothing here blocks.
Earlier points:
- Not fixed: explicit
uc_limited_capability_for_WRA: false.- The changelog now states the wider rule, which was the alternative I offered.
- But the body ("Changes > Limited capability for work") still says results "are as before for every input that does not set the new variables". They aren't.
- My case: a single 35-year-old in the North East in 2025,
is_disabled_for_benefits: true,uc_limited_capability_for_WRA: falseset explicitly, £6,000 earnings and rent £9,000. Main against this head:- work allowance: £0 → £4,932;
- UC: £7,381.68 → £10,094.28.
- With
uc_has_limited_capability_for_workgone, the same person now also falls in the work preparation group (uc_limited_capability_for_work.py:32-35). - Please correct that sentence, and add a YAML case pinning the explicit-false input under whichever rule you keep.
- Code fixed, body not.
- The carer test reads
is_entitled_to_carer_benefit(is_benefit_cap_exempt_health_disability.py:49-52), and main's overlap cases incarers_allowance_overlapping_benefits.yamlpass. benefit_cap_reductionreadsbenefit_cap_couple, which usesis_uc_assessed_claimantfor a family on UC (utils/benefit_cap.py:18-24).is_benefit_cap_exempt_otheris main's reg 5 test, with the AFCS and ESA terms dropped.- The body still treats #1944 and #1994 as pending, in two places. Both merged in
c2a8c35fc.- "Review of the other exceptions": Age "still exempts a family with any member over State Pension age"; "#1994 switches the carer test".
- "Known violations".
- "The head is
5d543f169" is also out of date.
- The carer test reads
- Fixed. The impact section no longer reports any cell below 10.
- Fixed. The comment at
is_benefit_cap_exempt_health_disability.py:196-212andelement_includedcover it. - Not taken. Reg 80(2A) still isn't named. That's fine as part of #2089.
New:
A. Merging with #1820 (4a5174c8c).
- I merged #1820 into this head, keeping this PR's
_health_disabilityfile and #1820's_earningsfile. 532 of 534gov/dwpYAML cases pass. - The two failures are #1820's expectations in
benefit_cap/is_benefit_cap_exempt.yaml, and on both this PR has the law right:- "A child's Armed Forces Independence Payment excepts the benefit unit" (a 10-year-old): HB reg 75F(1)(ea) names a young person, not a child, and UC counts AFIP as attendance allowance, which only a claimant's lifts the cap. The expectation should be false.
- "Armed Forces Compensation Scheme payments except from the benefit cap" expects
is_benefit_cap_exempt_other: true. AFCS has moved to_health_disability, which is still true, so the_otherline should go.
- Whichever lands second updates those two cases. The rest of the merge is mechanical:
- this PR's
_health_disability, which already has AFIP and no duplicate earnings test; - #1820's
_earnings; - either label in
is_benefit_cap_exempt.py.
- this PR's
B. The #2354 recipe is out of date.
- Your 21:02 comment says to combine the two with
forget_model_value(self, variable_name, period). This head has noforget_model_value. set_input(simulation.py:268-277) now takesmodel_value_input_recordsbeforesuper().set_input, and callsforget_replaced_model_valuesin afinally.- Merging #2354 (
11b806732) gives no conflict but twoset_inputdefinitions. The combined method should be:
records = model_value_input_records(self, variable_name)
try:
super().set_input(variable_name, period, value)
finally:
forget_replaced_model_values(self, variable_name, records)
hold_identifiers_in(self, variable_name, period)Please update the recipe on #2354 as well.
What I checked:
- Law. I re-read HB Regs 2006 reg 75F and UC Regs 2013 reg 83 on legislation.gov.uk. The person scopes match head by head, including:
- the support component for "the claimant or the claimant's partner" (HB) and "the claimant" (UC);
- AFIP under 75F(1)(ea);
- "entitled to" for carer's allowance and carer support payment.
- Tests at
d4984fb34, in a fresh venv on policyengine-core 3.33.2:- YAML in
gov/dwpandfinance/benefit/family: 1,522 passed. - 2,187 passed across the cap specified-benefits, legacy award readers, UC single claim, UC work-related groups and NI class 4 property tests, plus
test_uc_rebalancing.py,test_dataframe_dataset.pyandcode_health.
- YAML in
- Merged with main
3381500f4: no conflicts. The same YAML (1,539) and the cap property, rebalancing, dataframe andcode_healthtests (2,394) all pass. - Impact. No variable file has changed since
399da7fc1apart from main's merge, so the Enhanced FRS runs in the body still apply to this head. - Leftovers.
uc_has_limited_capability_for_workis no longer referenced anywhere except an old CHANGELOG entry.uc_unable_to_provide_childcarenow reads limited capability for work, as agreed after #2088.
|
For whoever merges main into this PR after #1820 (UK hub, 2026-10-12). An independent review of #1820 (issuecomment on #1820) found that this PR's current earnings rewrite in
|
A child's Armed Forces Independence Payment excepted the whole benefit unit, because AFIP was summed over every member. HB Regs 2006 reg 75F(1)(ea) names the claimant, partner or a young person they are responsible for, not a child under 16; for Universal Credit AFIP is within "attendance allowance" (UC Regs 2013 reg 2), which excepts only where a claimant receives it (reg 83(1)(c)). AFIP now counts for the claimant, partner or a Housing Benefit young person. The child test now expects false, with a new young-person test. The AFCS test drops its is_benefit_cap_exempt_other assertion, which #2076 removes when it moves AFCS into is_benefit_cap_exempt_health_disability, and asserts is_benefit_cap_exempt instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main now has #1978 (is_uc_assessed_claimant), #1896, #1944 and #2084 (the reg 3(3) single claim, is_uc_single_or_joint_claimant). Resolution: - uc_LCWRA_element and uc_carer_element read is_uc_single_or_joint_claimant, which keeps #2084's rule that the other member of a single claim is not a claimant, and this branch's regs 27(4), 29(2) and 29(4). - is_uc_work_allowance_eligible reads is_uc_assessed_claimant, which keeps the other member of a single claim as reg. 22(3) requires, and main's is_responsible_for_child_or_qualifying_young_person_for_universal_credit. - is_benefit_cap_exempt_health_disability and is_benefit_cap_exempt_other take main's version. The cap exceptions are now #2076's (reg 83/75F person scopes) and #2089's (separate UC and HB caps); this branch's cap test file and cap properties are removed with them. - disability_basic_income reads is_uc_single_or_joint_claimant, like the element it pays on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Overlap with #1989, for whichever of the two merges main second. Both PRs rewrite the limited-capability line of
Reg 22(1)(b)(i) needs both changes: "limited capability for work" of "a single claimant ... or ... joint claimants". Reg 22(3) treats a single claim by a member of a couple as joint for the deduction, so the other member of a single claim counts; has_LCW = benunit.any(
person("is_uc_assessed_claimant", period)
& person("uc_limited_capability_for_work", period)
)The docstrings here say the LCWRA element and work allowance "still read every member of the benefit unit". After #1989 they don't.
#1989 no longer touches any benefit cap file; the cap exceptions are this PR's and #2089's. |
|
More for whoever merges second, #2076 or #1989 (follow-up to the comment above). These checks were found in #1989's independent review and read here at d4984fb. After #1989,
Nothing here needs #2076 to change before #1989 lands. It is a heads-up for the merge. |
Brings in #2119 (UC claims at legacy closure), #2373, #1905, #2177, #2305, #2306, #2325, #2376, #2379, #2380, #2388 and #2364. One conflict, in the UC docs notebook: kept main's new paragraph on claims at legacy closure and this branch's benefit cap sentence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…riance test Vahid Ahmadi's review of d4984fb asked for a YAML case pinning an entry of false for `uc_limited_capability_for_WRA`. `uc_limited_capability_for_work` is LCWRA or the disability flag, so a claimant flagged disabled with LCWRA entered as false keeps limited capability for work: the work allowance (4,932 in 2025-26), the work preparation group and UC of 10,094.28, where main gives no work allowance and UC of 7,381.68. #2294 held `benefit_cap_reduction` at zero in `test_other_members_awards_never_change_the_readers` because the cap counted another member's own income-based JSA and income-related ESA (#2298). This branch counts only the couple's, so the hold goes. With it gone the test passes here, and on main 1d3abec it fails on its pinned family (the council tax reduction income moves when a member with 3,000 of JSA joins). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2261 said the benefit cap still counts every member's award, so a binding cap could carry another member's award to a reader through Universal Credit. #2076 merged right after it, in the same merge-queue group: benefit_cap_reduction now counts only the couple's own awards and the family's. The note now says so, and points to JSA_COUPLE_WITH_LODGER, which the first property checks: it is £1,952.48 below the cap in 2025, so an added member's £3,000 of JSA would take it over if the cap counted it. Comment only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolve conflicts with #2399, #2076 and #1965: - is_benefit_cap_exempt_earnings: keep main's per-claimant uc_individual_earned_income_before_mif test and documentation; keep this PR's dated threshold parameter in place of 10_152 and its reg 57 and FA 2004 s.188 references. - is_benefit_cap_exempt_health_disability: take main's version (#2076) and add the UC route for AFIP: on a Universal Credit award only a claimant's counts; otherwise Housing Benefit's young person counts too. - is_benefit_cap_exempt: take main's label. - test_uc_single_claim_properties: keep main's AFCS assertions and this PR's partner-only AFIP example. Pin main's young-person AFIP YAML case to the Housing Benefit route, and give the specified-benefits property oracle the family's scheme. Rewrite the changelog fragment to what the PR still changes relative to main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cap-lha-rules Ports #2076's per-person scopes into the per-scheme files instead of keeping the four shared exception files it rewrote (they stay deleted): - UC reg 83 (is_uc_benefit_cap_exempt_specified_benefit): #2076's payee and support-component tests, scoped to "a claimant" (not the reg 3(3) other member), with UC's own child and young-person tests. - HB reg 75F (is_housing_benefit_benefit_cap_exempt_specified_benefit): claimant or partner, ESA via the couple's award and payee, HB's own child and young-person tests. - benefit_cap_welfare_benefits: #2076's benefit_cap_couple and award_of_members scoping of the capped total. - utils/benefit_cap.py and utils/benefit_unit.py: both sides' helpers. - #2076's converted tests (capped total, specified benefits, and its property file) read the per-scheme variables; the #2298 cap hold in the legacy-readers property file is dropped (fixed by #2076). Resolved by the 2026-10-13 landing lane (job 20261013-115007), which lost DNS before committing; snapshot pushed as wip/uc-hb-split-merge-a98f8f084 (3e27c7f). Targeted cap YAML at this tree: 143 passed (merge-2026-10-13b/logs/yaml_cap_targeted.log). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- P3-1: document that the HB cap rate counts a 16-year-old for the year (has_sixteen_year_old_dependant) while the HB reg 75F exceptions read the model's Child Benefit qualifying young person, which leaves out one outside education; in law one status decides both (CB (General) Regs 2006 regs 5 and 7), and the model has no school-leaver terminal date (#2287). No formula changes: main's #2076 case "A 16-year-old out of education with armed forces independence payment does not lift the cap" pins this reading of reg 75F(1)(ea). - P3-2: the changelog said AFIP "now lifts both caps"; main already lifts them. Against main the UC exception narrows to a claimant's AFIP (UC reg 83(1)(c) with reg 2); HB keeps the young person's (reg 75F(1)(ea)). - P3-3: benefit_cap_welfare_benefits' documentation now says the total includes UC and HB before the cap, which uc_benefit_cap_reduction relies on for reg 80(2A); the capital-income property test's comment no longer names exemption routes the UC exemption stopped reading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review r11 (Opus and GPT-6.1 Sol) on 871e46d: main's benefit cap readers (#2076, #2089) called award_of_members on esa_income and jsa_income. Under disable_simulated_benefits the held total matches neither of its readings after the dataset year, so another member's held award was read as the couple's: it raised benefit_cap_welfare_benefits and could exempt a claimant with an ESA support component who receives no ESA. - utils/benefit_unit.py: award_of_couple reads claimant_or_partner_* wherever the rule's couple is the claimant and partner, and award_of_members for any other couple (a UC couple with is_uc_claimant entered). CLAIMANT_OR_PARTNER_AWARDS moves here; the reform imports it. - benefit_cap_welfare_benefits and both specified-benefit exemptions read award_of_couple. - The reform's docstring says it reads its inputs when it is applied, so a region a scenario's after-load modifier or set_input changes later is not followed; applying the reform after the change reads it (r11 Sol finding 2, Opus nit 4). New test for that route. - Changelog: the first bullet no longer claims what #2047 shipped (r11 Opus finding 2); new bullet for the benefit cap. - New test_disable_simulated_benefits_benefit_cap.py: metamorphic (another member's report never changes the cap, reform on), differential against main's replaced reader (reform off), the fallback couple, and an entered award reaching the cap. Each reader's mutant fails it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
The benefit cap lifted in two cases the law does not, and counted benefits it should not:
is_benefit_cap_exempt_other), lifted the cap. HB Regs 2006 reg 75F(1)(a) and UC Regs 2013 reg 83(1)(a) need ESA "which includes a support component".is_benefit_cap_exempt_other), LCWRA flag or caring.benefit_cap_reductionsummed every member's contributory ESA and JSA, incapacity benefit and SDA, and the whole unit's income-related ESA and income-based JSA. UC Regs 2013 reg 80(1) and HB Regs 2006 reg 75A count the benefits "to which the single person or couple is entitled". With UC of £20,000 before the cap, a non-dependent adult's £5,000 of ESA cut the family's UC from £14,753 to £9,753. Count only the claimant's and partner's legacy awards in means tests and passports #2027's review found this, and Count only the claimant's and partner's legacy awards in means tests and passports #2027 now leaves the whole cap to this PR. Fixes Benefit cap counts another member's own income-based JSA and income-related ESA #2298.A third defect hid the first. Datasets set
is_disabled_for_benefits, the default foruc_limited_capability_for_WRA, from receipt of any of ten benefits, ESA included (policyengine-uk-datadisability_benefits.py). So the UC LCWRA exception lifted the cap for every ESA recipient, whatever their ESA group. Universal Credit takes the ESA work capability assessment (UC Regs 2013 reg 40(1)(a)(ii)). So a person whose own ESA lacks the support component is now taken not to have LCWRA, whatever the flag. The work allowance and the reduced minimum age need only limited capability for work, so they get a separateuc_limited_capability_for_work, which such a person keeps.#2027 merged at
bbb9576e8. This branch has merged main up to1d3abecef(merges285317c8c,399da7fc1,d79a189eband1c946fafb); the head is298df66a0.Law
Fetched verbatim from legislation.gov.uk (
/data.xml, current revised text) on 2026-10-02.HB Regs 2006 regs 75A, 75E(2), 75F; UC Regs 2013 regs 2, 40(1), 79(1), 80(1), 83(1); UC (TP) Regs 2014 reg 19(4); WRA 2007 ss.2(2), 4(4); WRA 2012 s.96(10); HB Regs 2006 regs 2(1), 19, 20(1); UC Regs 2013 regs 4(6), 5(5)
HB Regs 2006 (SI 2006/213) reg 75F:
Reg 75E(2):
UC Regs 2013 (SI 2013/376) reg 83(1):
UC Regs 2013 reg 2: "attendance allowance" includes "armed forces independence payment under the Armed Forces and Reserve Forces (Compensation Scheme) Order 2011". WRA 2012 s.40: "claimant" means a single claimant or each of joint claimants.
UC Regs 2013 reg 40(1):
UC (Transitional Provisions) Regs 2014 reg 19(4): where it had been determined that a claimant moving from old style ESA "had limited capability for work-related activity ... (b) the claimant is to be treated as having limited capability for work and work-related activity for the purposes of regulation 27(1)(b) of those Regulations".
Welfare Reform Act 2007 s.2(2) (contributory allowance), and s.4(4) in the same words (income-related allowance):
UC Regs 2013 reg 79(1) and reg 80(1), the capped total:
HB Regs 2006 reg 75A:
Welfare Reform Act 2012 s.96(10): "welfare benefit" means bereavement allowance, child benefit, child tax credit, employment and support allowance (including income-related), housing benefit, incapacity benefit, income support, jobseeker's allowance (including income-based), maternity allowance, severe disablement allowance, universal credit, widow's pension, widowed mother's allowance or widowed parent's allowance.
HB Regs 2006 reg 2(1): "child" means a person under the age of 16. Reg 19(1): a "young person" is a person who falls within the definition of qualifying young person in section 142 of the Act; reg 19(2) excludes a person on income support, income-based JSA or income-related ESA, or entitled to universal credit. Reg 20(1): a person is responsible for a child or young person who is normally living with them. UC Regs 2013 reg 5(5): "A person who is receiving universal credit, an employment and support allowance or a jobseeker's allowance is not a qualifying young person." Reg 4(6): a child or qualifying young person looked after by a local authority is treated as not being anyone's responsibility.
Changes
ESA with the support component
has_own_esa_award(Person): the person claims ESA themselves. That means reported contributory ESA or a reported income-related award. When the family's income-related award is entered directly, the award goes to the claimant or partner who heads the benefit unit (else the eldest), so a couple's award has one recipient.esa_includes_support_component(Person): whether the person's ESA includes the support component (WRA 2007 ss.2(2), 4(4)).is_on_income_related_esa, from Count only the claimant's and partner's legacy awards in means tests and passports #2027).esa_contrib > 0term leavesis_benefit_cap_exempt_other.On the default: policyengine-uk-data also builds
esa_support_group_proxy, from labour-market status (working age, reported status long-term sick or disabled, no hours of work, and its ESA health-condition proxy). It agrees with the survey's own answer for 524 of those 629 records (83%). Assuming the support component agrees for 584 (93%). So the model uses the constant default and does not read the proxy. The survey's own answer is the better source; see the follow-ups.Who counts
is_responsible_for_child_or_young_person_for_uc_or_housing_benefit).is_child_or_young_person_for_legacy_benefits(HB regs 2, 19) oris_child_or_qualifying_young_person_for_universal_credit(UC regs 4-5) counts.uc_limited_capability_for_WRAstill defaults tois_disabled_for_benefits. A person whose own ESA award lacks the support component is now taken not to have LCWRA, whatever the flag. A determination of limited capability for work-related activity is what gives ESA its support component, and Universal Credit takes it (UC Regs 2013 reg 40(1)(a)(ii); UC (TP) Regs 2014 reg 19(4)).uc_LCWRA_element, the cap and thedisability_basic_incomecontrib reform.uc_LCWRA_elementand the work allowance still read every member of the benefit unit: a non-dependant's own ESA would add an LCWRA element to the family's Universal Credit. Count only the claimant's and partner's legacy awards in means tests and passports #2027's legacy-award invariance test caught exactly that. It can follow Give the UC LCWRA and carer elements, the work allowance and the benefit cap exceptions on the claimants' circumstances only #1989's claimant-only element.uc_limited_capability_for_work=uc_limited_capability_for_WRAoris_disabled_for_benefits.uc_limited_capability_for_WRAentered as false and the disability flag now has limited capability for work. They get the work allowance and fall in the work preparation group, where main gave neither (a YAML case pins it: work allowance £0 to £4,932, UC £7,381.68 to £10,094.28).calculated_bymatches the simulation's formula with the model's by code location, since the tax-benefit system loads each variable file as its own module);benunit_has_carerentry names no member and counts; a nil element never does.scenarios/uc_reform.pyrescalesuc_LCWRA_elementfor 2026-2029 in every simulation, and stored it withset_input, whichsupplied_inputread as an entry. So, before this head, another member's limited capability lifted the cap in 2026-2029 but not in 2025 or 2030. The scenario now stores the element withutils/supplied_inputs.set_model_value. That is stillset_input, so reforms keep the value (core'sapply_reformreplays only recorded inputs), butsupplied_inputdoes not return it unless the period was supplied before, so a user's entry stays an entry. The rebalanced amounts are unchanged (test_uc_rebalancing.py; every Enhanced FRS array other than the cap's is identical to main's).Simulationforgets it whenset_inputstores a value for the period (even an equal one), whendelete_arraysremoves the value, and when the populations are rebuilt (build_from_situation,build_from_dataframe).set_inputdetects a store by policyengine-core's record of the period's input (Holder._user_input_storage), which core replaces on every store. An input for a longer period (year:2026:2) or a month consistent with the year stores nothing for the year, so it leaves the model's value the model's (review r6). Each clone and branch keeps its own copy. So an entry equal to the rebalanced amount is still an entry, however it is made (review r5).apply_reformreplays inputs through storage, so the model's value stays the model's across a reform.is_benefit_cap_exempt_earningsandis_benefit_cap_exempt_otherlose the benefit sums they computed and never used. The earnings test and the State Pension age test return what they returned before. The labels that named the wrong test are corrected.The capped total
benefit_cap_reductionnow counts:claimant_or_partner_esa_incomeandclaimant_or_partner_jsa_income, from Count only the claimant's and partner's legacy awards in means tests and passports #2027);For a family on Universal Credit the couple is the award's claimants (
is_uc_assessed_claimant, including the other member of a reg 3(3) single claim, reg 78(2)); otherwise Housing Benefit's claimant and partner. The two are the same unlessis_uc_claimantis entered.Another member's own award no longer reduces the family's Universal Credit or Housing Benefit.
esa,jsa,household_benefitsand household income keep the full awards. Maternity allowance and the bereavement benefits are welfare benefits too (s.96(10)); they were not in the model's total and are not added here.The rate.
is_benefit_cap_single_claimant_ratekeeps main'sis_coupletest (which reads an enteredrelation_type), unless the entered claimants of a family on Universal Credit (is_uc_claimant) are not Housing Benefit's claimant and partner; then the award's claimants decide (UC Regs 2013 reg 80A). For every input that leavesis_uc_claimantunset it is main's formula.Review of the other exceptions
is_benefit_cap_exempt_earnings, UC reg 82): unchanged here. It reads only the UC claimants' earnings (reg 82(1)(a)). Its remaining defects, the deduction of total income tax and the hard-coded £10,152 a year, are fixed by Fix benefit cap exemption defects (#1818) #1820 and Use each rule's own Universal Credit earned income in the benefit cap, targeted childcare and local CTR #1999.is_benefit_cap_exempt_other): main's test from Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944 and Use the State Pension Credit qualifying age, and start-of-year status for Class 4 NI #1907,housing_benefit_pension_age_regulations_apply. It reads the claimant and partner at the Pension Credit qualifying age (UC regs 79-83 have no age exception apart from SI 2014/1230 reg 60C; HB (SPC) Regs have no cap). This PR only moves its armed forces and ESA terms out.is_entitled_to_carer_benefit(Reduce Carer's Allowance and Carer Support Payment by overlapping benefits #1994, on main), which this PR scopes to the claimant, partner or a young person.Invariants (property-tested)
test_benefit_cap_specified_benefits_properties.pydraws up to six families per simulation.hypothesis.eventrecords every role and circumstance drawn.is_benefit_cap_exempt_health_disability,is_benefit_cap_exempt_other,is_benefit_cap_exempt,benefit_cap,benefit_cap_reductionoruniversal_credit(with £30,000 of UC before the cap), whatever disability or carer benefits, ESA, JSA, incapacity benefit, SDA, disability flag or caring they have.Properties 1-3 run 40 random examples each. Property 4 is a deterministic table. #2027's legacy-award invariance test reads the cap exemption again (#2027 had dropped it when it handed the cap over). It now calculates the cap reduction too: #2294 had held it at zero because the cap counted another member's own JSA and ESA (#2298), and its pinned family (a couple on income-based JSA with a lodger, adding a member with £3,000 of JSA) now leaves the cap, UC and the council tax reduction income unchanged. Further tests pin an element a reform gives (including one equal to the model's own amount), and that the rebalancing adds no entry and keeps a user's.
set_input, after deleting it, and through a rebuild from a situation or an input frame; each lifts the cap, as in a simulation built with the entry.See Runs for the results.
No known violations. Main's age test (#1944, #1907) and earnings test read only the claimant and partner, so the draws include a non-dependant over State Pension age and one with earnings.
On the base (
3803dda0d), in the single-head table with the support component left to the default, 60 of the 128 families disagree with the reference. For example:On #2027's earlier head
200a1cdc4, Hypothesis's minimal counterexample for properties 1 and 2 was a 25-year-old claimant whose benefit unit adds a 17-year-old non-dependant receiving attendance allowance: the family became exempt.Tests
YAML:
gov/dwp/benefit_cap/benefit_cap_specified_benefits.yamlhas 67 cases, each hand-computed from the regulation and the 2025-26 caps (UC reg 80A(2), HB reg 75CA). Every head has a case where a non-dependent adult holds the benefit.benunit_has_carerwith no member flagged (exempt), and a nil one though the claimant cares (reduction £3,247);YAML, the capped total:
gov/dwp/benefit_cap/benefit_cap_capped_total.yamlhas 10 cases on UC and Housing Benefit amounts.relation_type: COUPLEwhose younger member the model would presume a child keeps the couple limit (£22,020), on Housing Benefit alone and on UC.Other YAML:
benefit_cap.yaml: a 16-year-old out of education gives the family rate (£22,020). This is unchanged; it pins the reg 5(1)(a) approximation. The family-rate helper does not yet apply reg 5(5), because the LHA non-dependant test shares the rule and must change with it (follow-up).legacy_award_readers/passports.yaml(from Count only the claimant's and partner's legacy awards in means tests and passports #2027): the two benefit cap cases now state the support component.On the original base (
3803dda0d, when the files had 56 and 5 cases):benefit_cap_specified_benefits.yamlfails 36 of 56 cases.benefit_cap_capped_total.yamlfails 3 of 5 cases, all on value. A non-dependant's ESA exempts the whole family there, and a non-dependant's income-based JSA takes £247 off the family's Housing Benefit.Runs on the head
1c946fafb, with policyengine-core 3.33.2 as main'suv.locknow pins:gov/dwpandfinance/benefitYAML: 1,635 passed.test_uc_rebalancing.py::test_section_4_floor_properties, was Hypothesis's slow-input health check on this loaded host (one draw took 367 s), not a counterexample; it passed on a rerun (27 s) and in CI.ruff format --check: clean.1c946fafb(run 38346827099).On the head
298df66a0, which adds only tests to1c946fafb: the cap YAML file, 67 passed;test_other_members_awards_never_change_the_readerswithout the hold, 1 passed (on main1d3abecef's code it fails on its pinned family, at the council tax reduction income, as #2298 describes). CI: every check passes (run 38360222263).Enhanced FRS impact
Real
Microsimulationruns, 2025-2030, on a private copy of the Enhanced FRS 2024-25 (sha256e433e532…), with policyengine-core 3.33.2: main1d3abecef(the commit merged here) against this branch's head1c946fafb. Both trees were clean. The head298df66a0adds only tests to1c946fafb, so these runs stand for it. Aggregates only; nothing below rests on fewer than 10 survey records.The previous runs were main
6d89338abagainst399da7fc1. Every change this PR makes, below, matches them, with one exception: 2025's UC before the cap on the survey ESAGroup copy, −£0.128bn then, is now −£0.129bn, as one more record changes in that year. Main's own cap count, given for scale at the end, moved from about 302,000 to 293,000. Both moves come from main's intervening merges, which include policyengine-core 3.33.2.The dataset as it stands: £0 in every year 2025-2030.
gov_spending) and the poverty rates do not change in any year. Some families' amounts differ only in float32 rounding, every one by under 5p.is_benefit_cap_exempt_otherloses its armed forces and contributory ESA terms, which flips it for 920-947 records (about 778,000-796,000 benefit units weighted); they stay exempt through the scopedis_benefit_cap_exempt_health_disabilityor earnings.is_benefit_cap_exempt_health_disabilitychanges for 69 records (about 27,000 weighted) each year; all but the few above stay exempt another way.Sensitivity: the survey's own ESA group. The same copy, with
esa_includes_support_componenttaken from FRS 2024-25ESAGroupfor the 629 ESA recipients in FRS-sourced records who answered it (584 in the support group). The stacked SPI-synthetic and capital-gains copies do not link back to FRS records and keep the default. Same two package states:Review
Independent reviews of the heads after #2027 merged:
a6100a7fc), r2 (a6a3073a5) and r3 (e756d1b91) requested changes, and each was answered in the next commit.2f341de77, with three nits (follow-ups below). The reviewer was an Opus 5.5 agent, run in the landing job's own session because the Subfleet daemon was offline.399da7fc1, the merge of main6d89338ab, and requested changes. Its one should-fix: an entry equal to the rebalanced amount was read as the model's after a rebuild throughbuild_from_dataframe.5d543f169fixes it, and also r4's nit 3 (clones shared the record).e249a42c7and requested changes. Its one should-fix:set_inputforgot the model's value for every period overlapping the one passed, even where it stored nothing, so an input foryear:2026:2or a consistent month made the rebalancing's element an entry.d4984fb34forgets it only where the call stores a value.d4984fb34, was lost with its lane before it wrote a verdict.1c946fafb, the merge of main1d3abecefunder policyengine-core 3.33.2, with one nit (follow-ups below). It found:simulation.pycode (_start_new_population, parameter rebuilds) composing with this PR's overrides;e249a42c7's code (7 of 16) and passing on this head.e648b2db5(10/5) andd4984fb34(10/12).298df66a0answers the 10/12 points: a YAML case pins LCWRA entered as false, and this body no longer says such results are unchanged or treats Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944 and Reduce Carer's Allowance and Carer Support Payment by overlapping benefits #1994 as pending.298df66a0with no findings. It derived the new YAML case by hand and ran it on main, and found that the property without the hold passes here and fails on main's cap (a lodger's £3,000 of JSA gives a reduction of £1,047.52).Axiom
axiom: TheAxiomFoundation/rulespec-uk#425 queued
None of these provisions is in the corpus: HB Regs 2006 regs 75A, 75E and 75F; UC Regs 2013 regs 79, 80 and 83; WRA 2007 ss.2 and 4; WRA 2012 s.96. rulespec-uk encodes UC regs 80A, 81 and 82, and its reg 81 takes the capped total as an input. The issue holds the verbatim law, the required outputs, a pasteable
review_findingand companion tests taken from this PR's YAML. It extends #389 (regs 79/83, the age question) and #416 (reg 75F(1)(a), from #2027).Coordination
c2a8c35fc: Count only the claimant's and partner's legacy awards in means tests and passports #2027, Model a Universal Credit claim by a member of a couple as a single person (UC Regs 2013 reg 3(3)) #2084, Apply the benefit cap to mixed-age couples on Universal Credit, and keep them off pensioner Council Tax Reduction #1944, Use the State Pension Credit qualifying age, and start-of-year status for Class 4 NI #1907, Count only claimants' income in Universal Credit #1978 and Reduce Carer's Allowance and Carer Support Payment by overlapping benefits #1994.285317c8c: Default the BRMA from the household's region #2021, Test Winter Fuel Payment and PAWHP receipt per person #2038, Limit salary sacrifice to the pay it comes out of #2063, Index the income tax and NICs thresholds by September CPI after the 2030-31 freeze #2180, Pay pre-2026 UC health element claimants the legislated protected amount #2248, Count a loss on one source as nil in Pension Credit income and earnings #2259, Drop the clone override now that policyengine-core keeps each clone's input record #2262 and Stop counting a benefit unit's claimant or partner as its own child or qualifying young person #2285. Its one conflict wasis_payee_of_couple_award, which now takes both main'scan_claim(Pension Credit) and this branch'scouple(the cap's couple).399da7fc1: Stop deciding a household's UC health element rate by its position #2251, Load a DataFrame simulation input as the dataset it describes #2270, Use the Universal Credit young person in Scotland's working-age Council Tax Reduction #2288 and Narrow the legacy award readers property: an adult non-dependant ends the severe disability premium #2294, with no conflict. Stop deciding a household's UC health element rate by its position #2251 and this branch both edit the end ofadd_universal_credit_reform: main's new-claimant status decides the rate, and this branch stores the result as the model's value.d79a189eb: Set DWP benefit rates to the announced amounts, not CPI projections #1925 and Export the identifiers for every year an input frame names, so it round-trips #2349, with no conflict. Export the identifiers for every year an input frame names, so it round-trips #2349 fixed main's Exported input DataFrame no longer round-trips: main CI fails test_an_exported_frame_loads_back_and_exports_itself #2333 round-trip failure.1c946fafb: Move families onto Universal Credit when a legacy benefit they receive closes #2119, Require a Pension Credit payment for savings-credit-only receipt #2373, Impute UC deductions in constituency and local-authority runs #1905, Preserve universal and targeted hours alongside extended childcare #2177, Apply dated reforms on the statutory timeline on every route #2305, Publish only the policyengine-uk release files whose checks passed #2306, Require fix pull requests to change a test and name their reproducer #2325, Project single-year datasets to 2032, past the OBR horizon #2376, Guard the process's warning filters against the model #2379, Land six reviewed pull requests together (rollup B) #2380, Publish to PyPI with trusted publishing #2388 and Land ten reviewed pull requests together (rollup A) #2364. Its one conflict was the UC docs paragraph: main's new text on claims at legacy closure, with this branch's benefit cap sentence. Main moved policyengine-core to 3.33.2. r8 checked the merged rules and the new core.uc-hb-split-on-2076.supplied_inputandsupplied_input_periodsto read only tiers that still hold the value. Keep both rules: its tier rule, and this PR's check that the stored value is not the model's own (_is_model_value).Simulation.set_input. Keep both: its identifiers, and this PR's forgetting of a model value whose period the call stores into.Follow-ups
ESAGroup, benefits table VAR3 for BENEFIT 16: 1 work-related activity group, 2 support group, 3 assessment phase). policyengine-uk-data can supply a completeesa_includes_support_componentcolumn from it. Until then, no dataset result depends on the support component.is_responsible_for_child_or_young_person_for_uc_or_housing_benefitandlha_renter_has_non_dependantshould stop counting a 16-year-old who receives benefits in their own right or is looked after. Both have to change together.uc_LCWRA_elementin 2026-2029 (on main). The UC rebalancing stores the element for 2026-2029 before areform=is applied, and core'sapply_reformreplays it, so a reform that replaces the element's formula has no effect in those years. The cap then credits such a reform with the rebalanced value (r4 nit 1).set_inputof exactly the rebalanceduc_LCWRA_elementmakes it an entry, but core keeps the cap's cached values, because the stored array did not change. Only a caller entering that amount on a branch reaches this; situations, frames and datasets set inputs first. A fix: inset_input, when the call replaces a model value on a branch, drop the values that depend on it (_drop_values_that_may_depend_on).relation_type: SINGLEalso entered, get the couple limit where main gives the single one.🤖 Generated with Claude Code
Reproducer:
policyengine_uk/tests/policy/baseline/finance/benefit/family/legacy_award_readers/passports.yaml::Another member's income-related ESA does not exempt the family from the benefit cap,policyengine_uk/tests/policy/baseline/finance/benefit/family/legacy_award_readers/passports.yaml::The claimant's own income-related ESA with the support component exempts the family from the benefit cap,policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/childcare_element/uc_childcare_work_condition_reg_32.yaml::Reg. 32(1)(b)(i) - a partner whose own ESA lacks the support component still has limited capability for work,policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/income_floor/uc_MIF_applies.yaml::Limited capability for work (section 21),policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/income_floor/uc_MIF_applies.yaml::Limited capability for work with an ESA award lacking the support component (section 21),policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/income_floor/uc_minimum_income_floor.yaml::A claimant aged 19 in the work preparation group has a 16-hour threshold at the rate for their age