Skip to content

Move families onto Universal Credit when a legacy benefit they receive closes - #2119

Merged
MaxGhenis merged 14 commits into
mainfrom
uc-claim-at-legacy-closure
Oct 12, 2026
Merged

MaxGhenis merged 14 commits into
mainfrom
uc-claim-at-legacy-closure

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2118

Tax credit closure in 2025 and Income Support/income-based JSA closure in 2026 ended families' legacy awards even when their ordinary UC take-up flag was false. This PR adds would_claim_uc_at_legacy_closure (default true), combines it with ordinary take-up in claims_universal_credit, and terminates other legacy awards at migration. It uses annual closure years rather than migration dates.

The Sol review blockers are addressed:

  • Shared benefit-cap and LHA rules use the actual UC claim flag, including claimants with an ineligible partner. The differential property generator includes those partners and a deterministic reproducer.
  • A protected mixed-age couple leaves its pension-age route only with positive pre-cap UC entitlement. A claim with nil entitlement retains the Housing Benefit reclaim route under SI 2024/604 art. 2. The 72/40 couple earning £37,500 with £9,000 council rent retains £139.83 HB with the reviewed allowance; current main's corrected 2025 allowance gives £410.90. Both are regression cases. UC reduced to nil by the cap still counts as entitlement.
  • Pension-age reg 60A migrant UC awards receive working-age CTR treatment in Scotland (SSI 2021/249 reg. 3). England disregards them for schemes from April 2025 (SI 2025/39); Wales only from April 2026 (WSI 2026/13). Scottish and Welsh 2025 cases exercise the former incorrect pensioner classification.
  • Pension Credit used in UC non-dependant exemptions is calculated separately for non-rent-liable families, whose own housing element is zero. This breaks the UC/PC dependency cycle without duplicating either means test. Mixed-family and changed-input regressions cover this path.

The migration destinations follow SI 2014/1230 regs. 8, 44, 46 and 60A, SI 2019/167 art. 3A, and DWP HB circular A9/2024. Positive reported WTC pension-age families may claim UC; PC reporters and pension-age CTC recipients without reported WTC take the PC route, subject to the limitation below. Claimants who decline migration or have nil UC entitlement retain the modelled pension-age route.

Known methodology gap requiring Max

DWP A9/2024 paragraphs 6 and 10 send pension-age/protected mixed-age CTC recipients whose WTC entitlement tapered to nil to UC. Enhanced FRS reports award amounts and current annual hours/income, but does not identify pre-migration WTC entitlement, historical hours, or a migration notice. Existing WTC variables require positive reported WTC and refer back to legacy closure, so they cannot identify this historical entitlement independently.

No proxy has been chosen. Max needs to choose between a historical-entitlement input upstream, an explicitly approved reconstruction proxy, or retaining this disclosed gap pending better data. The requested cos add-decision ... --source https://github.com/PolicyEngine/policyengine-uk/pull/2119 --resolves-on-merge no failed because this job cannot write the global ledger lock at /Users/maxghenis/chief-of-staff/state/decisions/.lock. The decision must be transferred to the global queue by the hub; it is not yet queued there.

Other limitations remain: in-year migration timing and two-week run-ons; transitional protection including the capital disregard; specified/temporary accommodation savings; and benefit-maximising choice between UC and pension-age routes. Existing HB-only/ESA-only abolition work remains separate.

2026 enhanced-FRS impact

2026 Microsimulation: main 3381500f4b01bc0a0cd5f447e56f07741af36ae2 against branch 4cb49f45363c3540ac6c62c05c429090d166b4f4.

Annual total main (£m) branch (£m) Change (£m) Change (%)
Universal Credit 83,648.742 83,793.741 +144.999 +0.1733%
Housing Benefit 8,481.532 8,456.238 -25.294 -0.2982%
Pension Credit 7,053.484 7,053.484 +0.000 +0.0000%
Council Tax Reduction 2,160.302 2,160.302 +0.000 +0.0000%
Household net income 1,709,287.759 1,709,379.519 +91.759 +0.0054%

