Repository navigation
Calculate the ESA permitted work limit from the national living wage - #2687
Conversation
|
Review status: COMPLETE No actionable defects found in this PR's changed behavior or affected dependencies. The wage-derived ESA permitted-work limit, adult-rate selection, rounding and downstream work screen agree with ESA Regulations 2008 reg. 45, the 2011 amendment, and DWP DMG chapter 41, paragraph 41190. The added 2010/2011 minimum-wage rates and the published 2024–2026 ESA limits were corroborated against official sources. Validation:
Relationship to other open PRs#2684 — concrete historical wage integration issue. At its captured/current head
Align #2684's eligibility-parameter history with the newly available October 2010 wage history and cover the intervening 2011/2012 calculations when combining these PRs. The shared test file merges without a textual conflict. This is a demonstrated composition issue, not a standalone #2687 defect; the diagnostic isolates the changed wage components rather than running a full merged-branch suite. #2679 — complementary ESA/JSA claim screening. #2687 sets the person-level work earnings limit; #2679 determines which separate reported claims survive screening and how readers attribute their awards. Neither supersedes the other. Its work-screen call paths retain #2687's gate, with no shared changed files or stale consumer of the removed parameter found in its changed files. A combined regression should include a couple and an outside reporting adult whose earnings sit between the baseline and reformed work caps. That combined multi-claim behavior was traced, not executed. #2219 — related Housing Benefit permitted-work disregard. This adds an externally pre-assessed annual HB input rather than an ESA eligibility calculation. #2687 does not automatically populate or reform that input. No direct dependency on #2687 or consumer of its removed parameter was found; #2219's declared dependency is #2225. #1969 and #2131 — separate ESA capital work. These change the capital arm of screening, while #2687 changes its work arm. No direct changed-file overlap or required order involving #2687 was identified. #2131 is explicitly stacked on #1969. Other downstream receipt/passport readers remain relevant for combined regression coverage, but they do not duplicate this work-limit fix. Keep #2687 separate, preserve its wage-derived work limit alongside #2679's per-claim screening, and reconcile the historical parameter dates with #2684 before both wage changes are combined. |
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 91 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
|
ESA Regs 2008 reg 45(4) sets the permitted work higher earnings limit at 16 x National Minimum Wage from 11 April 2011 (SI 2011/674 reg 16(5)), rounded up to the next 50p (reg 45(9A)). Reg 2(1) points to the rate in reg 11 of the NMW Regulations 1999, which DWP reads as the highest rate, now the national living wage (DMG 41190). The model listed the limit year by year and projected it with average earnings, so it ignored changes to gov.hmrc.minimum_wage and disagreed with the model's own projection of the national living wage from 2027. - esa_exempt_work_higher_earnings_limit calculates the limit: the fixed amount (£92, £93 from 1 October 2009) until 10 April 2011, then 16 x the top rate of gov.hmrc.minimum_wage.non_apprentice, rounded up to 50p. esa_income_claimant_remunerative_work reads it. - gov.dwp.ESA.exempt_work.fixed_higher_earnings_limit and higher_earnings_limit_minimum_wage_hours replace higher_earnings_limit, which is registered as removed so saved reforms fail with directions. - The minimum wage rates now start at 1 October 2010 (SI 2010/1901 and SI 2011/2345), so the limit has a rate from April 2011. JSA is unchanged: the JSA Regs 1996 never use the minimum wage, and the JSA Regs 2013 use it only to end sanctions (reg 25(3)), which the model does not include. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dc54701 to
283ea2b
Compare
Should-address fixedThe review follow-ups are addressed in commit 283ea2b:
VerificationAll 180 targeted tests passed, including the complete ESA YAML directory and affected wage, parameter and migration regressions. The same 180 tests passed again after formatting and rebasing onto Ten additional isolated composition cases passed using exact captured definitions from #2684 and #2679: two historical wage/category cases and eight simultaneous couple/outside-adult claim cases covering work status, member order and the wage reform. These checks cover the focused interactions; the full local suite and full merged sibling suites were not run. Merge coordination#2684 adds the same parameter file. The second merge or rebase must resolve any add/add overlap while preserving the 1 October 2010 start date. This work does not modify either sibling PR's remote branch. |
|
#2687 now includes the actual commits from #2684 at The shared 281 targeted tests passed against the actual combined worktree, including ESA, historical wages/categories, apprentice eligibility, the Universal Credit income floor and employer National Insurance coverage. Independent verification found the combined tree clean. These results cover the targeted manifest, not the full suite or GitHub CI. This updates #2687's branch; it does not merge #2684 on GitHub or modify #2684's remote branch. |
|
Round 1 at Verdict: the 16 x NLW calculation is right in law and is independent of #2684's apprentice rules; one should (a missing £95 step in 2010-11), no musts. CI was still pending at this head when I posted. Scope: this round covers Findings
Checked and fine
What I ranIn a fresh clone at
Not run: the full suites or any microsimulation. CI at 🤖 Generated with Claude Code |
|
Addressed both points from your review in commit bb685f9. The fixed permitted-work limit now rises from £93 to £95 on 1 October 2010, following S.I. 2010/2126, regulation 5(2). The annual 2011 result now reads £95. Annual 2010 remains £93 because the model reads these pre-2015 annual rules on 1 January. New regressions check the dated boundaries and the subsequent minimum-wage transition. Production and the independent reference now select the designated adult/National Living Wage band with 209 targeted tests passed, including the reference consumers, final ESA award regressions and complete ESA YAML directory. All 10 tests in the formatted Python file passed again after formatting. The branch retains the actual #2684 commits and the previous ESA fixes. The PR description also includes the corrected £92/£93/£95 history and adult-band wording. These results cover local targeted validation; the full local suite was not run for this follow-up. |
|
Round 2 at Verdict: both round 1 points are fixed in
One note, not a finding: What I did: read the diff of 🤖 Generated with Claude Code |
Fixes #2686
What and why
ESA Regs 2008 reg. 45(4) sets the permitted work higher earnings limit at "16 x National Minimum Wage" from 11 April 2011 (SI 2011/674 reg. 16(5)), rounded up to the next 50p (reg. 45(9A)). Reg. 2(1) points to the rate in reg. 11 of the NMW Regulations 1999. DWP reads that as the adult rate, now the national living wage (Decision Makers' Guide ch. 41, para. 41190).
The model listed the limit year by year and projected it with average earnings. As a result, a minimum wage reform didn't move it, and from 2027 it no longer matched 16 × the model's own national living wage (£208.50 against £203.50).
esa_exempt_work_higher_earnings_limitcalculates the limit:gov.hmrc.minimum_wage.non_apprentice, rounded up to 50p.esa_income_claimant_remunerative_workreads it.gov.dwp.ESA.exempt_work.fixed_higher_earnings_limitandgov.dwp.ESA.exempt_work.higher_earnings_limit_minimum_wage_hours(16) replacegov.dwp.ESA.exempt_work.higher_earnings_limit. The old path is inREMOVED_PARAMETERS, so saved reforms that set it fail with directions to the new parameters.The minimum wage rates now start at 1 October 2010 (SI 2010/1901 regs. 3 and 5, SI 2011/2345 regs. 3 and 5). Without these rates the limit had no minimum wage rate for April 2011 to September 2012.
test_minimum_wage_rates.pyhas the two new rows.Results change in two ways:
JSA is unchanged. The JSA Regs 1996 never use the minimum wage. The JSA Regs 2013 use it only in reg. 25(3), which decides when a sanction ends, and the model doesn't include sanctions. ESA Regs 2008 also use 16 × NMW in reg. 76 (councillor's allowance) and in the Sch. 7 permitted work disregards; the model includes neither.
Test plan
esa_income_remunerative_work.yamlcases at DWP's published £195.50 (2025-26) and £203.50 (2026-27) limits still pass. The new Python tests check every year against the rates in DMG ch. 41 Appendix 5 and DWP's published limits for 2024 to 2026.make formatequivalent:ruff format --check .andruff check .are clean.changelog.d/esa-permitted-work-limit-from-nlw.changed.mdFocused tests run locally, all passing:
test_legacy_benefit_parameters.py,test_removed_esa_higher_earnings_limit_parameter.py,test_minimum_wage_rates.py,test_parameter_descriptions.py,test_legacy_award_work_properties.py,test_legacy_award_readers_properties.py,test_income_support_eligibility_properties.pyand the two existing removed-parameter test files.The full YAML and Python suites weren't run locally; CI runs them.
Reproducer
Reproducer: policyengine_uk/tests/test_legacy_benefit_parameters.py::test_esa_exempt_work_higher_limit_follows_a_national_living_wage_reform; policyengine_uk/tests/test_legacy_benefit_parameters.py::test_esa_exempt_work_higher_limit_is_16_x_nmw_rounded_up
axiom: needed — rulespec-uk has no module for ESA Regs 2008 reg. 45 (it has reg. 118 and NMW Regulations 2015 regs. 4 and 4A). Encoding reg. 45 needs a billed run of the signed encoder, which hasn't been approved.
🤖 Generated with Claude Code