Repository navigation
Give Gift Aid relief by raising the rate limits, not by deducting the donation - #2271
Conversation
Extend UK and eligible Scottish rate limits by gross Gift Aid, remove the net-donation allowance, and adjust ANI once without changing taxable income. Preserve CGT and zero-gift behavior, with policy and property tests plus statutory documentation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
test_gift_aid.py on head |
Review of the Gift Aid fix. The reform's net_income override read the income components only, so a supplied adjusted_net_income no longer set the taxable base: a married couple with supplied ANI of £50,000 and £0 paid no tax instead of £7,486. The override now returns a supplied ANI plus the grossed-up gift, as the baseline net_income does. Also from the review: - a helper test against each scale shape callers pass: a UK extra bracket at a distinct rate, and the three- and six-rate Scottish scales; - 2017-18 Scottish YAML cases on the three-rate scale; - a frozen positive-gift CGT case (unchanged from main); - corrected descriptions of the CGT test oracle and the maintenance loan income measure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Coordination note from #2240 (annual allowance charge, fixes #2237). The two PRs touch the same quantities, so whichever merges second needs a small change. #2240's relief_at_source = min_(personal_pension_contributions, pension_contributions_relief)
rate_limit_extension = gift_aid_grossed_up + relief_at_source
allowances_at_step_3 = max_(0, allowances - gift_aid - relief_at_source)
reduced_net_income = max_(0, adjusted_net_income - allowances_at_step_3)After this PR, allowances_at_step_3 = max_(0, allowances - relief_at_source)
reduced_net_income = max_(0, net_income - allowances_at_step_3)
Regression to keep: #2240's YAML case "Gift Aid raises the rate limits by its grossed-up amount (s. 227(4C))". It is 2025: £60,000 employment, £10,000 personal contributions, £60,000 employer contributions and £1,000 Gift Aid, giving a charge of £3,696. It must still give £3,696 after both PRs. If #2240 merges first, this PR needs the two-line change above. If this PR merges first, I'll make it in #2240. |
|
Status at head
🤖 Generated with Claude Code |
…ncome) Conflicts in the three savings band variables and property_income_tax: keep Gift Aid's raised rate limits (ITA 2007 s. 414(2)(b)) and stack on #2352's non_savings_taxable_income, with property income taxed from non_savings_income_after_allowances. Two readers main added start from adjusted_net_income, which on this branch has the grossed-up gift deducted (s. 58). Both now read net_income: - non_savings_income_after_allowances, the base property income and savings stack on, would otherwise drop by the gift; - savings_allowance's band test now compares net income less allowances with the limits raised by the gift. That gives the same band as main's formula today, but stays right once adjusted net income gains the other s. 58 deductions (#2243). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With #2352, savings and dividends sit above property income (ITA 2007 s. 16). Two YAML cases check that the s. 414(2)(b) extension applies on that order: £40,000 of property income with £20,000 of dividends (dividend tax £4,278.75 against £4,528.75) or £20,000 of savings (savings tax £5,646 against £5,846). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The frozen expectations predated #2352 (savings and dividends above property income) and main's Scottish personal savings allowance on the UK bands, so the mixed-income rows and one allowance changed on main. Regenerated from main 3381500. With no gift, the branch matches main byte for byte on all 21 variables and the tax band. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round-3 review nit. The design note listed two limitations the #2352 merge removed: savings and dividends now stack above property income, and the Personal Savings Allowance tests net income against the UK limits raised by the gift. It now describes that behaviour instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round-4 review nit: property income is taxed on top of non_savings_income_after_allowances less property after allowances, and savings and dividends on top of non_savings_taxable_income. Both derive from net_income; they differ only with Marriage Allowance (#1947). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hand-off to the UK hub (from session
🤖 Generated with Claude Code |
|
UK hub (2026-10-12 11:05Z): this PR's head |
Fixes #2253
Reproducer: policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/gift_aid.yaml::Gift Aid gives no income tax relief to a UK basic-rate earner
What was wrong
allowancesincludedgift_aid, so income tax deducted the net Gift Aid donation from taxable income. The law gives no deduction. Instead it raises the rate limits by the grossed-up gift, and it lowers adjusted net income by the same amount. On main, a basic-rate donor got relief they are not due, and higher and additional-rate donors got the wrong relief.Main
a3752304e, 2026-27, one person aged 40 with employment income and an £800 donation (£1,000 grossed up):Each branch figure was checked by hand. For example, at £150,000: £1,000 moves from 40% to 20% (£200) and £1,000 from 45% to 40% (£50). At £101,000: £200 from the band, plus the £500 of allowance s.58 restores, taxed at 40% (£200).
The law
Change
gift_aidleavesallowances, so it no longer reduces taxable income.calc_income_tax_with_gift_aid(utils/income_tax.py):earned_income_tax,property_income_tax,uc_income_tax_on_earnings. Moving a threshold t to t + G changes the tax by (rate above t − rate below t) × the overlap of income with [t, t + G], summed over the raised thresholds. That is exact for any gift, including one spanning several bands, and leaves the scale itself untouched.adjusted_net_incomedeductsgift_aid_grossed_uponce (s.58). A newnet_incomeholds the income before that step.net_income. These readadjusted_net_incomeas the taxable base or as a general income measure, not as s.58's adjusted net income, so they keep their main behaviour:earned_taxable_income,pension_annual_allowance,property_finance_costs_relieved, the student loan variables, the maintenance loan income variables, and the CPS marriage tax reform's override.adjusted_net_incomealready includes the s.58 step, sonet_income(and the CPS marriage reform's override) returns it plus the grossed-up gift. With no gift that is main's result.adjusted_net_incomeand now see the s.58 deduction. These are the ones s.58 or the provisions they model point to:personal_allowance,CB_HITCandchild_benefit(HICBC), the tax-free childcare and extended childcare income conditions, andis_higher_earner.capital_gains_taxalready extended its basic rate band bygift_aid_grossed_up. It tookgift_aidback out ofallowances, and that add-back is now removed. CGT answers are unchanged.Invariants (tested)
Tests
YAML,
income_tax/gift_aid.yaml: 21 cases. They cover:Existing YAML fixtures that hand-set Gift Aid were corrected.
YAML,
reforms/cps/marriage_tax_reforms.yaml: the marriage-neutral reform with a supplied adjusted net income, with and without a gift.Helper test.
calc_income_tax_with_gift_aidequals the scale recomputed with its limits raised, for three scale shapes: a UK scale whose extra bracket has a distinct rate (so a wrongly raised extra limit would show), and the three-rate and six-rate Scottish scales.Python,
test_gift_aid.py(Hypothesis): the invariants above. A differential test compares an independent earned-income calculation with the raised limits against the model, for rUK and Scotland.Bit-for-bit replay. A harness compared zero-gift outputs with the pre-change revision: 24,192 random scalar comparisons over seven years, 264 frozen comparisons, and 640 positive-gift CGT comparisons all matched.
Mutation.
Local runs on head
9d104544(maincfa0c556merged in):income_tax231 passed,reforms/cps9, UC income 153.64dff7b2:capital_gains_tax48,dfe218.test_gift_aid.py12 passed.child_benefit24,student_loans28,tax_free_childcare116 andpensions25 passed;test_uc_earnings_deductions_properties.pyplustest_capital_gains_tax_components.py44 passed, 1 skipped.Impact
None on the local enhanced FRS 2023-24 file for 2026: income tax is £349.67bn and CGT £21.24bn on main and on this branch. That file carries no Gift Aid: its person table has no
gift_aidcolumn, andgift_aidsums to £0. The change matters for household calculations with Gift Aid, and for any dataset that stores it. The uk-data pipeline has code to imputegift_aidfor SPI-synthetic records, but this build holds none.Merged with #2352 (savings and dividends above property income)
Main's #2352 conflicted with this PR in the three savings band variables and in
property_income_tax. The resolution:non_savings_taxable_income;non_savings_income_after_allowances.Two places main added read
adjusted_net_income, which here already has the grossed-up gift deducted (s.58), so both now readnet_income:non_savings_income_after_allowanceswould otherwise lower the stacking base by the gift.savings_allowancenow compares net income less allowances with the limits raised by the gift (s.12B with s.414(2)(b)). That gives the same band as main's formula today, and stays right once adjusted net income gains the other s.58 deductions (Pension contributions do not reduce adjusted net income (ITA 2007 s. 58), so the personal allowance taper and HICBC ignore them #2243).New YAML cases check the raised limits on the property-first order. With £40,000 of property income and an £800 gift:
The zero-gift snapshot test was re-frozen from main
3381500f4. With no gift, the branch matches main byte for byte on all 21 tested variables and the tax band.Impact, re-run at head
3bf52c5cagainst main3381500f4on the local enhanced FRS 2023-24 file for 2026: no record differs in income tax (£349.65bn), CGT (£21.24bn) or household net income. The file holds no Gift Aid. The household reproducer above is unchanged.Interaction with #2240
#2240 (not merged) adds Gift Aid back in its annual allowance charge, because main deducted it from income. After this PR, #2240 should:
- gift_aidfromallowances_at_step_3, keeping its relief-at-source subtraction;reduced_net_incomefromnet_income;rate_limit_extension = gift_aid_grossed_up + relief_at_source;I'll note this on #2240.
Not in this PR
These are existing departures from the statute, left as they are so that zero-gift outputs do not change:
axiom: ukpga/2007/3/414 TheAxiomFoundation/rulespec-uk#445 queued (rulespec-uk has no s.414 or s.415 module,
10.yaml's limits are never raised, and58.yamlis deferred; the issue carries the verbatim law, a pasteablereview_finding, required outputs and eight companion cases from this PR's YAML)🤖 Generated with Claude Code