The released Enhanced FRS 2024/25 v1.58.0 has SHA256 5ba399ea5ab9a6c7d4e9aaf6c623080beb34d9ad5f330f6244dbad72b8d960b6. Its hash matches the release manifest. Both sequential runs use the same file and frozen environment (policyengine-core 3.33.2). The dataset lacks would_claim_uc_at_legacy_closure, so the default true applies. No recalibration or dataset rebuild was run. Totals sum household-mapped awards against household weights.

Validation

  • Full policy YAML suite: 3,094 passed. All 14 new regression cases passed; the pension/non-dependant focused run passed 17 cases.
  • Focused Python differential property and three native-PC helper regressions: 4 passed.
  • The previous full Python suite was interrupted by the reboot at 24%, with six failures and one error in unchanged code-health subprocess tests and no surviving traceback summary. This was not a passing run. Fresh serial code-health reproduction and exact-head property validation were attempted in the workspace frozen environment, with at most four workers/threads, and remain incomplete. An isolated core import took 1,032 seconds; stack traces identify importlib file reads/stat operations, and comparison with Homebrew3.13.15 showed similar delays. This exceeds the nested pytest fixture's 600-second timeout, but the original failures' causes remain unverified. The final changed property was restarted serially after interrupting a stalled two-worker launch before collection. CI is queued and remains a merge gate. External dataset credentials/default are unset; the two explicit enhanced-FRS impact runs above separately validate the real dataset.
  • make format and uvx ruff format --check . passed, including the final test-only commit. Notebook JSON is valid and code cells are unchanged from the reviewed PR; a full local book build was not run for this prose-only correction.

Reproducer: policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/legacy_closure_ineligible_partner.yaml; policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/legacy_closure_pension_route.yaml; policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/legacy_closure_migrant_nations.yaml

Independent GPT-6.1 Sol code review: APPROVE at final head fa4389d6f6d79f68312e3961981f9ea11abe2ea4. This includes the final property-test correction at 84c760bf4 and a merge of current main e01f2f5ec that only updates release bookkeeping. Variables and parameters are byte-identical Git trees to impact head 4cb49f45363c3540ac6c62c05c429090d166b4f4; current main retains the baseline impact code trees. The prescribed Subfleet launcher failed staging to its external inbox; the fresh review used an independently spawned exact GPT-6.1 Sol model. Runtime validation and the blocked global decision enqueue remain separate follow-ups.

axiom: SI 2014/1230 regs 8, 46 and 60A; SI 2019/167 art 3A: TheAxiomFoundation/rulespec-uk#433 queued. The queued issue includes SI 2024/604 and national CTR source provisions, verbatim operative-law quotations, required outputs and law-derived companion cases: TheAxiomFoundation/rulespec-uk#433 (comment) . The signed encoder is blocked; no encoder was run by this job.

MaxGhenis and others added 3 commits October 3, 2026 10:33
…e closes

Tax credits closed on 6 April 2025 and Income Support and income-based JSA
on 1 April 2026, but the model kept paying a family's other legacy awards
and paid Universal Credit only through would_claim_uc, which datasets draw
without regard to legacy receipt. A family that drew it false was left
with nothing once its tax credits stopped.

- would_claim_uc_at_legacy_closure: dataset input (default true) saying
  whether the family claims Universal Credit when its legacy benefits close.
- legacy_benefits_closed: a working-age family reports a legacy benefit that
  has closed (tax credits from 2025, IS and income-based JSA from 2026).
- claims_universal_credit: would_claim_uc, or the closure and the flag. It
  replaces would_claim_uc in universal_credit, universal_credit_pre_benefit_cap,
  uc_has_deduction, is_CTC_eligible and housing_benefit_eligible.
- Once a family's legacy benefits have closed, its Housing Benefit continuing
  award, Income Support, income-related ESA and income-based JSA end,
  whether or not it claims (SI 2014/1230 regs 8 and 46).

Years before any closure are unchanged.

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

