Skip to content

Model a Universal Credit claim by a member of a couple as a single person (UC Regs 2013 reg 3(3)) - #2084

Merged
MaxGhenis merged 15 commits into
mainfrom
uc-reg3-3-single-claim
Oct 8, 2026
Merged

MaxGhenis merged 15 commits into
mainfrom
uc-reg3-3-single-claim

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

When the other member of a couple cannot be a joint Universal Credit claimant, the member who can claims as a single person (UC Regs 2013 reg 3(3)). #2081 added the input uc_is_ineligible_partner for that other member and used it only for the minimum income floor. This PR models the rest of the award. It follows reg 3(3), which says "regulations 18 (capital limit), 36 (amount of elements) and 22 (deduction of income and work allowance) provide for the calculation of the award in such cases":

  • Amounts are a single claimant's (reg 36(3)): the single standard allowance at the claimant's own age. There is no LCWRA or carer element for the other member, who is not "a claimant" (regs 27(1), 29(1)).
  • Capital and income are the couple's (regs 18(2), 22(3)). The deduction is what joint claimants would have, so the other member's limited capability for work still gives the work allowance. The model already did this; tests now pin it.
  • The claimant must meet the basic conditions. A claimant who has reached the qualifying age for State Pension Credit cannot claim this way (WRA 2012 s.4(1)(b)): the mixed-age route of reg 3(2)(a) is only for joint claimants. The model then treats it as no single claim at all.
  • Childcare work condition (reg 32(1)). The claimant must meet the paid-work limb (a). The other member must meet limb (b), which applies "whether claiming jointly or as a single person" (reg 32(1)(b); ADM F7012). Only a claimant can be treated as in paid work under reg 32(2).
  • Benefit cap. A childless single claimant has the single cap (£14,753, or £16,967 in London; reg 80A(2), ADM E5007 note 3). The other member's PIP, DLA, carer's allowance, LCWRA, AFCS or contributory ESA does not lift it (reg 83(1), "a claimant"). Their earnings count towards the earnings exception (regs 78(2), 82(1)(a)).
  • Shared accommodation rate. A renter under 35 claiming as a single person is a specified renter, judged on their own age and their own disability exception (Sch 4 para 28(2), para 29(5); ADM F3213). The other member is not a non-dependant (para 9(2)(b)).
  • Limb (a) is now derived. A member of a couple under 18 to whom the reg 8 minimum age of 16 does not apply is now the ineligible partner by formula (meets_uc_minimum_age_condition). This is ADM E2017's worked example: Jane is 17 and Tom is 19, so "Tom is required to claim for himself as a single person". Limbs (b)-(e) (not in Great Britain, prisoner, reg 19, s.115 IAA 1999) are not observed and stay inputs.

Example, 2026-27: two 30-year-olds, no children, no rent. One cannot be a joint claimant, and that member earns £6,000. The figures are this branch's Simulation output for that household, run on 2026-10-07 and again on 2026-10-08 at the final head 5000a8e4a, which gave the same figures.

Joint claimants Single claim (this PR)
Standard allowance £666.97 × 12 = £8,003.64 £424.90 × 12 = £5,098.80
Deduction (55% of £6,000, no work allowance) £3,300 £3,300
Universal Credit £4,703.64 £1,798.80

Impact: £0 on the Enhanced FRS, as expected. Each figure comes from real Microsimulation runs on the Enhanced FRS 2024-25 (sha256 e433e532…), one run per package state, for every year 2025 to 2030.

Base

Law (legislation.gov.uk, fetched 2026-10-02)

