You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
UK trading allowance: store the claim status once policyengine-uk#2765 is released #1439
#1428 adds a trading_allowance_receipts spine stage, which stores the self-employed's gross receipts so that policyengine-uk applies the trading allowance against receipts. Neither the FRS nor the SPI tape records turnover, so the stage encodes who claims the allowance through receipts:
a drawn claimant's receipts are profit + £1,000;
any other trader's are profit + £3,000.
That gets the Budget 2026 raise to £3,000 right. Its own review on #1428 (findings 2 and 8) shows two limits.
Allowances above £3,000 are mis-scored.
The non-claimants' stored £3,000 expense grows with profit (mixed income per head), so any allowance above £3,000 times that index gives every non-claimant relief. That relief comes from the stored expense, not from data.
At £4,000–£5,000 this is a material error in reform scoring: hundreds of millions to about £1.5bn a year, on a rough estimate from public counts.
A claimant's £1,000 grows with the same index while the allowance is nominal.
The raise's extra relief is £1,932 in 2027-28, falling to £1,758 by 2031-32: 3.4% to 12.1% below £2,000.
Proposal
Once PolicyEngine/policyengine-uk#2765 is released, store each trader's claim status, its trading_allowance_claim_status input, instead of encoding it in receipts:
claimants as CLAIMANT (against the £1,000 input allowance, which is not uprated);
other traders as NON_CLAIMANT;
leave self_employment_gross_receipts at its default.
That removes both limits:
a non-claimant gets no static relief at any allowance;
a claimant's relief is the new allowance less the £1,000 nominal.
Until then:#1428 documents the limit in the stage spec, the module and the changelog (María's ruling of 2026-11-01). Allowance reforms above £3,000 should not be scored on the #1428 national.
Done when
The receipts stage stores the claim status.
The pinned policyengine-uk carries #2765.
The stage's tests cover an allowance above £3,000 and a later year.
The national is rebuilt and the trading allowance measure rescored.
Whatever decides who claims (HMRC claimant counts, or the interim rates calibrated to HMRC's 400,000 gainers at about £380) is committed as a tool with aggregate evidence, and a post-build check re-measures the gainers and the average gain. SPI donor savings rebased to SPI's 2023-24 bands (savings follow-up to #1418) #1428's rates were calibrated off-repo (its review, finding 12).
Two more points from finding 8 of the #1428 review, for when the stage stores the claim status:
Full relief. A trader whose receipts are within the allowance gets full relief automatically (ITTOIA 2005 Part 7A); only partial relief needs an election.
The receipts encoding gives every drawn non-claimant receipts of profit + £3,000, so those whose real receipts are within the allowance lose that relief.
The calibrated rates then move their gain onto claimants.
The claim status should leave them their full relief.
Capital allowances. A trader who claims capital allowances can't also have used partial relief, so SPI copies with capital allowances should be non-claimants.
The frame doesn't carry capital allowances today, so the SPI draw would need to pass a flag.
The rates drift with each national. On the #1428 national from 9f70c71e7, the claimant rates calibrated on b441bb5a0 give about 436,000 gainers in 2028-29, at about £407 on average, against HMRC's 400,000 and £380. So the post-build check under "Done when" is needed for every national, not once.
Plan review at main f44512d. I read the proposal and the follow-up comment against the trading allowance code in policyengine-uk 2.174.1 (policyengine_uk/utils/trading_allowance.py), which main now locks.
Should
The gate has already opened.Lock policyengine-uk 2.174.1 and follow what its releases change #1511 locks policyengine-uk 2.174.1. That release carries trading_allowance_claim_status from 2.172.0, and main keeps it at UNKNOWN in UK_ENGINE_DEFAULT_INPUTS, with the note "so microcosm#1428's receipts encoding stands until microcosm#1439" (changelog.d/uk-policyengine-uk-2-174-1.changed.md). So the "Done when" item "the pinned policyengine-uk carries #2765" is met, and the stage change can start now rather than "once released". Suggested fix: tick that item, and add a check that the next lock bump keeps trading_allowance_claim_status in the engine's inputs.
"Other traders as NON_CLAIMANT, receipts at default" can't give the full relief the follow-up comment asks for. In trading_allowance.py, a NON_CLAIMANT gets the allowance only through full relief, and only when receipts are known: within_allowance = receipts_known & (receipts + miscellaneous_income <= allowance), then ordinary = (non_claimant & ~within_allowance) | .... With self_employment_gross_receipts at its default of 0, receipts_known is False, so every NON_CLAIMANT takes ordinary treatment and gets nil relief at any profit and any allowance. The engine's own input documentation says to leave fully relieved people at UNKNOWN ("Flag only profits net of the allowance: leave a person whose receipts were within it, and so fully relieved, at UNKNOWN", variables/input/trading_allowance_claim_status.py).
Failure case: a trader with a profit of £600 who isn't drawn as a claimant. As NON_CLAIMANT with default receipts, trading_allowance_deduction is 0 in 2025-26 and in 2027-28 at £3,000. As UNKNOWN it is £600 in both years.
Suggested fix: give the stage three outcomes, not two:
CLAIMANT for drawn claimants;
UNKNOWN, or supplied receipts, for traders the stage treats as within full relief;
NON_CLAIMANT for the rest.
Note: UNKNOWN relieves any profit up to the simulated year's allowance in full, so at £3,000 it would also relieve profits between £1,000 and £3,000 whose real receipts are higher. Who goes into that group is a modelling choice to record in the stage spec.
Add one more test case to "Done when". Alongside the allowance above £3,000 and the later year, test a trader with a profit at or below £1,000 under each status, so that the full-relief choice in item 2 is pinned.
Checked and fine
A CLAIMANT's relief is min(profit, allowance - input_allowance) less capital allowances. The input allowance is read from the baseline tree at the data year, so reforms don't move it. For the 2024 national that is £1,000, which gives the £2,000 extra relief at £3,000 in every year. That removes the drift from £1,932 to £1,758.
Capital allowances supplied for a CLAIMANT are not deducted (partial relief replaces them, s. 783AI), which fits the comment's point that traders with capital allowances should be non-claimants.
Activity
juaristi22 commentedon Nov 1, 2026
Two more points from finding 8 of the #1428 review, for when the stage stores the claim status:
The rates drift with each national. On the #1428 national from
9f70c71e7, the claimant rates calibrated onb441bb5a0give about 436,000 gainers in 2028-29, at about £407 on average, against HMRC's 400,000 and £380. So the post-build check under "Done when" is needed for every national, not once.🤖 Generated with Claude Code
vahid-ahmadi commentedon Nov 6, 2026
Plan review at main
f44512d. I read the proposal and the follow-up comment against the trading allowance code in policyengine-uk 2.174.1 (policyengine_uk/utils/trading_allowance.py), which main now locks.Should
The gate has already opened. Lock policyengine-uk 2.174.1 and follow what its releases change #1511 locks policyengine-uk 2.174.1. That release carries
trading_allowance_claim_statusfrom 2.172.0, and main keeps it at UNKNOWN inUK_ENGINE_DEFAULT_INPUTS, with the note "so microcosm#1428's receipts encoding stands until microcosm#1439" (changelog.d/uk-policyengine-uk-2-174-1.changed.md). So the "Done when" item "the pinned policyengine-uk carries #2765" is met, and the stage change can start now rather than "once released". Suggested fix: tick that item, and add a check that the next lock bump keepstrading_allowance_claim_statusin the engine's inputs."Other traders as NON_CLAIMANT, receipts at default" can't give the full relief the follow-up comment asks for. In
trading_allowance.py, a NON_CLAIMANT gets the allowance only through full relief, and only when receipts are known:within_allowance = receipts_known & (receipts + miscellaneous_income <= allowance), thenordinary = (non_claimant & ~within_allowance) | .... Withself_employment_gross_receiptsat its default of 0,receipts_knownis False, so every NON_CLAIMANT takes ordinary treatment and gets nil relief at any profit and any allowance. The engine's own input documentation says to leave fully relieved people at UNKNOWN ("Flag only profits net of the allowance: leave a person whose receipts were within it, and so fully relieved, at UNKNOWN",variables/input/trading_allowance_claim_status.py).trading_allowance_deductionis 0 in 2025-26 and in 2027-28 at £3,000. As UNKNOWN it is £600 in both years.Add one more test case to "Done when". Alongside the allowance above £3,000 and the later year, test a trader with a profit at or below £1,000 under each status, so that the full-relief choice in item 2 is pinned.
Checked and fine
min(profit, allowance - input_allowance)less capital allowances. The input allowance is read from the baseline tree at the data year, so reforms don't move it. For the 2024 national that is £1,000, which gives the £2,000 extra relief at £3,000 in every year. That removes the drift from £1,932 to £1,758.🤖 Generated with Claude Code