Review r1 found that excluding every family on the Pension Credit route
left out families DWP moved to Universal Credit: protected mixed-age
couples and pension-age claimants on Working Tax Credit without Pension
Credit (SI 2019/167 art. 3A; SI 2014/1230 reg 60A; DWP HB circular A9/2024).

- legacy_benefits_closed now sends to Pension Credit only families on it,
  and families on Child Tax Credit but not Working Tax Credit that meet
  the Pension Credit age conditions (art. 3A(1)). IS and income-based JSA
  closures do not move wholly pension-age families (reg 8(2B)).
- claims_uc_at_legacy_closure: the closure claim.
- is_uc_eligible admits a closure claimant on the pension-age route: a
  protected mixed-age couple claims jointly, and a pension-age WTC
  recipient has the upper age condition waived (reg 60A).
- left_pension_route_at_legacy_closure: such a family leaves the route if
  it claims, or as a protected mixed-age couple loses its Housing Benefit
  and saving at the deadline; Housing Benefit's pension-age route and
  Pension Credit eligibility honour it.
- Tax credits (CTC and WTC) are masked for families moved off legacy
  benefits, so a reform keeping tax credits open does not pay them with UC.
- Documentation: claims_universal_credit's scope, the UC notebook's two
  claim routes and how to decline both.
- Tests: seven YAML cases for these routes and the reform; property tests
  now generate mixed-age couples, pension-age families and Pension Credit
  reporters, and check UC/PC and UC/HB exclusivity. The childcare grant
  overlap test pins legacy_benefits_closed false to keep testing the overlap.

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

Copy link
Copy Markdown
Collaborator Author

Status 02:45Z: head cf40b02 = 4313fbd (round-1 review fixes) + main merge, which brings main's read-only cache fixture fix for policyengine-core 3.32.16 (the earlier CI Test failure). The 2,109 policy YAML tests pass locally on core 3.32.16. Delta review r2 (Opus, 20261003-224153-mtuc-pe2119-review-r2c) is running; the hard-tier lanes had no capacity for 9 hours. After CI and an approving review, this merges on gates; PolicyEngine/policyengine-uk-data#534 and #1910 follow.

MaxGhenis and others added 2 commits October 10, 2026 17:24
…osure

# Conflicts:
#	docs/book/programs/gov/dwp/universal-credit.ipynb
#	policyengine_uk/variables/gov/dwp/universal_credit/is_uc_eligible.py
…ependants for closure claims

Review r2 (at cf40b02) found two blocking issues:

- B1: a protected mixed-age couple that does not claim Universal Credit at
  the closure keeps its route. SI 2019/37 art. 4(3)(b)(ii) (inserted by SI
  2024/604) lets it reclaim Housing Benefit within three months and keep
  the saving (DWP HB circular A9/2024 paras 12-13). left_pension_route_at_
  legacy_closure now needs a closure claim and eligibility for Universal
  Credit, so a claimant refused on capital (reg 51 is not modelled) stays
  on the route rather than losing everything.
