Gap
Python:
policyengine_uk/variables/gov/hmrc/capital_gains_tax/ — CGT bands, residential vs non-residential rates, annual exempt amount, behavioural elasticity to rate changes (realisation response)
policyengine_uk/variables/gov/hmrc/pensions/ — annual allowance, tapered annual allowance, lifetime allowance (legacy), pension input amounts, salary-sacrifice-adjusted pensionable earnings, relief-at-source vs net-pay
Rust src/variables/wealth_taxes.rs has 4 functions and no CGT or pensions-tax logic.
Why it matters
- Salary-sacrifice cap reform (existing notebooks:
salary_sacrifice_cap_*.ipynb, including a published comparison vs OBR) — requires the pension-relief stack to model what 'capping at £2k/£10k' actually means for taxable income and NICs
- CGT rate increases were a major Oct-2024 budget topic — the user's
tax_reform_* and reeves_budget_2025_* notebooks need this; without behavioural elasticities, scores will be too high
- Pensions tax changes (annual-allowance taper, removal of LSA) cannot be modelled
What to port
- CGT taxable gains, AEA, residential surcharge, basic-rate / higher-rate splits
- CGT behavioural elasticity (realisation response to rate changes — Python uses a configurable elasticity parameter)
- Pension input amount, employer + employee contributions, salary-sacrifice treatment
- Annual allowance + tapered annual allowance + carry-forward (or document any simplifications)
- Pension tax relief (relief at source vs net pay) and how it lands in income tax
Effort
Medium. The CGT calculation itself is small; behavioural-response infrastructure overlaps with the dynamics issue. Pensions are more complex due to the relief-mode interactions.
References
- Python:
policyengine_uk/variables/gov/hmrc/capital_gains_tax/, policyengine_uk/variables/gov/hmrc/pensions/
- Python params:
policyengine_uk/parameters/gov/hmrc/capital_gains_tax/, parameters/gov/hmrc/pensions/
- Rust:
src/variables/wealth_taxes.rs
Gap
Python:
policyengine_uk/variables/gov/hmrc/capital_gains_tax/— CGT bands, residential vs non-residential rates, annual exempt amount, behavioural elasticity to rate changes (realisation response)policyengine_uk/variables/gov/hmrc/pensions/— annual allowance, tapered annual allowance, lifetime allowance (legacy), pension input amounts, salary-sacrifice-adjusted pensionable earnings, relief-at-source vs net-payRust
src/variables/wealth_taxes.rshas 4 functions and no CGT or pensions-tax logic.Why it matters
salary_sacrifice_cap_*.ipynb, including a published comparison vs OBR) — requires the pension-relief stack to model what 'capping at £2k/£10k' actually means for taxable income and NICstax_reform_*andreeves_budget_2025_*notebooks need this; without behavioural elasticities, scores will be too highWhat to port
Effort
Medium. The CGT calculation itself is small; behavioural-response infrastructure overlaps with the dynamics issue. Pensions are more complex due to the relief-mode interactions.
References
policyengine_uk/variables/gov/hmrc/capital_gains_tax/,policyengine_uk/variables/gov/hmrc/pensions/policyengine_uk/parameters/gov/hmrc/capital_gains_tax/,parameters/gov/hmrc/pensions/src/variables/wealth_taxes.rs