Skip to content

Commit e65ddcd

Browse files
authored
Fix abolish_council_tax to refund net council tax, not gross (#1668)
The `gov.contrib.abolish_council_tax` switch removed gross council tax from `household_tax` and `gov_tax` but left `council_tax_benefit` untouched. CTR was not in any of the household benefit aggregates (`household_benefits`, `hbai_household_net_income`, `pre_budget_ change_household_benefits`) or in `gov_spending`, so CTR never flowed through net income or the government balance in the first place. Abolition therefore refunded the full gross amount to every household — overstating CTR-recipient households' real-world out- of-pocket saving by their CTR amount, ~£4bn aggregate. Add `council_tax_benefit` to the four aggregates. The existing `if abolish_council_tax: [b for b in benefits if b != "council_ tax_benefit"]` filters become meaningful (no-ops before). Applied the same filter pattern to `hbai_household_net_income.formula` and a fresh `gov_spending.formula`. Now abolition: household net income rises by net council tax, and government balance falls by net council tax revenue. Added regression test for a CTR-recipient household.
1 parent f9230c4 commit e65ddcd

6 files changed

Lines changed: 64 additions & 9 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Include `council_tax_benefit` in `household_benefits`, `gov_spending`, `hbai_household_net_income`, and `pre_budget_change_household_benefits`. Previously CTR was absent from these aggregates, so abolishing council tax via `gov.contrib.abolish_council_tax` refunded the gross billed amount to households (and removed gross revenue from the government balance) rather than the net out-of-pocket amount, overstating household savings by about £4 billion in aggregate.

policyengine_uk/tests/microsimulation/test_abolish_council_tax_reform.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,48 @@ def test_abolish_council_tax_removes_budget_impact():
3737
assert reform_household_tax == baseline_household_tax - 2000
3838
assert reform_gov_balance == baseline_gov_balance - 2000
3939
assert reform_hbai == baseline_hbai + 2000
40+
41+
42+
CTR_SITUATION = {
43+
"people": {
44+
"person": {
45+
"age": {YEAR: 40},
46+
"employment_income": {YEAR: 8000},
47+
"council_tax_benefit_reported": {YEAR: 800},
48+
}
49+
},
50+
"benunits": {"benunit": {"members": ["person"]}},
51+
"households": {
52+
"household": {
53+
"members": ["person"],
54+
"council_tax": {YEAR: 2000},
55+
"council_tax_band": {YEAR: "C"},
56+
}
57+
},
58+
}
59+
60+
61+
@pytest.mark.microsimulation
62+
def test_abolish_council_tax_nets_out_council_tax_benefit():
63+
"""CTR recipient should see net-CT saving, not gross-CT saving.
64+
65+
Pre-reform: household pays £2,000 gross council tax and receives £800
66+
CTR, so out-of-pocket is £1,200 (the net bill). Abolishing council
67+
tax saves them the £1,200, not the £2,000 — because the £800 CTR
68+
rebate disappears alongside the council tax it was rebating.
69+
"""
70+
baseline = Microsimulation(situation=CTR_SITUATION)
71+
reform = Microsimulation(
72+
situation=CTR_SITUATION,
73+
reform={"gov.contrib.abolish_council_tax": True},
74+
)
75+
76+
baseline_hbai = baseline.calculate("hbai_household_net_income", YEAR).sum()
77+
reform_hbai = reform.calculate("hbai_household_net_income", YEAR).sum()
78+
baseline_gov_balance = baseline.calculate("gov_balance", YEAR).sum()
79+
reform_gov_balance = reform.calculate("gov_balance", YEAR).sum()
80+
81+
# Net council tax = £2,000 - £800 CTR = £1,200 saving.
82+
assert reform_hbai == pytest.approx(baseline_hbai + 1200, abs=1)
83+
# Government loses net council tax revenue (gross - CTR forgone).
84+
assert reform_gov_balance == pytest.approx(baseline_gov_balance - 1200, abs=1)

policyengine_uk/variables/contrib/policyengine/pre_budget_change_household_benefits.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class pre_budget_change_household_benefits(Variable):
1010
unit = GBP
1111
adds = [
1212
"child_benefit",
13+
"council_tax_benefit",
1314
"esa_income",
1415
"housing_benefit",
1516
"income_support",

policyengine_uk/variables/gov/gov_spending.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class gov_spending(Variable):
1010
unit = GBP
1111
adds = [
1212
"child_benefit",
13+
"council_tax_benefit",
1314
"esa_income",
1415
"esa_contrib",
1516
"housing_benefit",
@@ -57,3 +58,10 @@ class gov_spending(Variable):
5758
"nhs_spending",
5859
"carer_support_payment",
5960
]
61+
62+
def formula(household, period, parameters):
63+
variables = list(gov_spending.adds)
64+
abolish_council_tax = parameters.gov.contrib.abolish_council_tax(period)
65+
if abolish_council_tax:
66+
variables = [v for v in variables if v != "council_tax_benefit"]
67+
return add(household, period, variables)

policyengine_uk/variables/household/income/hbai_household_net_income.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class hbai_household_net_income(Variable):
2626
"free_school_milk",
2727
"free_tv_licence_value",
2828
"child_benefit",
29+
"council_tax_benefit",
2930
"esa_income",
3031
"esa_contrib",
3132
"housing_benefit",
@@ -74,15 +75,13 @@ class hbai_household_net_income(Variable):
7475
def formula(household, period, parameters):
7576
abolish_council_tax = parameters.gov.contrib.abolish_council_tax(period)
7677
if abolish_council_tax:
77-
return add(
78-
household,
79-
period,
80-
hbai_household_net_income.adds,
81-
) - add(
82-
household,
83-
period,
84-
[s for s in hbai_household_net_income.subtracts if s != "council_tax"],
85-
)
78+
adds = [
79+
a for a in hbai_household_net_income.adds if a != "council_tax_benefit"
80+
]
81+
subtracts = [
82+
s for s in hbai_household_net_income.subtracts if s != "council_tax"
83+
]
84+
return add(household, period, adds) - add(household, period, subtracts)
8685
return add(household, period, hbai_household_net_income.adds) - add(
8786
household, period, hbai_household_net_income.subtracts
8887
)

policyengine_uk/variables/household/income/household_benefits.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class household_benefits(Variable):
1010
unit = GBP
1111
adds = [
1212
"child_benefit",
13+
"council_tax_benefit",
1314
"esa_income",
1415
"esa_contrib",
1516
"housing_benefit",

0 commit comments

Comments
 (0)