UC Regs 2013 (https://www.legislation.gov.uk/uksi/2013/376):

3(3) A person who is a member of a couple may make a claim as a single person if the other member of the couple— (a) does not meet the basic condition in section 4(1)(a) (at least 18 years old) and is not a person in respect of whom the minimum age specified in regulation 8 applies; (b) does not meet the basic condition in section 4(1)(c) (in Great Britain); (c) is a prisoner; (d) is a person other than a prisoner in respect of whom entitlement does not arise by virtue of regulation 19 (restrictions on entitlement); or (e) is a person to whom section 115 of the Immigration and Asylum Act 1999 (exclusion from benefits) applies, and regulations 18 (capital limit), 36 (amount of elements) and 22 (deduction of income and work allowance) provide for the calculation of the award in such cases.

18(2) In a case where the claimant is a member of a couple, but makes a claim as a single person, the claimant's capital is to be treated as including the capital of the other member of the couple.

22(3) In the case of an award where the claimant is a member of a couple, but makes a claim as a single person, the amount to be deducted from the maximum amount in accordance with section 8(3) of the Act is the same as the amount that would be deducted in accordance with paragraph (1) if the couple were joint claimants.

Reg 22(1)(b)(i) has no work allowance only "where a single claimant does not have, or neither of joint claimants has, responsibility for a child or qualifying young person or limited capability for work".

36(3) In the case of an award where the claimant is a member of a couple, but claims as a single person, the amounts are those shown in the table for a single claimant.

27(1) An award of universal credit is to include an amount in respect of the fact that a claimant has limited capability for work and work-related activity ("the LCWRA element").

29(1) An award of universal credit is to include an amount ("the carer element") ... where a claimant has regular and substantial caring responsibilities for a severely disabled person ...

32(1) The work condition is met in respect of an assessment period if— (a) the claimant is in paid work ...; and (b) if the claimant is a member of a couple (whether claiming jointly or as a single person), the other member is either in paid work or is unable to provide childcare because that person— (i) has limited capability for work, (ii) has regular and substantial caring responsibilities for a severely disabled person, or (iii) is temporarily absent from the claimant's household.

78(2) In this Part "couple" means— (a) joint claimants; or (b) a single claimant who is a member of a couple within the meaning of section 39 of the Act and the other member of that couple ...

80A(2)(c) £14,753 for a single claimant not resident in Greater London who is not responsible for a child or qualifying young person; (d) £22,020 for— (i) joint claimants not resident in Greater London; (ii) a single claimant not resident in Greater London who is responsible for a child or qualifying young person.

82(1)(a) the claimant's earned income or, if the claimant is a member of a couple, the couple's combined earned income, is equal to or exceeds ...

83(1) The benefit cap does not apply ... where— (a) the LCWRA element is included in the award of universal credit or the claimant is receiving an employment and support allowance that includes the support component; ... (g) a claimant, or a qualifying young person for whom a claimant is responsible, is receiving personal independence payment; ...

Sch 4 para 9(2) A person is a non-dependant if the person normally lives in the accommodation with the renter (or joint renters) and is none of the following— ... (b) where the renter is a member of a couple claiming as a single person, the other member of the couple; ...

Sch 4 para 28(2) The first condition is that the renter is a single person (or a member of a couple claiming as a single person) who— (a) is under 35 years old; and (b) is not an excepted person under paragraph 29.

Welfare Reform Act 2012 s.40 (https://www.legislation.gov.uk/ukpga/2012/5/section/40): "'claimant' means a single claimant or each of joint claimants".

DWP Advice for Decision Making:

Change

New:

  • is_uc_single_or_joint_claimant (Person). The claimant in WRA s.40's sense: is_uc_claimant (the two eldest), less uc_is_ineligible_partner.
  • uc_member_of_couple_claims_as_single_person (BenUnit). One member of the couple is the ineligible partner. The other is a claimant who meets the reg 8 minimum age and has not reached the qualifying age for State Pension Credit (WRA s.4(1)(a)-(b)), tested as is_uc_eligible tests them.
  • In utils/uc_work_related_requirements.py:
    • other_member_of_single_claim: the partner of such a claimant. A flag with no claimant beside it marks nothing.
    • single_claim_in_rules_shared_with_legacy_benefits and other_member_of_single_claim_in_shared_rules: the same, for the rules Housing Benefit shares, and false for a family that stays on legacy benefits (stays_on_legacy_benefits).

Changed:

  • uc_is_ineligible_partner: has a formula for limb (a) (a couple member who fails meets_uc_minimum_age_condition); still an input for limbs (b)-(e). A member under 16 is treated as within (a) whatever their circumstances. Strictly, reg 3(3)(a) then gives the other member no single claim; the model does not follow that.
  • uc_standard_allowance_claimant_type: counts s.40 claimants and uses their ages (reg 36(3)).
  • is_uc_eligible: the qualifying claimant must be an s.40 claimant.
  • uc_LCWRA_element, uc_carer_element: nothing for the other member of a single claim (regs 27(1), 29(1)). The carer element keeps its benunit_has_carer route.
  • uc_childcare_work_condition: Apply the UC childcare work condition's partner exceptions and treated-as-working rules (UC Regs 2013 reg 32) #2088's reg 32 rule, with the reg 3(3) split.
  • is_benefit_cap_single_claimant_rate: true for a single claim without a child (reg 80A(2)), unless the family stays on legacy benefits.
  • is_benefit_cap_exempt_health_disability, is_benefit_cap_exempt_other: the other member's own benefits, LCWRA, AFCS and contributory ESA lift no cap (reg 83(1)), unless the family stays on legacy benefits.
  • is_lha_shared_accommodation_rate_specified_renter: applies to a member of a couple claiming as a single person, on the renter's own age and exception (Sch 4 paras 28(2), 29(5)), unless the family stays on legacy benefits.
  • is_uc_claimant: docstring only, pointing to is_uc_single_or_joint_claimant.

Unchanged and already right, now pinned by tests:

  • capital (reg 18(2)): uc_assessable_capital counts both members of the couple;
  • income and work allowance (reg 22(3)): uc_earned_income, uc_unearned_income and is_uc_work_allowance_eligible read both members (Count only claimants' income in Universal Credit #1978's is_uc_assessed_claimant keeps the other member of a single claim);
  • the cap earnings exception (reg 82(1)(a)).

Two existing tests change expectation. A couple aged 30 and 17 used to be treated as joint claimants, and benefit_cap.yaml said "UC reg 3(3) permits some couples to claim as singles, not modelled here". The 30-year-old now claims as a single person (ADM E2017), so they get the single cap of £14,753 and the shared accommodation rate. A new sibling case in each file gives the 17-year-old a reg 8(1)(c) circumstance (caring); that couple claims jointly, with the couple cap and no shared rate.

Modelling choices and limits

  1. Housing Benefit shares the cap rate, the cap exceptions and the LHA category, but has no single claim by a member of a couple.
    • A family that stays on legacy benefits keeps the couple rules there. That is stays_on_legacy_benefits = claims_legacy_benefits (a reported CTC, WTC, HB, income-related ESA, IS or income-based JSA award) and not would_claim_uc, the continuing-award route housing_benefit_eligible uses.
    • Otherwise the UC rule applies, which Housing Benefit then shares.
    • A family that would claim UC is calculated on UC whatever it reports, so its UC housing element, cap and shared rate follow the UC rule. The standard allowance and elements never read the gate.
    • A flag with no claimant beside it (a single adult, both members of a couple, or a claimant over the State Pension Credit qualifying age) changes none of the shared rules; a property test pins that.
    • Give Universal Credit and Housing Benefit their own benefit cap and LHA shared-accommodation rules #2089, stacked on this PR, gives each scheme its own cap and LHA variables and removes this gate.
  2. Limbs (b)-(e) are not observed. The FRS does not record a partner abroad, in prison, in a religious order or subject to immigration control. Only limb (a) arises in the data.

Tests

  • claims_as_single_person.yaml (33 cases). Each expected value is hand-computed from the reg 36, 22 and 80A tables in force for 2026-27 (UC Act 2025, SI 2026/113, SI 2026/148) and NMW Regs reg 4 (£12.71). The cases cover:
    • the standard allowance at the claimant's own age;
    • the Jane/Tom example, with a reg 8 sibling;
    • pension age either way round;
    • capital (two Lifetime ISAs over the limit together);
    • earned and unearned income;
    • the work allowance from the other member's LCW;
    • LCWRA and carer elements either way round;
    • seven reg 32 cases: limb (a) for the claimant only, the other member's limb (b) exception, reg 32(2) for a claimant only, and joint-claim controls;
    • the cap rate with and without a child;
    • PIP and the cap either way round, against joint claimants;
    • the earnings exception;
    • the shared accommodation rate by the renter's age and the partner's PIP;
    • a single adult flagged;
    • a family that reports Housing Benefit but claims UC: single cap, no exception for the partner's PIP, shared rate;
    • a family that stays on legacy benefits: couple rate, the partner's PIP lifts the cap (HB reg 75F(1)(ea), "the claimant or the claimant's partner"), no shared rate.
  • test_uc_single_claim_properties.py: 7 Hypothesis properties and an examples test.
    • Generated couples are calculated as a single claim, as joint claimants and as the claimant alone.
    • Each property also runs on nine explicit example families, each holding one case:
      • the other member with LCWRA and PIP, with caring, with AFCS, or with contributory ESA;
      • the claimant with LCWRA, with caring, or with AFCS;
      • a private renter under 35;
      • an older partner;
      • ADM E2017's Tom and Jane.
    • LCWRA and caring are never in one person, since reg 29(4) would then allow only the LCWRA element, which the model does not yet apply.
    • The properties:
      1. The single standard allowance at the claimant's age.
      2. The single claim's maximum amount equals the claimant-alone maximum. This covers the standard allowance, LCWRA, carer and housing elements and the shared accommodation test.
      3. Earned income, unearned income and the work allowance equal the joint claimants', and the deduction is min(maximum amount, 55% × earned + unearned).
      4. Capital equals the joint claimants', and the sum of each member's capital calculated alone.
      5. In families whose children are all under 16, the single cap rate applies exactly when there is no child. Both cap exceptions equal the joint claimants' with the other member's own disability, caring and benefits removed. The model takes any contributory ESA as including the support component; that proxy predates this PR.
        • Main's is_benefit_cap_exempt_other also lifts the cap where housing_benefit_pension_age_regulations_apply: a claimant or partner over the State Pension Credit qualifying age, with no UC award for one under it and no Income Support, income-based JSA or income-related ESA.
        • Whether there is an award can differ between the single claim and the stripped calculation, either way round. So that exception is compared across calculations only for families the route reaches in none.
        • Within each calculation it is checked against its inputs: the route, or AFCS or contributory ESA of the members whose own benefits count.
      6. Limb (a) against the law's own test: under 18 with none of the generated reg 8(1) circumstances, or under 16.
      7. A flag marking no single claim leaves every Housing-Benefit-shared rule as it was. The second cap exception is handled as in property 5.
    • test_examples_reach_the_cases checks that the examples change each rule they target.
    • Mutation-checked: reverting the LCWRA, standard allowance, cap rate or guard change each fails its property.
  • CI on b997b0079 failed properties 5 and 7 (run 37523832169). It found a claimant of 19 whose single-claim maximum amount was wholly deducted, with a flagged partner of 70: there was no award, so main's pension-age route applied, while the stripped calculation had an award. It also found both members flagged with a 70-year-old partner. These differences are intended and are not reg 83 ones. 0f16b40d1 and 7cb62d76c change the oracle as described in property 5, and the model is unchanged.
  • Runs on this branch:
    • On the final head 5000a8e4a (after the merge of main f1a9a3cc2):
      • the whole policyengine_uk/tests/policy YAML tree, in one process: 2,747 passed, including all 33 claims_as_single_person.yaml cases;
      • test_uc_single_claim_properties.py: 8 passed;
      • test_uc_work_related_groups_properties.py: 14 passed;
      • ruff format --check policyengine_uk: clean.
    • Before that, on 929a9d4bb: the YAML tree, 2,690 passed; test_uc_single_claim_properties.py, 8 passed.
    • Earlier, on fa1e7448b, the related property files (work-related groups, minimum income floor, child and adult definitions, earnings deductions, State Pension, unearned benefits, Lifetime ISA capital, abolish-benefit-cap scenario, UC deductions, rebalancing, Housing Benefit pension age, means-test income and code health): 1,851 passed, plus 1 test already marked as an expected failure.
    • CI ran the full suite on 5000a8e4a and passed (run 37798326067).

Coordination with other PRs

Coordination comments on #1978, #1989, #2076 and #2080 say the same.

axiom: uk/regulations/uksi/2013/376/18, /22, /32, /90 and schedule/4/paragraph/28 are encoded-correct for this case. Their companion tests are, in order, single_claimant_member_of_couple_includes_other_member_capital, member_of_couple_claiming_as_single_uses_joint_claimant_deduction, couple_claimant_treated_as_paid_work_and_other_member_unable, couple_claiming_as_single_by_regulation_3_3_meets_combined_threshold and renter_meets_all_specified_renter_conditions. The rest is queued:

Review

Independent reviews ran through Subfleet. None found a P1. Each review from round 3 on approved the head it was given, up to the final one, 5000a8e4a.

  • Round 1 (Opus, 649503f7b) asked for changes. Every finding is addressed in 17b9b8a16.

  • Round 2 (GPT-6.1 Sol, 17b9b8a16) ran the tests, reproduced its finding and asked for changes:

    • the legacy gate also switched UC results;
    • an example asserted a carer element against reg 29(4).

    Both are fixed in fa1e7448b, along with its P3s.

  • Round 3 (Codex lane, tier hard, fa1e7448b) approved with no findings.

  • After the first merge of main (Opus 5.5, b997b0079) approved, with three P3s:

    • this body;
    • a consistency note on the reg 90(3)(b) 35-hour amount where both members are flagged, a case with no award;
    • the pension-age cases cannot tell State Pension age from the State Pension Credit qualifying age, which are now equal in law.
  • The property-test fix (Opus 5.5, 0f16b40d1) approved, with docstring P3s and an optional unmasked oracle. Both are done in 7cb62d76c.

  • After the second merge of main (Opus 5.5, 929a9d4bb) approved. It found that nothing main brought in, Apply the Income Support conditions to the claimant and partner only #2013 included, reaches the reg 3(3) rules. It had two docstring P3s, fixed in 6d584bd3a; a review of that commit approved it.

  • The rewrap caa114a33 is whitespace only. Its review approved it.

  • After the third merge of main (Opus 5.5, 5000a8e4a) approved, with no P1 or P2. The PR's diff against main is unchanged. Nothing main brought in, Assess each Council Tax Reduction claim under its own family's scheme and exemption #2015 and Key the Housing Benefit Guarantee Credit passport on receipt #1927 included, reaches the UC, cap or LHA rules this PR edits, or the variables they read. Its one P3 asked that this body be checked against the merge, which this update does.

🤖 Generated with Claude Code

MaxGhenis and others added 5 commits October 2, 2026 10:50
…3-single-claim

# Conflicts:
#	policyengine_uk/tests/test_uc_earnings_deductions_properties.py
#	policyengine_uk/variables/gov/dwp/universal_credit/income/uc_individual_earned_income.py
A member of a couple whose partner cannot be a joint claimant claims as a
single person (UC Regs 2013 reg 3(3)); regs 18, 22 and 36 then set the award.

- is_uc_single_or_joint_claimant: the WRA 2012 s.40 claimant (claimant or
  partner, less the partner who cannot be a joint claimant).
- uc_member_of_couple_claims_as_single_person: the benefit unit flag.
- uc_is_ineligible_partner derives reg 3(3)(a) (under 18, outside reg 8)
  from meets_uc_minimum_age_condition; (b)-(e) stay inputs.
- reg 36(3): single standard allowance at the claimant's own age.
- s.4 / reg 3(3): only a claimant can meet the age conditions.
- regs 27(1), 29(1): no LCWRA or carer element for the other member.
- reg 80A(2): single-claimant cap limits (ADM E5007 note 3).
- reg 83(1): the other member's benefits do not lift the cap.
- Sch 4 para 28(2): shared accommodation rate on the renter's own age and
  exceptions (ADM F3213).
- reg 32(1): the claimant must be in paid work; the other member is tested
  as a partner (no change in result).
- regs 18(2), 22(3), 82(1)(a): unchanged; the partner's capital, income,
  LCW for the work allowance and earnings already count. Tests pin them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seven invariants over generated couples, each calculated as a reg 3(3)
single claim, as joint claimants and as the claimant alone: single
standard allowance at the claimant's age (reg 36(3)); maximum amount equal
to the solo claimant's (regs 27, 29, 36(3), Sch 4 paras 9, 10, 28, 29);
deduction equal to the joint claimants' (reg 22(3)); capital equal to the
joint claimants' (reg 18(2)); single cap rate exactly when childless and
cap exceptions ignoring the other member (regs 80A, 83); reg 3(3)(a)
derivation; and a flag marking no single claim leaving the rules Housing
Benefit shares unchanged. Mutation-checked: reverting the LCWRA, standard
allowance, cap rate or guard change each fails its property.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y fixtures

Main's claimant-or-partner inference (#1896) presumes a member under 20
who is at least 16 years younger than the claimant to be the claimant's
child. The work-related group properties generate couples such as 52 and
18 without relationship inputs, so after main was merged in the 18-year-old
was read as a child, the reg 3(3) flag landed on someone outside the
couple, and test_partner_who_cannot_be_a_joint_claimant failed (it fails
the same way on 6db0ab1, before this branch's own changes). Set
is_claimant_or_partner from each generated role, as #1949 did for its
fixtures in a57caf1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…per properties

From the independent review of 649503f (no P1s; three P2s and P3s):
- The benefit cap rate and exceptions and the LHA shared accommodation
  test serve Housing Benefit too, which has no single claim by a member of
  a couple. A family claiming legacy benefits (claims_legacy_benefits) now
  keeps the couple rules there; the UC award itself is unchanged. Helpers
  single_claim_in_rules_shared_with_legacy_benefits and
  other_member_of_single_claim_in_shared_rules; changelog says so.
- uc_member_of_couple_claims_as_single_person requires a claimant who meets
  the s.4(1)(a) and (b) age conditions, so a claimant over State Pension
  age with a flagged partner is no single claim (docstring corrected).
- Property tests: generate AFCS and contributory ESA (the docstring
  claimed them); explicit examples, including ADM E2017's Tom and Jane, on
  every property, and test_examples_reach_the_cases showing each rule
  changes; property 6 uses the reg 3(3)(a)/reg 8 text as its oracle; the
  cap-rate oracle reads only families whose children are under 16.
- YAML: a legacy-claiming family case; a child in the childcare cases; the
  reg 82 comment states the model's fixed 10,152 threshold too; the
  pension-age case asserts no single claim.
- is_uc_claimant's docstring points to is_uc_single_or_joint_claimant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 2, 2026
@MaxGhenis

MaxGhenis commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator Author

Coordination with #2088 (updated for #2088's rename of the offer input), which models UC Regs 2013 reg 32 (the childcare work condition's partner exceptions, reg 32(2) treated-as-working, and offers of paid work). Both PRs edit uc_childcare_work_condition.py, so whichever merges second has a conflict there. This is the resolved formula, keeping this PR's reg 3(3) structure:

    def formula(benunit, period, parameters):
        person = benunit.members
        # WRA 2012 s. 40 claimants: a single claimant or each joint claimant.
        claimant = person("is_uc_single_or_joint_claimant", period)
        # Also the other member of a reg. 3(3) single claim, who is tested
        # under reg. 32(1)(b) "whether claiming jointly or as a single person".
        claimant_or_partner = person("is_uc_claimant", period)
        # Reg. 32(2) treats "a claimant" as in paid work, so not the other
        # member of a single claim.
        treated = claimant & person("uc_childcare_treated_as_in_paid_work", period)
        in_paid_work = person("in_work", period) | treated
        meets_claimant_limb = in_paid_work | person(
            "uc_has_offer_of_paid_work_starting_by_end_of_next_assessment_period",
            period,
        )
        meets_other_member_limb = in_paid_work | person(
            "uc_unable_to_provide_childcare", period
        )
        fails_other_member_limb = claimant_or_partner & ~meets_other_member_limb
        others_failing = (
            benunit.project(benunit.sum(fails_other_member_limb))
            - fails_other_member_limb
        )
        return benunit.any(claimant & meets_claimant_limb & (others_failing == 0))

Your two reg 32 cases in claims_as_single_person.yaml. Both keep their results. Neither has an exception, a listed payment or an offer for the ineligible partner.

A case worth adding after the merge. In a reg 3(3) single claim, the claimant works and the other member receives SMP (no work, no exception). Expected: uc_childcare_work_condition: false, because the other member is not a claimant, so reg 32(2)(b) does not treat them as in paid work. In a joint claim the same facts give true (#2088's "a partner on statutory maternity pay with a working claimant").

#2088's property tests (test_uc_childcare_work_condition_properties.py) set is_claimant_or_partner and never uc_is_ineligible_partner, so they should pass unchanged after the merge.

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

#2089 is stacked on this PR. It gives Universal Credit and Housing Benefit their own benefit cap and LHA shared-accommodation variables and drops the claims_legacy_benefits stopgap:

  • reg 3(3) applies to the UC rules directly;
  • HB treats the couple as a couple whatever the family claims.

#2089 removes single_claim_in_rules_shared_with_legacy_benefits and other_member_of_single_claim_in_shared_rules. If this PR changes them or their callers after #2089's base (17b9b8a), #2089 will merge the change in.

#2089's landing job waits for this PR to merge.

…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>
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

#2088 has merged to main (99d0448), ahead of this PR, so merging main here will conflict in uc_childcare_work_condition.py. The resolved formula is in my earlier comment above. In short:

  • limb (a) is tested for is_uc_single_or_joint_claimant;
  • limb (b) is tested for every other is_uc_claimant member;
  • reg 32(2) treatment (uc_childcare_treated_as_in_paid_work) is masked to s.40 claimants, so the other member of a reg 3(3) single claim doesn't get it.

The suggested extra case: a single claim where the claimant works and the other member receives SMP (no work, no exception) gives uc_childcare_work_condition: false.

🤖 Generated with Claude Code

MaxGhenis and others added 3 commits October 6, 2026 13:32
…-3-single-claim

#2081, #1973 and #1949 have merged, so main now carries this PR's base.
Conflicts and their resolutions:

- uc_individual_earned_income_before_mif.py: main's version (the age-75
  pension contribution limit as #1949 landed it). uc_individual_earned_income.py
  and test_uc_earnings_deductions_properties.py merged cleanly and equal
  main's; so does test_uc_work_related_groups_properties.py, which now
  declares is_claimant_or_partner itself.
- utils/uc_work_related_requirements.py: main's claimants() (it reads
  is_uc_assessed_claimant, which replaced couple_members() with the same
  formula), plus this PR's single-claim helpers.
- uc_member_of_couple_claims_as_single_person.py and
  uc_is_ineligible_partner.py read is_uc_assessed_claimant instead of the
  removed couple_members(); no output changes.
- is_uc_eligible.py: both docstrings' sentences.
- uc_childcare_work_condition.py: #2088's reg 32 formula with this PR's
  reg 3(3) split, as posted on #2084: limb (a) for the s.40 claimant
  (is_uc_single_or_joint_claimant), limb (b) for every other member of the
  couple (is_uc_assessed_claimant), and reg 32(2) treatment only for a
  claimant.
- is_benefit_cap_exempt_other.py merged without a conflict but lost
  `person = benunit.members`, which main removed and this PR's reg 83 line
  reads; restored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…igible does

- claims_as_single_person.yaml: five cases for the childcare work condition
  after #2088: the other member's reg 32(1)(b) exception applies on a single
  claim; their statutory maternity pay does not treat them as in paid work
  (reg 32(2) reads "a claimant"), against a joint-claim control; only the
  claimant can meet limb (a), against a joint-claim control.
- uc_member_of_couple_claims_as_single_person: the claimant's pension-age
  test reads has_attained_state_pension_credit_qualifying_age, as main's
  is_uc_eligible now does for WRA 2012 s.4(1)(b). The two differ only for
  men born before 6 December 1953.
- Changelog: main's cap now has only the reg 60C pension-age exception, so
  an older partner no longer lifts a UC single claimant's cap; the note that
  it did is dropped, and the reg 32 change is described.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2160 reads the State Pension Credit qualifying age for UC reg 89(1)(a) in
uc_work_related_group_apart_from_earnings and extends
test_uc_work_related_groups_properties.py. No conflicts; it touches none of
this PR's files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis changed the base branch from uc-reg3-3-single-claim-base to main October 6, 2026 20:04
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 6, 2026 20:09
MaxGhenis and others added 6 commits October 6, 2026 17:25
CI on b997b00 (run 37523832169) failed properties 5 and 7 of
test_uc_single_claim_properties.py. Main's is_benefit_cap_exempt_other now
lifts the cap where housing_benefit_pension_age_regulations_apply holds: a
claimant or partner over the State Pension Credit qualifying age and no
Universal Credit award. The reg. 3(3) flag changes whether there is an
award, as intended:

- property 5 (generated, 2021): claimant 19, flagged partner 70. The single
  claim's maximum amount (reg. 36(3)) of £14,223.33 is wholly deducted, so
  there is no award and the route applies; the stripped joint calculation
  has £4,103.58, so it does not.
- property 7 (explicit example): with both members flagged no one can claim,
  so there is no award and the 70-year-old partner puts the family on the
  route; joint claimants have £25,151.68.

These are intended differences, not reg. 83 ones. The oracles now compare
is_benefit_cap_exempt_other only for families the route reaches in neither
calculation (off_pension_age_route), and assert that within each
calculation the route lifts the cap. The other shared rules, and the health
and disability exception, are still compared for every family. No model
change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Answers the review of 0f16b40 (subfleet/review-proptest-fix.md):

- Docstrings: the pension-age route is not "held fixed"; families on it in
  either calculation are left out of the cross-calculation comparison. And
  whether there is an award can differ either way round: the single claim
  has a single claimant's amounts (reg. 36(3)) but keeps the work allowance
  the other member's limited capability gives (reg. 22(3)), which the
  stripped calculation loses.
- The review's optional stronger oracle: in each calculation,
  is_benefit_cap_exempt_other must equal the pension-age route or AFCS or
  contributory ESA of the members whose own benefits count (the claimant
  alone on a single claim, in the stripped calculation and with no partner;
  both members otherwise). This checks the masked families too, so a wrong
  AFCS or ESA term for the other member cannot hide behind the route.

Test-only; no model change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rd differs

Answers the P3s of the review of 929a9d4
(subfleet/review-after-merge-2.md):

- Stripping the other member also removes their contributory ESA from
  unearned income, which a single claim keeps (reg. 22(3)), so that is a
  second reason the single claim's award can be the lower. The module and
  off_pension_age_route docstrings now name it.
- exempt_other_from_inputs takes the pension-age route from the model; its
  docstring now says so and names the tests of the route itself.

Docstrings only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Whitespace only (review-docstrings.md P3): the words are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nto uc-reg3-3-single-claim

No conflicts. None of this PR's files changed on main since 9dd771a.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis merged commit 4ed5b3c into main Oct 8, 2026
6 checks passed
@MaxGhenis
MaxGhenis deleted the uc-reg3-3-single-claim branch October 8, 2026 17:47
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Merged at head 5000a8e4a (merge commit 4ed5b3c), on these gates:

  • Apply the UC minimum income floor only to claimants subject to all work-related requirements #2081 merged (47df7b0) and is on main. The PR targets main, and the head contains main at f1a9a3cc2.
  • CI passed on 5000a8e4a (run 37798326067): Lint, Test, and Install + smoke-import on Python 3.11 to 3.14. The PR was MERGEABLE and CLEAN, not a draft, with no CHANGES_REQUESTED review.
  • An independent review (Opus 5.5 on a Subfleet lane, job 20261008-110856-reg33-review-after-merge-3) approved 5000a8e4a, with no P1 or P2 findings. Earlier rounds approved each earlier head, as the PR body's Review section lists.
  • Runs at 5000a8e4a:
    • the policyengine_uk/tests/policy YAML tree: 2,747 passed;
    • test_uc_single_claim_properties.py: 8 passed;
    • test_uc_work_related_groups_properties.py: 14 passed;
    • ruff format --check: clean;
    • the body's worked example, recomputed: £4,703.64 joint, £1,798.80 single.
  • Impact: £0 on the Enhanced FRS for 2025 to 2030, from real runs. The last two merges of main changed none of this PR's files, so the run was not repeated.

🤖 Generated with Claude Code

MaxGhenis added a commit that referenced this pull request Oct 8, 2026
MaxGhenis added a commit that referenced this pull request Oct 9, 2026
…acy-award-readers-claimant-partner

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 10, 2026
#2084 has merged, so this branch now targets main. Conflict resolutions:

- LHA (#2006, #2134, #2022): main's housing_benefit_LHA_category,
  housing_benefit_LHA_rate, housing_benefit_severe_disability_premium_applies,
  LHA_cap, BRMA_LHA_rate, LHA_category and uncapped_BRMA_LHA_rate. This
  branch's reg 3(3) lines stay in is_lha_shared_accommodation_rate_specified_renter
  (#2030 is still open, so lha_renter_has_non_dependant and the union
  responsibility term stay). Its expectations in LHA_claimant_composition.yaml
  and housing_benefit_lha_order.yaml; the two HB categories this branch added
  there are now C under main's HB size criteria (reg 13D(3)(b)).
- #1944: housing_benefit_pension_age_regulations_apply is main's. Its edit to
  the deleted is_benefit_cap_exempt_other is dropped. Its tests now read the
  per-scheme variables; the property file's "before" reform adds the age test
  to each scheme's exceptions.
- #1978: the UC earnings exception and the capped total
  (benefit_cap_welfare_benefits) sum over is_uc_assessed_claimant.
- Carer's Allowance overlap: both specified-benefit exceptions read
  is_entitled_to_carer_benefit (UC reg 83(1)(i)-(ia), HB reg 75F(1)(h)-(ha)).
- #2084 (final head): the stays_on_legacy_benefits helpers stay deleted; its
  two routing cases are rewritten on the per-scheme variables.
- SI 2014/1230 reg 60C: is_uc_benefit_cap_exempt_qualifying_age lifts the UC
  cap where every claimant has reached the qualifying age for State Pension
  Credit. That keeps the result #1944 pinned for such awards (inputs only;
  the model's UC eligibility needs a claimant under that age).
- Tests main added that read the removed shared variables now read the
  per-scheme ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 10, 2026
…1994) into benefit-cap-75f-claimant-partner

Conflicts resolved, keeping main's rules and this branch's person scopes,
ESA support-component test and capped total:

- benefit_cap_reduction: this branch's claimant-or-partner lists, counted
  for is_claimant_or_partner | is_uc_assessed_claimant (#1978's claimant
  set; the two are the same unless is_uc_claimant is entered). That set
  includes the other member of a reg 3(3) single claim (UC Regs 2013 reg
  78(2)).
- is_benefit_cap_exempt_health_disability: this branch's scopes, with
  #2084's reg 3(3) exclusion (other_member_of_single_claim_in_shared_rules)
  on "a claimant", and #1994's is_entitled_to_carer_benefit in
  YOUNG_PERSON_BENEFITS.
- is_benefit_cap_exempt_other: #1944's Housing Benefit pension-age test;
  the AFCS and ESA terms stay moved, scoped, into the health and
  disability file.
- is_benefit_cap_exempt_earnings: #1978's claimant-only earnings, without
  the dead LCWRA and carer sums.
- UC notebook: main's means-test text with this branch's cap sentence,
  without the State Pension age exception #1944 removed.

test_benefit_cap_specified_benefits_properties: the reference reads
entitlement to a carer benefit for the young-person heads, as #1994's
is_entitled_to_carer_benefit does (75F(1)(h)-(ha); 83(1)(i)-(ia)), and
invariant 1 now also draws a non-dependant over State Pension age or with
earnings, which main's age and earnings exceptions no longer count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant