Repository navigation
Apply the £10,000 accommodation threshold to legacy tariff income - #2788
Conversation
… income IS Regs 1987 reg 53(1A)-(1C), JSA Regs 1996 reg 116(1A)-(1C) and ESA Regs 2008 reg 118(2)-(4), and their Northern Ireland equivalents, set a £10,000 lower capital threshold where the claimant lives permanently in a care home, independent hospital, Abbeyfield Home or (GB) Polish Resettlement Act accommodation with care. The three tariff income formulas read a new pre-assessed input, legacy_prescribed_accommodation_capital_exception, which defaults to false. Housing Benefit's circumstances differ (HB Regs 2006 reg 52(4), (8)), so the existing HB input stays separate. Fixes #1758. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hypothesis checks, for capital on a penny grid with and without the exception, that each of the IS, income-based JSA, income-related ESA and working-age Housing Benefit tariffs matches the regulations' formula, never falls as capital rises and never exceeds the ordinary tariff, and that programmes with the same tariff figures agree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The three legacy tariff formulas built a threshold array with where(), which promoted the float32 capital subtraction to float64. Under a fractional threshold reform, capital equal to the threshold then counted one £250 step. Each branch now subtracts its own scalar threshold, as the ordinary branch did before, and where() picks between the two excesses. Adds regression cases for each programme with the input omitted, false and true under fractional thresholds, a property test that gives each programme its own six thresholds in pence, and documentation that keeps the statutory range up to £16,000 apart from the arithmetic the variables continue above it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rewrites the input's documentation to say how a caller assesses it: the claimant's own stay, the places in each jurisdiction, the 13-week and 52-week absences, the Polish Resettlement Act absence with no fixed limit, and the shared tariff for own-right claims. Puts the programme second in the three parameter descriptions and splits the changelog sentence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DWP and the Department for Communities, the model and the caller now act in the tariff documentation, the formula comments, the YAML headers and the property test docstrings, in place of the regulations and benefits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aggregate impact on certified data: passBase Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 0 (thresholds in Notes
Moves flagged for reviewNone. Spending by benefit and service
Caseloads
Standard reform costings (change in gov_balance)
Standard reforms: change in each reform's target
Household net income by decileNo household's net income changes in any year. No change in any year: receipts by tax head; government balance, each component counted once; model totals; household income totals; population; poverty rates; people in poverty; inequality; mean household net income in each side's own deciles. Checks failing on both base and head (1)
Counted-once checkEach of 92 components was raised by £1 per unit in 2026-27, and every head of its totals was read household by household: its own head must rise by exactly £1, no other tax head may move, no other benefit may rise, and the model's own total must move by what its heads moved. A head that breaks a rule is measured again twice: with every other head held at its baseline value, and with every other head held at its value after the first £1 while the component rises again. It fails where either still shows the response. 0 failed; 0 were skipped.
Provenance
Dataset: Receipts by tax head: head levels
Spending by benefit and service: head levels
Caseloads: head levels
Government balance, each component counted once: head levels
Model totals: head levels
Household income totals: head levels
Population: head levels
Poverty rates: head levels
People in poverty: head levels
Inequality: head levels
Mean household net income in each side's own deciles: head levels
Standard reform costings (change in gov_balance): head levels
Standard reforms: change in each reform's target: head levels
|
juaristi22
left a comment
There was a problem hiding this comment.
Reviewed f2602255e4058bf961af9406b32c2ca5e89d8071. Complete review; no findings or material evidence gaps.
The £10,000 threshold, commencement dates and caller-assessed claimant/accommodation conditions agree with the GB/NI sources. The ordinary branch preserves its previous arithmetic, and Housing Benefit's separate flag remains independent. The benefit-unit status/ownership limits and above-limit reform convention are documented. The queued Axiom record meets the required criteria.
Validation: 102 combined checks and the focused raised-limit control passed. Native ESA/JSA cases in GB and NI calculate tariff £884→£52 and final awards £2,116→£2,948 at £10,001 capital; household income rises £832. Final IS and all three current £16,000 upper-limit gates are also covered. Exact-head hosted CI passed. Private dataset coverage and population effects were outside this review.
Fixes #1758
What and why
DWP, and Northern Ireland's Department for Communities, treat capital above a lower threshold as tariff income in Income Support, income-based JSA and income-related ESA. They count £1 a week for each complete £250 above the threshold and £1 for any part of £250 left over, up to £16,000 of capital. They use a lower threshold of £6,000, or £10,000 where the claimant lives permanently in prescribed accommodation, under these regulations:
The government introduced the £10,000 threshold for IS from each claimant's first benefit week on or after 8 April 1996 (SI 1996/462 regs 1(2) and 12(1)(b)), and for JSA on 7 October 1996 (SI 1996/1516 regs 1(1) and 12(b)). The government built it into the ESA regulations, which came into force on 27 October 2008. Northern Ireland's departments made the same changes on the same dates (SR 1996/93 regs 1(2) and 11(1)(b), SR 1996/356 regs 1(1) and 10, and SR 2008/280 reg 118).
The model starts in 2015. In every model year the ordinary threshold stands at £6,000, and the accommodation and absence provisions read as they do today, so we give each new parameter one value, £10,000, from its commencement date. Until April 2006 the ordinary tariff ran from £3,000 to £8,000 of capital, and until April 2002 some JSA claimants could stay away for 52 weeks.
On main the three formulas apply £6,000 to everyone. At £10,001 of capital each returns £884 a year, where DWP and the Department for Communities count £52 a year for a claimant in prescribed accommodation.
What the change does
The three tariff formulas read one new input,
legacy_prescribed_accommodation_capital_exception(benefit unit, boolean, default false). Each formula subtracts the ordinary threshold and the prescribed accommodation threshold from capital separately, then takes the excess the input selects. NumPy keeps the float32 capital in float32 when it subtracts a scalar threshold, so the ordinary branch computes what main computes. If a user reforms the ordinary threshold to £6,000.02 and sets capital to £6,000.02, tariff income stays £0.We add a separate parameter for each programme, following Housing Benefit's file:
gov.dwp.income_support.means_test.capital.residential_threshold: £10,000 from 1996-04-08gov.dwp.JSA.income.capital.residential_threshold: £10,000 from 1996-10-07gov.dwp.ESA.income.capital.residential_threshold: £10,000 from 2008-10-27Who qualifies, and how to set the input
A claimant qualifies under all three regulations by living permanently in one of these places:
The Secretary of State defines "care home", "independent hospital" and "Abbeyfield Home" the same way in all three (IS reg 2(1), JSA reg 1(3), ESA reg 2(1)).
The claimant must live there, and the claimant doesn't qualify through a partner's stay. A claimant still counts as living there permanently while away:
Under JSA reg 116(1C) the limit stays at 13 weeks at every age in the model years. The 52-week limit never applies in these benefits, because no one over pensionable age can claim them (Jobseekers Act 1995 s.1(2)(h); Welfare Reform Act 2007 s.1(3)(c); for IS, SSCBA 1992 s.124(1)(aa) with State Pension Credit Act 2002 s.1(6)).
The model gives other members who claim ESA or JSA in their own right the benefit unit's tariff income, so the input sets their threshold too. The model doesn't assess their own stay or divide capital between claims. Callers assess the input under the rules for the year and jurisdiction they model.
We keep Housing Benefit's input separate, because its accommodation conditions differ. Under HB Regs 2006 reg 52(3)-(9) (NI reg 49(2)-(8)) a claimant gets the £10,000 threshold in "residential accommodation" as reg 52(8) defines it, and in saved 2005 cases. Reg 52(8) covers local authority homes without board, Royal Charter or statutory bodies that provide board and personal care, and Abbeyfield Homes. Neither input sets the other, and YAML cases check both directions.
Above £16,000
DWP and the Department for Communities stop counting capital at £16,000. Above that amount the three variables continue the same arithmetic, which the regulations don't prescribe, and at £16,001 the variables give £2,132 a year without the exception and £1,300 with it. The model pays nothing while capital exceeds the configured £16,000 capital limit, and some award formulas compute tariff income before they apply that test:
esa_income_eligible.py:66(reg 110) gates the couple's award, whichesa_income.py:10takes aswhere(eligible, ...);esa_income.py:33gates each own-right claim.jsa_income_eligible.py:64(reg 107) gatesjsa_income.py:13;jsa_income.py:41gates each own-right claim._legacy_award_payee.py:67checks capital againstcapital_limitbeside the report-against-tariff comparison.income_support_eligible.py:187(reg 45) applies the test.income_support_entitlement.py:16multiplies the award by that eligibility, and nothing else readsincome_support_applicable_income, which adds the tariff.So while the limit stays at £16,000 the arithmetic above it changes no award, and the YAML cases at £16,001 assert a nil award with and without the exception. If a user raises the limit by reform, the model subtracts the continued tariff from awards. With each limit at £30,000 and capital of £16,001 in 2025, the model pays a £3,000 reported ESA or JSA award as £868 without the exception and £1,700 with it. It pays IS to a lone parent aged 26 with one child at £2,654.60 without the exception and £3,486.60 with it.
Who sees the change
The input defaults to false, and no dataset supplies it. With the input false the formulas compute main's figures, so dataset runs don't change. Household calculations that set the input see the change.
Which years
ESA, JSA and IS tariff income on £10,001 of capital comes to £884 without the exception and £52 with it in each of 2015, 2020, 2024, 2025, 2026, 2027, 2030 and 2035. Housing Benefit's working-age tariff gives the same with its own exception. Each
residential_thresholdstarts in 1996 or 2008, before any model year.The model pays awards in fewer years. With £16,000 of capital, it pays these annual awards on a £3,000 reported ESA or JSA award, and in IS to a lone parent aged 26 with one child:
The IS applicable amounts come to £4,706 (2024) and £4,786.60 (2025), and the exception lowers tariff income by £832 a year in each. The model returns £0 for JSA and IS from model year 2026, because
gov.dwp.JSA.income.activeandgov.dwp.income_support.activehold false from 2026-04-01. On this branch the model still pays ESA of £920 and £1,752 in 2026 and 2027. The fix for #2562 (branchfix-2562-esa-abolition) stops income-related ESA from 1 July 2026 in Great Britain and 1 October 2026 in Northern Ireland, which changes the 2026 and 2027 ESA figures.Overlap with open work
This branch's head merges cleanly (
git merge-tree) with each of #1969 (3a3241cf6), #2131 (6a0d26d61), #2279 (c5b9850a3), #2756 (c34662736),fix-2562-esa-abolition(68ccc0856),fix-2565-esa-pension-credit(cef744bc2) andfix-2729-person-isa-capital(cb6e5a875). #1969 and the #2729 branch change the three*_assessable_capitalvariables, which the tariff variables read as before; this PR's tests set assessable capital directly. The #2562 branch changes ESA awards from 2026.Invariants
These statutory invariants hold for every capital amount up to £16,000 and either exception status:
These model invariants hold for every capital amount:
test_legacy_capital_tariff_properties.pychecks 1 to 6 with Hypothesis. It checks 1, 3, 4, 5 and 6 on a penny grid that Hypothesis biases towards the thresholds, in six years from 2015 to 2029. For 2 it draws all six thresholds in pence and puts capital at each threshold, a penny below it and a penny above it. The YAML files check the nil awards above £16,000. Where capital lies a whole number of £250 steps above a threshold in pence, the float32 capital can fall either side of the step on main as on this branch, so the own-parameters test skips those points.Test plan
income_support_capital.yamlalready does.ruff format --checkandruff check(0.17.2) on the changed Python files,ruff check --select F811,F821 policyengine_uk,git diff --check.changelog.d/1758.fixed.md.We ran each file or directory locally, one at a time, with
-n 0:esa_income/directory (the new file's 11 cases among them)jsa_income/directory (new file: 10 cases)income_support/directory (new file: 10 cases)legacy_award_readers/directoryhousing_benefit/housing_benefit_residential_capital.yamltest_legacy_capital_tariff_properties.py(new; 25 Hypothesis examples per property)test_reported_legacy_award_screening.pytest_parameter_descriptions.pycode_health/test_input_variable_definitions.pycode_health/test_variables.pytest_variable_units.pyWhen we copy the new test files onto main (
2da212abc), the Python file fails 6 of 6 and the three YAML files fail 28 of 31. The three that pass leave the input out under the £6,000.02 ordinary threshold, which main already computes correctly.Each YAML file adds three cases under fractional thresholds. Two leave the input out or set it false, with the ordinary threshold at £6,000.02, and one sets it true, with the prescribed accommodation threshold at £10,000.07. Each puts capital at the threshold, a penny above it and £250 above it. The minimal case,
esa_income_tariff_incomeat capital of £6,000.02 with the threshold at £6,000.02, returns £0 on this branch and on main (2da212abc).Each mutation we made to the fix makes the test files fail:
whereWe ran the mutants in a scratch copy with Hypothesis shrinking off, so Hypothesis didn't reduce the property examples to minimal ones. Under the ESA-reads-JSA mutant the other five property tests and 30 of the 31 YAML cases pass; the own-parameters test and the fractional ESA case catch it.
No existing test's expected value changes. We didn't run the full suite or the microsimulation tests locally; the input defaults to false and no dataset supplies it.
Reproducer: policyengine_uk/tests/test_legacy_capital_tariff_properties.py::test_prescribed_accommodation_uses_higher_threshold, policyengine_uk/tests/policy/baseline/finance/benefit/family/esa_income/esa_income_residential_capital.yaml
axiom: TheAxiomFoundation/rulespec-uk#512 queued
rulespec-uk encodes the Great Britain regulations as
uk/regulations/uksi/1987/1967/53,uk/regulations/uksi/1996/207/116anduk/regulations/uksi/2008/794/118, each with a prescribed accommodation input and the £10,000 threshold. Each module's companion caseprescribed_accommodation_uses_higher_threshold(capital £10,251 with the exception, £2 a week) matches the YAML cases at £10,251 (£104 a year), and in every model year the modules agree with this PR at every capital up to £16,000. The IS and JSA modules date today's amounts from 1988 and 1996, but the ordinary figures stayed lower until April 2006, and the government added the £10,000 branch to IS in April 1996. All nine companion cases fall in April 2026. rulespec-uk has no Northern Ireland module for SR 1987/459 reg 53, SR 1996/198 reg 116 or SR 2008/280 reg 118. In the queued issue we ask for the three Northern Ireland modules, the corrected Great Britain dates and dated companion cases.🤖 Generated with Claude Code