Skip to content

National Insurance: split into Class 1 / 2 / 3 / 4 with employee, employer, self-employed detail #43

@vahid-ahmadi

Description

@vahid-ahmadi

Gap

src/parameters/mod.rs collapses National Insurance into a small NationalInsuranceParams struct with a handful of rates and thresholds, and src/variables/income_tax.rs computes a single aggregate NIC figure.

Python has separate trees for each class:

  • policyengine_uk/variables/gov/hmrc/national_insurance/class_1/ — employee + employer, primary + secondary thresholds, UEL, contracted-out rates
  • policyengine_uk/variables/gov/hmrc/national_insurance/class_2/ — flat self-employed
  • policyengine_uk/variables/gov/hmrc/national_insurance/class_3/ — voluntary contributions
  • policyengine_uk/variables/gov/hmrc/national_insurance/class_4/ — self-employed profit-based
  • Salary-sacrifice NIC interaction variables (employer-side savings)

Why it matters

  • Salary-sacrifice cap analysis (existing notebooks: salary_sacrifice_cap_*.ipynb) — requires Class 1 employee + employer split
  • Self-employment reforms — Class 2 abolition (already enacted in 2024/25), Class 4 rate changes
  • Employer NIC reforms (Reeves Oct-2024 budget secondary-threshold cut) — reeves_budget_2025_analysis*.ipynb already needs this
  • NIC exemption for disabled employees (nics-exemption-disabled-employees) — requires per-employee Class 1 modelling
  • Without class-level granularity, employer-side NIC scoring is impossible (the policy lever is on secondary thresholds, not aggregate NICs).

What to port

  1. Split NationalInsuranceParams into class-specific structs
  2. Per-class compute functions taking the relevant earnings concept (employment income, self-employment profit, etc.)
  3. Employer NIC as a separate output, surfaced to net-income calculations correctly (incidence assumption follows current PE convention)
  4. Parameter tree mirroring the Python directory structure

Effort

Medium. The arithmetic is well-specified by HMRC; the work is mostly fanning out the existing compute_national_insurance into four class functions plus parameter restructuring.

References

  • Python: policyengine_uk/variables/gov/hmrc/national_insurance/
  • Python params: policyengine_uk/parameters/gov/hmrc/national_insurance/
  • Rust: src/variables/income_tax.rs, src/parameters/mod.rs::NationalInsuranceParams

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions