Skip to content

Count only the claimant's and partner's legacy awards in means tests and passports - #2027

Open
MaxGhenis wants to merge 12 commits into
is-eligibility-claimant-partner-gatesfrom
legacy-award-readers-claimant-partner
Open

MaxGhenis wants to merge 12 commits into
is-eligibility-claimant-partner-gatesfrom
legacy-award-readers-claimant-partner

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2026

Summary

esa_income and jsa_income sum every benefit-unit member's reported award. That is right for household income. But a member who is neither the claimant or partner nor a child or young person they are responsible for, such as a non-dependent adult, also had their award read by means tests and passports that the law ties to the claimant and partner. This PR audits each reader against the governing regulation. Readers that name the claimant and partner now read a new claimant-and-partner award; person-level readers read the person's own award. The aggregation definitions of household totals are unchanged, and the measured change on the Enhanced FRS is £0.

Stacked on #2013 (is-eligibility-claimant-partner-gates, merged in at 0953c8aa6), which is stacked on #2001 and then #1896.

New variables

Reader by reader

Reader Governing law (fetched verbatim from legislation.gov.uk) Who the law names Change
housing_benefit_applicable_income SSCBA 1992 s.136(1) (income of "any member of that family"; s.137(1) family) and HB Regs 2006 reg 25(1), (3) claimant and partner reads claimant_or_partner_*
council_tax_reduction_applicable_income SI 2012/2885 Sch 1 para 11(1)-(2): "the income and capital of— (a) an applicant; and (b) any partner of that applicant" applicant and partner reads claimant_or_partner_*
council_tax_reduction_relevant_income_based_benefit SI 2012/2886 (the default scheme the councils' working-age schemes follow) Sch 8 para 8: "Where an applicant is on income support, an income-based jobseeker's allowance or an income-related employment and support allowance, the whole of his income", with Sch para 33(2): "any reference to the applicant applies equally to any partner of that applicant" applicant and partner reads claimant_or_partner_*
CTR non-dependant exemption (_legacy.py) SI 2012/2885 Sch 1 para 8(8)(a); SI 2012/2886 Sch para 30(8)(a): "a non-dependant who is on income support ..." the non-dependant reads is_on_*
tax_credits_applicable_income (exempt benefits) TCA 2002 s.7(2): "the person, or either of the persons, is entitled to any social security benefit prescribed"; SI 2002/2008 reg 4(1) the claimant or joint claimants reads claimant_or_partner_*
is_scp_eligible SSI 2020/351 reg 18(e)-(f): "the individual is responsible for the child" and "the individual has been awarded ... assistance of a kind specified in regulation 14". Responsibility runs through the individual's or partner's Child Benefit, Pension Credit or Universal Credit award, or kinship care (regs 9, 11, 12) the responsible individual (modelled as the claimant or partner) reads claimant_or_partner_*
targeted childcare qualifying_benefits SI 2014/2147 reg 1(2), "eligible child": "a young child ... whose parent is entitled to any one or more of the following" the parent list now names claimant_or_partner_*
maintenance_loan_entitled_to_benefits SI 2011/1986 regs 61(2) and 71(1)(h): conditions on "the student" the student the ESA proxy reads is_on_income_related_esa, alongside the existing parent and disability tests
would_claim_IS (and so income_support_assessable_capital) take-up flag; Income Support is the claimant's claim (#2013's gate) the claimant or partner counts only the claimant's and partner's reports, or claims_all_entitled_benefits
is_benefit_cap_exempt_health_disability HB Regs 2006 reg 75F(1)(a): "the claimant or the claimant's partner is receiving an employment and support allowance ... which includes a support component" claimant and partner unchanged here. benefit_cap_reduction, out of this PR's scope, caps every member's ESA and JSA. Scoping the exemption on its own would cap the claimant with another adult's own award in the capped sum (review r2). Both halves go to the benefit-cap follow-up
is_benefit_cap_exempt_earnings, is_benefit_cap_exempt_other none: they compute the ESA sum but never use it — unchanged (no effect on the result)
Cost-of-living payments Social Security (Additional Payments) Acts 2022 and 2023 s.1: a payment to "any person who has a qualifying entitlement", a person being "an individual or a couple" anyone with their own award unchanged: another member's own award would entitle them, so the household test should count it
Winter Fuel Payment, PAWHP SI 2025/969 regs 3-4 (benefit "paid to P", or to P's partner); SSI 2024/351 regs 2A and 10 (the individual, or their partner) the pension-age person and their partner unchanged here: the model pools awards across the whole household, every benefit unit included. Removing only other members' awards would not make it follow the law, and would drop the award of a pension-age member who is their own claimant. The person-level rewrite is a follow-up
income_support readers income_support already needs the claimant's or partner's own award (#2013) — unchanged

Aggregation definitions not changed: esa, jsa, household_benefits, HBAI, gov_spending, benefit_cap_reduction, and the ESA/JSA capital allocation (*_assessable_capital), which is part of the award's own definition.

Behaviour beyond the other member's own award

Person-level "on" is now each person's own award:

  • Non-dependant couples. In a non-dependant benefit unit, another adult who is not the claimant's partner or dependant is no longer exempt through the claimant's award. They are a separate non-dependant and attract their own deduction, unless their own award exempts them.
  • Dependants. A child or qualifying young person no longer carries their parent's income-related ESA into maintenance_loan_entitled_to_benefits. None is in higher education, so no maintenance loan changes; see the impact section.

Invariants (property-tested)

  1. Adding a member who is neither the claimant, the partner nor a dependant, whatever Income Support, income-based JSA or income-related ESA they report, never changes:

    • any family reader: the scoped awards, HB and CTR income, the CTR passport, tax credit income, targeted childcare, would_claim_IS and income_support_eligible;
    • any existing member's is_scp_eligible, maintenance_loan_entitled_to_benefits or is_on_*.

    This holds when the awards are formula-computed, with the take-up mode fixed per benefit unit: claims_all_entitled_benefits sums reports across the whole simulation. An entered esa_income that happens to equal the reports is read through them; entering the scoped variable states ownership.

  2. 0 <= claimant_or_partner_esa_income <= esa_income, likewise for JSA, with equality when no other member reports the award.

  3. The scoped awards equal a direct reading of the regulations: the claimant's and partner's reports less tariff income of £1 a week for each £250 or part above £6,000, nothing above £16,000 (ESA Regs 2008 regs 110, 118; JSA Regs 1996 regs 107, 116). This is a differential test against an independent Python reference.

  4. is_on_* is the couple's award for the claimant and partner, and for anyone else their own report while the benefit unit's modelled award is positive.

  5. Adding such a member to a non-dependant benefit unit never changes the existing members' Merton non-dependant deductions.

Tests

  • YAML: 57 cases in tests/policy/baseline/finance/benefit/family/legacy_award_readers/, each computed by hand from the regulation and parameter values. Every changed reader has a case with an excluded adult. On the base (0953c8aa6), 42 cases fail: 17 on value (every excluded-member case for an existing reader) and 25 only because the new variables do not exist there.
  • Python:
    • test_legacy_award_readers_properties.py: the invariants above, an exact-difference check that the claimant's and partner's own awards count in full in HB and CTR income, and 4 direct-entry tests.
    • test_claimant_or_partner_awards_entered_directly.py: 25 cases across ESA and JSA. They cover deletion, clones, branches, an entered award equal to the reports, the raw total with capital, a neutralised award, a stored zero, float32 precision, explicit ownership through the scoped variable, and a removed award taking an excluded student's status with it.
  • Full suites on 3803dda0d: YAML 1,572 passed; pytest 2,077 passed, 45 skipped.
  • ruff format and ruff check are clean.

Enhanced FRS impact

Real Microsimulation runs on a private copy of the Enhanced FRS 2024-25 (sha256 e433e532…), for two package states: base 0953c8aa6 (#2013) and this branch at 3803dda0d. Earlier pairs of runs at each intermediate head, back to b1977d936 against a135639b2, gave the same results. Every year 2025-2030 changes by £0, for every benefit, household total (including gov_spending and hbai_household_net_income) and poverty rate. 107 of the 108 arrays compared are identical.

The one array that changes is maintenance_loan_entitled_to_benefits, on 64 dataset records (about 20,000 people weighted). All are children or qualifying young persons aged 19 or under whose parent is on income-related ESA. None has a maintenance loan, and maintenance_loan is identical.

Why the effect is zero: the dataset has 74 records (about 18,000 people weighted) of members who are neither claimant, partner nor dependant. None of them reports income-related ESA, income-based JSA or Income Support. None is in a benefit unit whose claimant or partner reports any of them, so the non-dependant and maintenance-loan cases cannot arise either. The H5 inputs and per-record NPZ arrays stay private; the summaries are aggregates.

Review

  • Review r2 (Subfleet, Opus) asked for changes. Each finding is fixed or answered in 3f3134755; the response is in the PR thread. A follow-up review covers the delta.

Axiom

axiom: TheAxiomFoundation/rulespec-uk#416 queued

Of these provisions only SSI 2020/351 reg 18 is in the corpus, and its module encodes only 18(b). HB reg 25, Sch 5 and reg 75F, SSCBA s.136, TCA 2002 s.7, SI 2002/2008 reg 4, SI 2014/2147 reg 1, SI 2012/2885 Sch 1 paras 8 and 11, SI 2012/2886 and SI 2011/1986 reg 61 are not ingested. The issue holds the verbatim law, the required outputs, a pasteable review_finding and companion tests taken from this PR's YAML.

Coordination and follow-ups

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 1, 2026 18:19
claimant_or_partner_esa_income and claimant_or_partner_jsa_income are the
income-related awards on the claimant's and partner's reported amounts,
after the same capital test as esa_income and jsa_income (the
income_related_esa_award and income_related_jsa_award helpers, byte-identical
to the copies on #2013 and #2025). A directly entered esa_income or
jsa_income is taken to be the claimant's or partner's.

is_on_income_related_esa, is_on_income_based_jsa and is_on_income_support
say whether the award is payable to a person (HB Regs 2006 reg 2(1), (3),
(3A)): the claimant and partner through their couple's award, anyone else
through an award they report themselves.

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

esa_income and jsa_income sum every benefit-unit member's reported award, so
a member who is neither the claimant, the partner nor their dependant (for
example a non-dependent adult) fed means tests and passports that the law
ties to the claimant and partner:

- HB and CTR income (SSCBA s.136(1), HB Regs 2006 reg 25(1); CTR (PR)
  (England) Regs 2012 Sch 1 para 11) and the working-age CTR passport;
- the tax credit income test (TCA 2002 s.7(2), SI 2002/2008 reg 4);
- Scottish Child Payment (SSI 2020/351 reg 18(e)-(f));
- the benefit cap health exemption (HB Regs 2006 reg 75F(1)(a));
- targeted childcare (SI 2014/2147 reg 2(1));
- would_claim_IS.

The CTR non-dependant exemption ("who is on") and the maintenance loan
benefits proxy now read the person's own award. Household totals (esa,
household_benefits, HBAI, gov_spending, benefit_cap_reduction) are
unchanged: another member's award is still household income.

Tests: 53 YAML cases computed by hand from the regulations, and Hypothesis
properties (adding such a member never changes any reader; the scoped awards
are bounded by, and without other awards equal to, the benefit-unit awards;
they match a direct reference; the person-level flags follow their
definition; Merton's non-dependant deductions are unchanged).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 2, 2026 00:20
…was input

claimant_or_partner_esa_income and claimant_or_partner_jsa_income took
esa_income / jsa_income as the claimant's or partner's award whenever the
name was in Simulation.input_variables. That list is fixed at construction
and ignores the period: an input for 2024 alone made 2025 read the
benefit-unit total, so another member's 2025 award counted, and an award set
later with set_input or on a branch was ignored. Both now use
entered_directly (policyengine_uk/utils/inputs.py, byte-identical to #2013
and #2025), which reads core's record of each input's variable, branch and
period.

jsa_income.py is re-copied from #2025 (6337f31): the formula returns early
while income-based JSA is inactive, before reading reports.

Tests: YAML cases for an award entered for an earlier year only, and Python
tests for a late set_input, a set_input after the value was cached, a branch
and a late zero entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Takes policyengine_uk/simulation.py and policyengine_uk/utils/inputs.py
byte-identical from 48abd88 on #2025 (is-remunerative-work-jsa-conditions).
In policyengine-core 3.32.9, delete_arrays keeps the deleted arrays'
_user_input_keys entries, and clone shares the record. A formula value could
then look like a direct input, after a deletion or an input on a clone or on
a parent after a branch. The UK Simulation now gives each clone its own copy
of the record and drops the entries for deleted arrays, and entered_directly
asks about the stored value the simulation actually reads.

test_claimant_or_partner_awards_entered_directly.py mirrors #2025's lifecycle
cases on claimant_or_partner_esa_income and claimant_or_partner_jsa_income.
6 of its 12 cases fail without the Simulation changes. #2025's own test file
asserts its s.124(1)(f) JSA bar, which this branch does not have, so it is
not copied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2013 and #2025 replaced entered_directly and the Simulation overrides with a
value rule, after #2025's round-3 review found the record of direct inputs
unsound in policyengine-core 3.32.9:
- a Simulation without inputs has no record;
- the YAML runner and SimulationBuilder bypass the UK Simulation;
- disk-backed clones share files;
- branch names and ETERNITY periods diverge;
- delete_arrays becomes O(keys).

This merge takes their removal of policyengine_uk/utils/inputs.py and their
simulation.py (identical to 63b633c's). claimant_or_partner_esa_income and
claimant_or_partner_jsa_income now mirror the gate. Where esa_income /
jsa_income holds what the reported awards give, either after the capital
test (the formula) or as their plain total (disable_simulated_benefits), they
use the claimant's and partner's reported awards. Otherwise they take the
stored value to be the claimant's or partner's: an award entered directly, or
a reform that replaces or removes it. An entered award equal to either amount
is read through the reports.

test_claimant_or_partner_awards_entered_directly.py gains cases for an
entered award equal to the reports, the raw total with capital (partner
£200, other adult £3,000, savings £10,000: £0), and a neutralised award. The
lifecycle cases (deletion, clone, branches) keep their expectations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 4 commits October 2, 2026 03:08
Docstring only: jsa_income.py is byte-identical to #2025's ffe3a58, matching
#2013's esa_income.py (44d59d9). No code changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t cap left unscoped

Review r2 of #2027 (subfleet job 20261002-044711) and #2013/#2025's latest
value-rule refinements (0953c8a, 081ec14):

- claimant_or_partner_{esa,jsa}_income: a stored zero is zero. References
  are compared at the stored float32 precision. When the stored award is
  the plain total of the reports (the disable_simulated_benefits reform),
  the claimant's and partner's plain reported total passes through
  unscreened, so a claimant's own £200 at £10,000 capital is no longer
  zeroed. Entering these variables directly is the explicit way to state
  ownership.
- is_on_income_related_esa / _based_jsa: another member's own report counts
  only while the benefit unit's modelled award is positive, so a reform
  that removes the benefit takes the status with it. is_on_income_support:
  likewise only while Income Support is active and not neutralised.
- is_benefit_cap_exempt_health_disability is reverted to the benefit unit's
  esa_income. benefit_cap_reduction (out of scope) still caps every
  member's ESA and JSA, so scoping the exemption alone would cap the
  claimant with another adult's own award. Both go to the benefit-cap
  follow-up.
- The property generator fixes claims_all_entitled_benefits per benefit
  unit (it sums reports across the simulation). SCP comments name the
  kinship route. The childcare citation is reg 1(2), not 2(1). Changelog
  wording matches the paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 2, 2026
Inferring limited capability for work-related activity from the ESA support
component in both directions gave a non-dependant's own ESA an LCWRA element
in the family's Universal Credit, because uc_LCWRA_element and the work
allowance still read every member of the benefit unit (#2027's legacy-award
invariance test caught it). Now a person whose own ESA lacks the support
component is taken not to have LCWRA (UC Regs 2013 reg 40(1)(a)(ii)), and
otherwise uc_limited_capability_for_WRA keeps its is_disabled_for_benefits
default. uc_limited_capability_for_work is LCWRA or the disability flag, so
the work allowance and reduced minimum age are as before for every input
that does not set the new variables. The cap property's family-rate
reference now counts any 16-year-old, as the family-rate helper does.

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

Copy link
Copy Markdown
Collaborator Author

Response to review r2 of #2027 (job 20261002-044711)

Reviewed head 57b37fd. The fixes are in 3f31347, and the merge of #2013 0953c8a is 3803dda.

  1. Blocker: benefit cap. Agreed that scoping the exemption on its own exposes benefit_cap_reduction, which still caps every member's ESA and JSA. The task brief excluded benefit_cap_reduction from this PR, so Count only the claimant's and partner's legacy awards in means tests and passports #2027 reverts its change to is_benefit_cap_exempt_health_disability, which reads the benefit unit's esa_income as on main. Count only the claimant's and partner's legacy awards in means tests and passports #2027 now leaves the benefit cap untouched.
    • The excluded-member YAML case and the property's cap reader are removed. The claimant's-own-ESA case stays.
    • Both halves (the reg 75F(1)(a) exemption, and the capped sum under UC reg 80(1)) were handed to the benefit-cap session (local_63f27869, task_181405fd) with your reproduction. That session is to test UC and HB amounts, not just the flag.
  2. Disabled-benefits reform.
    • Claimant-only capital case: fixed. When the stored award equals the raw reported total, the scoped variables now pass the claimant's and partner's raw reported sum, unscreened. So a claimant's own £200 at £10,000 capital stays £200 (YAML case "The claimant's raw reported award passes through…"). cp ≤ stored still holds.
    • Later years: the reform cannot reach these variables today, because it raises first on attendance_allowance_reported, which does not exist (you noted this too). Task task_3193768f fixes the reform. It routes the claimant/partner awards explicitly for each year and unifies the reading with both Income Support gate limbs through one helper.
  3. Direct-input collision. Equality-based detection cannot tell an entered esa_income from the formula's value when the two coincide. The explicit ownership contract is to enter claimant_or_partner_esa_income / _jsa_income directly. Core inputs override formulas, so the value then holds whatever other members report.
    • The variable documentation and changelog now say so.
    • New tests: YAML "An entered claimant-or-partner award is the claimant's whatever another member reports", where the CTR passport stays true; Python test_an_entered_scoped_award_states_ownership, with the other member's report at both £2,000 and £3,000.
    • The invariance claim in the PR body is qualified to formula-computed awards.
  4. Own-report path after reform removal. Fixed. Another member's own report counts in is_on_income_related_esa / is_on_income_based_jsa only while the benefit unit's modelled award (esa_income / jsa_income) is positive. In is_on_income_support it counts only while IS is active and not neutralised; the model calculates the IS award only for the claimant and partner, so that is not used as a gate.
    • New test test_a_removed_esa_award_takes_an_excluded_students_status_with_it: neutralising esa_income turns off both the status and the maintenance-loan schedule for an excluded tertiary student.
  5. Shared take-up flag in the property. Fixed. The generator now sets claims_all_entitled_benefits to false per benefit unit, so the two variants no longer share it. The docstring and PR body note that would_claim_IS can also be set by claims_all_entitled_benefits.
  6. Legal wording.
    • SCP: the comments and PR body now name the kinship-carer route (regs 11 and 12(1)(b)) and call the claimant/partner mapping a modelling assumption.
    • Childcare: the citation is now reg 1(2), with the URL fixed in the parameter, YAML comments, the property docstring and the PR body.
    • Benefit cap comment: moot, since the change is reverted.
  7. Changelog and validation wording.
    • The changelog now describes each path: maintenance loans read ESA alongside the parent and disability tests, would_claim_IS also follows claims_all_entitled_benefits, and the direct-entry equality exception is stated.
    • The PR body's base failure counts are re-measured on the new base.
    • "Household totals do not change" now reads as "aggregation definitions unchanged; measured dataset result £0".

Also adopted from #2013 and #2025's latest refinements: a stored zero is zero (test_a_stored_zero_is_never_the_claimants_award), and references are compared at the stored float32 precision (test_large_reports_are_compared_at_storage_precision).

MaxGhenis added a commit that referenced this pull request Oct 2, 2026
…efit-cap-75f-claimant-partner

#2027 now leaves the benefit cap to this branch and deletes utils/inputs.py
(entered_directly), deciding a directly entered award by value. Conflicts:
- is_benefit_cap_exempt_health_disability.py: keep this branch's version;
  an entered UC LCWRA or carer element is now recognised by value (positive
  although no member's circumstances give it) instead of entered_directly.
- passports.yaml: keep this branch's support-component cap cases.
- utils/inputs.py: deleted, as on #2027.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 2, 2026
UC Regs 2013 reg 80(1) caps "the amount to which the single person or
couple is entitled", and HB Regs 2006 reg 75A the welfare benefits to which
the claimant or couple is entitled. benefit_cap_reduction summed every
benefit-unit member's contributory ESA and JSA, incapacity benefit and SDA,
and the whole unit's income-related ESA and income-based JSA, so another
member's own award reduced the family's Universal Credit or Housing Benefit:
with UC of 20,000 before the cap, a non-dependent adult's 5,000 of ESA cut
the family's UC from 14,753 to 9,753 (#2027 review r2).

The capped total now takes the claimant's and partner's person-level awards,
claimant_or_partner_esa_income, claimant_or_partner_jsa_income, and the
family's Child Benefit, CTC, Income Support, UC and Housing Benefit. Household
income keeps the full awards. YAML tests check UC and Housing Benefit
amounts; the non-dependant invariance property now also covers
benefit_cap_reduction and universal_credit, with JSA, incapacity benefit and
SDA among the circumstances. #2027's legacy-award invariance reads the
benefit cap exemption again.

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

Copy link
Copy Markdown
Collaborator Author

Cross-reference from #2000, the HB passport for IS, income-based JSA and income-related ESA (fixes #1993). #2000 meets its merge gates and is on the merge train.

#2000 adds in_receipt_of_income_support_jsa_ib_or_esa_ir (BenUnit):

(benunit("income_support", period) > 0)
| (benunit("jsa_income", period) > 0)
| (benunit("esa_income", period) > 0)

It zeroes housing_benefit_applicable_income and housing_benefit_assessable_capital when that holds (SI 2006/213 Sch 5 para 4, Sch 6 para 5).

When this PR meets #2000 on main, the receipt test is one more reader of the whole-benefit-unit jsa_income / esa_income that the law ties to the claimant and partner. It should probably read claimant_or_partner_jsa_income / claimant_or_partner_esa_income, or your is_on_* person flags summed over claimant and partner. On the Enhanced FRS every member who reports IS, income-based JSA or income-related ESA is a claimant or partner (2025 and 2026), so I expect £0 there too.

🤖 Generated with Claude Code

A person is on income-based JSA or income-related ESA on a day it "is
payable to him" (reg 2(3), (3A)), and a person on income support is one "in
receipt of" it (reg 2(1)). A couple's award is paid to the claimant, not the
partner. is_on_income_related_esa, is_on_income_based_jsa and
is_on_income_support now hold, of the claimant and partner, only for the
payee: the one who reports the award, or the claimant where neither does
(is_payee_of_couple_award). Another member's report never moves the payee.
Anyone else is unchanged (their own report while the award is modelled as
paid).

Agreed with #2007, whose round-2 review raised the same point and which
applies the same reading through its is_award_payee helper; the codebase now
reads "who is on" one way.

Effects: in the local working-age CTR schemes a non-dependant couple on one
of these benefits pays the partner's deduction (one deduction per couple, the
higher: Default Scheme Sch para 30(3)); the maintenance-loan ESA proxy follows
the student's own award, not their partner's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
is_on_income_related_esa and is_on_income_based_jsa gated a member outside
the couple on the benefit unit's award over every report. Another member's
report could then lift that award above the tariff income and put them on
it: an excluded student's loan schedule or a Merton non-dependant deduction
changed when another adult was added (review r3's probes on 3803dda).

They now ask whether the award on that member's own report alone is
positive: the report exceeds the tariff income from the benefit unit's
capital, within the capital limit, while the benefit unit's award is
positive. Once the member reports, the capital test reads the household's
capital whoever else reports, so no other report can change the result.

The property generators now give qualifying young persons and an existing
outside adult reports of their own, and the Merton property has savings and
an existing outside adult; both failed on the old code. Two YAML cases are
hand-computed from ESA Regs 2008 reg 118. The maintenance-loan proxy cites
SI 2011/1986 reg 71(1)(h)(iii), reg 61(2)(b) and HB Regs 2006 reg 56(2)(a).

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

#2027 makes "on" a legacy award payee-only: of the claimant and partner,
only the one the award is payable to (who reports it, or the claimant who
heads the family when it is entered directly) is on it (HB Regs 2006 reg
2(1), (3), (3A)). The cap's ESA head reads is_on_income_related_esa for
receipt, so a partner who does not hold the couple's award no longer
receives it. Two YAML cases now expect the payee only, and the property
reference counts an income-related award as received by its reporter. The
direct-entry attribution in has_own_esa_award already picks the same person.

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

#2027 now puts a member outside the couple on an income-related award only
when the award on their own report alone is positive. The cap's ESA head
reads is_on_income_related_esa only for the claimant and partner, so the
exemption is unchanged; the cap YAML and the single-head table pass.

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

This branch has not been deployed

No deployments
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