Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a89d9e1
Relieve pension contributions to relevant earnings and charge the exc…
MaxGhenis Oct 10, 2026
1bb293c
Raise the rate limits for relief at source and Gift Aid in the charge
MaxGhenis Oct 10, 2026
c922b58
Allow float32 rounding in the charge bounds
MaxGhenis Oct 10, 2026
896d8a3
Merge remote-tracking branch 'origin/main' into fix-pension-relief-an…
MaxGhenis Oct 11, 2026
bb0d6bf
Merge remote-tracking branch 'origin/main' into fix-pension-relief-an…
MaxGhenis Oct 11, 2026
ce1bf17
Merge remote-tracking branch 'origin/main' into fix-pension-relief-an…
MaxGhenis Oct 11, 2026
4da35fc
Merge current main into pension relief fix
MaxGhenis Oct 16, 2026
dfbba87
Reconcile pension annual allowance charge with Gift Aid
MaxGhenis Oct 16, 2026
cc355ce
Condition pension charge RAS limits on ordinary tax liability
MaxGhenis Oct 16, 2026
15acaae
Cover conditional RAS extension and isolate Scottish threshold depend…
MaxGhenis Oct 16, 2026
efe429f
Merge current main including Scottish top-rate threshold fix
MaxGhenis Oct 16, 2026
183e64b
Apply named-rate RAS gate and strengthen pension charge regressions
MaxGhenis Oct 16, 2026
2154a31
Isolate historic RAS gate control with statutory personal allowance
MaxGhenis Oct 16, 2026
93a21a3
test: reproduce missing pension relief in adjusted net income
MaxGhenis Oct 16, 2026
1dbc881
fix: include relieved pension contributions in adjusted net income
MaxGhenis Oct 16, 2026
9a9a917
Merge reviewed pension relief and annual allowance fix (#2240)
MaxGhenis Oct 16, 2026
ded019a
docs: correct pension relief test explanations
MaxGhenis Oct 16, 2026
c2f3fd5
fix: preserve pension relief when supplied ANI is inverted
MaxGhenis Oct 16, 2026
e4e6323
test: bound pension contributions by restored personal allowance
MaxGhenis Oct 16, 2026
7f1b608
Use pre-pension income in trading-loss reference
MaxGhenis Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/2237.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Limited pension contributions relief by relevant UK earnings (or the £3,600 basic amount through relief at source) instead of the annual allowance. Calculated the annual allowance charge across UK or Scottish tax bands with unused allowance carried forward, applying the statutory named-rate ordinary-income condition to the RAS band extension and preserving Gift Aid's separate gross band extension. Separate savings and UK property rates do not establish RAS eligibility.
1 change: 1 addition & 0 deletions changelog.d/2243.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Deducted relieved pension contributions from adjusted net income so that the Personal Allowance taper and High Income Child Benefit Charge reflect pension relief, while retaining a single deduction from the income tax base and restoring pension relief consistently for supplied ANI in the marriage-neutral reform.
101 changes: 86 additions & 15 deletions docs/engineering/gift-aid.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,49 @@ corrected tax at its top gives the tax on that slice. This preserves the
original scale calculation when the gift is zero and handles gifts that cross
several thresholds.

`net_income` holds the income base previously exposed as `adjusted_net_income`.
Taxable-income calculations and allowance allocation use this base.
When adjusted net income is supplied explicitly, its gross Gift Aid adjustment
is added back to obtain the taxable-income base. This preserves direct income
inputs when the gift is zero without recovering ordinary taxable income from a
rounded adjusted-net-income calculation. The marriage-neutral income-tax
reform splits `net_income` before each person's Gift Aid adjustment.
`adjusted_net_income` deducts the gross gift once, as [s. 58(1), Step
2](https://www.legislation.gov.uk/ukpga/2007/3/section/58) requires. The Personal
Allowance taper and High Income Child Benefit Charge therefore see the lower
adjusted net income. The Personal Allowance formula does not deduct Gift Aid a
second time. Capital gains tax uses `net_income`, retains its gross Gift Aid
band extension, and no longer removes the net gift from `allowances`.
`net_income` holds the model's income base before pension relief, personal
allowances and Gift Aid adjustments. Taxable-income calculations and allowance
allocation use this base. When adjusted net income is supplied explicitly,
gross Gift Aid and relieved pension contributions are added back to recover
that base. Ordinary cases calculate it directly to avoid recovering income
from rounded adjusted net income. The marriage-neutral income-tax reform
splits `net_income` before each person's adjustments.

`adjusted_net_income` deducts the gross gift and relieved pension contributions
once, as [ITA 2007 s. 58](https://www.legislation.gov.uk/ukpga/2007/3/section/58)
requires. Statutory net income already excludes net-pay contributions under
[FA 2004 s. 193](https://www.legislation.gov.uk/ukpga/2004/12/section/193) and
relief on claim under [s. 194(1)](https://www.legislation.gov.uk/ukpga/2004/12/section/194);
s. 58 then deducts gross relief-at-source contributions under
[s. 192(1)](https://www.legislation.gov.uk/ukpga/2004/12/section/192).
The model represents employment income gross of employee and personal pension
contributions and deducts their aggregate relief through `allowances`.
Consequently, its ANI calculation deducts that relieved aggregate too. Pension
inputs follow the existing gross contribution convention; do not gross them
up again. The Personal Allowance taper and High Income Child Benefit Charge
see the resulting ANI without making a second adjustment.

Pension relief remains in `allowances`, and the rate-band bases continue to
read `net_income`, so it reduces the ordinary income tax base once. Property,
savings and dividend income retain that same allocation. Capital gains tax
removes relieved personal pension contributions from its deducted allowances
and instead extends its basic-rate band by that amount plus gross Gift Aid.
The annual allowance taper continues to use its separate income base; its
statutory adjusted-income definition is distinct from s. 58 ANI. Contribution
relief follows the earnings/basic-amount limit. Pension input above the annual
allowance attracts the separate annual allowance charge.

Both the baseline and marriage-neutral reform reconstruct `net_income` from
supplied ANI by restoring gross Gift Aid and relieved pension contributions
through the same helper. Supplying the ANI derived by the model therefore
preserves the pre-allowance base, including when an annual allowance is
explicitly supplied. That allowance determines the separate charge rather
than contribution relief.

For example, £150,000 employment income and £60,000 gross personal pension
contributions in London in 2024 give ANI of £90,000 and the full £12,570
Personal Allowance. The ordinary taxable base is £77,430, giving £23,432
income tax (£37,700 at 20% and £39,730 at 40%).

Savings and dividends stack above all non-savings income, property income
included ([ITA 2007 s. 16](https://www.legislation.gov.uk/ukpga/2007/3/section/16);
Expand All @@ -64,8 +94,8 @@ including s. 12B(8) for Scottish taxpayers, with s. 414(2)(b)).

Several limitations remain relevant when interpreting mixed-income results:

- Adjusted net income still omits other adjustments in s. 58, including the
deduction for pension contributions relieved at source in Step 3.
- Adjusted net income does not implement the s. 58 Step 4 add-back of relief
for trade union or police organisation payments.
- Gifts are assumed to qualify. The model does not charge the donor for a
shortfall in income tax and capital gains tax covering the tax attributed to
gifts under [ss. 423–424](https://www.legislation.gov.uk/ukpga/2007/3/section/424).
Expand All @@ -85,3 +115,44 @@ additional relief. Changing tax band can also increase the Personal Savings
Allowance discretely under s. 12B, so its relief cannot be bounded by a constant
times a very small gift. Tests of the continuous band-extension bound must
allow for that allowance change or hold the zero-rate allowance fixed.

## Pension annual allowance charge

The annual allowance charge uses reduced net income after ITA 2007 s. 23
Step 3 ([FA 2004 s. 227(4B)](https://www.legislation.gov.uk/ukpga/2004/12/section/227)).
It starts from `net_income`, before the s. 58 gross Gift Aid deduction, and
subtracts `allowances` after removing relieved relief-at-source pension
contributions. Gift Aid is already excluded from those allowances. The charge
then stacks the excess pension input amount on this base. Gross Gift Aid
extends the rate limits under s. 227(4C), independently of pension relief.
This keeps the Gift Aid adjustment to adjusted net income separate from the
amount charged to tax.

The pension extension is conditional. [FA 2004 s. 192(4)/(4A)](https://www.legislation.gov.uk/ukpga/2004/12/section/192)
requires ordinary income, apart from relief under that section, to attract
higher/additional-rate tax, or a Scottish rate above basic. The charge uses
only limits increased under s. 192; s. 227(5) excludes the pension excess from
income, so that excess cannot satisfy the condition. The model tests ordinary
liability before RAS relief, retaining Gift Aid's extension and the existing
allowance allocation. Scottish liability uses non-savings income, including
property income. The UK condition names the higher and additional rates:
separate dividend rates, savings rates from 2017-18 and property rates from
2027-28 do not satisfy it. [FA 2016 s. 6](https://www.legislation.gov.uk/ukpga/2016/24/section/6/enacted)
introduced savings rates and expressly added them to some other higher-rate
tests, without expanding s. 192(4). [FA 2026 s. 6](https://www.legislation.gov.uk/ukpga/2026/11/section/6/enacted)
and [Schedule 1](https://www.legislation.gov.uk/ukpga/2026/11/schedule/1/enacted)
introduce property rates without expanding s. 192 either. Before those
changes, income charged at ordinary higher/additional rates can qualify.
Scottish property remains subject to Scottish rates under ITA 2007
s. 11CA(4), so it can still meet s. 192(4A).

[HMRC PTM056120](https://www.gov.uk/hmrc-internal-manuals/pensions-tax-manual/ptm056120)
describes the RAS extension for the annual allowance charge without stating
this condition. Its examples do not resolve low-income contributors whose
pension excess crosses a band. The model follows the statutory condition;
the [2018/459 explanatory memorandum, paragraph 7.4](https://www.legislation.gov.uk/uksi/2018/459/pdfs/uksiem_20180459_en.pdf)
also describes an above-basic Scottish liability requirement. Assessment
practice under the broader manual description remains a methodology question.
The charge can exceed relief on the contribution when ordinary income fails
the condition, so contribution and Gift Aid tax-monotonicity comparisons must
hold eligibility for the RAS extension fixed.
12 changes: 6 additions & 6 deletions policyengine_uk/reforms/cps/marriage_tax_reforms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from policyengine_uk.model_api import *
from policyengine_uk.utils.income_tax import net_income_from_adjusted_net_income
from policyengine_uk.utils.supplied_inputs import supplied_input
from typing import Union, Optional

Expand Down Expand Up @@ -157,20 +158,19 @@ def formula(person, period, parameters):
class net_income(Variable):
label = "Optimised net income"
documentation = (
"Income before Gift Aid adjustments, split equally between married partners"
"Income before pension relief and Gift Aid adjustments, split equally "
"between married partners"
)
entity = Person
definition_period = YEAR
value_type = float

def formula(person, period, parameters):
# A supplied adjusted net income already includes the s.58 Gift
# Aid step, and it took precedence over this reform's split before
# the reform moved to net_income. Keep that: restore the gift for
# the taxable base, as the baseline net_income does.
# Supplied ANI takes precedence over this reform's split. Restore
# gross Gift Aid and relieved pensions, as the baseline inverse does.
supplied_ani = supplied_input(person, "adjusted_net_income", period)
if supplied_ani is not None:
return supplied_ani + person("gift_aid_grossed_up", period)
return net_income_from_adjusted_net_income(person, period, supplied_ani)
income = person("unadjusted_net_income", period)
# Split between the spouses or civil partners only, never their
# children.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# MOCK cases: gross relieved contributions reduce ANI without becoming a
# second deduction from the rate-band base (ITA 2007 s.58).

- name: RAS contributions restore the full Personal Allowance
period: 2024
absolute_error_margin: 0.01
input:
people:
taxpayer:
age: 45
employment_income: 150_000
personal_pension_contributions: 60_000
households:
household:
members: [taxpayer]
region: LONDON
output:
net_income: 150_000
adjusted_net_income: 90_000
personal_allowance: 12_570
allowances: 72_570
received_allowances_earned_income: 72_570
earned_taxable_income: 77_430
pension_annual_allowance: 60_000
personal_pension_contributions_tax: 0
income_tax: 23_432

- name: Pension and Gift Aid adjustments both restore the allowance without double deduction
period: 2024
absolute_error_margin: 0.01
input:
age: 45
employment_income: 150_000
personal_pension_contributions: 30_000
gift_aid: 16_000
output:
net_income: 150_000
gift_aid_grossed_up: 20_000
adjusted_net_income: 100_000
personal_allowance: 12_570
earned_taxable_income: 107_430
# £57,700 at 20% and £49,730 at 40%.
income_tax: 31_432

- name: Supplied ANI restores pension relief to the taxable base
period: 2024
absolute_error_margin: 0.01
input:
age: 45
employment_income: 70_000
personal_pension_contributions: 10_000
adjusted_net_income: 60_000
output:
net_income: 70_000
personal_allowance: 12_570
earned_taxable_income: 47_430
income_tax: 11_432

- name: Personal and employee contributions represented gross both reduce ANI once
period: 2024
absolute_error_margin: 0.01
input:
age: 45
employment_income: 130_000
personal_pension_contributions: 20_000
employee_pension_contributions: 10_000
output:
net_income: 130_000
pension_contributions_relief: 30_000
adjusted_net_income: 100_000
personal_allowance: 12_570
allowances: 42_570
earned_taxable_income: 87_430
income_tax: 27_432

- name: Pension relief applies once when property income fills the higher-rate band
period: 2024
absolute_error_margin: 0.01
input:
age: 45
employment_income: 110_000
taxable_property_income: 10_000
personal_pension_contributions: 20_000
output:
net_income: 120_000
adjusted_net_income: 100_000
personal_allowance: 12_570
received_allowances_earned_income: 32_570
non_savings_income_after_allowances: 87_430
taxable_property_income_after_allowances: 10_000
property_income_tax: 4_000
income_tax: 27_432

- name: Allocation to earned savings and dividend income uses the unchanged taxable base
period: 2024
absolute_error_margin: 0.01
input:
age: 45
employment_income: 10_000
savings_interest_income: 15_000
dividend_income: 110_000
personal_pension_contributions: 10_000
output:
net_income: 135_000
adjusted_net_income: 125_000
personal_allowance: 70
allowances: 10_070
received_allowances_earned_income: 10_000
received_allowances_savings_income: 70
received_allowances_dividend_income: 0

- name: Restored Personal Allowance and RAS extension each enter CGT bands once
period: 2025
absolute_error_margin: 0.01
input:
age: 45
employment_income: 110_000
personal_pension_contributions: 60_000
capital_gains: 30_000
output:
adjusted_net_income: 50_000
personal_allowance: 12_570
# Taxable income £97,430; extended basic-rate limit £97,700 leaves
# £270 at 18%, with £26,730 at 24%, after the £3,000 AEA.
capital_gains_tax: 6_463.80

- name: ANI pension deduction does not feed back into annual allowance taper or charge
period: 2024
absolute_error_margin: 0.01
input:
age: 45
employment_income: 340_000
personal_pension_contributions: 10_000
employer_pension_contributions: 30_000
output:
net_income: 340_000
adjusted_net_income: 330_000
pension_annual_allowance: 20_000
# £40,000 contributions less £20,000 AA, charged at 45%.
personal_pension_contributions_tax: 9_000
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,5 @@
pension_contributions_via_salary_sacrifice: 0
output:
# Total: 10_000 + 5_000 + 50_000 = 65_000
# This exceeds the 2024 AA of 40_000 (verified separately by AA tax charge test)
# This exceeds the 2024 AA of 60_000 (verified separately by AA tax charge test)
pension_contributions_for_annual_allowance: 65_000
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@
personal_pension_contributions: 40000
output:
pension_contributions_relief: 40000
- name: Pension relief excessive
- name: Pension relief is not capped at the (tapered) annual allowance
period: 2020
absolute_error_margin: 0
absolute_error_margin: 0.01
input:
employment_income: 2000000
personal_pension_contributions: 400000
output:
pension_contributions_relief: 4000
# FA 2004 s. 190: relief up to relevant UK earnings, so all 400,000 is
# relieved even though the tapered annual allowance is 4,000.
pension_contributions_relief: 400000
# The annual allowance charge recovers the relief on the excess:
# (400,000 - 4,000) at 45% on top of reduced net income of 2,000,000:
# the charge adds relieved RAS back to income after allowances.
pension_annual_allowance_chargeable_amount: 396000
personal_pension_contributions_tax: 396000 * 0.45
- name: £30k self-employment income, no private pension contributions
period: 2023
absolute_error_margin: 0.01
Expand Down Expand Up @@ -49,3 +56,64 @@
output:
pension_contributions_relief: 6_000
income_tax: 11432 - 6000 * 0.4

- name: Relief on the basic amount when relevant earnings are lower (s. 190(2))
period: 2024
absolute_error_margin: 0.01
input:
employment_income: 2_000
personal_pension_contributions: 5_000
output:
pension_contributions_relief: 3_600

- name: A net pay arrangement cannot give the basic-amount increase (s. 191(7))
period: 2024
absolute_error_margin: 0.01
input:
employment_income: 2_000
employee_pension_contributions_reported: 3_000
output:
pension_contributions_relief: 2_000

- name: Only relief at source fills the basic-amount increase (s. 191(7))
period: 2024
absolute_error_margin: 0.01
input:
employment_income: 2_000
employee_pension_contributions_reported: 1_500
personal_pension_contributions: 1_000
output:
# 2_000 is relieved within earnings, plus 500 through the RAS-only
# basic-amount increase. Of the 1_000 of relief at source, 500 remains
# after using earnings: 2_000 + 500.
pension_contributions_relief: 2_500

- name: Relief up to relevant earnings, not beyond (s. 190(1))
period: 2024
absolute_error_margin: 0.01
input:
employment_income: 40_000
self_employment_income: 10_000
personal_pension_contributions: 70_000
output:
pension_contributions_relief: 50_000

- name: A trading loss does not reduce relevant earnings from employment
period: 2024
absolute_error_margin: 0.01
input:
employment_income: 40_000
self_employment_income: -10_000
personal_pension_contributions: 45_000
output:
pension_contributions_relief: 40_000

- name: No relief on contributions paid at 75 or over (s. 188(3)(a))
period: 2024
absolute_error_margin: 0.01
input:
age: 75
employment_income: 40_000
personal_pension_contributions: 10_000
output:
pension_contributions_relief: 0
Loading
Loading