From b442dcbdf79377a18285185e7465dfe483b9ab13 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 19:21:19 +0000 Subject: [PATCH 1/5] Read the claimants' WTC on the reg 60A UC route is_uc_eligible now sums working_tax_credit_reported over the claimant and partner only, so a child's or another adult's report no longer opens the reg 60A route on a closure claim. Adds YAML cases A to E from #2805 and Hypothesis properties. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LwQq6JcN54KSxCfD7zav9D --- changelog.d/2805.fixed.md | 1 + .../reg_60a_working_tax_credit.yaml | 131 ++++++++++++ ...c_reg_60a_working_tax_credit_properties.py | 194 ++++++++++++++++++ .../dwp/universal_credit/is_uc_eligible.py | 19 +- 4 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 changelog.d/2805.fixed.md create mode 100644 policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml create mode 100644 policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py diff --git a/changelog.d/2805.fixed.md b/changelog.d/2805.fixed.md new file mode 100644 index 0000000000..1ddc31c403 --- /dev/null +++ b/changelog.d/2805.fixed.md @@ -0,0 +1 @@ +The reg 60A Universal Credit route on a legacy closure claim now opens only on a Working Tax Credit report by the claimant or partner, not by a child or another adult in the benefit unit. diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml new file mode 100644 index 0000000000..ba0b1686d3 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml @@ -0,0 +1,131 @@ +# SI 2014/1230 reg 60A(1) waives the upper age condition (WRA 2012 +# s.4(1)(b)) for a qualifying claim by a single claimant, or joint claimants +# both, who have reached the qualifying age for State Pension Credit and are +# entitled to an award of Working Tax Credit. Members of a couple claim a tax +# credit jointly (Tax Credits Act 2002 s.3(3)(a)), so the couple's award +# belongs to both; anyone else in the benefit unit claims as a single person +# (s.3(3)(b)), so their award is not the claimant's. Each family makes a +# closure claim (claims_uc_at_legacy_closure), lives in the North East, owns +# its home outright and has no income, so an eligible family's Universal +# Credit is 12 times its 2026-27 monthly standard allowance: 12 x £424.90 +# single and 12 x £666.97 couple. + +- name: Reg 60A route opens for a single claimant aged 70 who reports Working Tax Credit + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + working_tax_credit_reported: 1_000 + benunits: + benunit: + members: [claimant] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant] + region: NORTH_EAST + tenure_type: OWNED_OUTRIGHT + output: + is_uc_eligible: true + universal_credit: 5_098.80 + +- name: Reg 60A route stays shut for a single claimant aged 70 with no Working Tax Credit + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + benunits: + benunit: + members: [claimant] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant] + region: NORTH_EAST + tenure_type: OWNED_OUTRIGHT + output: + is_uc_eligible: false + universal_credit: 0 + +- name: Another adult's Working Tax Credit does not open the reg 60A route for a single claimant aged 70 + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + other_adult: + age: 40 + is_claimant_or_partner: false + working_tax_credit_reported: 1_000 + benunits: + benunit: + members: [claimant, other_adult] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant, other_adult] + region: NORTH_EAST + tenure_type: OWNED_OUTRIGHT + output: + is_uc_eligible: false + universal_credit: 0 + +- name: A dependant's Working Tax Credit does not open the reg 60A route for a single claimant aged 70 + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + is_parent: true + dependant: + age: 17 + is_claimant_or_partner: false + current_education: POST_SECONDARY + working_tax_credit_reported: 1_000 + benunits: + benunit: + members: [claimant, dependant] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant, dependant] + region: NORTH_EAST + tenure_type: OWNED_OUTRIGHT + output: + is_uc_eligible: false + universal_credit: 0 + +- name: A partner's Working Tax Credit opens the reg 60A route for a couple aged 72 and 70 + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 72 + is_claimant_or_partner: true + partner: + age: 70 + is_claimant_or_partner: true + working_tax_credit_reported: 1_000 + benunits: + benunit: + members: [claimant, partner] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant, partner] + region: NORTH_EAST + tenure_type: OWNED_OUTRIGHT + output: + is_uc_eligible: true + universal_credit: 8_003.64 diff --git a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py new file mode 100644 index 0000000000..ba5ca72c06 --- /dev/null +++ b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py @@ -0,0 +1,194 @@ +"""Whose Working Tax Credit opens the reg 60A Universal Credit route. + +SI 2014/1230 reg 60A(1) waives the upper age condition in WRA 2012 +s.4(1)(b) for a qualifying claim by a single claimant, or joint claimants +both, who have reached the qualifying age for State Pension Credit and are +entitled to an award of Working Tax Credit. Members of a couple claim a tax +credit jointly (Tax Credits Act 2002 s.3(3)(a)); anyone else claims as a +single person (s.3(3)(b)). is_uc_eligible therefore reads the Working Tax +Credit reports of the claimant and partner (is_claimant_or_partner) only. + +Invariants, for every drawn benefit unit: + +P1 On a closure claim (claims_uc_at_legacy_closure), a Working Tax Credit + report by a member who is neither claimant nor partner never changes + is_uc_eligible. +P2 On a closure claim, with capital within the limit and a claimant or + partner aged 18 or over, a positive report by the claimant or partner + makes the family eligible. +P3 Without a closure claim, is_uc_eligible equals the formula that sums + every member's report, whoever reports Working Tax Credit. +""" + +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st +from policyengine_core.reforms import Reform + +from policyengine_uk import Simulation +from policyengine_uk.model_api import * + +MODEL_YEAR = 2026 +PROPERTY_SETTINGS = settings( + max_examples=10, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], +) +# Half the draws are unambiguously over the State Pension Credit +# qualifying age, where only the reg 60A route can open. +ADULT_AGE = st.one_of(st.integers(67, 100), st.integers(18, 100)) +OTHER_AGE = st.integers(0, 60) +REPORT = st.sampled_from([0, 1, 500, 2_000, 6_000]) +POSITIVE_REPORT = st.sampled_from([1, 500, 2_000, 6_000]) +# Mostly no report, so other members' reports are often the only ones. +MOSTLY_NO_REPORT = st.sampled_from([0, 0, 0, 2_000]) +# The 2026 capital limit is £16,000; draws straddle it. +CAPITAL = st.sampled_from([0, 6_000, 15_999, 16_001, 40_000]) + + +class is_uc_eligible(Variable): + """The formula that sums every benefit-unit member's Working Tax Credit + report, the reference for P3.""" + + value_type = bool + entity = BenUnit + label = "Eligible for Universal Credit (any member's Working Tax Credit)" + definition_period = YEAR + + def formula(benunit, period, parameters): + capital = benunit("uc_assessable_capital", period) + limit = parameters(period).gov.dwp.universal_credit.means_test.capital.limit + claimant = benunit.members("is_uc_single_or_joint_claimant", period) + meets_minimum_age = benunit.members("meets_uc_minimum_age_condition", period) + pension_age = benunit.members( + "has_attained_state_pension_credit_qualifying_age", period + ) + has_qualifying_claimant = benunit.any( + claimant & meets_minimum_age & ~pension_age + ) + pension_credit_route = benunit("meets_pension_credit_age_conditions", period) + closure_claim = benunit("claims_uc_at_legacy_closure", period) + on_working_tax_credit = ( + add(benunit, period, ["working_tax_credit_reported"]) > 0 + ) + reg_60a = on_working_tax_credit & benunit.any(claimant & meets_minimum_age) + route = (has_qualifying_claimant & ~pension_credit_route) | ( + closure_claim & (has_qualifying_claimant | reg_60a) + ) + return route & (capital <= limit) + + +class any_member_working_tax_credit(Reform): + def apply(self): + self.update_variable(is_uc_eligible) + + +@st.composite +def families( + draw, + couple_report=REPORT, + couple_reports_wtc=False, + other_report=REPORT, + min_others=0, +): + """A claimant, an optional partner and other members, each with + is_claimant_or_partner set from their role. With couple_reports_wtc, the + claimant or the partner reports a positive Working Tax Credit.""" + couple = ["claimant"] + (["partner"] if draw(st.booleans()) else []) + people = { + name: { + "age": draw(ADULT_AGE), + "is_claimant_or_partner": True, + "working_tax_credit_reported": draw(couple_report), + } + for name in couple + } + if couple_reports_wtc: + reporter = draw(st.sampled_from(couple)) + people[reporter]["working_tax_credit_reported"] = draw(POSITIVE_REPORT) + for index in range(draw(st.integers(min_others, 2))): + people[f"other_{index}"] = { + "age": draw(OTHER_AGE), + "is_claimant_or_partner": False, + "working_tax_credit_reported": draw(other_report), + } + return {"people": people, "capital": draw(CAPITAL)} + + +def eligible(family, closure_claim, others_report=True, reform=None): + people = {} + for name, person in family["people"].items(): + values = dict(person) + if not others_report and not values["is_claimant_or_partner"]: + values["working_tax_credit_reported"] = 0 + people[name] = {key: {MODEL_YEAR: value} for key, value in values.items()} + members = list(people) + simulation = Simulation( + situation={ + "people": people, + "benunits": { + "b": { + "members": members, + "claims_uc_at_legacy_closure": {MODEL_YEAR: closure_claim}, + "uc_reported_capital": {MODEL_YEAR: family["capital"]}, + } + }, + "households": { + "h": { + "members": members, + "region": {MODEL_YEAR: "NORTH_EAST"}, + "tenure_type": {MODEL_YEAR: "OWNED_OUTRIGHT"}, + } + }, + } + ) + if reform is not None: + simulation.apply_reform(reform) + return bool(simulation.calculate("is_uc_eligible", MODEL_YEAR)[0]) + + +@PROPERTY_SETTINGS +@given( + families(couple_report=MOSTLY_NO_REPORT, other_report=POSITIVE_REPORT, min_others=1) +) +def test_other_members_working_tax_credit_never_changes_closure_eligibility(family): + assert eligible(family, closure_claim=True) == eligible( + family, closure_claim=True, others_report=False + ) + + +@PROPERTY_SETTINGS +@given(families(couple_reports_wtc=True)) +def test_claimant_or_partner_working_tax_credit_opens_closure_route(family): + family = {**family, "capital": min(family["capital"], 15_999)} + assert eligible(family, closure_claim=True) + + +@PROPERTY_SETTINGS +@given(families(couple_report=MOSTLY_NO_REPORT, other_report=POSITIVE_REPORT)) +def test_no_closure_claim_matches_any_member_reading(family): + assert eligible(family, closure_claim=False) == eligible( + family, closure_claim=False, reform=any_member_working_tax_credit + ) + + +def test_other_adults_report_opens_route_under_any_member_reading(): + """The reference formula differs from the model on a closure claim, so + P3's agreement without one is not vacuous.""" + family = { + "people": { + "claimant": { + "age": 70, + "is_claimant_or_partner": True, + "working_tax_credit_reported": 0, + }, + "other_0": { + "age": 40, + "is_claimant_or_partner": False, + "working_tax_credit_reported": 1_000, + }, + }, + "capital": 0, + } + assert not eligible(family, closure_claim=True) + assert eligible(family, closure_claim=True, reform=any_member_working_tax_credit) diff --git a/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py b/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py index bfd3232943..f646d3391f 100644 --- a/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py +++ b/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py @@ -16,7 +16,9 @@ class is_uc_eligible(Variable): "member's (regulation 18(2)). A family on the Pension Credit route " "(meets_pension_credit_age_conditions) is not eligible unless it " "claims when DWP moves it off its legacy benefits " - "(claims_uc_at_legacy_closure)." + "(claims_uc_at_legacy_closure). On that claim, a pension-age claimant " + "can qualify through reg 60A when the claimant or partner reports " + "Working Tax Credit; another member's report does not count." ) definition_period = YEAR reference = ( @@ -25,6 +27,7 @@ class is_uc_eligible(Variable): "https://www.legislation.gov.uk/uksi/2013/376/regulation/3", "https://www.legislation.gov.uk/uksi/2014/1230/regulation/5", "https://www.legislation.gov.uk/uksi/2014/1230/regulation/60A", + "https://www.legislation.gov.uk/ukpga/2002/21/section/3", ) def formula(benunit, period, parameters): @@ -76,9 +79,21 @@ def formula(benunit, period, parameters): # does not report is treated as a reg 60A migrant, where the # regulation refuses the waiver, and one reporting Pension Credit it # is not awarded makes no closure claim. + # The formula reads the Working Tax Credit reports of the claimant and + # partner only. Members of a couple claim a tax credit jointly (Tax + # Credits Act 2002 s.3(3)(a)), so the couple's award belongs to both, + # as reg 60A(1)(b) requires, and either member's report counts for + # both. A child, a qualifying young person or another adult in the + # benefit unit claims, if at all, as a single person (s.3(3)(b)), so + # their award is not the claimant's and does not open the route. closure_claim = benunit("claims_uc_at_legacy_closure", period) + claimant_or_partner = benunit.members("is_claimant_or_partner", period) on_working_tax_credit = ( - add(benunit, period, ["working_tax_credit_reported"]) > 0 + benunit.sum( + benunit.members("working_tax_credit_reported", period) + * claimant_or_partner + ) + > 0 ) reg_60a = on_working_tax_credit & benunit.any(claimant & meets_minimum_age) route = (has_qualifying_claimant & ~pension_credit_route) | ( From c643315a002107e6ddaffd4e0134a4a493914355 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 15:13:10 +0000 Subject: [PATCH 2/5] Read the claimant's and partner's WTC in the CTR pensioner test council_tax_reduction_pensioner now recognises a reg 60A award only where the claimant or partner reports Working Tax Credit, as is_uc_eligible does. Adds Council Tax Reduction cases for Scotland 2026 and England 2024, a UC case with no closure claim and a UC case with a 17-year-old partner's report. Restates P3 as an invariant that needs no reference formula and widens partner draws to ages 16 and 17. Corrects the Tax Credits Act citations and adds reg 60A(1)(a)(iii) to the headers and docstring. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LwQq6KMhHstAXQyqiYRAcW --- changelog.d/2805.fixed.md | 2 +- .../reg_60a_working_tax_credit.yaml | 74 +++++++-- .../ctr_reg_60a_award_owner.yaml | 149 ++++++++++++++++++ ...c_reg_60a_working_tax_credit_properties.py | 127 ++++++--------- .../dwp/universal_credit/is_uc_eligible.py | 20 ++- .../council_tax_reduction_pensioner.py | 24 ++- 6 files changed, 297 insertions(+), 99 deletions(-) create mode 100644 policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/ctr_reg_60a_award_owner.yaml diff --git a/changelog.d/2805.fixed.md b/changelog.d/2805.fixed.md index 1ddc31c403..a3e78c13d7 100644 --- a/changelog.d/2805.fixed.md +++ b/changelog.d/2805.fixed.md @@ -1 +1 @@ -The reg 60A Universal Credit route on a legacy closure claim now opens only on a Working Tax Credit report by the claimant or partner, not by a child or another adult in the benefit unit. +The model now opens the reg 60A Universal Credit route on a legacy closure claim only when the claimant or partner reports Working Tax Credit, and the pension-age Council Tax Reduction test reads the same reports; a report by a child or another adult in the benefit unit no longer opens the route. diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml index ba0b1686d3..ad67dd5b5d 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/reg_60a_working_tax_credit.yaml @@ -1,13 +1,16 @@ -# SI 2014/1230 reg 60A(1) waives the upper age condition (WRA 2012 -# s.4(1)(b)) for a qualifying claim by a single claimant, or joint claimants -# both, who have reached the qualifying age for State Pension Credit and are -# entitled to an award of Working Tax Credit. Members of a couple claim a tax -# credit jointly (Tax Credits Act 2002 s.3(3)(a)), so the couple's award -# belongs to both; anyone else in the benefit unit claims as a single person -# (s.3(3)(b)), so their award is not the claimant's. Each family makes a -# closure claim (claims_uc_at_legacy_closure), lives in the North East, owns -# its home outright and has no income, so an eligible family's Universal -# Credit is 12 times its 2026-27 monthly standard allowance: 12 x £424.90 +# Under SI 2014/1230 reg 60A(1), the upper age condition in WRA 2012 +# s.4(1)(b) does not apply to a qualifying claim by a single claimant, or +# joint claimants both, who have reached the qualifying age for State Pension +# Credit, hold an award of Working Tax Credit and hold no award of State +# Pension Credit when the migration notice is issued. A couple both aged 16 +# or over and in the UK must claim a tax credit together (Tax Credits Act +# 2002 s.3(3)), and s.10(1) ties entitlement to "the person or persons by +# whom a claim ... has been made". So both members hold the couple's award, +# and the claimant holds no part of an award another member claimed. Each +# family lives in the North East, owns its home outright and has no income, +# and every family but one makes a closure claim +# (claims_uc_at_legacy_closure). An eligible family receives 12 times its +# 2026-27 monthly standard allowance in Universal Credit: 12 x £424.90 # single and 12 x £666.97 couple. - name: Reg 60A route opens for a single claimant aged 70 who reports Working Tax Credit @@ -129,3 +132,54 @@ output: is_uc_eligible: true universal_credit: 8_003.64 + +- name: Reg 60A route stays shut without a closure claim for a single claimant aged 70 who reports Working Tax Credit + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + working_tax_credit_reported: 1_000 + benunits: + benunit: + members: [claimant] + claims_uc_at_legacy_closure: false + households: + household: + members: [claimant] + region: NORTH_EAST + tenure_type: OWNED_OUTRIGHT + output: + is_uc_eligible: false + universal_credit: 0 + +- name: A 17-year-old partner's Working Tax Credit opens the reg 60A route for a claimant aged 70 who claims alone + # The partner can't be a joint claimant (UC Regs 2013 reg 3(3)), so + # the claimant claims Universal Credit as a single person. Both members + # hold the couple's Working Tax Credit award (TCA 2002 ss.3(3), 10(1)). + period: 2026 + absolute_error_margin: 0.01 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + partner: + age: 17 + is_claimant_or_partner: true + working_tax_credit_reported: 1_000 + benunits: + benunit: + members: [claimant, partner] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant, partner] + region: NORTH_EAST + tenure_type: OWNED_OUTRIGHT + output: + is_uc_single_or_joint_claimant: [true, false] + is_uc_eligible: true + universal_credit: 5_098.80 diff --git a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/ctr_reg_60a_award_owner.yaml b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/ctr_reg_60a_award_owner.yaml new file mode 100644 index 0000000000..3ed8496ebe --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/ctr_reg_60a_award_owner.yaml @@ -0,0 +1,149 @@ +# Council Tax Reduction disregards a Universal Credit award "where regulation +# 60A ... applies in respect of the award" in England from the 2025-26 +# scheme year and in Wales from 2026-27 (SI 2012/2885 reg 3(2)(b); +# WSI 2013/3029 reg 3(2)(b)). Scotland counts it (SSI 2021/249 reg 3(2)(b)). +# Under SI 2014/1230 reg 60A(1), the upper age condition in WRA 2012 +# s.4(1)(b) does not apply to a qualifying claim by a single claimant, or +# joint claimants both, who have reached the qualifying age for State Pension +# Credit, hold an award of Working Tax Credit and hold no award of State +# Pension Credit when the migration notice is issued. A couple both aged 16 +# or over and in the UK must claim a tax credit together (Tax Credits Act +# 2002 s.3(3)), and s.10(1) ties entitlement to "the person or persons by +# whom a claim ... has been made". So both members hold the couple's award, +# and the claimant holds no part of an award another member claimed. Where +# reg 60A does not apply, the formula keeps its approximation for a wholly +# pension-age award awaiting termination or made in error (SI 2012/2885 +# reg 3(2); SSI 2021/249 reg 3(2)), so the family stays a pensioner family. + +- name: Another adult's Working Tax Credit doesn't make a Scottish pensioner's UC award a reg 60A award + period: 2026 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + other_adult: + age: 40 + is_claimant_or_partner: false + working_tax_credit_reported: 1_000 + benunits: + family: + members: [claimant, other_adult] + claims_uc_at_legacy_closure: true + universal_credit_pre_benefit_cap: 4_000 + households: + household: + members: [claimant, other_adult] + country: SCOTLAND + local_authority: GLASGOW_CITY + council_tax: 2_000 + savings: 0 + output: + is_uc_entitled: true + council_tax_reduction_pensioner: true + +- name: A dependant's Working Tax Credit doesn't make a Scottish pensioner's UC award a reg 60A award + period: 2026 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + is_parent: true + dependant: + age: 17 + is_claimant_or_partner: false + current_education: POST_SECONDARY + working_tax_credit_reported: 1_000 + benunits: + family: + members: [claimant, dependant] + claims_uc_at_legacy_closure: true + universal_credit_pre_benefit_cap: 4_000 + households: + household: + members: [claimant, dependant] + country: SCOTLAND + local_authority: GLASGOW_CITY + council_tax: 2_000 + savings: 0 + output: + is_uc_entitled: true + council_tax_reduction_pensioner: true + +- name: Another adult's Working Tax Credit doesn't make an English pensioner's 2024 UC award a reg 60A award + period: 2024 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + other_adult: + age: 40 + is_claimant_or_partner: false + working_tax_credit_reported: 1_000 + benunits: + family: + members: [claimant, other_adult] + claims_uc_at_legacy_closure: true + universal_credit_pre_benefit_cap: 4_000 + households: + household: + members: [claimant, other_adult] + region: NORTH_EAST + council_tax: 2_000 + savings: 0 + output: + is_uc_entitled: true + council_tax_reduction_pensioner: true + +- name: A Scottish pensioner's own Working Tax Credit makes the UC award a reg 60A award + period: 2026 + input: + people: + claimant: + age: 70 + is_claimant_or_partner: true + working_tax_credit_reported: 1_000 + benunits: + family: + members: [claimant] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant] + country: SCOTLAND + local_authority: GLASGOW_CITY + council_tax: 2_000 + savings: 0 + output: + is_uc_eligible: true + is_uc_entitled: true + council_tax_reduction_pensioner: false + +- name: A partner's Working Tax Credit makes a Scottish pensioner couple's UC award a reg 60A award + period: 2026 + input: + people: + claimant: + age: 72 + is_claimant_or_partner: true + partner: + age: 70 + is_claimant_or_partner: true + working_tax_credit_reported: 1_000 + benunits: + family: + members: [claimant, partner] + claims_uc_at_legacy_closure: true + households: + household: + members: [claimant, partner] + country: SCOTLAND + local_authority: GLASGOW_CITY + council_tax: 2_000 + savings: 0 + output: + is_uc_eligible: true + is_uc_entitled: true + council_tax_reduction_pensioner: false diff --git a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py index ba5ca72c06..87ea1d0725 100644 --- a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py +++ b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py @@ -1,31 +1,31 @@ """Whose Working Tax Credit opens the reg 60A Universal Credit route. -SI 2014/1230 reg 60A(1) waives the upper age condition in WRA 2012 -s.4(1)(b) for a qualifying claim by a single claimant, or joint claimants -both, who have reached the qualifying age for State Pension Credit and are -entitled to an award of Working Tax Credit. Members of a couple claim a tax -credit jointly (Tax Credits Act 2002 s.3(3)(a)); anyone else claims as a -single person (s.3(3)(b)). is_uc_eligible therefore reads the Working Tax -Credit reports of the claimant and partner (is_claimant_or_partner) only. +Under SI 2014/1230 reg 60A(1), the upper age condition in WRA 2012 s.4(1)(b) +does not apply to a qualifying claim by a single claimant, or joint +claimants both, who have reached the qualifying age for State Pension +Credit, hold an award of Working Tax Credit and hold no award of State +Pension Credit when the migration notice is issued. A couple both aged 16 +or over and in the UK must claim a tax credit together (Tax Credits Act 2002 +s.3(3)), and s.10(1) ties entitlement to "the person or persons by whom a +claim ... has been made". is_uc_eligible reads the Working Tax Credit +reports of the claimant and partner (is_claimant_or_partner) only. Invariants, for every drawn benefit unit: P1 On a closure claim (claims_uc_at_legacy_closure), a Working Tax Credit report by a member who is neither claimant nor partner never changes is_uc_eligible. -P2 On a closure claim, with capital within the limit and a claimant or - partner aged 18 or over, a positive report by the claimant or partner - makes the family eligible. -P3 Without a closure claim, is_uc_eligible equals the formula that sums - every member's report, whoever reports Working Tax Credit. +P2 On a closure claim, with capital within the limit and a claimant aged + 18 or over, a positive report by the claimant or partner makes the + family eligible. +P3 Without a closure claim, zeroing every member's Working Tax Credit + report never changes is_uc_eligible. """ from hypothesis import HealthCheck, given, settings from hypothesis import strategies as st -from policyengine_core.reforms import Reform from policyengine_uk import Simulation -from policyengine_uk.model_api import * MODEL_YEAR = 2026 PROPERTY_SETTINGS = settings( @@ -34,53 +34,20 @@ derandomize=True, suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], ) -# Half the draws are unambiguously over the State Pension Credit +# Half the adult draws fall from 67 to 100, past the State Pension Credit # qualifying age, where only the reg 60A route can open. ADULT_AGE = st.one_of(st.integers(67, 100), st.integers(18, 100)) +# A partner aged 16 or 17 can't be a joint claimant of Universal Credit +# (UC Regs 2013 reg 3(3)) but still holds the couple's tax credit award. +PARTNER_AGE = st.one_of(st.integers(67, 100), st.integers(16, 17), ADULT_AGE) OTHER_AGE = st.integers(0, 60) REPORT = st.sampled_from([0, 1, 500, 2_000, 6_000]) POSITIVE_REPORT = st.sampled_from([1, 500, 2_000, 6_000]) -# Mostly no report, so other members' reports are often the only ones. +# Three draws in four report nothing, so another member often reports alone. MOSTLY_NO_REPORT = st.sampled_from([0, 0, 0, 2_000]) -# The 2026 capital limit is £16,000; draws straddle it. +# The draws straddle the £16,000 capital limit for 2026. CAPITAL = st.sampled_from([0, 6_000, 15_999, 16_001, 40_000]) - - -class is_uc_eligible(Variable): - """The formula that sums every benefit-unit member's Working Tax Credit - report, the reference for P3.""" - - value_type = bool - entity = BenUnit - label = "Eligible for Universal Credit (any member's Working Tax Credit)" - definition_period = YEAR - - def formula(benunit, period, parameters): - capital = benunit("uc_assessable_capital", period) - limit = parameters(period).gov.dwp.universal_credit.means_test.capital.limit - claimant = benunit.members("is_uc_single_or_joint_claimant", period) - meets_minimum_age = benunit.members("meets_uc_minimum_age_condition", period) - pension_age = benunit.members( - "has_attained_state_pension_credit_qualifying_age", period - ) - has_qualifying_claimant = benunit.any( - claimant & meets_minimum_age & ~pension_age - ) - pension_credit_route = benunit("meets_pension_credit_age_conditions", period) - closure_claim = benunit("claims_uc_at_legacy_closure", period) - on_working_tax_credit = ( - add(benunit, period, ["working_tax_credit_reported"]) > 0 - ) - reg_60a = on_working_tax_credit & benunit.any(claimant & meets_minimum_age) - route = (has_qualifying_claimant & ~pension_credit_route) | ( - closure_claim & (has_qualifying_claimant | reg_60a) - ) - return route & (capital <= limit) - - -class any_member_working_tax_credit(Reform): - def apply(self): - self.update_variable(is_uc_eligible) +WITHIN_LIMIT = 15_999 @st.composite @@ -94,17 +61,21 @@ def families( """A claimant, an optional partner and other members, each with is_claimant_or_partner set from their role. With couple_reports_wtc, the claimant or the partner reports a positive Working Tax Credit.""" - couple = ["claimant"] + (["partner"] if draw(st.booleans()) else []) people = { - name: { + "claimant": { "age": draw(ADULT_AGE), "is_claimant_or_partner": True, "working_tax_credit_reported": draw(couple_report), } - for name in couple } + if draw(st.booleans()): + people["partner"] = { + "age": draw(PARTNER_AGE), + "is_claimant_or_partner": True, + "working_tax_credit_reported": draw(couple_report), + } if couple_reports_wtc: - reporter = draw(st.sampled_from(couple)) + reporter = draw(st.sampled_from(list(people))) people[reporter]["working_tax_credit_reported"] = draw(POSITIVE_REPORT) for index in range(draw(st.integers(min_others, 2))): people[f"other_{index}"] = { @@ -115,11 +86,16 @@ def families( return {"people": people, "capital": draw(CAPITAL)} -def eligible(family, closure_claim, others_report=True, reform=None): +def eligible(family, closure_claim, zero_reports=None): + """is_uc_eligible for the family. zero_reports is "others" to zero the + reports of members who are neither claimant nor partner, or "all" to + zero every member's report.""" people = {} for name, person in family["people"].items(): values = dict(person) - if not others_report and not values["is_claimant_or_partner"]: + if zero_reports == "all" or ( + zero_reports == "others" and not values["is_claimant_or_partner"] + ): values["working_tax_credit_reported"] = 0 people[name] = {key: {MODEL_YEAR: value} for key, value in values.items()} members = list(people) @@ -142,8 +118,6 @@ def eligible(family, closure_claim, others_report=True, reform=None): }, } ) - if reform is not None: - simulation.apply_reform(reform) return bool(simulation.calculate("is_uc_eligible", MODEL_YEAR)[0]) @@ -153,42 +127,41 @@ def eligible(family, closure_claim, others_report=True, reform=None): ) def test_other_members_working_tax_credit_never_changes_closure_eligibility(family): assert eligible(family, closure_claim=True) == eligible( - family, closure_claim=True, others_report=False + family, closure_claim=True, zero_reports="others" ) @PROPERTY_SETTINGS @given(families(couple_reports_wtc=True)) def test_claimant_or_partner_working_tax_credit_opens_closure_route(family): - family = {**family, "capital": min(family["capital"], 15_999)} + family = {**family, "capital": min(family["capital"], WITHIN_LIMIT)} assert eligible(family, closure_claim=True) @PROPERTY_SETTINGS -@given(families(couple_report=MOSTLY_NO_REPORT, other_report=POSITIVE_REPORT)) -def test_no_closure_claim_matches_any_member_reading(family): +@given(families(couple_reports_wtc=True, other_report=POSITIVE_REPORT)) +def test_working_tax_credit_never_changes_eligibility_without_closure_claim(family): + # Every draw has a report by the claimant or partner and capital within + # the limit, so a reg 60A route that opened without a closure claim + # would make a wholly pension-age family eligible. + family = {**family, "capital": min(family["capital"], WITHIN_LIMIT)} assert eligible(family, closure_claim=False) == eligible( - family, closure_claim=False, reform=any_member_working_tax_credit + family, closure_claim=False, zero_reports="all" ) -def test_other_adults_report_opens_route_under_any_member_reading(): - """The reference formula differs from the model on a closure claim, so - P3's agreement without one is not vacuous.""" +def test_working_tax_credit_changes_eligibility_on_closure_claim(): + """On a closure claim, zeroing a pension-age claimant's own report closes + the route, so the comparison in P3 can tell the two claims apart.""" family = { "people": { "claimant": { "age": 70, "is_claimant_or_partner": True, - "working_tax_credit_reported": 0, - }, - "other_0": { - "age": 40, - "is_claimant_or_partner": False, "working_tax_credit_reported": 1_000, }, }, "capital": 0, } - assert not eligible(family, closure_claim=True) - assert eligible(family, closure_claim=True, reform=any_member_working_tax_credit) + assert eligible(family, closure_claim=True) + assert not eligible(family, closure_claim=True, zero_reports="all") diff --git a/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py b/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py index f646d3391f..08485d6d0a 100644 --- a/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py +++ b/policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py @@ -18,7 +18,8 @@ class is_uc_eligible(Variable): "claims when DWP moves it off its legacy benefits " "(claims_uc_at_legacy_closure). On that claim, a pension-age claimant " "can qualify through reg 60A when the claimant or partner reports " - "Working Tax Credit; another member's report does not count." + "Working Tax Credit; the formula ignores another member's report. " + "council_tax_reduction_pensioner reads the same reports." ) definition_period = YEAR reference = ( @@ -28,6 +29,7 @@ class is_uc_eligible(Variable): "https://www.legislation.gov.uk/uksi/2014/1230/regulation/5", "https://www.legislation.gov.uk/uksi/2014/1230/regulation/60A", "https://www.legislation.gov.uk/ukpga/2002/21/section/3", + "https://www.legislation.gov.uk/ukpga/2002/21/section/10", ) def formula(benunit, period, parameters): @@ -80,12 +82,16 @@ def formula(benunit, period, parameters): # regulation refuses the waiver, and one reporting Pension Credit it # is not awarded makes no closure claim. # The formula reads the Working Tax Credit reports of the claimant and - # partner only. Members of a couple claim a tax credit jointly (Tax - # Credits Act 2002 s.3(3)(a)), so the couple's award belongs to both, - # as reg 60A(1)(b) requires, and either member's report counts for - # both. A child, a qualifying young person or another adult in the - # benefit unit claims, if at all, as a single person (s.3(3)(b)), so - # their award is not the claimant's and does not open the route. + # partner only. A couple both aged 16 or over and in the UK must + # claim a tax credit together (Tax Credits Act 2002 s.3(3)), and + # s.10(1) gives entitlement to the persons who made the claim, so both + # members hold the couple's award, as reg 60A(1)(b) requires, and + # either member's report counts for both. That includes a partner who + # can't be a joint claimant of Universal Credit (UC Regs 2013 + # reg 3(3)). A child, a qualifying young person or another adult in + # the benefit unit claims, if at all, without the claimant (s.3(3)), + # so the claimant holds none of that award and it does not open the + # route. closure_claim = benunit("claims_uc_at_legacy_closure", period) claimant_or_partner = benunit.members("is_claimant_or_partner", period) on_working_tax_credit = ( diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_pensioner.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_pensioner.py index f070259c7d..c66fd1275a 100644 --- a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_pensioner.py +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_pensioner.py @@ -17,7 +17,9 @@ class council_tax_reduction_pensioner(Variable): "tax credit migrants whose upper UC age limit is waived under " "regulation 60A retain pensioner treatment in England from the " "2025-26 scheme year and Wales from 2026-27; Scotland treats their " - "UC awards under the working-age rules. Other wholly pension-age " + "UC awards under the working-age rules. As in is_uc_eligible, the " + "formula recognises a reg 60A award only where the claimant or " + "partner reports Working Tax Credit. Other wholly pension-age " "UC input awards retain the model's approximation for an award " "awaiting termination or made in error. Each applicant's " "scheme follows their own family, so where families share the rent " @@ -39,6 +41,9 @@ class council_tax_reduction_pensioner(Variable): "https://www.legislation.gov.uk/ssi/2021/249/regulation/3", "https://www.legislation.gov.uk/ssi/2012/319/regulation/12", "https://www.legislation.gov.uk/ssi/2012/303/regulation/12", + "https://www.legislation.gov.uk/uksi/2014/1230/regulation/60A", + "https://www.legislation.gov.uk/ukpga/2002/21/section/3", + "https://www.legislation.gov.uk/ukpga/2002/21/section/10", ) def formula(benunit, period, parameters): @@ -79,11 +84,22 @@ def formula(benunit, period, parameters): # identifies the pensioner as the parent. working_age_applicant = benunit.any(applicant_or_partner & ~over_qualifying_age) # The model recognises reg 60A awards through the closure claim and - # reported WTC. The waiver applies to a single pension-age claimant - # or joint claimants both pension age, not mixed-age couples. + # the Working Tax Credit reported by the claimant or partner, as + # is_uc_eligible does. The waiver applies to a single pension-age + # claimant or joint claimants both pension age, not mixed-age + # couples, and only where they hold the Working Tax Credit award. A + # couple claims the credit together (Tax Credits Act 2002 s.3(3)), + # so both members hold its award (s.10(1)); the claimant holds no + # part of an award another benefit-unit member claimed. + claimant_or_partner = person("is_claimant_or_partner", period) pension_age_tax_credit_migrant = ( benunit("claims_uc_at_legacy_closure", period) - & (add(benunit, period, ["working_tax_credit_reported"]) > 0) + & ( + benunit.sum( + person("working_tax_credit_reported", period) * claimant_or_partner + ) + > 0 + ) & ~working_age_applicant ) country = benunit.household("country", period) From ba7b57344ce82c4de02f90c266d944564d5f1bbf Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 17:51:40 +0000 Subject: [PATCH 3/5] Test that moving a WTC report between claimant and partner never changes reg 60A eligibility Add property P4: on a closure claim, moving a Working Tax Credit report between the claimant and partner never changes is_uc_eligible, since both members hold the couple's award. Name the CTR formula in the changelog fragment and make the fixed test's docstring say what P3 needs from it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01N2tyHTWc6VfYZtLyAQvnrU --- changelog.d/2805.fixed.md | 2 +- ...c_reg_60a_working_tax_credit_properties.py | 52 ++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/changelog.d/2805.fixed.md b/changelog.d/2805.fixed.md index a3e78c13d7..174606678e 100644 --- a/changelog.d/2805.fixed.md +++ b/changelog.d/2805.fixed.md @@ -1 +1 @@ -The model now opens the reg 60A Universal Credit route on a legacy closure claim only when the claimant or partner reports Working Tax Credit, and the pension-age Council Tax Reduction test reads the same reports; a report by a child or another adult in the benefit unit no longer opens the route. +The model now opens the reg 60A Universal Credit route on a legacy closure claim only when the claimant or partner reports Working Tax Credit, and the formula for the pension-age Council Tax Reduction test reads the same reports; a report by a child or another adult in the benefit unit no longer opens the route or makes the award a reg 60A award. diff --git a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py index 87ea1d0725..6cb5484d8d 100644 --- a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py +++ b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py @@ -20,6 +20,8 @@ family eligible. P3 Without a closure claim, zeroing every member's Working Tax Credit report never changes is_uc_eligible. +P4 On a closure claim, moving a Working Tax Credit report between claimant + and partner never changes is_uc_eligible. """ from hypothesis import HealthCheck, given, settings @@ -152,7 +154,8 @@ def test_working_tax_credit_never_changes_eligibility_without_closure_claim(fami def test_working_tax_credit_changes_eligibility_on_closure_claim(): """On a closure claim, zeroing a pension-age claimant's own report closes - the route, so the comparison in P3 can tell the two claims apart.""" + the route, so the zeroing that P3 applies without a closure claim can + change is_uc_eligible.""" family = { "people": { "claimant": { @@ -165,3 +168,50 @@ def test_working_tax_credit_changes_eligibility_on_closure_claim(): } assert eligible(family, closure_claim=True) assert not eligible(family, closure_claim=True, zero_reports="all") + + +@st.composite +def couples(draw): + """A claimant and a partner, one of whom reports Working Tax Credit.""" + people = { + "claimant": { + "age": draw(ADULT_AGE), + "is_claimant_or_partner": True, + "working_tax_credit_reported": 0, + }, + "partner": { + "age": draw(PARTNER_AGE), + "is_claimant_or_partner": True, + "working_tax_credit_reported": 0, + }, + } + people[draw(st.sampled_from(["claimant", "partner"]))][ + "working_tax_credit_reported" + ] = draw(POSITIVE_REPORT) + for index in range(draw(st.integers(0, 1))): + people[f"other_{index}"] = { + "age": draw(OTHER_AGE), + "is_claimant_or_partner": False, + "working_tax_credit_reported": 0, + } + return {"people": people, "capital": WITHIN_LIMIT} + + +def swapped(family): + people = {name: dict(person) for name, person in family["people"].items()} + claimant, partner = people["claimant"], people["partner"] + claimant["working_tax_credit_reported"], partner["working_tax_credit_reported"] = ( + partner["working_tax_credit_reported"], + claimant["working_tax_credit_reported"], + ) + return {**family, "people": people} + + +@PROPERTY_SETTINGS +@given(couples()) +def test_moving_report_between_claimant_and_partner_never_changes_closure_eligibility( + family, +): + assert eligible(family, closure_claim=True) == eligible( + swapped(family), closure_claim=True + ) From 21900e3d5e7d75cf4c9d7b34b6c6daa14985a955 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 18:22:08 +0000 Subject: [PATCH 4/5] Say when a 16- or 17-year-old partner can't be a UC joint claimant in the reg 60A tests The draws set no carer or limited capability input, so a partner aged 16 or 17 meets the minimum age condition only beside a member under 16. Reword the fixed test's docstring so it doesn't read as contradicting P3. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01N2tyHTWc6VfYZtLyAQvnrU --- .../test_uc_reg_60a_working_tax_credit_properties.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py index 6cb5484d8d..e699ab7a40 100644 --- a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py +++ b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py @@ -39,8 +39,11 @@ # Half the adult draws fall from 67 to 100, past the State Pension Credit # qualifying age, where only the reg 60A route can open. ADULT_AGE = st.one_of(st.integers(67, 100), st.integers(18, 100)) -# A partner aged 16 or 17 can't be a joint claimant of Universal Credit -# (UC Regs 2013 reg 3(3)) but still holds the couple's tax credit award. +# These draws set no carer or limited capability for work input, so a +# partner aged 16 or 17 meets the minimum age condition +# (meets_uc_minimum_age_condition) only beside a member under 16. Without +# one, the partner can't be a joint claimant of Universal Credit (UC Regs +# 2013 reg 3(3)) but still holds the couple's tax credit award. PARTNER_AGE = st.one_of(st.integers(67, 100), st.integers(16, 17), ADULT_AGE) OTHER_AGE = st.integers(0, 60) REPORT = st.sampled_from([0, 1, 500, 2_000, 6_000]) @@ -154,8 +157,8 @@ def test_working_tax_credit_never_changes_eligibility_without_closure_claim(fami def test_working_tax_credit_changes_eligibility_on_closure_claim(): """On a closure claim, zeroing a pension-age claimant's own report closes - the route, so the zeroing that P3 applies without a closure claim can - change is_uc_eligible.""" + the route. So the zeroing that P3 applies can change is_uc_eligible, and + P3 checks that it never does without a closure claim.""" family = { "people": { "claimant": { From 8afd8c7fc1f0528024f85eb43b0d688c06dcc5ae Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 3 Nov 2026 18:58:57 +0000 Subject: [PATCH 5/5] Use the review's wording for the fixed reg 60A test's docstring Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QmsZJYWxEGz33tNMYHxuwP --- .../tests/test_uc_reg_60a_working_tax_credit_properties.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py index e699ab7a40..b2ae6cd906 100644 --- a/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py +++ b/policyengine_uk/tests/test_uc_reg_60a_working_tax_credit_properties.py @@ -157,8 +157,8 @@ def test_working_tax_credit_never_changes_eligibility_without_closure_claim(fami def test_working_tax_credit_changes_eligibility_on_closure_claim(): """On a closure claim, zeroing a pension-age claimant's own report closes - the route. So the zeroing that P3 applies can change is_uc_eligible, and - P3 checks that it never does without a closure claim.""" + the route, so the zeroing that P3 applies without a closure claim can + change is_uc_eligible.""" family = { "people": { "claimant": {