From adac4407925c860e23ac5ae21174052a7f4ee8a9 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 10:06:40 -0500 Subject: [PATCH 1/2] Count Carer Support Payment after the overlap cut in Scottish CTR Scottish Council Tax Reduction income counted carer_support_payment_pre_overlap, so a carer whose State Pension or contributory ESA reduces Carer Support Payment to nil under SSI 2023/302 reg 16(2) still had 86.45 a week counted. SSI 2021/249 reg 57(1)(b) counts the CSP the carer is entitled to be given, and Social Security Scotland's guidance reduces CTR by the CSP received; the pension-age SSI 2012/319 reg 27(3) text leaves both readings open, so the agency's reading applies at both ages. Fixes #2820 Co-Authored-By: Claude Opus 5.5 --- changelog.d/2820.fixed.md | 1 + ...l_tax_reduction_carer_support_payment.yaml | 69 +++++++++---------- ...l_tax_reduction_carer_income_properties.py | 69 +++++++++++-------- ...council_tax_reduction_applicable_income.py | 22 +++--- 4 files changed, 89 insertions(+), 72 deletions(-) create mode 100644 changelog.d/2820.fixed.md diff --git a/changelog.d/2820.fixed.md b/changelog.d/2820.fixed.md new file mode 100644 index 0000000000..6d3b42f6bf --- /dev/null +++ b/changelog.d/2820.fixed.md @@ -0,0 +1 @@ +Scottish Council Tax Reduction counts Carer Support Payment after the overlapping-benefit reduction, so a carer whose State Pension or contributory ESA reduces it to nil has none counted. diff --git a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml index f18404306e..d31d26ceed 100644 --- a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml @@ -147,19 +147,15 @@ # 2,000 - 0.2 x (7,000 - 4,968.60) council_tax_reduction: 2_000 - 0.2 * (7_000 - 95.55 * 52) -- name: A working-age carer on contributory ESA above the Carer Support Payment rate has it counted in Council Tax Reduction +- name: A working-age carer whose contributory ESA reduces Carer Support Payment to nil has none counted in Council Tax Reduction # Contributory ESA (96.15 a week here) is an overlapping benefit, so CSP - # Regs (SSI 2023/302) reg 16(2)(b) reduces the CSP given to nil. Until it is - # decided which amount CTR counts, CTR counts the 86.45 x 52 before the - # reduction (carer_support_payment_pre_overlap). - # SSI 2021/249 reg 57(1)(b) counts CSP "to which the applicant is entitled, - # subject to any adjustment ... in accordance with Regulations under - # section 73 of the Social Security Administration Act 1992"; reg 16(2) is - # made under the Social Security (Scotland) Act 2018, not section 73. - # Whoever settles which amount CTR counts must update this case; it fails - # if CTR income silently drops the CSP. Taxable income, - # 5,000 + 4,495.40 + 608.40 = 10,103.80, is below the personal allowance - # either way. + # Regs (SSI 2023/302) reg 16(2)(b) reduces the CSP given to nil. SSI + # 2021/249 reg 57(1)(b) counts the CSP the applicant is entitled to be + # given, which is nil; counting the 86.45 x 52 before the reduction would + # count the ESA that replaces it twice. The carer premium still applies: + # Sch 1 para 6(1)(b) covers a carer who would be in receipt of CSP but for + # reg 16. The case fails if CTR income counts CSP before the reduction. + # Taxable income, 5,000, is below the personal allowance. period: 2026 absolute_error_margin: 0.01 input: @@ -184,12 +180,14 @@ carer_support_payment: 0 carer_support_payment_pre_overlap: 86.45 * 52 income_tax: 0 - # 5,000 + 4,495.40. Leaving the CSP out would give 5,000, below the - # applicable amount, and a full award of 2,000. - council_tax_reduction_applicable_income: 5_000 + 86.45 * 52 + # The ESA alone. Counting the CSP before the reduction would give + # 5,000 + 4,495.40 = 9,495.40 and an award of + # 2,000 - 0.2 x (9,495.40 - 7,472.40) = 1,595.40. + council_tax_reduction_applicable_income: 5_000 council_tax_reduction_applicable_amount: (95.55 + 48.15) * 52 - # 2,000 - 0.2 x (9,495.40 - 7,472.40) - council_tax_reduction: 1_595.40 + # Income is below the applicable amount of 7,472.40, so the award is the + # whole bill. + council_tax_reduction: 2_000 - name: Carer Support Payment counts in 2025, before the Scottish Carer Supplement period: 2025 @@ -322,21 +320,20 @@ # 2,000 - 0.2 x (22,995.40 - 22,438.00) council_tax_reduction: 1_888.52 -- name: A pension-age carer whose State Pension exceeds the Carer Support Payment rate has it counted in Council Tax Reduction +- name: A pension-age carer whose State Pension reduces Carer Support Payment to nil has none counted in Council Tax Reduction # The partner's State Pension (142.31 a week) exceeds the CSP rate, so CSP # Regs (SSI 2023/302) reg 16(2)(b) reduces the CSP given to them to nil, - # and with it the supplement. Whether pension-age CTR should count CSP - # before or after that reduction is open: SSI 2012/319 reg 27(3) counts a - # benefit before any deduction other than the reg 27(5) adjustments, and - # reg 27(5) lists the Overlapping Benefits Regulations 1979 but not reg - # 16(2). Until it is decided CTR counts the 86.45 x 52 before the - # reduction (carer_support_payment_pre_overlap). Whoever settles it must - # update this case; it fails if CTR income silently drops the CSP. The - # couple is unmarried, so no marriage allowance links the claimant's tax to - # the partner's income. The partner's taxable income is 7,400, below the - # personal allowance, and would stay below it (7,400 + 4,495.40 + 608.40 = - # 12,503.80) if the CSP were paid, so the tax does not depend on the - # choice. Guarantee Credit is nil either way. + # and with it the supplement. SSI 2012/319 reg 27(3) counts a benefit + # before any deduction other than the reg 27(5) adjustments, and reg 27(5) + # lists the Overlapping Benefits Regulations 1979 but not reg 16(2), so the + # text could be read as counting the 86.45 x 52 before the reduction. + # Social Security Scotland's guidance reduces CTR by the CSP received, and + # that reading would count both the State Pension and the CSP it replaces, + # so CTR counts the CSP after the reduction: nil. The case fails if CTR + # income counts CSP before the reduction. The couple is unmarried, so no + # marriage allowance links the claimant's tax to the partner's income. The + # partner's taxable income is 7,400, below the personal allowance. + # Guarantee Credit is nil. period: 2026 absolute_error_margin: 0.01 input: @@ -369,12 +366,14 @@ # Income is above the minimum guarantee of (363.25 + 48.15) x 52 = # 21,392.80 with or without the CSP: 15,000 + 7,400 - 461.70 = 21,938.30. guarantee_credit: 0 - # 15,000 + 7,400 + 86.45 x 52 - 461.70. Leaving the CSP out would give - # 21,938.30, below the applicable amount, and a full award of 2,000. - council_tax_reduction_applicable_income: 15_000 + 7_400 + 86.45 * 52 - 461.70 + # 15,000 + 7,400 - 461.70 = 21,938.30. Counting the CSP before the + # reduction would give 26,433.70 and an award of + # 2,000 - 0.2 x (26,433.70 - 22,438.00) = 1,200.86. + council_tax_reduction_applicable_income: 15_000 + 7_400 - 461.70 council_tax_reduction_applicable_amount: (383.35 + 48.15) * 52 - # 2,000 - 0.2 x (26,433.70 - 22,438.00) - council_tax_reduction: 1_200.86 + # Income is below the applicable amount of 22,438.00, so the award is the + # whole bill. + council_tax_reduction: 2_000 - name: A pension-age couple below the applicable amount keeps full Council Tax Reduction period: 2026 diff --git a/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py b/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py index 031f5b855e..a8710af0f9 100644 --- a/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py +++ b/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py @@ -30,12 +30,14 @@ 1. Counts the component: claiming Carer Support Payment raises Council Tax Reduction income, before income tax and National Insurance and apart from - the other benefits it counts, by exactly the Carer Support Payment - component (86.45 a week), not by the component plus the supplement, and - by that amount before any overlapping-benefit reduction (see below). The - reduction itself never rises, and where both awards are partial it falls - by 20% of the rise in income less the rise in the applicable amount (the - carer premium comes with the claim). + the other benefits it counts, by exactly the Carer Support Payment paid + after any overlapping-benefit reduction (86.45 a week where nothing + overlaps; see below), not by the component plus the supplement. The + claim also brings the carer premium, even where an overlapping benefit + reduces the payment to nil. The reduction moves against the rise in + income less the rise in the applicable amount: it never rises where that + difference is positive, never falls where it is negative, and where both + awards are partial it falls by 20% of it. 2. Invariant to the supplement: setting the Scottish Carer Supplement to zero leaves Carer Support Payment and the other benefits counted in Council Tax Reduction income (Child Benefit, the income-related benefits, @@ -46,11 +48,10 @@ 3. Differential: Council Tax Reduction and Housing Benefit assess the same carer income. Where Guarantee Credit does not passport Housing Benefit, Housing Benefit applicable income, before its disregard, childcare element - and tariff income, equals Council Tax Reduction income less the part of - Carer Support Payment that an overlapping benefit removes, which Housing - Benefit counts after the reduction (HB (SPC) Regs reg 29(4)(g)). This holds in - Scotland, where the carer's benefit is Carer Support Payment, and in - England and Wales, where it is Carer's Allowance. + and tariff income, equals Council Tax Reduction income. Both count Carer + Support Payment after any overlapping-benefit reduction (HB (SPC) Regs + reg 29(4)(g)). This holds in Scotland, where the carer's benefit is Carer + Support Payment, and in England and Wales, where it is Carer's Allowance. Invariants 1 to 3 concern Council Tax Reduction income under the general rules. A pension-age family in receipt of a guarantee credit has its whole income @@ -66,10 +67,9 @@ benefit the model pays. The model reduces Carer Support Payment by overlapping benefits such as State Pension (the Carer's Assistance (Carer Support Payment) (Scotland) Regulations 2023 reg 16(2)), and the supplement -with it. Whether Council Tax Reduction counts the payment before or after -that reduction is unsettled; until it is decided the model counts -carer_support_payment_pre_overlap. It applies the Housing Benefit applicable -amounts to every nation's Council Tax Reduction. +with it. Council Tax Reduction counts the payment after that reduction, as +Social Security Scotland's guidance does. It applies the Housing Benefit +applicable amounts to every nation's Council Tax Reduction. """ import numpy as np @@ -148,6 +148,18 @@ council_tax=2_000.0, ) +# A Scottish pensioner carer whose State Pension (173.08 a week) reduces Carer +# Support Payment to nil: the claim brings only the carer premium, so on the +# general rules it raises the reduction. +OVERLAP_CARER = dict( + pension_age=True, + adults=[dict(age=75, state_pension=9_000.0)], + carer=0, + by_hours=True, + country="SCOTLAND", + council_tax=2_000.0, +) + def money(high): return st.floats(0, high, allow_nan=False, allow_infinity=False) @@ -268,6 +280,7 @@ def partial(g, i): @PROPERTY_SETTINGS @given(st.lists(family(), min_size=1, max_size=3)) @example([SAVINGS_CREDIT_CARER]) +@example([OVERLAP_CARER]) def test_council_tax_reduction_income_counts_the_carer_support_payment_component( families, ): @@ -295,19 +308,23 @@ def test_council_tax_reduction_income_counts_the_carer_support_payment_component # rules with positive income, so the comparison is never empty. assert compared.any(), fam rise = g["income_before_tax"][i, :, 0] - g["income_before_tax"][i, :, 1] - assert np.allclose(rise[compared], CARER_SUPPORT_PAYMENT, atol=0.05), ( + csp_paid = g["carer_support_payment"][i, :, 0] + assert np.allclose(rise[compared], csp_paid[compared], atol=0.05), ( fam, rise[compared], + csp_paid[compared], ) - # Claiming never raises the reduction: on the general rules income - # rises by more than the carer premium the claim brings. - assert np.all((award[i, :, 0] <= award[i, :, 1] + 0.01)[general]), fam - both_partial = partial(g, i)[:, 0] & partial(g, i)[:, 1] & general amount = g["council_tax_reduction_applicable_amount"][i] excess_rise = (income[i, :, 0] - amount[:, 0]) - ( income[i, :, 1] - amount[:, 1] ) fall = award[i, :, 1] - award[i, :, 0] + # The award moves against the excess of income over the applicable + # amount. Where an overlapping benefit cuts the payment below the + # carer premium, claiming raises the reduction. + assert np.all((fall >= -0.01)[general & (excess_rise > 0)]), fam + assert np.all((fall <= 0.01)[general & (excess_rise < 0)]), fam + both_partial = partial(g, i)[:, 0] & partial(g, i)[:, 1] & general assert np.allclose( fall[both_partial], WITHDRAWAL_RATE * excess_rise[both_partial], @@ -369,6 +386,7 @@ def test_council_tax_reduction_income_ignores_the_scottish_carer_supplement( @PROPERTY_SETTINGS @given(st.lists(family(countries=tuple(REGIONS)), min_size=1, max_size=3)) +@example([OVERLAP_CARER]) def test_council_tax_reduction_and_housing_benefit_assess_the_same_carer_income( families, ): @@ -379,12 +397,6 @@ def test_council_tax_reduction_and_housing_benefit_assess_the_same_carer_income( + g["carer_support_payment_pre_overlap"][i] ) assert np.all(carer_benefit[:, 0] > 0), fam - # Housing Benefit counts Carer Support Payment after any - # overlapping-benefit reduction; Council Tax Reduction, for now, - # before it. - removed_by_overlap = ( - g["carer_support_payment_pre_overlap"][i] - g["carer_support_payment"][i] - ) ctr_income = g["council_tax_reduction_applicable_income"][i] hb_income = g["housing_benefit_applicable_income"][i] # Guarantee Credit passports pension-age Housing Benefit to nil @@ -400,10 +412,9 @@ def test_council_tax_reduction_and_housing_benefit_assess_the_same_carer_income( + g["housing_benefit_applicable_income_childcare_element"][i] - g["housing_benefit_tariff_income"][i] ) - ctr_less_overlap = ctr_income - removed_by_overlap assert np.allclose( - hb_before_adjustments[compared], ctr_less_overlap[compared], atol=0.05 - ), (fam, hb_before_adjustments[compared], ctr_less_overlap[compared]) + hb_before_adjustments[compared], ctr_income[compared], atol=0.05 + ), (fam, hb_before_adjustments[compared], ctr_income[compared]) @PROPERTY_SETTINGS diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py index e1494e88cb..4ea11fc7ab 100644 --- a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py @@ -53,6 +53,8 @@ class council_tax_reduction_applicable_income(Variable): "https://www.legislation.gov.uk/ssi/2012/319/regulation/25", "https://www.legislation.gov.uk/ssi/2012/319/regulation/27", "https://www.legislation.gov.uk/ssi/2021/249/regulation/57", + "https://www.legislation.gov.uk/ssi/2023/302/regulation/16", + "https://www.socialsecurity.gov.scot/publications/2017/07/carer-support-payment-decision-making-guide/pages/payment-of-carer-support-payment/effect-on-other-benefits-for-carer-support-payment-clients", "https://www.legislation.gov.uk/uksi/2012/2885/schedule/5/paragraph/7", "https://www.legislation.gov.uk/uksi/2012/2885/schedule/5/paragraph/20", "https://www.legislation.gov.uk/uksi/2012/2886/appendix/8/paragraph/21", @@ -119,14 +121,18 @@ def formula(benunit, period, parameters): # reg 27(1)(j) at pension age. Neither counts the Scottish Carer # Supplement (reg 57(1) does not list it; reg 27(1)(j)(xxib) # excepts it), so scottish_carer_supplement is not listed. - # Whether CTR counts CSP before or after the CSP Regs reg 16(2) - # overlapping-benefit reduction is unsettled: SSI 2012/319 reg - # 27(3) grosses up deductions other than the reg 27(5) - # adjustments, which do not list reg 16(2), while SSI 2021/249 reg - # 57(1)(b) counts the amount the applicant is entitled to. Until - # that is decided, the amount before the reduction is counted, as - # it was before the reduction was modelled. - "carer_support_payment_pre_overlap", + # Both count CSP after the CSP Regs (SSI 2023/302) reg 16(2) + # overlapping-benefit reduction, so a carer whose State Pension or + # contributory ESA reduces CSP to nil has none counted. Reg + # 57(1)(b) counts the CSP the applicant is entitled to be given. + # At pension age SSI 2012/319 reg 27(3) counts a benefit before + # any deduction other than the reg 27(5) adjustments, and reg + # 27(5) does not list reg 16(2), which could be read as counting + # CSP before the reduction. Social Security Scotland's guidance + # reduces CTR by the CSP received, and the before-reduction + # reading would count both the overlapping benefit and the CSP it + # replaces, so the agency's reading is taken. + "carer_support_payment", "esa_contrib", "jsa_contrib", "state_pension", From 445f873074303467e5a979ee4d80fbe1dd56115b Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 7 Nov 2026 13:07:41 -0500 Subject: [PATCH 2/2] Count Carer Support Payment after the overlap at working age only Scotland's pension-age scheme keeps main's reading. SSI 2012/319 reg 27(3) counts a benefit before any deduction other than the reg 27(5) adjustments, and reg 27(5) doesn't list the CSP Regs reg 16(2), though the Pension Credit and pension-age Housing Benefit regulations do (SI 2002/1792 reg 15(4)(g); SI 2006/214 reg 29(4)(g)). Until a ruling settles that question, the shared formula, which Scottish pension-age claims follow, counts the CSP before the reduction. The devolved working-age route keeps the after-reduction reading. Invariant 5 now states the sign rule: on the devolved route a claim that brings only the carer premium can raise the award, and a working-age ESA overlap example pins it. The ESA YAML case drops the shared-formula outputs, which a Scottish working-age award doesn't read. Co-Authored-By: Claude Opus 5.5 --- changelog.d/2820.fixed.md | 2 +- ...l_tax_reduction_carer_support_payment.yaml | 64 +++++----- ...l_tax_reduction_carer_income_properties.py | 111 ++++++++++-------- ..._pension_credit_carer_income_properties.py | 2 +- ...council_tax_reduction_applicable_income.py | 27 +++-- ...x_reduction_working_age_unearned_income.py | 15 ++- 6 files changed, 118 insertions(+), 103 deletions(-) diff --git a/changelog.d/2820.fixed.md b/changelog.d/2820.fixed.md index 6d3b42f6bf..1c274f9489 100644 --- a/changelog.d/2820.fixed.md +++ b/changelog.d/2820.fixed.md @@ -1 +1 @@ -Scottish Council Tax Reduction counts Carer Support Payment after the overlapping-benefit reduction, so a carer whose State Pension or contributory ESA reduces it to nil has none counted. +Scottish working-age Council Tax Reduction counts Carer Support Payment after the overlapping-benefit reduction, so a carer whose contributory ESA or another overlapping benefit reduces it to nil has none counted. diff --git a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml index 3702c07fb7..6613b39b05 100644 --- a/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/council_tax_reduction_carer_support_payment.yaml @@ -158,12 +158,15 @@ - name: A working-age carer whose contributory ESA reduces Carer Support Payment to nil has none counted in Council Tax Reduction # Contributory ESA (96.15 a week here) is an overlapping benefit, so CSP # Regs (SSI 2023/302) reg 16(2)(b) reduces the CSP given to nil. SSI - # 2021/249 reg 57(1)(b) counts the CSP the applicant is entitled to be - # given, which is nil; counting the 86.45 x 52 before the reduction would - # count the ESA that replaces it twice. The carer premium still applies: - # Sch 1 para 6(1)(b) covers a carer who would be in receipt of CSP but for - # reg 16. The case fails if CTR income counts CSP before the reduction. - # Taxable income, 5,000, is below the personal allowance. + # 2021/249 reg 57(1)(b) counts benefits "to which the applicant is + # entitled". We read that as the CSP the carer "is entitled to be given + # under a determination" (Social Security (Scotland) Act 2018 s. 24), + # which reg 16(2) sets at nil here. Counting the 86.45 x 52 before the + # reduction would count both the ESA and the CSP it replaces. The carer + # premium still applies: Sch 1 para 6(1)(b) covers a carer who would be in + # receipt of CSP but for reg 16. The case fails if the working-age route + # counts CSP before the reduction. The personal allowance covers the + # taxable income of 5,000. period: 2026 absolute_error_margin: 0.01 input: @@ -190,15 +193,13 @@ income_tax: 0 # The ESA alone. Counting the CSP before the reduction would give # 5,000 + 4,495.40 = 9,495.40 and an award of - # 2,000 - 0.2 x (9,495.40 - 7,472.40) = 1,595.40. - council_tax_reduction_applicable_income: 5_000 - council_tax_reduction_applicable_amount: (95.55 + 48.15) * 52 - # The working-age route counts the same amount. Scotland's 2026-27 - # amounts (SSI 2026/56 reg 14) equal these: 95.55 + 48.15 carer premium. + # 2,000 - 0.2 x (9,495.40 - 7,472.40) = 1,595.40. Scotland's 2026-27 + # working-age amounts (SSI 2026/56 reg 14): 95.55 plus the 48.15 carer + # premium. council_tax_reduction_working_age_applicable_income: 5_000 council_tax_reduction_working_age_applicable_amount: (95.55 + 48.15) * 52 - # Income is below the applicable amount of 7,472.40, so the award is the - # whole bill. + # The applicable amount of 7,472.40 exceeds the income, so the award is + # the whole bill. council_tax_reduction: 2_000 - name: Carer Support Payment counts in 2025, before the Scottish Carer Supplement @@ -332,20 +333,21 @@ # 2,000 - 0.2 x (22,995.40 - 22,438.00) council_tax_reduction: 1_888.52 -- name: A pension-age carer whose State Pension reduces Carer Support Payment to nil has none counted in Council Tax Reduction +- name: A pension-age carer whose State Pension exceeds the Carer Support Payment rate has it counted in Council Tax Reduction # The partner's State Pension (142.31 a week) exceeds the CSP rate, so CSP # Regs (SSI 2023/302) reg 16(2)(b) reduces the CSP given to them to nil, - # and with it the supplement. SSI 2012/319 reg 27(3) counts a benefit - # before any deduction other than the reg 27(5) adjustments, and reg 27(5) - # lists the Overlapping Benefits Regulations 1979 but not reg 16(2), so the - # text could be read as counting the 86.45 x 52 before the reduction. - # Social Security Scotland's guidance reduces CTR by the CSP received, and - # that reading would count both the State Pension and the CSP it replaces, - # so CTR counts the CSP after the reduction: nil. The case fails if CTR - # income counts CSP before the reduction. The couple is unmarried, so no - # marriage allowance links the claimant's tax to the partner's income. The - # partner's taxable income is 7,400, below the personal allowance. - # Guarantee Credit is nil. + # and with it the supplement. Whether pension-age CTR should count CSP + # before or after that reduction is open: SSI 2012/319 reg 27(3) counts a + # benefit before any deduction other than the reg 27(5) adjustments, and + # reg 27(5) lists the Overlapping Benefits Regulations 1979 but not reg + # 16(2). Until it is decided CTR counts the 86.45 x 52 before the + # reduction (carer_support_payment_pre_overlap). Whoever settles it must + # update this case; it fails if CTR income silently drops the CSP. The + # couple is unmarried, so no marriage allowance links the claimant's tax to + # the partner's income. The partner's taxable income is 7,400, below the + # personal allowance, and would stay below it (7,400 + 4,495.40 + 608.40 = + # 12,503.80) if the CSP were paid, so the tax does not depend on the + # choice. Guarantee Credit is nil either way. period: 2026 absolute_error_margin: 0.01 input: @@ -378,14 +380,12 @@ # Income is above the minimum guarantee of (363.25 + 48.15) x 52 = # 21,392.80 with or without the CSP: 15,000 + 7,400 - 461.70 = 21,938.30. guarantee_credit: 0 - # 15,000 + 7,400 - 461.70 = 21,938.30. Counting the CSP before the - # reduction would give 26,433.70 and an award of - # 2,000 - 0.2 x (26,433.70 - 22,438.00) = 1,200.86. - council_tax_reduction_applicable_income: 15_000 + 7_400 - 461.70 + # 15,000 + 7,400 + 86.45 x 52 - 461.70. Leaving the CSP out would give + # 21,938.30, below the applicable amount, and a full award of 2,000. + council_tax_reduction_applicable_income: 15_000 + 7_400 + 86.45 * 52 - 461.70 council_tax_reduction_applicable_amount: (383.35 + 48.15) * 52 - # Income is below the applicable amount of 22,438.00, so the award is the - # whole bill. - council_tax_reduction: 2_000 + # 2,000 - 0.2 x (26,433.70 - 22,438.00) + council_tax_reduction: 1_200.86 - name: A pension-age couple below the applicable amount keeps full Council Tax Reduction period: 2026 diff --git a/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py b/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py index b1ce2a657b..681fac487a 100644 --- a/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py +++ b/policyengine_uk/tests/test_council_tax_reduction_carer_income_properties.py @@ -30,14 +30,12 @@ 1. Counts the component: claiming Carer Support Payment raises Council Tax Reduction income, before income tax and National Insurance and apart from - the other benefits it counts, by exactly the Carer Support Payment paid - after any overlapping-benefit reduction (86.45 a week where nothing - overlaps; see below), not by the component plus the supplement. The - claim also brings the carer premium, even where an overlapping benefit - reduces the payment to nil. The reduction moves against the rise in - income less the rise in the applicable amount: it never rises where that - difference is positive, never falls where it is negative, and where both - awards are partial it falls by 20% of it. + the other benefits it counts, by exactly the Carer Support Payment + component (86.45 a week), not by the component plus the supplement, and + by that amount before any overlapping-benefit reduction (see below). The + reduction itself never rises, and where both awards are partial it falls + by 20% of the rise in income less the rise in the applicable amount (the + carer premium comes with the claim). 2. Invariant to the supplement: setting the Scottish Carer Supplement to zero leaves Carer Support Payment and the other benefits counted in Council Tax Reduction income (Child Benefit, the income-related benefits, @@ -48,10 +46,11 @@ 3. Differential: Council Tax Reduction and Housing Benefit assess the same carer income. Where Guarantee Credit does not passport Housing Benefit, Housing Benefit applicable income, before its disregard, childcare element - and tariff income, equals Council Tax Reduction income. Both count Carer - Support Payment after any overlapping-benefit reduction (HB (SPC) Regs - reg 29(4)(g)). This holds in Scotland, where the carer's benefit is Carer - Support Payment, and in England and Wales, where it is Carer's Allowance. + and tariff income, equals Council Tax Reduction income less the part of + Carer Support Payment that an overlapping benefit removes, which Housing + Benefit counts after the reduction (HB (SPC) Regs reg 29(4)(g)). This holds in + Scotland, where the carer's benefit is Carer Support Payment, and in + England and Wales, where it is Carer's Allowance. Invariants 1 to 3 concern Council Tax Reduction income under the general rules. A pension-age family in receipt of a guarantee credit has its whole income @@ -80,9 +79,11 @@ less the disregard (never more than the earnings), plus unearned income, plus tariff income, and the claim changes no capital. The working-age applicable amount rises by exactly one Scottish carer premium (Sch 1 para - 6(1)). The reduction never rises, and where both awards are partial it - falls by 20% of the rise in working-age income less the rise in the - working-age applicable amount. + 6(1)), even where an overlapping benefit reduces the payment to nil. + Where the claim is not passported, the reduction moves against the rise + in working-age income less the rise in the working-age applicable amount: + it never rises where that difference is positive, never falls where it is + negative, and where both awards are partial it falls by 20% of it. 6. The supplement on the devolved route: setting the Scottish Carer Supplement to zero leaves the working-age unearned income, the working-age applicable amount, and the working-age income less net earnings after the @@ -104,8 +105,11 @@ benefit the model pays. The model reduces Carer Support Payment by overlapping benefits such as State Pension (the Carer's Assistance (Carer Support Payment) (Scotland) Regulations 2023 reg 16(2)), and the supplement -with it. Council Tax Reduction counts the payment after that reduction, as -Social Security Scotland's guidance does. It applies the Housing Benefit +with it. The devolved working-age route counts the payment after that +reduction (carer_support_payment). Whether the shared formula, which +pension-age Scottish claims follow, counts it before or after stays open; +until a ruling settles it, that formula counts +carer_support_payment_pre_overlap. The model applies the Housing Benefit applicable amounts to every nation's Council Tax Reduction. """ @@ -198,13 +202,12 @@ country="SCOTLAND", council_tax=2_000.0, ) - -# A Scottish pensioner carer whose State Pension (173.08 a week) reduces Carer -# Support Payment to nil: the claim brings only the carer premium, so on the -# general rules it raises the reduction. -OVERLAP_CARER = dict( - pension_age=True, - adults=[dict(age=75, state_pension=9_000.0)], +# A Scottish working-age carer whose contributory ESA (96.15 a week) reduces +# Carer Support Payment to nil: on the devolved route the claim brings only +# the carer premium, so it can raise the reduction. +ESA_OVERLAP_CARER = dict( + pension_age=False, + adults=[dict(age=40, employment_income=0.0, esa_contrib_reported=5_000.0)], carer=0, by_hours=True, country="SCOTLAND", @@ -264,6 +267,10 @@ def situation(families): # All private pension goes to the first adult. "private_pension_income": {YEAR: float(pension) * (j == 0)}, } + if "esa_contrib_reported" in a: + person["esa_contrib_reported"] = { + YEAR: a["esa_contrib_reported"] + } if j == fam["carer"]: # Keep the carer's pay within the Carer's Allowance # earnings limit (£204 a week in 2026-27), so the @@ -350,26 +357,24 @@ def check_devolved_carer_claim(g, i, fam): # The scheme follows the family's ages, not the claim. assert np.all(g["devolved"][i, :, 0] == g["devolved"][i, :, 1]), fam unearned = g["council_tax_reduction_working_age_unearned_income"][i] + paid = g["carer_support_payment"][i, :, 0] + pre_overlap = g["carer_support_payment_pre_overlap"][i, :, 0] assert np.allclose( - (unearned[:, 0] - unearned[:, 1])[devolved], - g["carer_support_payment"][i, :, 0][devolved], - atol=0.01, + (unearned[:, 0] - unearned[:, 1])[devolved], paid[devolved], atol=0.01 ), (fam, unearned) - # These working-age families have no overlapping benefit, so the full - # 86.45 a week is paid. - assert np.allclose( - g["carer_support_payment"][i, :, 0][devolved], - CARER_SUPPORT_PAYMENT, - atol=0.01, - ), fam + # The claim is a full award before any overlapping-benefit reduction, + # which never adds to it. + assert np.allclose(pre_overlap[devolved], CARER_SUPPORT_PAYMENT, atol=0.01), fam + assert np.all((paid <= pre_overlap + 0.01)[devolved]), fam income = g["council_tax_reduction_working_age_applicable_income"][i] passported = g["council_tax_reduction_working_age_passported"][i].astype(bool) assessed = devolved & ~passported[:, 0] & ~passported[:, 1] other_income = income_other_than_earnings(g)[i] other_income_rise = other_income[:, 0] - other_income[:, 1] - assert np.allclose(other_income_rise[assessed], CARER_SUPPORT_PAYMENT, atol=0.05), ( + assert np.allclose(other_income_rise[assessed], paid[assessed], atol=0.05), ( fam, other_income_rise[assessed], + paid[assessed], ) amount = g["council_tax_reduction_working_age_applicable_amount"][i] amount_rise = amount[:, 0] - amount[:, 1] @@ -378,10 +383,14 @@ def check_devolved_carer_claim(g, i, fam): amount_rise[devolved], ) award = g["council_tax_benefit"][i] - assert np.all((award[:, 0] <= award[:, 1] + 0.01)[devolved]), fam - both_partial = partial(g, i)[:, 0] & partial(g, i)[:, 1] & assessed excess_rise = (income[:, 0] - amount[:, 0]) - (income[:, 1] - amount[:, 1]) fall = award[:, 1] - award[:, 0] + # The award moves against the excess of working-age income over the + # applicable amount. Where an overlapping benefit cuts the payment below + # the carer premium, claiming raises the reduction. + assert np.all((fall >= -0.01)[assessed & (excess_rise > 0)]), fam + assert np.all((fall <= 0.01)[assessed & (excess_rise < 0)]), fam + both_partial = partial(g, i)[:, 0] & partial(g, i)[:, 1] & assessed assert np.allclose( fall[both_partial], WITHDRAWAL_RATE * excess_rise[both_partial], atol=0.05 ), (fam, fall[both_partial], excess_rise[both_partial]) @@ -390,7 +399,7 @@ def check_devolved_carer_claim(g, i, fam): @PROPERTY_SETTINGS @given(st.lists(family(), min_size=1, max_size=3)) @example([SAVINGS_CREDIT_CARER]) -@example([OVERLAP_CARER]) +@example([ESA_OVERLAP_CARER]) def test_council_tax_reduction_income_counts_the_carer_support_payment_component( families, ): @@ -422,23 +431,19 @@ def test_council_tax_reduction_income_counts_the_carer_support_payment_component assert compared.any() or not shared.any(), fam check_devolved_carer_claim(g, i, fam) rise = g["income_before_tax"][i, :, 0] - g["income_before_tax"][i, :, 1] - csp_paid = g["carer_support_payment"][i, :, 0] - assert np.allclose(rise[compared], csp_paid[compared], atol=0.05), ( + assert np.allclose(rise[compared], CARER_SUPPORT_PAYMENT, atol=0.05), ( fam, rise[compared], - csp_paid[compared], ) + # Claiming never raises the reduction: on the general rules income + # rises by more than the carer premium the claim brings. + assert np.all((award[i, :, 0] <= award[i, :, 1] + 0.01)[general]), fam + both_partial = partial(g, i)[:, 0] & partial(g, i)[:, 1] & general amount = g["council_tax_reduction_applicable_amount"][i] excess_rise = (income[i, :, 0] - amount[:, 0]) - ( income[i, :, 1] - amount[:, 1] ) fall = award[i, :, 1] - award[i, :, 0] - # The award moves against the excess of income over the applicable - # amount. Where an overlapping benefit cuts the payment below the - # carer premium, claiming raises the reduction. - assert np.all((fall >= -0.01)[general & (excess_rise > 0)]), fam - assert np.all((fall <= 0.01)[general & (excess_rise < 0)]), fam - both_partial = partial(g, i)[:, 0] & partial(g, i)[:, 1] & general assert np.allclose( fall[both_partial], WITHDRAWAL_RATE * excess_rise[both_partial], @@ -535,7 +540,6 @@ def test_council_tax_reduction_income_ignores_the_scottish_carer_supplement( @PROPERTY_SETTINGS @given(st.lists(family(countries=tuple(REGIONS)), min_size=1, max_size=3)) -@example([OVERLAP_CARER]) def test_council_tax_reduction_and_housing_benefit_assess_the_same_carer_income( families, ): @@ -546,6 +550,12 @@ def test_council_tax_reduction_and_housing_benefit_assess_the_same_carer_income( + g["carer_support_payment_pre_overlap"][i] ) assert np.all(carer_benefit[:, 0] > 0), fam + # Housing Benefit counts Carer Support Payment after any + # overlapping-benefit reduction; Council Tax Reduction, for now, + # before it. + removed_by_overlap = ( + g["carer_support_payment_pre_overlap"][i] - g["carer_support_payment"][i] + ) ctr_income = g["council_tax_reduction_applicable_income"][i] hb_income = g["housing_benefit_applicable_income"][i] # Guarantee Credit passports pension-age Housing Benefit to nil @@ -561,9 +571,10 @@ def test_council_tax_reduction_and_housing_benefit_assess_the_same_carer_income( + g["housing_benefit_applicable_income_childcare_element"][i] - g["housing_benefit_tariff_income"][i] ) + ctr_less_overlap = ctr_income - removed_by_overlap assert np.allclose( - hb_before_adjustments[compared], ctr_income[compared], atol=0.05 - ), (fam, hb_before_adjustments[compared], ctr_income[compared]) + hb_before_adjustments[compared], ctr_less_overlap[compared], atol=0.05 + ), (fam, hb_before_adjustments[compared], ctr_less_overlap[compared]) @PROPERTY_SETTINGS diff --git a/policyengine_uk/tests/test_pension_credit_carer_income_properties.py b/policyengine_uk/tests/test_pension_credit_carer_income_properties.py index be33c492f2..f3dafb623a 100644 --- a/policyengine_uk/tests/test_pension_credit_carer_income_properties.py +++ b/policyengine_uk/tests/test_pension_credit_carer_income_properties.py @@ -4,7 +4,7 @@ although the State Pension Credit Regulations 2002 reg 15(1) prescribe "all social security benefits" as income except those they list, and neither is listed. Pension-age Housing Benefit counted both, and Council Tax Reduction -counted Carer's Allowance (it does not yet count Carer Support Payment: #1955). +counted Carer's Allowance (it did not yet count Carer Support Payment, #1955). While Guarantee Credit was paid, both were passported to their maximum and hid the difference; when Guarantee Credit ended, both were assessed on the Carer's Allowance that Pension Credit had ignored, so a pensioner couple whose diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py index 0bee1610c0..18d8d81c89 100644 --- a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_applicable_income.py @@ -86,7 +86,8 @@ class council_tax_reduction_applicable_income(Variable): "https://www.legislation.gov.uk/ssi/2012/319/regulation/27", "https://www.legislation.gov.uk/ssi/2021/249/regulation/57", "https://www.legislation.gov.uk/ssi/2023/302/regulation/16", - "https://www.socialsecurity.gov.scot/publications/2017/07/carer-support-payment-decision-making-guide/pages/payment-of-carer-support-payment/effect-on-other-benefits-for-carer-support-payment-clients", + "https://www.legislation.gov.uk/uksi/2002/1792/regulation/15", + "https://www.legislation.gov.uk/uksi/2006/214/regulation/29", "https://www.legislation.gov.uk/uksi/2012/2885/schedule/5/paragraph/7", "https://www.legislation.gov.uk/uksi/2012/2885/schedule/5/paragraph/20", "https://www.legislation.gov.uk/uksi/2012/2886/appendix/8/paragraph/21", @@ -164,18 +165,18 @@ def formula(benunit, period, parameters): # reg 27(1)(j) at pension age. Neither counts the Scottish Carer # Supplement (reg 57(1) does not list it; reg 27(1)(j)(xxib) # excepts it), so scottish_carer_supplement is not listed. - # Both count CSP after the CSP Regs (SSI 2023/302) reg 16(2) - # overlapping-benefit reduction, so a carer whose State Pension or - # contributory ESA reduces CSP to nil has none counted. Reg - # 57(1)(b) counts the CSP the applicant is entitled to be given. - # At pension age SSI 2012/319 reg 27(3) counts a benefit before - # any deduction other than the reg 27(5) adjustments, and reg - # 27(5) does not list reg 16(2), which could be read as counting - # CSP before the reduction. Social Security Scotland's guidance - # reduces CTR by the CSP received, and the before-reduction - # reading would count both the overlapping benefit and the CSP it - # replaces, so the agency's reading is taken. - "carer_support_payment", + # Scottish working-age claims follow the devolved route, which + # counts CSP after the CSP Regs (SSI 2023/302) reg 16(2) + # overlapping-benefit reduction + # (council_tax_reduction_working_age_unearned_income). For the + # pension-age scheme the question stays open: SSI 2012/319 reg + # 27(3) counts a benefit before any deduction other than the reg + # 27(5) adjustments, and reg 27(5) doesn't list reg 16(2), while + # the Pension Credit and pension-age Housing Benefit regulations + # do (SI 2002/1792 reg 15(4)(g); SI 2006/214 reg 29(4)(g)). Until + # a ruling settles it, this formula counts the amount before the + # reduction, as it did before the model applied the reduction. + "carer_support_payment_pre_overlap", "esa_contrib", "jsa_contrib", "state_pension", diff --git a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_unearned_income.py b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_unearned_income.py index 40ae420f09..41979be5e7 100644 --- a/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_unearned_income.py +++ b/policyengine_uk/variables/gov/local_authorities/council_tax_reduction/working_age/council_tax_reduction_working_age_unearned_income.py @@ -16,8 +16,8 @@ class council_tax_reduction_working_age_unearned_income(Variable): "pensions, contributory Jobseeker's Allowance and Employment and " "Support Allowance, carer's allowance, carer support payment (the " "Carer Support Payment component after any overlapping-benefit " - "reduction, as the pension-age route counts it; the Scottish Carer " - "Supplement is a separate variable that does not count), " + "reduction; the Scottish Carer Supplement is a separate variable " + "that does not count), " "maternity allowance, industrial injuries benefit, incapacity benefit, " "severe disablement allowance, Part 5 miscellaneous income and " "working and child tax credits count. Child Benefit, the " @@ -34,6 +34,7 @@ class council_tax_reduction_working_age_unearned_income(Variable): "https://www.legislation.gov.uk/ssi/2021/249/regulation/57", "https://www.legislation.gov.uk/ssi/2021/249/regulation/63", "https://www.legislation.gov.uk/ssi/2023/302/regulation/16", + "https://www.legislation.gov.uk/asp/2018/9/section/24", "https://www.socialsecurity.gov.scot/publications/2017/07/carer-support-payment-decision-making-guide/pages/payment-of-carer-support-payment/effect-on-other-benefits-for-carer-support-payment-clients", "https://www.legislation.gov.uk/wsi/2013/3029/schedule/6/paragraph/17", "https://www.legislation.gov.uk/wsi/2013/3029/schedule/9", @@ -52,10 +53,12 @@ def formula(benunit, period, parameters): "esa_contrib", "carers_allowance", # Carer Support Payment after the CSP Regs (SSI 2023/302) reg - # 16(2) overlapping-benefit reduction. Reg 57(1)(b) counts the - # CSP the applicant is entitled to be given, and Social - # Security Scotland's guidance says Council Tax Reduction - # falls £1 for £1 with the CSP a carer receives. + # 16(2) overlapping-benefit reduction. Reg 57(1)(b) counts + # benefits "to which the applicant is entitled". We read that + # as the CSP the carer "is entitled to be given under a + # determination" (Social Security (Scotland) Act 2018 s. 24), + # the amount reg 16(2) reduces. Social Security Scotland's + # guidance also takes the CSP a carer receives into account. "carer_support_payment", "maternity_allowance", "iidb",