Skip to content

Apply the UC minimum income floor only to claimants subject to all work-related requirements - #2081

Merged
MaxGhenis merged 11 commits into
mainfrom
uc-mif-work-related-groups
Oct 5, 2026
Merged

MaxGhenis merged 11 commits into
mainfrom
uc-mif-work-related-groups

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

On main (after #1973) the Universal Credit minimum income floor (MIF) applies to every claimant with self-employment profit or loss outside a start-up period. The law is narrower. UC Regs 2013 reg 62(1) applies the floor only to a claimant who:

(a) is in gainful self-employment (see regulation 64); and
(b) would, apart from this regulation or regulation 90, fall within section 22 of the Act (claimants subject to all work-related requirements).

So the floor does not reach claimants whom Welfare Reform Act 2012 ss.19 to 21 put in another group. That includes claimants with limited capability for work or work-related activity, carers, claimants over State Pension Credit qualifying age, the responsible carer of a child under 3, and the prescribed descriptions in regs 89 and 91. Two other rules change the amount:

  • Expected hours. The floor uses each claimant's expected hours, which reg 88(2) lowers for the responsible carer of a child under 13. DWP uses up to 30 hours for these carers, against 35 for everyone else.
  • Couple threshold. For a couple, the threshold adds up each partner's own amount (reg 90(2) and (3)). That is 16 hours for a partner in the work-focused interview or work preparation group, and nothing for a partner with no work-related requirements.

This PR adds the work-related group, the responsible carer, the expected hours and the per-partner thresholds. It finishes the three scope gaps #1973 listed.

Two 2026 examples, each a lone parent aged 30 in the North East with £5,000 of profits and council rent of £9,600:

  • Youngest child aged 1 (s.20, so no floor). Main treats the parent as earning the net floor of £20,386.03, giving UC of £9,951.96. Here they keep their £5,000, which is under the £5,124 work allowance, so UC is £18,346.08: £8,394.12 a year more.
  • Youngest child aged 5 (s.22, at 30 expected hours). The net floor is £17,940.62, so UC is £11,296.94: £1,344.98 a year more.

On the Enhanced FRS this raises 2026 UC by £0.299bn. About 95,000 benefit units gain, by a mean of £3,137 a year, and nobody loses UC. The gain rests on 30 FRS survey households, so treat it as indicative. The couple's nomination of the responsible carer is the main modelling choice: nominating the other partner gives +£0.401bn (see "Modelling choices").

#1973 merged into main on 2026-10-04 (88a245012). This branch has main at 6b366b281 merged in, and the numbers above are from runs against that main.

Law (legislation.gov.uk, read 2026-09-30 and 2026-10-01)

Welfare Reform Act 2012 (https://www.legislation.gov.uk/ukpga/2012/5/part/1/chapter/2/crossheading/application-of-workrelated-requirements):

19(2) A claimant falls within this section if— (a) the claimant has limited capability for work and work-related activity, (b) the claimant has regular and substantial caring responsibilities for a severely disabled person, (c) the claimant is the responsible carer for a child under the age of 1, or (d) the claimant is of a prescribed description.

19(6) In this Part "responsible carer", in relation to a child means— (a) a single person who is responsible for the child, or (b) a person who is a member of a couple where— (i) the person or the other member of the couple is responsible for the child, and (ii) the person has been nominated by the couple jointly as responsible for the child.

20(1) A claimant falls within this section if— (a) the claimant is the responsible carer for a child who is aged 1, or (b) the claimant is of a prescribed description.

21(1) A claimant falls within this section if the claimant does not fall within section 19 or 20 and— (a) the claimant has limited capability for work, (aa) the claimant is the responsible carer for a child who is aged 2, or (b) the claimant is of a prescribed description.

22(1) A claimant not falling within any of sections 19 to 21 falls within this section.

The child ages took this form on 3 April 2017 (Welfare Reform and Work Act 2016 s.17). Before that, s.20(1)(a) covered "a child who is aged at least 1 and is under a prescribed age". The prescribed age was 5 (reg 91(1) as made), then 3 from 28 April 2014 (SI 2014/1097 reg 16). From 28 April 2014, reg 91A put the responsible carer of "a child aged 3 or 4" in s.21. The parameters carry these dates.

UC Regs 2013:

  • Reg 86(2) (https://www.legislation.gov.uk/uksi/2013/376/regulation/86): "Only one of joint claimants may be nominated as a responsible carer". Reg 86(3): "The nomination applies to all the children".

  • Reg 89(1) (https://www.legislation.gov.uk/uksi/2013/376/regulation/89): these claimants fall within s.19:

    • (a) "the claimant has reached the qualifying age for state pension credit";
    • (b) carers of a severely disabled person for 35 hours a week;
    • (c) "the claimant is pregnant and it is 11 weeks or less before her expected week of confinement, or was pregnant and it is 15 weeks or less since the date of her confinement";
    • (d) adopters in the first 12 months;
    • (da) and (e) students;
    • (f) "the responsible foster parent of a child under the age of 1".
  • Reg 91(2) (https://www.legislation.gov.uk/uksi/2013/376/regulation/91): foster parents, and friend or family carers in their first 12 months, fall within s.20.

  • Reg 88 (https://www.legislation.gov.uk/uksi/2013/376/regulation/88):

    (1) The "expected number of hours per week" in relation to a claimant for the purposes of determining their individual threshold in regulation 90 ... is 35 unless some lesser number of hours applies under paragraph (2).

    (2) The lesser number of hours is— ... (aa) where the claimant is a responsible carer of a child who has not yet reached compulsory school age, the number of hours that the Secretary of State considers is compatible with those caring responsibilities; (b) where the claimant is a responsible carer for a child who has reached compulsory school age but who is under the age of 13, the number of hours that the Secretary of State considers is compatible with the child's normal school hours (including the normal time it takes the child to travel to and from school); or (c) where the claimant has a physical or mental impairment, the number of hours that the Secretary of State considers is reasonable in light of the impairment.

  • Reg 90 (https://www.legislation.gov.uk/uksi/2013/376/regulation/90):

    (2) A claimant's individual threshold is the amount that a person of the same age as the claimant would be paid at the hourly rate applicable under regulation 4 or regulation 4A(1)(a) to (c) of the National Minimum Wage Regulations for— (a) 16 hours per week, in the case of a claimant who would otherwise fall within section 20 ... or section 21 ...; or (b) the expected number of hours per week in the case of a claimant who would otherwise fall within section 22 ...

    (3) ... (a) in the case of joint claimants, the sum of their individual thresholds; or (b) in the case of a claimant who claims universal credit as a single person by virtue of regulation 3(3), the sum of— (i) the claimant's individual threshold, and (ii) the amount a person would be paid for 35 hours per week at the hourly rate specified in regulation 4 of the National Minimum Wage Regulations ...

DWP guidance agrees on the scope.

  • ADM H4060: the floor applies where the claimant "would normally but for the minimum income floor be subject to all work-related requirements".
  • ADM H4061, example 3: a claimant who has had a baby "moves into the no work-related requirements group. The minimum income floor no longer applies".

Change

New variables, under variables/gov/dwp/universal_credit/work_related_requirements/:

  • uc_work_related_group_apart_from_earnings (Enum). The group the claimant would fall within apart from regs 62 and 90: no work-related requirements, interview only, work preparation, all requirements, or not a claimant. The sections are tested in the Act's order: s.21 only takes someone outside ss.19-20, and s.22 is what is left. The earnings routes of reg 90 are left out, as reg 62(1)(b) and reg 90(2) both require. The routes are:
    • s.19:
      • LCWRA (uc_limited_capability_for_WRA);
      • carers (is_carer_for_benefits; reg 30 and reg 89(1)(b));
      • the responsible carer of a child under 1;
      • State Pension Credit qualifying age (is_SP_age; reg 89(1)(a));
      • the reg 89(1)(c)-(f) inputs.
    • s.20: the responsible carer of a child aged 1; the reg 91(2) input.
    • s.21: limited capability for work (input); the responsible carer of a child aged 2.
  • uc_is_responsible_carer. A lone claimant with a child, or one member of a couple (s.19(6), reg 86). It is an input where the nomination is known; the default is described under "Modelling choices".
  • uc_youngest_child_age (benefit unit). The youngest person under 16 (WRA s.40) in the benefit unit who is not a member of the couple and is not looked after by a local authority (reg 4(6)(a)).
  • uc_expected_hours (reg 88). This is 35, or DWP's figure for the responsible carer of a child under 13. It is an input for the discretionary relevant-carer and impairment reductions.
  • uc_is_in_gainful_self_employment (reg 64). By default, any self-employment profit or loss. It is an input for a trader who breaks even, or whose self-employment is not gainful.
  • Inputs, all default false:
    • uc_has_limited_capability_for_work;
    • uc_is_in_pregnancy_or_post_confinement_period;
    • uc_is_adopter_in_first_year;
    • uc_is_student_with_no_work_related_requirements;
    • uc_is_responsible_foster_parent_of_child_under_one;
    • uc_is_foster_parent_or_new_friend_or_family_carer;
    • uc_is_ineligible_partner (reg 3(3)).

The claimants are main's is_uc_assessed_claimant (at most two per benefit unit), less a reg 3(3) partner (utils/uc_work_related_requirements.py).

Changed:

  • uc_mif_applies: the group is all requirements, the claimant is in gainful self-employment, and they are not in a start-up period.

  • uc_minimum_income_floor_gross: the hours follow the group.

    • All requirements: expected hours (reg 90(2)(b)).
    • Interview only or work preparation: 16 (reg 90(2)(a)).
    • No requirements: the no_requirements_partner_hours parameter (0).
    • A partner who cannot be a joint claimant: 35 hours (ineligible_partner_hours) at the national living wage, whatever their age (reg 90(3)(b)(ii)).
    • Not a claimant: nothing.

    uc_individual_earned_income is unchanged: the couple threshold was already the sum of the two members' uc_minimum_income_floor, which now follows the group.

New parameters:

  • under gov.dwp.universal_credit.work_requirements:
    • responsible_carer.child_age.{no_requirements, interview_only, work_preparation}, with the 2013, 2014 and 2017 ages;
    • responsible_carer.expected_hours.{below_compulsory_school_age, compulsory_school_age, child_age_limit};
    • interview_or_preparation_threshold_hours (16);
  • under gov.dwp.universal_credit.means_test.minimum_income_floor:
    • no_requirements_partner_hours (0);
    • ineligible_partner_hours (35). Reg 90(3)(b)(ii) has said "35 hours per week" since 29 April 2013, separately from reg 88's expected hours.

Modelling choices

  1. Who is the responsible carer in a couple. The law leaves the nomination to the couple (s.19(6)(b)(ii); reg 86), and the FRS does not record it. By default the model takes the claimant with fewer hours of paid work (hours_worked), then the elder. Max ruled on this default (decision d840).
    • In 2026, 122,000 people (33 survey households) are in couples with a child under 13 whom main's floor lifts. In most of them the self-employed partner works more paid hours than the other partner: across all 122,000, the self-employed partner works 32 hours a week on average and the other partner 15. So the default usually nominates the other partner, and the floor stays on the self-employed one with 35 expected hours. The number in which it nominates the self-employed partner rests on fewer than 10 survey households, so neither side of the split is shown.
    • Nominating the other partner instead is the run in the "Other nomination" column: 2026 UC +£0.401bn, against +£0.299bn here. That is the range the choice spans.
    • An earlier version took the nomination that gives the couple the higher award. That assumes couples choose the lead carer to beat the floor, which nothing in DWP's material supports, so I dropped it.
    • Households entered without hours. hours_worked is an input that defaults to 0, so a couple entered without hours ties, and the default falls to the elder. Calculator and API users should set uc_is_responsible_carer, or each member's hours, for a couple with a child. The docstring and changelog say so. An input set for some people sets it for everyone, so set it on both members. Whether to break a tie on lower earned income before age is queued for Max as d977.
  2. A partner with no work-related requirements adds nothing to the couple threshold. Reg 90(2) sets an individual threshold only for a claimant who would otherwise be in s.20 or 21 (16 hours) or s.22 (expected hours). It sets none for an LCWRA partner, a carer, a partner caring for a baby, or a partner over pension age. The ADM and the DWP floor guidance (v9 to v23) give no figure either. The model follows the text and gives such a partner nothing (parameter no_requirements_partner_hours, 0). The partner's earned income then reduces the self-employed partner's floor pound for pound (reg 62(3)). Setting it to 35 hours lowers UC, but the difference rests on fewer than 10 survey households in every year 2025-2030, so its size is suppressed.
  3. Expected hours are DWP's practice figures. Reg 88(2) leaves the number to the Secretary of State.
    • From 3 April 2017 DWP's guidance used up to 16 hours for a child aged 3 or 4 and 25 for a school-age child under 13 (ADM J2086; Work-related requirements for claimants with children, v1).
    • DWP raised both to a maximum of 30 hours for the floor. That applied to new gainfully self-employed claimants from 31 January 2024, and DWP began raising existing floors from February 2025 (DEP2024-0673/073, Gainfully self-employed lead carers with youngest child aged 3-12). The parameters switch on 1 February 2025.
    • Written answer 129349 (28 April 2026): "self-employed individuals with children aged 3-12 typically have their Minimum Income Floor set using a maximum of 30 hours per week".
    • The model uses the maximum. Work coaches can set fewer hours. DWP documents 25 hours first in April 2017, and the model uses it back to 2013, where reg 88(2)(b) already set hours "compatible with the child's normal school hours".
  4. Compulsory school age is age 5, the model's existing gov.dfe.compulsory_school_age scale in whole years. England and Wales start it on a prescribed day after the fifth birthday, and Scotland uses school commencement dates.
  5. State Pension Credit qualifying age is still is_SP_age. Use the State Pension Credit qualifying age, and start-of-year status for Class 4 NI #1907 has since landed has_attained_state_pension_credit_qualifying_age; a follow-up PR switches reg 89(1)(a) to it after this merges. In the independent review's probes they differ in 2016 (ages 63 and 64) and 2017 (age 64), and agree in 2018 and 2019 at ages 62 to 64.
  6. Carers are is_carer_for_benefits: receipt of or entitlement to Carer's Allowance or Carer Support Payment, or 35 hours of care. Reg 30 also requires that the person cared for gets a qualifying disability benefit, and reg 30(3) excludes a person who "derives earned income from those caring responsibilities". The flag tests neither itself, so it can over-include; the code notes this next to the reg 30 comment. Reg 30(1)(a)(i) keeps in s.19 a carer whose earnings exceed the Carer's Allowance limit, and the flag's hours route has no earnings test.

Tests

  • YAML: 77 new cases. Each expectation is computed by hand from the law, with the arithmetic in a comment.
    • work_related_requirements/uc_work_related_group_apart_from_earnings.yaml covers every route, the order of the sections, the 2016 child ages and qualifying young people.
    • work_related_requirements/uc_is_responsible_carer.yaml and work_related_requirements/uc_expected_hours.yaml cover the nomination and the hours.
    • income_floor/uc_MIF_applies.yaml covers scope for each route and for gainful self-employment.
    • income_floor/uc_minimum_income_floor.yaml covers 30- and 16-hour thresholds; ADM J2082 "Alison", J2085 "Louise", and J2086 "Richard" and "Laura" (Laura's arithmetic corrected: £7.05 × 25 × 52 / 12 is £763.75, not the ADM's £763.25); and the reg 90(3)(b) partner aged 17 at the national living wage.
    • income_floor/uc_mif_earned_income.yaml covers couples. Cases include an LCWRA partner's earnings reducing the floor pound for pound, a mixed-age couple, a partner with a 16-hour threshold (s.20) and one with a work-preparation threshold (s.21), a baby, and reg 3(3) partners.
    • Apply the UC minimum income floor to net earned income against a net threshold #1973's couple case with children aged 5 and 3 now uses children aged 15 and 14, keeping its 35-hour numbers. Its award is pinned again: the first child was born before 6 April 2017 and keeps the higher child element (SI 2014/1230 reg 43), so the maximum is £27,873.48 and UC £8,267.05. A new case covers the 30-hour responsible carer with children aged 5 and 3. The self-employed partner's floored earned income falls from £19,252.46 (main) to £16,807.06, and UC rises from £7,691.77 to £9,036.74.
    • After main was merged in, four expectations were re-derived by hand:
    • All 370 tests in the Universal Credit folder (369 YAML cases and one Python test) pass at 947fc3a23.
  • Hypothesis: tests/test_uc_work_related_groups_properties.py, 7 properties.
    • Populations are drawn across 2016, 2020 and 2026. They mix single people, couples and mixed-age couples; children of any age; disability, caring and every prescribed circumstance; paid hours, profits and losses, pay, pension contributions and start-up periods; and four regions. The generators declare each adult a claimant or partner (is_claimant_or_partner), so Replace generic child and adult flags with each programme's legal definitions #1896's presumption does not read an 18-year-old partner as a child. Each property is listed under "Invariants".
    • Results:
      • Locally, the 7 properties passed at 5ed0fd46e (66 minutes), and the 6 floor properties (test_uc_minimum_income_floor_properties.py) at 947fc3a23 (24 minutes), each file in its own process.
      • CI's Test job runs both files, and the earnings-deduction and State Pension property files, on every head. At 671da0f7e, with the reg 90(3)(b)(ii) oracle, it gave 3,108 passed, 1 skipped and 7 xfailed.

Invariants

  1. Scope. uc_mif_applies is exactly: in the all-requirements group, in gainful self-employment, and not in a start-up period. Everyone else keeps their actual earned income, and the floor never lowers anyone's earned income.
  2. Thresholds. The gross threshold is the minimum wage for the person's age × 52 × their expected hours (s.22), × 16 (ss.20-21), or nothing (s.19, or not a claimant). Expected hours are 35 unless a lesser number applies to the responsible carer of a child under 13, and never more than 35.
  3. Nomination. A benefit unit has exactly one responsible carer if it has a child under 16, and none otherwise; the responsible carer is always a claimant. A differential check compares the model with the default rule as written: fewest paid hours, then the elder, then the first listed.
  4. Either nomination. Whichever member of a couple is nominated, invariants 1 and 2 hold. The nomination changes nothing in a benefit unit with no child under 13 or no claimant the floor could apply to.
  5. Differential against Apply the UC minimum income floor to net earned income against a net threshold #1973's rule. Forcing every claimant into the all-requirements group at 35 hours reproduces Apply the UC minimum income floor to net earned income against a net threshold #1973. The scope rules never raise anyone's earned income, so they never lower UC before the benefit cap, under either nomination.
  6. Monotone. More earnings never lower a benefit unit's earned income and never raise its UC before the cap. The default nomination does not depend on earnings. The intended exception, from Apply the UC minimum income floor to net earned income against a net threshold #1973, is a loss raised to exactly zero, which the model reads as no self-employment.
  7. Reg 3(3) partner. A partner who cannot be a joint claimant never has the floor, and adds 35 hours at the national living wage to the couple threshold whatever their age. The oracle uses the regulation's own 35.

The Enhanced FRS runs check parts of invariants 1 and 5 on every record in every year 2025-2030, under the default and both sensitivity runs. No earned income rises, no UC before the cap falls, the floor never lowers anyone, and everyone outside its scope is unchanged.

Impact (Enhanced FRS, real runs)

These are real microsimulation runs. The dataset is a private copy of enhanced_frs_2024_25.h5 (sha256 e433e532…68712).

  • Heads. The base is main at 6b366b281, the main commit merged into this branch, which includes Apply the UC minimum income floor to net earned income against a net threshold #1973. The branch is 5ed0fd46e. Both are clean checkouts, run one at a time.
  • Later commits. The three later commits (359c67835, 671da0f7e, 947fc3a23) change tests and documentation, and they move reg 90(3)(b)(ii)'s 35 hours into their own parameter, which is 35 on every date. They change no output.
  • Sensitivity runs. Both are full runs of the branch:
    • "Other nomination" (the last column): every couple with a child nominates the other member, set as an input.
    • "Partner at 35 hours": no_requirements_partner_hours set to 35. It lowers UC, but for fewer than 10 survey households in each year, so it has no column (modelling choice 2).
  • Counts. Counts are FRS survey households. A capital-gains clone counts with its original, and SPI-synthetic households do not count. Cells under 10 survey households are suppressed, the rule Presume a member 20+ years younger is the claimant's child when no roles are supplied #2082 uses.
Year UC on main UC here Change Other nomination
2025 £79.00bn £79.28bn +£0.288bn +£0.390bn
2026 £83.27bn £83.57bn +£0.299bn +£0.401bn
2027 £85.24bn £85.53bn +£0.296bn +£0.393bn
2028 £86.90bn £87.19bn +£0.292bn +£0.385bn
2029 £87.98bn £88.27bn +£0.286bn +£0.379bn
2030 £84.89bn £85.17bn +£0.277bn +£0.366bn

Counts are given for 2026 only. Every year reuses the same records with weights uprated by the same factor, so the change in a count from one year to the next comes from a handful of survey households.

2026 detail:

  • 95,000 benefit units (30 survey households) gain, by a mean of £3,137 a year.
  • Nobody loses UC, in any of the three runs. Housing Benefit, council tax reduction and Pension Credit are unchanged, and household net income rises by £0.299bn. The rise in the UC caseload rests on fewer than 10 survey households (suppressed). So does a fall in household net income where a new UC award ends Tax-Free Childcare worth more than the UC paid: the model withholds Tax-Free Childcare from any benefit unit with UC before the cap (gov.hmrc.tax_free_childcare.disqualifying_benefits).
  • The floor lifts 221,000 people on main (61 survey households) and 181,000 here (50). Both count people in benefit units on UC under main or this branch; nobody leaves UC, so these are the branch's UC benefit units. Of the 221,000:
    • 40,000 (12 survey households) are no longer lifted.
      • They are now in one of ss.19-21, or they are still in s.22 but their lower floor or couple threshold is now below their own earnings.
      • These groups rest on fewer than 10 survey households each, so they are not split out.
    • 59,000 (19 survey households) are lifted by less. Most are responsible carers of a child aged 3 to 12 with a 30-hour floor. The rest keep 35 hours but have a partner whose lower threshold (30 hours, 16 hours or none) lowers the couple threshold.
    • 122,000 (33 survey households) are lifted by the same amount.
    • Their earned income falls by £0.564bn in all.
  • The change is concentrated in a few benefit units; treat the total as indicative. The changes in poverty rates rest on fewer than 10 survey households (suppressed).

The scripts write aggregates only:

  • dataset_impact.py and compare_impact.py produce the runs and comparisons;
  • survey_map.py, survey_cells.py and disclosure_check.py produce the survey-household counts and the people the floor lifts;
  • zero_profit.py produces the zero-profit figure under "Known gaps".

Known gaps

  • Reg 3(3) single claims are modelled only for the floor. uc_is_ineligible_partner keeps the partner out of the floor and puts the 35-hour amount into the couple threshold. The rest of a single claim by a member of a couple is not modelled here: the standard allowance (reg 36(3)), capital (reg 18(2)) and the work allowance (reg 22(3)). Model a Universal Credit claim by a member of a couple as a single person (UC Regs 2013 reg 3(3)) #2084 takes that up.
  • Limited capability for work (s.21(1)(a)) is the input uc_has_limited_capability_for_work. 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 adds a formula, uc_limited_capability_for_work. As it lands second, it is to make s.21 read that variable and drop this input, so the model has one LCW variable.
  • The discretionary reductions for relevant carers (reg 88(2)(a)) and impairment (reg 88(2)(c)) are inputs through uc_expected_hours. So are pregnancy, adoption, students, fostering and limited capability for work alone: the Enhanced FRS has no fields for them.
  • Zero-profit self-employment. In a 2026 run of the branch (671da0f7e, whose outputs match 5ed0fd46e), about 186,000 claimants in UC benefit units (24 survey households) report full- or part-time self-employment but zero profit. The model reads them as not self-employed, as Apply the UC minimum income floor to net earned income against a net threshold #1973 did. Whether they are gainfully self-employed traders who broke even is a data question; uc_is_in_gainful_self_employment takes the answer when there is one.
  • Years before 2015. uc_mif_applies reads is_carer_for_benefits, which needs Carer's Allowance parameters that start in 2015, so it raises a missing-parameter error for 2013 and 2014. universal_credit itself already errors in those years on main (vahid-ahmadi's review), so no award changes.
  • Annual ages. Child ages are whole years, so a child's birthday inside the year does not move the group mid-year.

Review

  • vahid-ahmadi (human), at 94b7129b4. The law reading holds. His items and how each was handled:
    1. Merging main broke 4 YAML cases and 1 property. Fixed: main merged in, expectations re-derived by hand, and the property generators declare is_claimant_or_partner.
    2. The nomination default when hours are not supplied. Documented in the docstring, the changelog and the notebook; the tie-break question is queued for Max as d977.
    3. Use the State Pension Credit qualifying age. This is the follow-up after merge (modelling choice 5).
    4. One LCW variable. 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 makes the switch, as it lands second.
    5. Reuse is_uc_assessed_claimant. Done (7a71c869e); the outputs are identical.
    6. Small cells. Counts here are survey households, and cells under 10 are suppressed, including cells a reader could recover by subtraction (the 35-hour sensitivity, the nomination split and year-to-year changes in counts). The concentration shares are dropped.
    7. Reg 30(3) paid carers. Noted in the code and in modelling choice 6.
  • Independent reviews (Opus 5.5), all APPROVE:
    • The full PR at 5ed0fd46e. It recomputed every re-derived expectation, checked the merge resolution and main's interactions, and ran the 370 tests in the UC folder.
    • The deltas to 671da0f7e and 947fc3a23.
    • Their nits are applied.

Axiom parity

axiom: TheAxiomFoundation/rulespec-uk#396 queued (scope comment TheAxiomFoundation/rulespec-uk#396 (comment): UC Regs 2013 regs 62(1)(b), 88 and 90(2)-(3); WRA 2012 ss.19-22; new modules for regs 3, 30, 85, 86, 89, 91 and 91A)

🤖 Generated with Claude Code

MaxGhenis and others added 3 commits October 1, 2026 11:01
…ements group

UC Regs 2013 reg. 62(1)(b) applies the floor to a claimant who would, apart
from regs. 62 and 90, fall within Welfare Reform Act 2012 s. 22. Add the
work-related group (ss. 19 to 21, regs. 89 and 91), the responsible carer
nomination (s. 19(6), reg. 86), the expected hours of reg. 88, and the
individual and couple thresholds of reg. 90(2) and (3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t with fewer paid hours

The responsible carer is the couple's nomination (WRA 2012 s. 19(6), UC Regs
reg. 86). Without one, take the claimant who works fewer hours, then the
elder, rather than the nomination that maximises the award. Put the group,
hours and threshold rules back in their own variables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rk-related-groups

# Conflicts:
#	docs/book/programs/gov/dwp/universal-credit.ipynb
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Follow-up for item 5 of the caveats (reg 89(1)(a) uses is_SP_age until #1907 lands). It is prepared and will not be stacked on this PR or on #1907. When both this PR and #1907 have merged, a scheduled job opens a separate PR from main (branch uc-wrr-spc-qualifying-age). That PR:

  • switches the reg 89(1)(a) line in uc_work_related_group_apart_from_earnings to has_attained_state_pension_credit_qualifying_age;
  • adds YAML cases where the two ages differ (a man born 6 April 1952 in 2016-17, a man born 6 June 1953 in 2016-17 and 2017-18, and the floor case), checked against Pensions Act 1995 Sch 4 para 1 as at 6 October 2016;
  • adds a statute differential and a Hypothesis differential to test_uc_work_related_groups_properties.py.

Nothing in this PR needs to change for it. The prepared patch is anchored on these lines of this PR:

  • # Reg. 89(1)(a): the qualifying age for State Pension Credit. / | person("is_SP_age", period)
  • the reg 62(1)(b) reference entry
  • the YAML case "A claimant over State Pension Credit qualifying age, regulation 89(1)(a)"
  • the property file's import block and the "Marriage Allowance is switched off throughout" docstring line

If you change those before merging, the follow-up adapts by hand.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

#2084 is stacked on this PR. It models the rest of a reg 3(3) single claim: single amounts (reg 36(3)), the elements, the benefit cap and the shared accommodation rate. Two things in it touch this PR:

  1. uc_is_ineligible_partner gets a formula for limb (a). A member of a couple who fails meets_uc_minimum_age_condition is the ineligible partner. This is ADM E2017's example: Jane is 17, Tom is 19, and "Tom is required to claim for himself as a single person". It is still an input for limbs (b)-(e). This PR's floor rules read it unchanged. On the Enhanced FRS the formula never fires: no couple has a member under 18.
  2. A fixture fix this PR will need when it merges main. Main's claimant-or-partner presumption (Replace generic child and adult flags with each programme's legal definitions #1896) reads a generated 18-year-old partner of a 52-year-old as their child. So test_partner_who_cannot_be_a_joint_claimant in test_uc_work_related_groups_properties.py fails once main is merged in, with the flag landing on someone outside the couple. Model a Universal Credit claim by a member of a couple as a single person (UC Regs 2013 reg 3(3)) #2084's commit 0dfcc26 declares is_claimant_or_partner in the fixtures, as Deduct only each person's own tax and NI on earnings from UC earned income #1949 did in a57caf1; the same two lines will do here.

@vahid-ahmadi vahid-ahmadi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Max. The law reading holds. I checked reg 62(1)–(5), 63, 64, 86, 88, 89, 90 and 91, the 2014 versions of 91/91A and SI 2014/1097 reg 16, and WRA 2012 ss.19–22 against legislation.gov.uk. Your quotes match, and so do the child-age parameters (5 → 3 from 28 Apr 2014, 91A "aged 3 or 4", then 1/2 from 3 Apr 2017). At head 94b7129b4 all 275 UC YAML cases pass, and so do the four property files (work-related groups 7, MIF 6, earnings deductions 4, State Pension 5 + 1 xfail).

Household probes for 2026, all reproduced:

  • Lone parent with a child aged 1: no floor, UC £18,346.08.
  • Lone parent with a child aged 5: 30 hours, UC £11,296.94.
  • Couple where the self-employed partner is the responsible carer of a 2-year-old (s.21): not floored, £3,000 kept.
  • The same couple with the s.21 partner employed and the s.22 partner self-employed: the threshold is £20,386.03 + £10,574.72. The s.22 partner is floored, as reg 62(3) requires.
  • Single self-employed claimants with LCWRA, caring 35+ hours, or in a start-up period: no floor.
  • Mixed-age couple: the 70-year-old adds £0, the 60-year-old is floored.
  • 2013 and 2014 already error on main, so nothing new breaks there.
  1. Blocking: merge main, which breaks 5 tests. The PR conflicts with main, and no CI has run on it since it was retargeted. GitHub's diff still lists #1973's 15 files.

    • I did a trial merge. I kept this PR's uc_mif_applies.py (main had only swapped is_uc_claimant for is_uc_assessed_claimant) and took main's notebook. 4 YAML cases and 1 property then fail:
      • income/income_floor/uc_minimum_income_floor.yaml:105 (main's #1973 case): the 66-year-old reaching State Pension age is now in s.19, so the notional NI is £0, not £633.73. That's right under reg 89(1)(a). Make them 65 or assert a £0 floor.
      • uc_mif_earned_income.yaml:602, work_related_requirements/uc_is_responsible_carer.yaml:65 and :97: uc_individual_earned_income_before_mif is £14,368.20, not £14,568.20, after main's earned-income changes. Re-derive.
    • test_uc_work_related_groups_properties.py::test_partner_who_cannot_be_a_joint_claimant also fails. Main's #1896 presumption reads the generated 18-year-old partner of a 52-year-old as a child, so uc_minimum_income_floor_gross is £0, not £13,104 (2016). #2084 already fixed this by declaring is_claimant_or_partner in the generators. Port that here.
  2. Should fix: the default nomination is arbitrary when hours aren't supplied. In uc_is_responsible_carer.py:40-43, hours_worked is a pure input that defaults to 0. Most calculator and API households tie on hours and fall through to "the elder".

    • Probe: a couple with a child aged 1, one self-employed on £4k and one employed on £20k, no hours entered.
      • Self-employed partner 35 and the other 33: no floor, UC £11,874.74.
      • Swap the ages: floored, UC £7,040.71.
    • Two years of age difference moves the award by £4,834. Before the age tie-break, add a second one on hours, such as lower earned income. Or at least say in the docstring and changelog that calculator users should set uc_is_responsible_carer.
  3. Should fix: use main's SPC qualifying age. #1907 has landed, so uc_work_related_group_apart_from_earnings.py:62 can read has_attained_state_pension_credit_qualifying_age instead of is_SP_age. The comment in the body ("until #1907 lands") is now out of date.

  4. Should fix: one variable for limited capability for work.

    • This PR adds uc_has_limited_capability_for_work, an input that defaults to false.
    • #2076 adds uc_limited_capability_for_work, a formula: uc_limited_capability_for_WRA | is_disabled_for_benefits.
    • With both merged, a disabled-flagged ESA claimant without the support component would have LCW for the work allowance but not for s.21(1)(a). They would keep the floor.
    • Fix: whichever lands second drops its own variable. s.21 should read #2076's variable, because LCW puts them in s.21, so no floor.
  5. Should fix: reuse is_uc_assessed_claimant after the merge. utils/uc_work_related_requirements.py:10-18 (couple_members) restates main's is_uc_assessed_claimant line for line. Read the variable instead so the two can't drift.

  6. Should fix: the PR body discloses small cells. The single-benefit-unit share of the 2026 change (and the top-five share) lets a reader work back to one record's weighted gain. Several weighted cells also rest on fewer than 10 records: the two "(N records)" figures and the s.19–21 split by group.

    Suppress them under the same under-10 rule #2082 uses, and drop the top-1/top-5 concentration figures. A line like "concentrated in a few benefit units; treat as indicative" says the same thing.

  7. Nit: uc_work_related_group_apart_from_earnings.py:57. is_carer_for_benefits counts paid carers. Reg 30(3) excludes anyone who "derives earned income from those caring responsibilities". Mention it in the comment next to the reg 30 note in "Modelling choices", so it's recorded in the code too.

MaxGhenis and others added 8 commits October 5, 2026 12:07
Conflicts:
- uc_mif_applies.py: keep this PR's formula (reg 62(1)(b) group test);
  main had only swapped is_uc_claimant for is_uc_assessed_claimant, and the
  group variable already limits the floor to claimants.
- universal-credit.ipynb: take main's cell and re-insert this PR's minimum
  income floor sentences.

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.
(cherry picked from commit 0dfcc26)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
couple_members() in utils/uc_work_related_requirements.py repeated main's
is_uc_assessed_claimant formula line for line (is_uc_claimant, the two
eldest). Read the variable instead, so the two cannot drift. No output
changes: the formulas were identical.

Review: vahid-ahmadi on #2081, item 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- uc_is_responsible_carer and the changelog: hours_worked defaults to 0,
  so a couple entered without hours is nominated by age; calculator and
  API users should set uc_is_responsible_carer or each member's hours.
- uc_work_related_group_apart_from_earnings: is_carer_for_benefits does
  not apply reg 30(3) ("derives earned income from those caring
  responsibilities"), so a carer paid for that care still counts.

No formula changes. Review: vahid-ahmadi on #2081, items 2 and 7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…age changes moved

- Three cases with £15,000 of profit (uc_mif_earned_income.yaml, "the
  elder nominated by default"; uc_is_responsible_carer.yaml, "works more
  hours" and "a recorded nomination"): main's #1880 fix gives no trading
  allowance relief on a profit above £1,000 when gross receipts are not
  given, so income tax is (15,000 - 12,570) x 20% = 486, not 286, and
  earnings before the floor are 14,368.20. The floored partner is
  20,386.03 - 14,368.20 = 6,017.83, and 30,960.75 - 14,368.20 = 16,592.55
  where the nominated carer has a 16-hour threshold.
- uc_minimum_income_floor.yaml, main's #1973 case for someone reaching
  State Pension age after 6 April: at 66 they are over State Pension Credit
  qualifying age, so in section 19 (reg. 89(1)(a)) with no threshold. Set
  the group as the age-70 case does, to keep testing the notional Class 4.

Review: vahid-ahmadi on #2081, item 1.

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

- uc_mif_earned_income.yaml, "Couple from gross incomes": the children
  became 15 and 14 in this PR (to keep 35 expected hours), and the
  universal_credit line was dropped. Both were born before 6 April 2017, so
  the first has the higher child element: uc_maximum_amount is 666.97 x 12 +
  (351.88 + 303.94) x 12 + 12,000 = 27,873.48 and universal_credit is
  27,873.48 - 0.55 x 35,648.06 = 8,267.05.
- universal-credit.ipynb: the nomination default ends with the elder and
  hours_worked defaults to 0; the responsible carer's hours are 30 only from
  February 2025 (16 and 25 from April 2017); the couple threshold includes
  35 hours at the national living wage for a reg. 3(3) partner.

Review: independent review of 5ed0fd4, findings 3 and 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The amount a reg. 3(3) partner adds to the couple threshold reused
work_requirements.default_expected_hours, the reg. 88(1) expected hours. Reg.
90(3)(b)(ii) sets its own "35 hours per week" (in force since 29 April
2013), so a reform of the expected hours should not move it. Add
gov.dwp.universal_credit.means_test.minimum_income_floor.ineligible_partner_hours
(35 from 2013-04-29). Both are 35 on every date, so no output changes. The
property oracle now uses the regulation's 35 directly.

Review: independent review of 5ed0fd4, finding 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k's hours

- uc_mif_earned_income.yaml: the higher first-child element survives from
  6 April 2017 only through the Universal Credit (Transitional Provisions)
  Regulations 2014 (SI 2014/1230) reg. 43, which needs one child born
  before that date. Comment only.
- universal-credit.ipynb: 25 hours for any child under 13 before April
  2017, and the adult rate before the national living wage (April 2016).

Review: delta review of 671da0f, nits 1 and 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Thanks @vahid-ahmadi. All seven items are handled at 947fc3a23:

  1. Merged main (17ab14070, main at 6b366b281). I re-derived the four YAML cases by hand (5ed0fd46e).
  2. Nomination without hours. Documented in uc_is_responsible_carer's docstring, the changelog and the notebook (44bfd87d2, 359c67835). A different tie-break, such as lower earned income before age, goes beyond the default Max ruled on, so it is queued for him rather than changed here.
  3. State Pension Credit qualifying age. Left as is_SP_age here. A prepared follow-up switches reg 89(1)(a) to has_attained_state_pension_credit_qualifying_age once this merges.
  4. One LCW variable. 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 lands second. It should make s.21(1)(a) read uc_limited_capability_for_work and drop uc_has_limited_capability_for_work and its YAML inputs. I'll note that on 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.
  5. is_uc_assessed_claimant. couple_members() is gone, and the three call sites read the variable (7a71c869e). The formula is the same, so no output changes.
  6. Small cells. The body now counts FRS survey households and suppresses cells under 10, as Presume a member 20+ years younger is the claimant's child when no roles are supplied #2082 does. A capital-gains clone counts with its original, and SPI-synthetic households don't count. The concentration shares are gone. The 2026 change rests on 30 survey households, and the body says so.
  7. Reg 30(3). Noted in the code next to the reg 30 comment (44bfd87d2) and in modelling choice 6.

An independent review led to three more changes:

The impact runs were redone against main: 2026 UC +£0.299bn, and +£0.401bn with the other nomination.

@MaxGhenis
MaxGhenis merged commit 47df7b0 into main Oct 5, 2026
12 of 14 checks passed
@MaxGhenis
MaxGhenis deleted the uc-mif-work-related-groups branch October 5, 2026 22:21
MaxGhenis added a commit that referenced this pull request Oct 5, 2026
Brings in #2081 (Universal Credit minimum income floor and work-related
groups) and the 2.122.0 release since 6b366b2. A clean merge: nothing
under local_authorities or council_tax_benefit changed on main, and no
conflict needed resolving.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Merged as 47df7b08d (head 947fc3a23) under Max's decision d840. Every check passed on that head. The independent reviews of 5ed0fd46e, 5ed0fd46e..671da0f7e and 671da0f7e..947fc3a23 all approved.

Before merging I checked the body against the run artifacts. The Summary, the yearly UC figures, both sensitivity runs and the worked examples all match. For @vahid-ahmadi's item 6 (small cells), I closed the places where a suppressed cell could still be worked out by adding or subtracting published figures:

  • Nomination split. The subgroup figure is gone. The body now says "most", and gives the hours averages for the whole group, which is what they were computed over.
  • "Partner at 35 hours". Its difference from the default rests on fewer than 10 survey households in every year, so the column is gone. The body says only that it lowers UC.
  • Counts by year. Every year reuses the same records with weights uprated by one factor, so a change between years isolates a few households. Counts are now given for 2026 only, and UC in pounds stays for every year.
  • People the floor lifts. The table and the 2026 detail used different definitions. Both now count people in benefit units on UC under main or this branch, and the 2026 figures moved into the detail.

Two smaller corrections. The 370 tests in the UC folder are 369 YAML cases and one Python test. The detail also notes that a new UC award can end Tax-Free Childcare (gov.hmrc.tax_free_childcare.disqualifying_benefits). That lowers net income for fewer than 10 survey households, so the figure is suppressed.

Follow-ups: #2076 carries the single LCW variable (noted there). The reg 89(1)(a) switch to the State Pension Credit qualifying age is a prepared follow-up. The tie-break when hours are absent is d977.

MaxGhenis added a commit that referenced this pull request Oct 6, 2026
…-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>
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.

2 participants