Skip to content

Set the Personal Savings Allowance on rest-of-UK bands for Scottish taxpayers - #2348

Merged
MaxGhenis merged 3 commits into
mainfrom
scottish-savings-allowance
Oct 12, 2026
Merged

MaxGhenis merged 3 commits into
mainfrom
scottish-savings-allowance

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 11, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2347

axiom: ukpga/2007/3/12B encoded-correct (rulespec-uk c65fd7df, uk/statutes/ukpga/2007/3/12B.yaml, which carries the s. 12B(8)(a)(iv) and (b)(iv) Scottish and Welsh limbs at lines 85 and 110, as inputs, from 2024-04-06)

What changes

ITA 2007 s. 12B gives a Personal Savings Allowance of £1,000 with no higher-rate income, £500 with higher-rate but no additional-rate income, and nil with any additional-rate income. For a Scottish or Welsh taxpayer, s. 12B(8)(a)(iv) and (b)(iv) count as higher- or additional-rate income what "would, if the individual were not a Scottish taxpayer or Welsh taxpayer", be charged at those rates. So the allowance follows the rest-of-UK bands for everyone.

savings_allowance read tax_band, which follows the Scottish bands for a Scottish taxpayer. In 2026-27:

  • taxable income from £62,430 (the Scottish advanced rate) to £125,140 got no allowance (law: £500);
  • taxable income from £31,092 (the Scottish higher rate) to £37,700 got £500 (law: £1,000).

savings_allowance now works out the band itself on the rest-of-UK thresholds (rates.uk.thresholds[1] and [2]), with taxable income taken as adjusted net income less allowances, as tax_band does. Income exactly at a limit has none in the band above (ITA 2007 s. 10(2)-(3)). So £37,700 of taxable income gives £1,000 and £125,140 gives £500; the old >= gave £500 and nil. tax_band is unchanged: the Marriage Allowance conditions read it and do look at the Scottish rates.

This also fixes the periods 2016 and 2017, which tax_band's earlier formula covers. It put the higher band at thresholds[-2] (£150,000), so a higher-rate taxpayer on £60,000 got £1,000 (law: £500) and an additional-rate taxpayer on £200,000 got £500 (law: nil). The same formula still feeds Marriage Allowance in those years: #2356.

Impact (real run)

Measured on enhanced_frs_2023_24.h5 (local policyengine-uk-data storage, 6 October build) for 2026. This branch and main's code (c6d15c8) each ran a full simulation of the same data (impact_psa.py).

main This PR Change
Income Tax £349,674.5m £349,666.1m −£8.4m
of which savings income tax £356.7m £348.4m −£8.4m
  • Who changes: 957 records (393k people weighted), all Scottish taxpayers. Each gets £500 more allowance, either nil → £500 or £500 → £1,000. No one's allowance falls.
  • Tax effect: 377 of those records (119k people) pay less tax, by up to £200 (£500 of interest at 40%). No one pays more.
  • At the new head (49fad84) the totals are unchanged, at −£8.37m.

Tests

  • New YAML (gov/hmrc/income_tax/allowances/savings_allowance.yaml):

    • a Scottish taxpayer on £80,000 with £1,000 of interest: £500 allowance and £200 savings tax (main: £0 and £400);

    • a Scottish taxpayer on £45,000: £1,000 and £0 (main: £500 and £100);

    • an English taxpayer on £80,000, unchanged;

    • a Scottish taxpayer on £130,000: nil;

    • 2016-17 at £60,000 (£500) and £200,000 (nil).

    • period 2017 (Case 7);

    • exactly at, and £1 over, each limit (Cases 8-11).

    On main, Cases 1, 2, 5, 6 and 7 fail and Cases 3 and 4 pass. At the previous head, Cases 8 and 10 failed.

  • Changed YAML (allowances.yaml): the three allowance cases set tax_band as an input, which no longer drives the allowance. They now set adjusted net income and allowances for the same three bands.

  • Property tests (test_savings_allowance_properties.py, Hypothesis, 12 single adults per example):

    • a Scottish and an English taxpayer with the same pay, interest and dividends get the same allowance;
    • the allowance equals the statute computed independently;
    • a higher pay never raises it.

    The first fails on main.

  • The property tests always run four boundary rows: taxable income at, and £1 over, each limit.

  • Run locally at 49fad84:

    • the full policy YAML suite, 3,019 passed;
    • the property tests, 2 passed. On main, the first fails.
  • Review: a GPT-6.1 Sol review agreed with the s. 12B(8)(iv) reading and asked for the boundary fix, which is made here. Its follow-ups are handled as follows:

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 11, 2026 15:40
…axpayers