- B2: uc_non_dependants_counted, merged from main (#2006), still read
  would_claim_uc, so a closure claimant's household non-dependants were not
  counted. It now reads claims_universal_credit.

Also: stale notes now that reg 60A migrants are modelled
(meets_pension_credit_age_conditions, housing_benefit_pension_age_
regulations_apply, the CTR pensioner comment, the HB passport doc); the
changelog credits reg 3(2)(a) for mixed-age couples. Tests: the protected
couple case, a capital-refused reg 60A claimant, a non-dependant case, a
property that every closure claimant within the capital limit is eligible,
and the sharers reference check reads claims_universal_credit.

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

Copy link
Copy Markdown
Collaborator Author

Independent review (GPT-6.1 Sol, UK hub sweep, 2026-10-12): REQUEST_CHANGES at the head below. The hub is routing it to this PR's owner session. Methodology readings the source leaves open go to Max as a decision before they're picked.

VERDICT: REQUEST_CHANGES
Head reviewed: 3b2a394

  1. [blocker] Shared rules still use the old claim flag. uc_work_related_requirements.py:46 treats closure claimants with would_claim_uc:false as retaining legacy benefits. This applies incorrect benefit-cap and LHA rules when a partner cannot claim UC. A synthetic 2025 case produces £13,801.68 UC versus £10,139.64 when only that flag changes, despite both cases claiming UC. Fix: use claims_universal_credit and extend the differential property test to include ineligible partners.

  2. [blocker] Nil UC entitlement wrongly removes the Housing Benefit reclaim route. left_pension_route_at_legacy_closure.py:39 tests age/capital eligibility rather than entitlement. SI 2024/604, article 2 preserves the saving when a protected mixed-age couple claims UC but is not entitled. A synthetic couple aged 72/40 with £37,500 earnings and £9,000 social rent loses £139.83 HB through this gate. Fix: use pre-cap UC entitlement, preserve the reclaim route, and correct the corresponding test invariant.

  3. [blocker] Newly reachable pension-age UC awards receive incorrect CTR classification. council_tax_reduction_pensioner.py:78 disregards these awards in every nation. Scottish regulation 3 requires working-age treatment; Wales introduces the migrant exemption only for schemes beginning April 2026. WSI 2026/13 Fix: implement nation/date-specific disregards and add Scottish and Welsh 2025 regression cases.

  4. [should-fix] Zero reported WTC does not establish the Pension Credit migration route. legacy_benefits_closed.py:50 excludes pension-age CTC recipients whose WTC tapered to nil, although DWP circular A9/2024, paragraph 10 routes them to UC. The notebook acknowledges this omission. Fix: model pre-migration WTC entitlement conditions, or obtain Max’s methodology decision on an explicit proxy.

Both changed YAML files passed: 36 tests. Property tests state invariants, with no introduced skips or xfails, but could not collect because hypothesis is unavailable; pytest-xdist is also missing. Compressor usage was below 30 GB before testing.

merge-tree against local origin/main (3f174d07ec03a9d05ca626939442442ddc23c87e) was clean; no semantic conflict or out-of-scope changes found. None of the specifically watched files changed.

Both requested gh commands failed to connect. PR-body mechanism claims and enhanced-FRS impact evidence remain unverified; this does not establish that impact evidence is missing. No files were edited.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Independent GPT-6.1 Sol review after the adopted fixes and current-main merge:

VERDICT: APPROVE — independent GPT-6.1 Sol code review
Exact head: fa4389d

No remaining code blockers. Actual UC claim helper, pre-cap UC entitlement pension-saving gate, national CTR scheme-year rules, native-PC non-dependant branch and corrected reg60A property exception reviewed. Variable/parameter trees match impact head.

Runtime gates: complete final properties and remaining Python suite; prior run had six failures and one error before interruption in unchanged code-health subprocess tests. Workflow follow-ups: append verbatim new operative law to Axiom433; global nil-WTC decision still unqueued due denied ledger lock. No proxy approved.

Follow-up by the build job: the Axiom operative-law requirement is now completed at TheAxiomFoundation/rulespec-uk#433 (comment) . Exact-head runtime checks are still in progress in the frozen environment; import profiling identifies slow ordinary filesystem reads before collection. Global methodology enqueue remains denied by the sandbox; its replay request is preserved.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Hand-off to the UK hub at fa4389d6f6d79f68312e3961981f9ea11abe2ea4 (pushed), from resumed job 20261012-075210-adopt-uk2119-r3.

The three Sol blockers and regressions were already pushed by the interrupted attempt; its source tree was clean. This job merged current main e01f2f5ec without rewriting history, verified the saved impact/model-tree equivalence, completed Axiom's operative-law addendum, and obtained fresh independent exact GPT-6.1 Sol code approval: #2119 (comment) . No watched ownership files changed in this resume.

Validation: preserved 3,094 passing policy YAML cases, 14 new YAML regressions and four focused Python passes from the completed prior checks; make format and uvx ruff format --check . pass at the final head. The reboot interrupted the prior broad Python suite at 24%, with six failures and one error in unchanged code-health subprocess tests and no final tracebacks. Fresh serial reproduction and final property checks were launched with frozen core3.33.2 and <=4 workers/threads, but have been delayed before collection by filesystem reads. An isolated core import took 1,032 seconds; the nested pytest fixture timeout is 600 seconds. Do not treat the broad Python suite as passed. CI at this head remains queued and is a merge gate.

2026 Enhanced FRS evidence remains in the PR body: main 3381500f4b01bc0a0cd5f447e56f07741af36ae2, impact branch 4cb49f45363c3540ac6c62c05c429090d166b4f4, dataset SHA256 5ba399ea5ab9a6c7d4e9aaf6c623080beb34d9ad5f330f6244dbad72b8d960b6. Final branch and current main retain the respective variable/parameter trees used in those runs. UC +£144.999m; HB -£25.294m; PC/CTR unchanged; household net income +£91.759m. No dataset rebuild was run.

Axiom operative-law/companion-case addendum: TheAxiomFoundation/rulespec-uk#433 (comment) . Signed encoder remains blocked; none was run.

Hub action required: nil/tapered WTC historical entitlement cannot be identified from the available inputs. No proxy selected. The requested global cos add-decision still fails writing /Users/maxghenis/chief-of-staff/state/decisions/.lock; this is not queued globally and has no decision ID. The hub must replay the prepared request below and record its returned ID. The global hub progress and handoff journal are also outside this job's writable workspace; local transfer records are preserved in .cache/uk2119/, and this PR comment provides the durable handoff. Waiting: Max/decision transfer and CI. Do not merge from this job.

cos add-decision 'PolicyEngine/policyengine-uk #2119: choose how to identify pension-age and protected mixed-age Child Tax Credit recipients whose Working Tax Credit entitlement tapered to nil before tax-credit closure. Should we add a verified pre-migration WTC entitlement input and arrange upstream data coverage; explicitly approve a survey work-condition proxy with a stated reference year and limitations; or retain the documented gap until better inputs exist? No proxy has been selected.' --org cross --workstream 'UK: legacy-benefit closure migration' --priority medium --class none --deadline 2026-10-19 --resolves-on-merge no --source https://github.com/PolicyEngine/policyengine-uk/pull/2119 --source https://www.gov.uk/government/publications/housing-benefit-adjudication-circulars-2024/a92024-the-social-security-state-pension-age-claimants-closure-of-tax-credits-amendment-regulations-2024 --why 'DWP Housing Benefit circular A9/2024 paragraphs 6 and 10 send these nil-award WTC families to Universal Credit, while true CTC-only pension-age recipients take the Pension Credit route. The released Enhanced FRS 2024/25 v1.58.0 records positive reported benefit amounts and contemporaneous hours/incomes, but no historical WTC entitlement, migration notice, or tax-credit award type. Existing is_WTC_eligible requires positive working_tax_credit_reported and calls legacy_benefits_closed; reusing it cannot classify nil awards without circularity. Applying contemporary work conditions to infer the historical entitlement would be a methodology assumption requiring Max'"'"'s decision. The current PR therefore still omits these families, and its impact estimate must disclose this gap. This choice is separate from whether PR #2119 merges and must remain unresolved until Max rules.'

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

UK hub (2026-10-12 13:05Z): the nil-WTC methodology question from the hand-off is now queued for Max as d1423: add a verified pre-closure WTC entitlement input, approve a survey work-condition proxy, or keep the documented gap. It is separate from merging this PR. The PR omits these families and says so. The hub is dispatching its own GPT-6.1 Sol review at fa4389d6f, from outside the build job, before landing. CI at this head is still a gate.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Independent re-review (GPT-6.1 Sol, UK hub, from outside the build job): APPROVE at fa4389d6f. The hub lands this once CI at this head is green. GitHub Actions has an incident running, so CI is queued. The nit (HB metadata comments) goes to a follow-up.

VERDICT: APPROVE
Head reviewed: fa4389d

  1. [nit] HB metadata contradicts the new migration route. housing_benefit_eligible.py:12 still says Universal Credit is unavailable to wholly pension-age families. Fix: describe the reg 60A exception and explain that positive pre-cap UC entitlement removes their HB route; update the matching comments at lines 39–43.

No remaining blocker or should-fix findings.

The three blockers are resolved:

  • Shared rules use claims_universal_credit; the £10,139.64 regression and differential property cover ineligible partners.
  • Pension-route departure uses pre-cap entitlement. The £139.83 HB regression is preserved, alongside the current-policy £410.90 case and a capped-to-zero case, consistent with SI 2024/604 article 2.
  • CTR treatment follows the national scheme dates, with Scottish and Welsh 2025 regressions. The implementation matches Scottish regulation 3 and the Welsh 2026 amendments.

The nil-tapered WTC gap is accurately documented, with no proxy selected; the hub confirms decision d1423. It is not a finding against this PR.

Final-head variable and parameter trees exactly match impact commit 4cb49f453. Saved totals agree with the body: UC +£145.0m, HB −£25.3m, PC/CTR unchanged, household net income +£91.8m.

No tests were weakened, skipped or xfailed. None of the PR-touched Python tests had executed before the six failures and one error in unchanged code-health subprocess tests. I found no plausible test-induced shared-state cause; missing tracebacks leave the actual cause unverified.

Tests were not rerun: compressor usage was approximately 10.4 GB, but this worktree has no venv, and global hypothesis/xdist are unavailable. Nothing was installed. Prior logs support 3,094 YAML passes and four focused Python passes; final property validation remains pending. Exact-head CI is still queued. The interrupted broad run is not a passing run.

No files changed or GitHub writes performed.

@MaxGhenis
MaxGhenis added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit 2e5cf2b Oct 12, 2026
15 of 17 checks passed
@MaxGhenis
MaxGhenis deleted the uc-claim-at-legacy-closure branch October 12, 2026 20:46
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Merged by the UK hub (audit). Merged with a merge commit at the tested head fa4389d6f (--match-head-commit, through the main merge queue). Gates:

  • CI: gh pr checks passed at the head.
  • MERGEABLE, not a draft. No outstanding change request: round 1 at 3b2a394e9 requested changes; all three blockers are fixed.
  • Independent review: the hub's GPT-6.1 Sol re-review 20261012-090137-uk2119-review-r4, from outside the build job, APPROVEs fa4389d6f with one nit (HB metadata comments, left to a follow-up). Report: ~/reviews/uk-hub/reviews/sweep-1011/review-2119-r4.md.
  • Real-run impact (2026, enhanced FRS, uk-data 1.58.0, sha256 5ba399ea…): UC +£145.0m, HB −£25.3m, PC and CTR unchanged, household net income +£91.8m (main 3381500f4 against impact branch 4cb49f453). The final head's variable and parameter trees match the impact branch (review check).
  • Open methodology question: the nil-tapered WTC families are documented and omitted; Max decides in d1423. That is separate from this merge.

MaxGhenis added a commit that referenced this pull request Oct 13, 2026
Conflicts in esa_income_eligible.py and jsa_income_eligible.py: #2119 ended
a reported award once one of the family's legacy benefits has closed
(legacy_benefits_closed). Both screens keep this PR's remunerative work
conditions and candidate rule unchanged and AND in main's closure term with
main's comment verbatim; the documentation now names the closure. The
closure is a benefit-unit condition separate from who claims, so the
claimant, partner and candidate rules are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
Brings in #2119 (UC claims at legacy closure), #2373, #1905, #2177,
#2305, #2306, #2325, #2376, #2379, #2380, #2388 and #2364.

One conflict, in the UC docs notebook: kept main's new paragraph on
claims at legacy closure and this branch's benefit cap sentence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
…able-simulated-benefits-scoped-awards

Conflict: tax_benefit_system.py's typing import (main added Callable and
Optional; this branch added Tuple). Took the union.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
#2119 (merged from main in 864eef6) ends every legacy award in a family
once one of its legacy benefits has closed, through esa_income_eligible and
jsa_income_eligible. own_report_is_paid read a failing benefit-unit screen
as the couple's claim failing the work tests, which leaves a member outside
the couple on their own claim; after the merge a closed family's screen
fails too, so a non-working outside member stayed on ESA or JSA after the
closure ended it. Main's own_report_is_paid required the screen to pass and
so ended it. The outside member's own claim now also requires
legacy_benefits_closed to be false.

