Repository navigation
Reported Council Tax Reduction is never uprated, so it covers less of the bill each projected year #2674
Description
What happens
council_tax_benefit_reported has no uprating, and the dataset projection in policyengine_uk/data/economic_assumptions.py does not grow it. A family whose Council Tax Reduction scheme the model does not simulate falls back to this reported amount (council_tax_benefit, council_tax_reduction_scheme_supported). These are mostly working-age claims in the English councils the model does not model.
Their reduction therefore stays at its data-year cash value, while uprate_council_tax grows their bill every year. The other benefits the model falls back to a reported amount for, such as housing_benefit_reported, pension_credit_reported and universal_credit_reported, all carry an uprating.
Size
Measured on Microcosm UK 2024-25 (staged build uk-frs-calibration-attempt-20261025T091414Z-a6299504) with policyengine-uk 2.151.0. All figures are for households whose reduction is reported only, not simulated: about 2,800 records, 1.62m households in 2024-25 and 1.70m in 2031-32.
| 2024-25 | 2031-32 | |
|---|---|---|
| Mean reported reduction (cash) | £492.50 | £492.07 |
| Mean council tax bill (cash) | £1,250 | £1,804 |
| Mean council tax net of the reduction (cash) | £757 | £1,312 |
| Total reported reduction | £0.80bn | £0.84bn |
| Total if each reduction kept its 2024-25 share of the bill | £0.80bn | £1.21bn |
By 2031-32 the reductions fall about £0.37bn a year short of their 2024-25 share of the bill (£0.15bn in 2027-28). The effect on the income distribution is small: about £9 a person (equivalised, 2027-28 prices) in the bottom BHC decile, 0.05% of its income.
The code is the same in 2.132.6 and 2.158.2: the variable has no uprating, and nothing outside the tests and the two CTR variables refers to it.
Suggested fix
Grow a reported reduction with its household's bill. In uprate_council_tax, multiply the person-level council_tax_benefit_reported by its household's factor, so the reduction keeps its share of the bill. Council Tax Reduction schemes work out the award from the council tax liability (a maximum share of the bill, then reduced for income), so an award moves with the bill. Uprating by CPI, as for other benefits, would still leave the reduction behind bills that the OBR forecasts to grow 5.5–6.2% a year in England.
A test could pin the share: a household whose reported reduction is half of its bill in the data year still has half in each projected year.
Reproduce
On any dataset with reported reductions:
from policyengine_uk import Microsimulation
sim = Microsimulation()
for year in (2024, 2027, 2031):
rep = sim.calculate("council_tax_benefit_reported", year, map_to="household")
bill = sim.calculate("council_tax", year)
print(year, round(rep[rep > 0].mean()), round(bill[rep > 0].mean()))The mean reduction stays at its data-year value while the mean bill grows.
Found while breaking down the bottom decile in the Living standards projections of PolicyEngine/uk-autumn-budget-dashboard-2026. Related: #1669 (closed), which added the simulated schemes this fallback sits beside.
Activity
vahid-ahmadi commentedon Oct 25, 2026
Checked at main
335bb01e32. The claim holds.council_tax_benefit_reportedis a person-level input with nouprating(variables/gov/dwp/council_tax_benefit_reported.py:4-10), and it is not indata/uprating_indices.yaml. So neither the YAML loop (economic_assumptions.py:342-360) nor_unmapped_uprating_indices(:142-153) grows it. It is not inDATASET_UPRATING_EXCLUSIONS,COUNTRY_UPRATED_INPUTSorYEAR_SPECIFIC_INPUTS(:94,:130,:139), so this is a gap, not a choice.uprate_council_tax(economic_assumptions.py:523-560) only rewriteshousehold["council_tax"], by the country's OBR receipts growth net of household weight growth.council_tax_benefit.py:80-87: a claimant whose scheme is not simulated (council_tax_reduction_scheme_supported) getsreported. It is capped at its share of the liability only next to a simulated claim in the same household.housing_benefit_reported(uprating_indices.yaml:58),pension_credit_reported(:70) anduniversal_credit_reported(:81) are all uprated, as the issue says.Duplicates: none that I found. #1669 (closed) and PRs #1668 and #1831 touch the same variables but not projection. The CTR scheme issues (#1934, #1935, #1962, #2090) are about simulated schemes.
Effect on published results:
council_tax_benefitfeedshousehold_benefits,household_net_income,hbai_household_net_incomeandgov_spending. So baseline net income, poverty and spending in projected years are slightly too low for these households, and the gap grows each year. Reform deltas move only where a reform changes the bill or CTR. I did not rerun your figures. They are internally consistent: £0.80bn × (£1,804 / £1,250) × (1.70m / 1.62m) ≈ £1.21bn in 2031-32, against £0.84bn modelled. One point supports your fix: the OBR series this code uses is receipts net of CTR (seetests/test_council_tax_uprating.py:44-63). Holding CTR's share of the bill fixed matches that basis. Growing the bill while CTR stays flat does not.Suggested fix, as you propose:
uprate_council_tax, map each person to their household'sfactorsviaperson_household_id(aseconomic_assumptions.py:677-680already does for region) and setperson["council_tax_benefit_reported"] = previous_year.person["council_tax_benefit_reported"] * person_factorwhen the column is present.council_tax_benefit_reportednext tocouncil_taxinreset_growthfactor_uprating(economic_assumptions.py:827). Otherwise a reset will not restore its base value before re-uprating.domestic_rates. Worth checking whether any NI records have a non-zero value before choosing.Test: in
tests/test_council_tax_uprating.py, extend_uprated_council_taxwith a person table (two people in one household, plus a second household in another country). Assert thatcouncil_tax_benefit_reported / council_taxstays the same after one and several projected years in England, Wales, Scotland and UNKNOWN, and that NI stays flat. Also assert thatreset_growthfactor_upratingrestores the base value. An end-to-end case with an unsupported English working-age claimant would show thatcouncil_tax_benefitkeeps half of its bill.What I ran: code reading at main only. No tests and no population run.
🤖 Generated with Claude Code