Conversation
This was referenced Oct 2, 2026
- 2023-24 weekly rate £3.45 (SI 2023/236 reg 3(a)); model year 2023 charged £3.15. - From 2022-23 Class 2 is payable only on profits that exceed the lower profits threshold (£11,908, SI 2022/1329; £12,570, SI 2023/236 reg 3(b)). Profits from the small profits threshold up to it are treated as paid (s.11(5A)-(5B)); the model charged 52 weeks on them. - Small profits threshold: £6,725 in 2023-24 and 2024-25 (not CPI uprated), £5,965 in 2015-16 and 2016-17 (not 3,965). CPI projections now run from the latest statutory value. - Compulsory Class 2 ends 6 April 2024 (NICRRA 2023 s.3), not 1 January. - Every value cites its amending instrument. - Tests: YAML cases per year and threshold; a statute-table differential, range and monotonicity property test over model years 2015-2030; a 2023-24 regulation 100 pin using the default £3.45 rate. - NI notebook: describe the rule and regenerate saved charts; the rates chart now selects percentage parameters by unit. Fixes #1887 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 2023-24 lower profits limit £12,570 from 6 April 2023 (NICs (Increase of Thresholds) Act 2022 s.2(3)-(4)); model year 2023 used £11,908. - 2022-23 main and additional rates 9.73% and 2.73% for the whole year (Health and Social Care Levy (Repeal) Act 2022 s.2(2)); the model used 10.25% and 3.5%. - 2023-24 additional rate 2% (s.15(3ZA)(b)); the model used 3.5%. - 2015-16 upper profits limit £42,385 (SI 2015/588 art 3(b)), not £42,386; the £43,000 limit dated 6 April 2016 (SI 2016/343 reg 2). - Main rate cut to 6% dated 6 April 2024 (NICRRA 2024 s.1(3)(a)). - Every Class 4 limit and rate cites its amending instrument. - Regulation 100 already reads the rate parameters; a comment records that its written percentages track the Class 4 rates in every year, including the 2022-23 modification (HSCL (Repeal) Act 2022 Sch para 6). - Tests: the four stale 2023 YAML expectations replaced with hand-derived statutory values (ni_class_4 1,568.70; ni_class_4_main 3,393; ni_class_4_maximum 1,748.60 by reg 100 Case 3), plus 2022-23, 2015-16 and 2016-17 cases; test_ni_class_4_statute.py adds a statute table for every year, 17 hand-derived liabilities and an exact-rational differential (s.15(3) capped by reg 100) at every limit and as a Hypothesis property. - Docs: NI notebook chart values and the model-baseline link. Fixes #1968 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Hand-derived table: add regulation 100 Case 3 before 2022-23 (2019-20, £827.36), Case 2 in 2022-23 (£3,998.25) and Case 3 in 2023-24 (£1,748.60), so each regime has all three cases. - ni_class_4_maximum comment: the percentages match from 2015-16; the 2024 Act changed only Steps Two and Five. - Class 4 maximum YAML: state the pay-spread assumption behind Case 3. - lower_profits_threshold_applies description: the treated-as-paid band applied in 2022-23 and 2023-24. - ni_class_2.yaml: Act name; changelog: citations run to 2025-26; notebook table: reg 100 also applied where Class 2 was paid before 2024-25. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1959 holds the PT, UEL, LPL and UPL through 2030-31 and corrects the 2025-26 LEL to £125, but left the notebook's saved chart on the old CPI-uprated values. Only the chart's y values change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
force-pushed
the
fix-class-2-class-4-ni-parameters
branch
from
October 2, 2026 13:43
25bd7a9 to
6cb67d6
Compare
This branch has not been deployed
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 #1968
Fixes #1887
Supersedes #1888. Its commit (the Class 2 fix) is the first commit here, unchanged apart from one notebook cell that
mainhad also edited. The second commit is the Class 4 fix that #1888 left for a follow-up.What was wrong
I read s.11 and s.15 of the Social Security Contributions and Benefits Act 1992 as in force on 6 April of each year from 2015 to 2026, the instrument behind each figure, and regulation 100 of SI 2001/1004. The model samples each tax year at 30 April, so "model year 2023" is 2023-24.
Class 4 (s.15)
2022-11-06: 0.09entry never took effect, because the year is sampled in April.Class 2 (s.11), from #1888:
Regulation 100 (the Class 4 annual maximum). The formula is right. Regulation 100 writes its percentages out, and in every year they equal the Class 4 rates: 9% and 2%; 9.73%, 100/9.73 and 2.73% for 2022-23 (Health and Social Care Levy (Repeal) Act 2022 Sch para 6(2)); 6% and 100/6 from 2024-25 (NICs (Reduction in Rates) Act 2024 s.2(3)).
ni_class_4_maximumreads the rate parameters, so it follows each year's text. A comment now records this. The wrong 2023 figures came from the stale parameters, not the formula.Changes
class_4/thresholds/lower_profits_limit.yaml: adds2023-04-06: 12_570, drops the duplicate2024-01-01entry, cites every value.class_4/thresholds/upper_profits_limit.yaml: 2015-16 is 42,385; £43,000 is dated 6 April 2016; cites every value to 2021-22.class_4/rates/main.yaml: 9.73% for 2022-23, 9% from 6 April 2023, 6% dated 6 April 2024.class_4/rates/additional.yaml: 2.73% for 2022-23, 2% from 6 April 2023; drops the2024-01-01entry.ni_class_4_maximum: the comment above; no formula change.flat_rate.yaml: £3.45 for 2023-24, zero dated 6 April 2024, citations.small_profits_threshold.yaml: corrected values, and CPI uprating now projects from the latest statutory value.lower_profits_threshold.yamlandlower_profits_threshold_applies.yaml.ni_class_2: liable on profits above the lower profits threshold when that test applies, else on profits at or above the small profits threshold.model-baseline.mdline links.#1959 (merged) holds the two Class 4 limits through 2030-31. This branch is rebased on it and keeps its 2026-27 to 2030-31 entries unchanged. The NI notebook's saved chart, which #1959 left on the old CPI-uprated thresholds, now shows its values too.
Invariants
For every tax year from 2015-16 to 2026-27, profits ≥ 0 and primary Class 1 ≥ 0:
ni_class_4equals an exact-rational reference: the s.15(3) amount on the full profits, capped by the regulation 100 maximum where primary Class 1 or, before 2024-25, Class 2 is payable.ni_class_2is 52 × the weekly rate when s.11(2) makes the earner liable, else 0.ni_class_4≤ the s.15(3) amount;ni_class_2∈ {0, 52 × rate}.ni_class_2is non-decreasing in profits.Tests
ni_class_2over the lower profits threshold: 3.45 × 52 = 179.40.ni_class_4under the UPL: (30,000 − 12,570) × 9% = 1,568.70.ni_class_4_mainover the UPL: 37,700 × 9% = 3,393.ni_class_4_maximumwith £100,000 of pay and £100,000 of profits: 1,748.60. Step Four is negative (Case 3, nil); Step Eight is 37,700 × 2% = 754; Step Nine is 49,730 × 2% = 994.60. The old 3,083.22, and the 3,060.05 seen after fixing only the limit, both used the 3.5% rate.main's parameters, 8 of the 10 Class 4 cases fail; the 2016-17 and 2026-27 cases are regression guards.test_ni_class_4_statute.py:ni_class_2.yaml(17 cases) andtest_ni_class_2.pyfrom Fix Class 2 NICs: 2023-24 rate, the 2022-23 lower profits threshold, and the small profits threshold #1888. Its regulation 100 pin no longer overrides the Class 4 parameters, since the defaults are now the statutory ones.Effect
Single-person households at default parameters,
main(8b2e6e1) against this branch (25bd7a9), each state run from its own worktree and venv.Household net income moves by the negative of the NI change in every row, to within 1p.
Enhanced FRS. The dataset's base year is 2024-25, so it covers model years 2024 onward. In those years the only parameters that change are read by
ni_class_2alone: the small profits threshold (2024-25, and the 2027-28 to 2030-31 projection) and the two new lower-profits-threshold parameters.ni_class_2multiplies them by a rate of zero. No other parameter read in 2024-2030 changes. I confirmed that with two real runs for each year from 2024 to 2030 (14 simulation-years), base against branch, each from its own worktree and venv on its own copy of the 2024-25 enhanced FRS (sha256 e433e532…).ni_class_2,ni_class_4,ni_class_4_main,ni_class_4_maximum,ni_self_employed,ni_class_1_employee,national_insurance,income_tax,self_employment_income,household_net_income,household_taxandhousehold_benefits.The dataset has no year before 2024-25, so there is no aggregate figure for the 2015-16, 2022-23 and 2023-24 changes. The household table above shows their size.
Not in this PR
Axiom parity
axiom: TheAxiomFoundation/rulespec-uk#353 queued (s.11) | TheAxiomFoundation/rulespec-uk#423 queued (s.15 and reg 100)
rulespec-uk's
uk/statutes/ukpga/1992/4/15.yamlanduk/regulations/uksi/2001/1004/100.yamlencode only the current text: limits from 2026-04-06, 6% from 2024-04-06 and a 2% additional rate from 2011 with no 2022-23 exception. None of the amending instruments are in the corpus. Both issues are dispatch-ready: module path, corpus citation, verbatim law, a figures table, a pasteablereview_finding, and companion tests built on the same statutory figures as the tests here.Verification of the figures
Independent review
Opus 5.5 via Subfleet (
--task review --tier standard, job 20261002-081207-ni-class-2-4-review-r1): APPROVE WITH NITS, with nothing blocking.The reviewer found:
ni_class_2and the regulation 100 formula follow the statutory text step by step;Its findings and what I did:
ni_class_4_maximumcomment, which now says "from 2015-16" and that the 2024 Act changed only Steps Two and Five;ni_class_2.yaml;lower_profits_threshold_appliesdescription;Commands run
ruff format --check .andruff check .: clean.policyengine-core test policyengine_uk/tests/policy/baseline/gov/hmrc -c policyengine_uk: 490 passed at 6cb67d6 (after the rebase onto Hold NICs thresholds at 2026-27 levels through 2030-31 #1959).pytest policyengine_uk/tests/test_ni_class_2.py test_ni_class_4_statute.py test_ni_class_4_maximum.py test_ni_class_4_properties.py test_parameter_descriptions.py test_parameter_metadata.py test_fiscal_year_parameters.py test_build_metadata.py: 83 passed, 1 skipped at 25bd7a9; after the rebase and review fixes,test_ni_class_4_statute.py,test_ni_class_4_maximum.pyandtest_ni_class_2.py: 62 passed.main's Class 4 parameters: 8 failed, 2 passed.esa_exempt_work_earnings170.19,esa_income_eligiblefalse).make documentation. CI runs all three.🤖 Generated with Claude Code