Repository navigation
Correct historical dividend income tax band thresholds - #2457
Merged
Merged
Conversation
vahid-ahmadi
left a comment
Collaborator
There was a problem hiding this comment.
Looks right, fine to approve. One follow-up is worth filing.
@juaristi22, the dated limits now match rates/uk.yaml and the cited Acts and Orders for 2016-17 to 2025-26. The £125,140 additional-rate threshold now applies from 6 April 2023.
- should,
policyengine_uk/parameters/gov/hmrc/income_tax/rates/dividends.yaml:57: the same lag comes back from 2031-32.uk[1].thresholdis now indexed bycreate_threshold_indexation.py, but the dividend scale is not. In the processed parameters I get £38,500 against £37,700 in 2031, and £41,900 against £37,700 in 2035. ITA 2007 s13 ties dividends to the same basic rate limit, so this is the bug in #1822 again, for future years. It is outside this PR's stated scope. It needs a follow-up issue (add the dividend limits to the indexation, or derive them fromuk), or a line in this PR saying it is deliberately left. - nit,
dividends.yaml:57and:111: 2015-16 still reads £37,500 and £150,000, whileuk.yamlgives £32,000 for that year. The README says the pre-2016 tax-credit regime is out of scope, so this is fine for now. A note in the issue would help. - nit,
policyengine_uk/parameters/gov/hmrc/income_tax/README.md: policyengine-core uses the text after a folder README's first line as that node's description. The wholegov.hmrc.income_taxnode would then be described by dividend-band notes. A## Dividend bandssection in a README forrates/, or a shorter description, would fit better.
What I checked
- Read the issue, the PR body and the full diff (including
test_dividend_band_dates.pyand the YAML file), and compared each new date withuk.yamland the cited instruments. - Worked two cases by hand. 2018, £40,000 pay and £10,000 dividends: 28,150 taxable pay leaves 6,350 of basic band; 2,000 nil-rate, then 4,350 x 7.5% + 3,650 x 32.5% = £1,512.50. 2025, £130,000 pay and £10,000 dividends: no personal allowance, all dividends above £125,140; 9,500 x 39.35% = £3,738.25. Both match. A case the PR body doesn't work through, 2017 with £160,000 of dividends: 28,500 x 7.5% + 116,500 x 32.5% + 10,000 x 38.1% = £43,810. This also matches.
- Ran
policyengine-core test .../dividend_band_dates.yaml: 9 passed.pytest test_dividend_band_dates.py: 16 passed. Withdividends.yamlreverted: 7 YAML cases and 12 pytest cases fail. ruff checkandruff format --checkon the new test file: clean.- Hosted CI on 83de1ef is green.
- Process: the changelog fragment is
.fixed.md; the Reproducer and axiom lines are present; the Fix evidence check is green. - Not checked: RuleSpec parity, and population effects.
🤖 Generated with Claude Code
vahid-ahmadi
approved these changes
Oct 18, 2026
vahid-ahmadi
left a comment
Collaborator
There was a problem hiding this comment.
Approving, per my review above. The shoulds and nits can follow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1822.
The dividend scale held a £37,500 basic-rate limit until 2026 and a £150,000 additional-rate threshold until 2026. This adds the missing statutory dates so historical dividend tax uses the corresponding UK bands under Income Tax Act 2007 s. 13.
For one adult aged 40 in England, the genuine-income regressions give:
The dividend nil-rate amount occupies band capacity. For the £49,000/£2,000 example, the Personal Allowance leaves £36,430 of taxable wages and £1,270 of basic-band capacity: £770 × 8.75% + £730 × 33.75% = £313.75. Tests also assert final
income_taxusing independently derived expectations.All existing rates, original and 2026 dated entries, the optional extra bracket, formulas, Gift Aid extensions and reform interfaces remain unchanged. The README records the historical dates and scope limits. This does not synchronize post-2026 projected thresholds or certify the pre-2016 dividend-tax-credit regime.
The inherited 2016 Personal Allowance discrepancy remains separate in #2359 / #2442. Existing fixed-order allowance allocation also does not always implement the most-beneficial split for mixed income. The new 2016, 2017, 2021 and 2026 final-tax cases therefore use £160,000 of dividends with a naturally zero allowance. The selected 2018, 2019 and 2025 mixed cases have independently checked allocations. No intermediate taxable-income or allowance input is forced.
Validation: final fixtures recorded 19 failures / 6 passes with the unchanged base dividend parameter, then 111 passed with the corrected parameter (25 new cases and 86 existing regressions; 24.30s pytest / 40.580s bounded invocation). The combined run covered dividend bases/allowances, Gift Aid, property band use, final income tax, fiscal conversion, generated-parameter processing and two dividend Scenario compatibility controls. Per-case outcomes and exact hashes were recorded from collection. Earlier fixture-oracle premises were corrected before the final paired run; those earlier logs remain separate and are not additional unique coverage. Formatting, Ruff and diff checks passed.
Local Python 3.13.14 / Core 3.32.27 differs from locked Core 3.33.2. Full locked CI, the documentation build and private population analysis were not run locally. No population impact is claimed.
Reproducer: policyengine_uk/tests/test_dividend_band_dates.py::test_raw_dividend_limits_change_on_the_statutory_tax_year_date
Reproducer: policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/dividend_band_dates.yaml::2025 dividends with wages 49000 and dividends 2000
axiom: needed
Maintainer follow-up: verify RuleSpec/Axiom parity for the six dated dividend band limits. No encoder or parity verification has been run. Draft #1963 documents the lag as an inherited limitation; its owner can integrate this separate fix.