Skip to content

Disregard allowable employment expenses in Universal Credit earnings - #2494

Open
juaristi22 wants to merge 1 commit into
mainfrom
fix-1997-uc-employment-expenses
Open

juaristi22 wants to merge 1 commit into
mainfrom
fix-1997-uc-employment-expenses

Conversation

@juaristi22

Copy link
Copy Markdown
Collaborator

Refs #1997. This implements the employment-expenses part; payroll giving and any remaining work stay open.

UC employed earnings currently omit the existing employment_expenses input even though it reduces taxable employment income. Deduct that specific input before adding separately calculated trading earnings. In the natural 2024 single-claimant test, £6,000 earnings and £600 allowable expenses now produce £5,400 UC earnings and £330 more annual UC. Existing tax/NI and pension deductions, trade floors, statutory pay, MIF, claimant aggregation and supplied-output overrides are preserved.

The input represents expenses already allowed under ITEPA Part 5 Chapter 2, after the relevant-employment and combined-deduction restrictions in Chapter 1. Reimbursements qualify only to the extent included in employment earnings; callers must avoid duplicate costs. The input metadata and UC documentation explain this contract. No raw-cost admissibility engine or general salary cap is added. The disregard follows GB regulation 55(3)(a) and its NI counterpart; this validation does not certify every historical commencement or payment-timing case.

Reproducer: policyengine_uk/tests/test_uc_employment_expenses.py::test_allowable_expenses_increase_natural_final_uc_cash

Validation: 151 distinct relevant tests passed across implementation and targeted runs, with unchanged cases carried forward after a fixture correction. Independent captured-head CODE/POLICY review is complete with no findings or material gaps; its 74 fresh tests overlap the implementation results. Formatting, lint, structure/protected-payload checks, the trusted base fix-evidence checker and a notebook HTML build without execution passed. All 807 existing parameter YAML files remain unchanged. Local Python 3.13/Core 3.32.27/microdf 1.2.1 differs from the lock; the full suite, private data, population impacts and encoded parity were not tested. Hosted CI remains to be checked.

The notebook is also touched by #1837 and #1999 in different sections. Preserve those edits when coordinating landing; #1999's downstream earnings-measure work remains separate.

Axiom: needed. The statutory UC expense disregard needs a supported encoding/parity follow-up; no encoding result is claimed.

@juaristi22 juaristi22 self-assigned this Oct 18, 2026

@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.

Fine once expenses can no longer push employed earnings below nil.

@juaristi22, the change follows UC Regs 2013 reg 55(3)(a), which disregards expenses allowed under ITEPA Part 5 Chapter 2. I hand-checked the main case. The 2024 single standard allowance is £4,721.40. Then 4,721.40 − 0.55 × 5,400 = £1,751.40, and the gain against the case with no expenses is 0.55 × 600 = £330.

  1. should: uc_individual_earned_income_before_mif.py:106-121. employed is not floored before it is added to self_employed, so expenses above employment income now reduce self-employed earnings. With 2025 inputs of £1,000 employment income, £3,000 employment_expenses and £10,000 self-employment income, taxable_employment_income is £0, but UC earned income is £8,000 instead of £10,000. ITEPA s.329(1) says a Part 5 deduction "may not exceed the earnings from which it is deductible", and taxable_employment_income already floors at nil. Cap the expenses at the employment earnings, or floor employed at nil before adding the trade figure.
  2. should: employment_expenses is not only a household-calculator input. policyengine-uk-data imputes it onto the FRS from the SPI (datasets/imputations/income.py:38, employment_expenses="EPB"). So this changes population UC results, not only the household cases in the tests. The PR body says population impacts were not tested. A one-line estimate in the PR, or a note in the changelog that microsimulation results move, would help whoever reviews the data release. Point 1 matters more here, because imputed values are not bound by s.329.
  3. nit: the UC reg 55(3)(a) reference reuses the same URL as the existing reg 55(4)/(5) entry. One entry titled "reg. 55(3)(a), (4) and (5)" would do.

What I checked

  • Read the full diff and issue #1997. Read reg 55 on legislation.gov.uk and ITEPA s.329.
  • policyengine-core test uc_employment_expenses.yaml: 2 passed. pytest test_uc_employment_expenses.py: 16 passed. All of tests/policy/baseline/finance/benefit/family/universal_credit: 484 passed.
  • Reverted the UC formula. The new YAML then fails 1 of 2, and the new pytest file fails 12 of 16.
  • Ran the over-deduction household above, on this head.
  • ruff check and ruff format --check on the changed Python files: clean.
  • Hosted CI on this head: all green.
  • Not checked: the notebook render, private-data impacts, and the NI regulations beyond the link.

🤖 Generated with Claude Code

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.

2 participants