Repository navigation
Fix Class 2 and Class 4 NICs against SSCBA 1992 for 2015-16 to 2026-27 - #2058
Merged
Merged
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
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…i-parameters # Conflicts: # docs/book/programs/gov/hmrc/national-insurance.ipynb
s.11(3) defines Class 2 "relevant profits" as the profits on which Class 4 is payable under s.15, which s.15(3) computes under Schedule 2. Since #1919 those are ni_class_4_profits: profit after capital allowances, the trading allowance and loss relief. ni_class_2 still read self_employment_income, so in 2023-24 £13,000 of profits with £1,000 of capital allowances paid £179.40 of Class 2 on relevant profits of £12,000, below the £12,570 threshold. - ni_class_2 reads ni_class_4_profits; documentation and references. - ni_class_2.yaml: 8 cases with capital allowances, the trading allowance and losses on each side of the 2015-16, 2021-22, 2022-23 and 2023-24 thresholds (6 fail on the previous formula). - test_ni_class_2.py: the statute differential and Hypothesis property now vary capital allowances, and check the shared-base invariant against the model's own ni_class_4_profits. - Notebook and changelog wording. Found by delta review r3 (job 20261003-220428-ni-class-2-4-review-r3c). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review r4 (job 20261007-121526-ni-class-2-4-review-r4): - The UC minimum income floor computed its notional Class 2 with the pre-2022 rule (threshold >= small profits threshold). In 2022-23 and 2023-24 it deducted £163.80 or £179.40 from thresholds that s.11(5A)-(5B) treats as paid, so it disagreed with ni_class_2 and moved UC away from the law (lone parent, 16-hour floor of £8,669.44 in 2023-24: UC £90.09 too high on main's figures, £98.67 on this branch's previous head). New policyengine_uk/utils/class_2.py holds the s.11(2) test and the contribution-week count; ni_class_2 and the floor both use it. - A contribution week starts at midnight between Saturday and Sunday (SI 2001/1004 reg 1(2)) and the year's first week on the first Sunday after 5 April (HMRC NIM70200), so a full year is 53 weeks in 2019-20 (and 2025-26, when the rate is nil). The model charged 52: £156 instead of £159. - Tests: floor YAML for 2019-20, 2022-23 and 2023-24; floor property years 2019, 2022 and 2023 with a lone-parent example; Class 2 YAML for 2019-20 and 2020-21 weeks; test_ni_class_2 draws relevant profits first, adds in-year trading losses, checks the week count against the calendar and NIM70200's example; the 2019-20 reg 100 rows in test_ni_class_4_statute use 53 weeks (£2,167.56). - Docstring, documentation, notebook and changelog wording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 9, 2026
- test_ni_class_2: a year has 53 contribution weeks when 6 April is a Sunday, or a Saturday in a 366-day year (2024-25 starts on Sunday 7 April but has 52); the carry-forward comment notes the trading allowance case. - class_2_liable: the s.11(2) threshold condition only; callers apply the rate, which handles the 2024 abolition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Merged on gates at 28b11c1 (merge commit,
Axiom parity stays queued in TheAxiomFoundation/rulespec-uk#353 (s.11), #379 (Sch 2 Class 4 profits) and #423 (s.15 and reg 100). Reports, logs and run outputs: |
MaxGhenis
added a commit
that referenced
this pull request
Oct 10, 2026
Brings in #2058 (cfee0e6), which fixes Class 2 and Class 4 National Insurance against SSCBA 1992 for 2015-16 to 2026-27. It conflicted with this branch's NI corrections in nine files, all resolved to main's version: - Parameters: class_2/flat_rate, class_2/small_profits_threshold, class_4/rates/main, class_4/rates/additional and class_4/thresholds/lower_profits_limit. Every value this branch set is the same on main (2015-16 and 2016-17 SPT £5,965; 2023-24 Class 2 £3.45; 2023-24 LPL £12,570; 2022-23 Class 4 9.73% and 2.73%; 2023-24 2%). Main also adds the 2023-24 and 2024-25 SPT of £6,725 (s.11(4)(b)) and dates each entry from 6 April with its statute. Class 2 ends on 6 April 2024 (NICs (Reduction in Rates) Act 2023 s.3) where this branch kept the model's 1 January 2024 entry. The Class 4 main rate falls to 6% on 6 April 2024, where this branch kept 4 April. - Tests: ni_class_2, ni_class_4, ni_class_4_main and ni_class_4_maximum. Main has this branch's statutory values (52 x £3.45 = £179.40; £1,568.70; £3,393; reg 100 maximum £1,748.60) plus 2015-16, 2016-17 and 2022-23 cases. So the PR no longer changes any shared NI parameter or test. The changelog drops its NI bullet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 10, 2026
Reg 99(3)(a) as at 6 April 2023 spares chargeable income "equal to or less than the amount specified in section 11(4)(a) ... (lower profits threshold)". #2058 added that amount as gov.hmrc.national_insurance.class_2.lower_profits_threshold (£11,908 in 2022-23, £12,570 in 2023-24). The rule and the test reference now read it instead of the Class 4 lower profits limit. The values are the same in both years the deduction applies, so no result changes. Two 2022-23 YAML cases pin the threshold and its date. At £11,908 of profit there is no Class 2: (£11,908 - £3,900) / 52 = £154.00, over the £152 higher limit. At £11,909, Class 2 of 52 x £3.15 and Class 4 of 9.73% x £1 come off: (£11,909 - £0.0973 - £163.80 - £3,900) / 52 = £150.87, within it. ESA YAML: 43 cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 10, 2026
Brings in #2027 (claimant and partner legacy awards) and #2058 (NI classes 2 and 4). Resolutions: - docs/book/programs/gov/dwp/housing-benefit.ipynb: main's passport paragraph (#2027's claimant-or-partner wording); this branch's benefit cap paragraph (each scheme's own cap). - legacy_award_readers/passports.yaml (#2027): its benefit-cap case read the removed shared is_benefit_cap_exempt_health_disability. It now asserts both per-scheme specified-benefit exceptions (HB reg 75F(1)(a), UC reg 83(1)(a)); both read the benefit unit's income-related ESA, so the claimant's own award lifts each cap as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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:
Class 2, found in review of this PR (commits 0278f13 and c1364a4):
self_employment_income. s.11(3) applies them to "relevant profits": the profits on which Class 4 is payable under s.15, which s.15(3) computes under Schedule 2. HMRC NIM70650: "From the 2015 to 2016 tax year, the profits used to determine whether a Class 2 NICs liability exists are those profits which are already used for Class 4 NICs purposes under section 15". Since Charge Class 4 NICs on Chapter 2 profits, after capital allowances, the trading allowance and Schedule 2 losses #1919 the model calls thoseni_class_4_profits(after capital allowances, the trading allowance and loss relief). With the fixes above but the old profit measure, £13,000 of profit with £1,000 of capital allowances in 2023-24 paid £179.40 of Class 2 on relevant profits of £12,000, which do not exceed the £12,570 threshold.ni_class_2and the floor now share one s.11(2) test and one week count (policyengine_uk/utils/class_2.py).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 relevant profits above the lower profits threshold when that test applies, else on relevant profits at or above the small profits threshold. Relevant profits areni_class_4_profits(s.11(3)). A full year is the year's contribution weeks.policyengine_uk/utils/class_2.py:class_2_liable(the s.11(2) test) andclass_2_contribution_weeks(Sundays from 6 April to the next 5 April).ni_class_2anduc_minimum_income_floor_national_insuranceboth use them.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 the weekly rate × the year's contribution weeks when s.11(2) makes the earner liable on relevant profits, else 0. The test's inputs are profit, whole-pound capital allowances and a whole-pound trading loss in the same year, with no gross receipts, so relevant profits are profit less both, computed exactly. (From 2017-18 a profit of £1,000 or less is covered by the trading allowance and gives nil relevant profits; such profits are below every threshold, so Class 2 is nil either way.) The trading allowance with gross receipts and losses brought forward are covered by YAML cases only.ni_class_2is the s.11(2) rule applied to the model's ownni_class_4_profits, on the same inputs.ni_class_4≤ the s.15(3) amount;ni_class_2∈ {0, a full year at the weekly rate}.ni_class_2is non-decreasing in relevant profits: non-decreasing in profit and non-increasing in capital allowances and losses.test_uc_minimum_income_floor_properties.py, now drawn over 2019, 2020, 2022, 2023, 2026 and 2027).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.ni_class_2.yamlcases put capital allowances, the trading allowance (with gross receipts) and losses (brought forward and the year's own) against the thresholds: below and at or above the 2021-22 and 2023-24 thresholds, and below the 2015-16 and 2022-23 ones. 6 of them fail on the previous formula; the other 2 sit at or just above a threshold.test_ni_class_2.pydraws relevant profits first (so sampled threshold points stay on their thresholds) and adds capital allowances and an in-year trading loss to the statute differential and the Hypothesis property, and checks invariant 4. Both tests fail on the previous formula, and on two narrower mutants (readingni_class_4_profits_before_losses, or profit less capital allowances only).ni_class_2.yamlcases for 2019-20 (53 × £3.00 = £159) and 2020-21 (52 weeks);test_ni_class_2.pychecks the week count against a typed table and NIM70200's example; the two 2019-20 rows oftest_ni_class_4_statute.pyuse 53 weeks (with £2,000 of Class 1 the regulation 100 maximum is £2,167.56: Step Four 3,723.12 + 159 − 159 − 2,000 = 1,723.12, plus 2% × (41,368 − 1,723.12 / 9%)).Effect
Single-person households at default parameters,
main(a094911) against this branch (c1364a4), each state run from its own worktree and venv on 2026-10-07.Household net income moves by the negative of the NI change in every row, to within 1p, in these runs.
These runs and the Universal Credit and Enhanced FRS runs below are at a094911 against c1364a4. Since then the branch has one comment-only commit (0e9736d) and two merges of
main:main's Energy Bills Support Scheme correction (Correct Energy Bills Support Scheme amounts and timing #2103): −£200 in the 2015-16, 2019-20 and 2021-22 rows, −£1 in 2022-23 and +£201 in 2023-24, against the figures behind this table.ni_class_1_employee_primary) and Class 2 only, so employer Class 1 does not enter it. I did not re-run the tables at this head, because the host was reserved for other work; CI ran the full test suite there.The first 14 rows are unchanged from this table's first run (8b2e6e1 against 25bd7a9). The next five isolate s.11(3) against the branch's previous formula; against
mainfour of them also include the threshold fixes (only the 2021-22 row is s.11(3) alone), and the Class 4 drops in the two 2023-24 rows come from the lower profits limit. The last two are the 53-week year: in the dual earner's row regulation 100 binds, so £3 more Class 2 lowers the Class 4 maximum by £2.33.Universal Credit. A lone parent aged 30 with a child aged 3 (a 16-hour floor), £3,000 of profit, £7,200 of private rent, in the North East:
Enhanced FRS. The dataset's base year is 2024-25 (its only
time_periodis 2024), so it covers model years 2024 onward. From 2024-25 the Class 2 rate is zero, so the changed Class 2 thresholds, profit measure and week count, inni_class_2and in the UC floor's notional Class 2 alike, multiply a zero rate. Each Class 4 limit and rate equals main's from 2024-25 on. The dataset has no capital allowance, trading loss or gross receipts inputs.On 2026-10-07 I ran main (a094911) and this branch (c1364a4), each from its own worktree and venv on its own copy of the 2024-25 enhanced FRS (sha256 e433e532…), for every year from 2024 to 2031: 16 simulation-years.
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(which includes Universal Credit).The dataset has no year before 2024-25, so there is no aggregate figure for the 2015-16 to 2023-24 changes. The household table above shows their size.
Not in this PR
ni_liable); s.11(7) stops Class 2 after the week of reaching pensionable age, and the model does not count weeks of self-employment within a year.Axiom parity
axiom: TheAxiomFoundation/rulespec-uk#353 queued (s.11) | TheAxiomFoundation/rulespec-uk#379 queued (Sch 2 Class 4 profits, which s.11(3) relevant profits import) | 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. All three 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.On 2026-10-07 #353 gained two sections. The first says that no small profits threshold after 2026-27 has been announced: the £7,105 for 2026-27 (Budget 2025 para 4.118; SI 2026/231 reg 3(a)) stands until amended, and this model's CPI projection from 2027-28 is not law. The second covers s.11(3) relevant profits: review_finding item 8 binds them to #379's
profits_chargeable_to_class_4_contributions, with two companion cases that use capital allowances. #353's oracle note now uses the year's contribution weeks (53 in 2019-20), and #379 lists s.11 among the consumers of its output. #423's companion row E (2019-20) now uses 53 weeks of Class 2 (£159; Class 4 £2,167.56), matchingtest_ni_class_4_statute.py.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;A delta review of 6cb67d6 (job 20261002-094504-ni-class-2-4-review-r2) checked the #1959 conflict resolution, the r1 fixes and the three new rows: APPROVE WITH NITS. Its nits are fixed in d978a9f:
A delta review of 8e62932 on GPT-6.1 Sol (
--task review --tier hard, job 20261003-220428-ni-class-2-4-review-r3c) gave REQUEST CHANGES:ni_class_2readsni_class_4_profits(s.11(3)), with the YAML cases and property tests above.A delta review of b3f3de5 on Opus 5.5 (
--task review --tier standard, job 20261007-121526-ni-class-2-4-review-r4) confirmed the s.11(3) fix in law, the tests, the merges and every Effect and Enhanced FRS number, and gave REQUEST CHANGES:ni_class_2(an existing property test failed once it sampled those years). Fixed in c1364a4 with a shared helper, YAML cases and wider property years; the UC table above shows the effect.>instead of>=for hours requirement #423, but the Class 4 profit measure is Change date format in PR template #379's. Fixed in Change PolicyEngine label for "Claims UC" to "Claims Universal Credit" #353 and Change date format in PR template #379, and in theaxiom:line above.class_2_contribution_weeks) instead of being listed as a gap.ni_class_2's documentation now cites NIM70650 and says "as modelled inni_class_4_profits".A delta review of 92acbb4 (c1364a4 merged with
main) on GPT-6.1 Sol (--task review --tier hard, job 20261008-093036-ni-class-2-4-review-r5b; a first dispatch was cancelled by a restart) gave APPROVE WITH NITS. It found all 13 r4 findings resolved; checked the week count against an independent calendar enumeration for 2015-2030 and regulation 155; recomputed the two 2019-20 statute rows and the four new floor cases exactly; swept 1,920 person-years at every threshold corner and eight ages (floor NI less Class 4 equalled Class 2 to £0.0002, and every age-gated row had nil Class 2); confirmed that b3f3de5's formulas fail 8 of the new Python tests and 4 of the new YAML cases; reproduced every NI and UC figure, explained the household net-income differences through #2103, and verified the saved Enhanced FRS comparison. Its nits, all fixed:>instead of>=for hours requirement #423's 2019-20 companion row still used 52 weeks. Updated (row E, and the week note).main's Energy Bills Support Scheme correction (Correct Energy Bills Support Scheme amounts and timing #2103). The Effect section now says which heads its runs used and what has merged since.class_2_liable's docstring described a full liability test; it is the threshold condition, and callers apply the rate (nil from 2024-25). Fixed in 0e9736d.A read-only delta review of 28b11c1, the head (GPT-6.1 Sol,
--task review --tier hard, job 20261009-200213-ni-class-2-4-review-r6), gave APPROVE WITH NITS: 0e9736d changes two test comments and one docstring and no behaviour; apart from themodel-baseline.mdresolution the merge is byte-for-bytemain's own changes; the threemodel-baseline.mdlinks point at the right lines; the PR's other 24 files are unchanged by the merge; all five r5 nits are resolved; #423's row E recomputes to £2,167.56; and #2227 conflicts with nothing here. Its two wording nits are fixed: #423's week note now names 2025-26, and the r5 summary above says what r5 reproduced and what it verified from saved results.Commands run
At 28b11c1 (the head): CI passed every check, including the full test job. I ran nothing locally at this head, because the host was reserved for other work. It differs from 92acbb4 by a comment-only commit and a merge of
main.At 92acbb4, c1364a4 merged with
main(logs in~/reviews/ni-class-2-4-2058-2026-10-07/logs/,*-92acbb446.log; run under the machine-wide heavy-test lock):ruff format --check .andruff check .: clean.policyengine-core test policyengine_uk/tests/policy -c policyengine_uk(the full YAML suite): 2,747 passed.pytest test_ni_class_2.py test_ni_class_4_statute.py test_ni_class_4_maximum.py test_ni_class_4_properties.py test_ni_class_4_profits_properties.py test_ni_class_1_age_properties.py test_ni_threshold_freeze.py test_uc_minimum_income_floor_properties.py test_parameter_descriptions.py test_parameter_metadata.py test_fiscal_year_parameters.py test_build_metadata.py: 184 passed, 1 skipped. (190 at c1364a4;main's Correct the 2015-16 and 2016-17 secondary threshold; pin the annual threshold to reg 11(3A)(b) in every year #2182 removed six parametrised cases fromtest_ni_threshold_freeze.py.)At c1364a4:
ni_class_2readingni_class_4_profits_before_losses, or profit less capital allowances: both failtest_ni_class_2_tests_thresholds_on_profits_after_deductionsandtest_ni_class_2_properties(mutants-ni_class_2-c1364a42f.log).impact/).At 0278f13 (the s.11(3) fix):
ni_class_2.yamlandtest_ni_class_2.pywith the previousni_class_2formula fail 6 of the 8 new YAML cases and both new pytest tests. Review r4 re-ran this independently; its logs are inreview_r4_artifacts/r4_logs/(mut_*.log).Earlier rounds:
main's Class 4 parameters: 8 failed, 2 passed (2026-10-02; no log was saved).esa_exempt_work_earnings170.19,esa_income_eligiblefalse).make documentation. CI runs both.🤖 Generated with Claude Code