Two YAML cases (2025, a Child Tax Credit report closes the family's legacy
benefits; a non-working lodger reports ESA or JSA) fail on 864eef6 and pass
here. Documentation and the changelog say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
…a simplification

Answers the review of e743d8e (subfleet/review_final_e743d8ee7.md):

1. legacy_award_work_reference gains legacy_benefits_closed, #2119's
   closure as the model applies it (a report of Income Support or
   income-based JSA once closed, by any member, unless someone reports
   Pension Credit or the claimant and partner have all reached its
   qualifying age), and esa_screen and jsa_screen apply it. The work
   properties draw JSA reports in 2026, when income-based JSA is closed, so
   test_screens_match_a_family_by_family_reading failed there.
2. Invariant 4 is qualified: an outside member changes a screen only
   through the closure, which reads every member's reports. The property now
   asserts exactly that (the screen with them equals the screen without them
   while their report has not closed the family's legacy benefits).
3. The outside member's status following the closure (e743d8e) matches
   main and the money calculation, but is a model simplification: SI
   2014/1230 regs 44(1), (4) and 46(1) reach only the claimant and partner.
   The docstring, the status variables' documentation, the YAML comments and
   the changelog now say so.

Nits: the readers properties' docstring names the closure, and the status
variables' documentation is reflowed (text otherwise unchanged).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
Review r6 (REQUEST_CHANGES on 587c0e7):

1. Main's #2119 closes income-based JSA and Income Support from April 2026
   and then moves a family reporting either off all its legacy benefits
   (legacy_benefits_closed), ending its ESA, JSA and Income Support. Under
   disable_simulated_benefits, which pays every reported award in every
   year, an adult outside the couple was then paid ESA and JSA but not on
   them, since own_report_is_paid reads esa_income_eligible. The reform now
   holds legacy_benefits_closed false for its ten years (NOT_MOVED), as it
   already holds Universal Credit and the legacy awards at their reports, so
   every reader of the closure agrees with the awards it pays. New test:
   with the reform off every test family is moved from 2026; with it on,
   none is, in any of the ten years. The clone-or-branch test now compares
   the parent's ESA with an unreformed simulation's, which the closure ends
   from 2026, instead of expecting the excluded adult's uprated report.

2. From policyengine-core 3.33.0 derivative keeps every input, named or
   not (3.32.x deleted every variable input_variables does not name). The
   comments, the test docstring and the changelog now say reset_calculations
   deletes unnamed variables, as derivative did before 3.33.0.

3. _InputKeyLog docstring: a deep copy or pickle of a simulation logs
   nothing; a shallow copy shares the record, as it shares the holders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
…97ed)

From the independent delta review (subfleet 20261013-010643,
review-delta-d7697edee.md):

- P1: utils/uc_work_related_requirements.py. The 10/9 merge (f4aa92b)
  kept this branch's whole copy of the file, which undid main's 7a71c86
  (#2081 review item 5): couple_members() came back and claimants()
  stopped reading is_uc_assessed_claimant. The file is now main's, less
  the three shared-rules helpers this PR removes. No output changes: the
  two formulas were identical.
- P2: is_uc_benefit_cap_exempt_qualifying_age said only a supplied award
  reaches reg 60C. Since #2119 a reg 60A claim by a Working Tax Credit
  recipient whose tax credits closed does too.
- P3: housing_benefit_pension_age_regulations_apply said its UC-award
  rule was "right for the cap"; UC's reg 60C exception no longer reads
  it, HB's cap does. benefit_cap_welfare_benefits now says the
  benefit-unit amounts are counted whole (#2298). The UC notebook's cap
  sentence names reg 60C. The legacy closure differential also compares
  uc_benefit_cap_reduction, which still reads the claim route through
  the UC award.

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.

Move families onto Universal Credit when a legacy benefit they receive closes

1 participant