ITA 2007 s. 12B(8)(a)(iv) and (b)(iv) count a Scottish or Welsh taxpayer's
higher- and additional-rate income as what would be charged at those rates
if they were not a Scottish or Welsh taxpayer. savings_allowance read
tax_band, which follows the Scottish bands, so a Scottish taxpayer with
taxable income from £62,430 to £125,140 got no allowance (law: £500) and one
from £31,092 to £37,700 got £500 (law: £1,000). It now works out the band on
the rest-of-UK thresholds itself; tax_band keeps the Scottish bands for the
Marriage Allowance conditions. This also corrects 2016-17, where tax_band put
the higher band at £150,000.

Fixes #2347

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review fixes for #2348:
- ITA 2007 s. 10(2)-(3) charges income up to a limit at the lower rate and
  only income above it at the higher one, so taxable income exactly at the
  basic rate limit has no higher-rate income (£1,000) and exactly at the
  higher rate limit no additional-rate income (£500). The test is now ">".
- YAML Cases 8-11 at and one pound over each limit; Case 7 for period 2017,
  which the old tax_band formula also covered; the property tests always run
  the boundary rows and the statute oracle uses ">".
- Changelog and comment wording.

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

Copy link
Copy Markdown
Collaborator Author

CI run cancelled to free runners (UK hub, 2026-10-11 23:30Z). The PolicyEngine org is at GitHub's limit of 60 concurrent jobs, with about 360 queued. Fleet ops asked the hub to let the Budget-critical #2305 take runners first. This PR's queued run had not started, so I cancelled it. Nothing is wrong with the PR.

Please don't re-run it or push just to retrigger CI. The hub re-runs this run itself once #2305 has runners. The record is ~/reviews/uk-hub/ci-yield-2026-10-11.json; see notice 17 in ~/reviews/uk-hub/notices.md.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Hand-off to the UK hub (session local_66e4b1fd, PolicyBench UK round 2).

  • Head: 60c6054a4ebaf2f1c7a1cdf05238c3719fceeb70 (includes main at ed7b42f95).
  • Review: GPT-6.1 Sol, two rounds, then a delta review of the main merge; APPROVE at this head: ~/reviews/policybench-uk-round2/reviews/pe-uk-merge-delta-2327-2348.md (round 2: pe-uk-2348-review-r2.md).
  • CI: not yet run at this head. The run was queued, and the hub cancelled it to free runners (notice 17, ~/reviews/uk-hub/ci-yield-2026-10-11.json); the hub re-runs it. No CI run has completed on this PR at any head: each was superseded by a push or cancelled while queued. Lint and Test are therefore the open gate.
  • Local tests (~/reviews/policybench-uk-round2/fixes/evidence/), at the approved head before the main merge, which changed none of this PR's files (pr2348_approved_net.diff and pr2348_merged_net.diff are identical): 3,019 YAML cases and the 2 boundary property tests (pr2348_r2_full_yaml.log, pr2348_r2_py.log).
  • PolicyBench check at this head: all 2,800 round 2 references recomputed on this head (audit/attribution/refs_psa_final.csv); 1 move, the same cells and values as at the reviewed head. With all five fix heads merged onto main ed7b42f95, 96 move, also unchanged.
  • Impact (enhanced FRS, 2026, in the PR body): Income Tax −£8.37m; 393k Scottish taxpayers get £500 more savings allowance.
  • Depends on: nothing. It and Band savings and dividends above property income #2352 both touch savings tax, in different files; they merge cleanly in either order.
  • Decision: none. A bug fix to ITA 2007 s. 12B.
  • Follow-ups filed, not owed here: tax_band before 2017-18 puts the higher band at £150,000, so 2016-17 higher-rate taxpayers get the Marriage Allowance #2356 (before 2017-18, tax_band puts the higher band at £150,000, which reaches the Marriage Allowance). Axiom parity: encoded correctly already (uk/statutes/ukpga/2007/3/12B.yaml).

@MaxGhenis
MaxGhenis merged commit 87cb78c into main Oct 12, 2026
6 of 12 checks passed
@MaxGhenis
MaxGhenis deleted the scottish-savings-allowance branch October 12, 2026 03:07
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.

Personal Savings Allowance uses the Scottish bands for Scottish taxpayers (ITA 2007 s. 12B(8))

1 participant