Repository navigation
Re-measure the hmrc SPI band exclusions: three 'sparse cell' premises fail on spine-i (hundreds of in-band carriers) #807
Description
Summary
Measured support inside every excluded hmrc/* SPI band cell on the current candidate-of-record spine (spine-i, sha 0cce0399…), prompted by the wealth-top-tail investigation (chronicle#205 context): the spine's wealth tail is full and WAS-faithful, the historic "£1m cap" was a capital-gains artifact fixed by the HMRC Table 3 stage — so the top-tail exclusion premises deserved re-measurement rather than inheritance.
Method: for each excluded cell, unweighted records and weighted mass of carriers (value_variable > 0) with total income in-band, under two income definitions — hmrc_spi_assessable_income (the SPI stage's own concept) and a component-sum proxy matching the model's total_income (ITA 2007 s.23, which excludes capital gains). Script: uk-candidate-eval/scripts/measure_excluded_cell_support.py; receipt: out/excluded_cell_support_spine_i.json.
Findings, by class
A. The 11 1_000_000_to_inf cells — premise HOLDS, wording should be tightened
Total-income support above £1m is 0–2 records on spine-i, even though the spine now carries capital gains to £20.4m and 6,925 records above £1m wealth. The CGT band donors carry large gains but not £1m+ incomes, and total_income excludes gains, so these exclusions stand.
Request: tighten each reason to say "total income (ITA 2007 s.23, excl. capital gains)" explicitly and cite the measured support. The previous drift of "no gains over ~£1m" into "no wealth over £1m" shows how a loose phrase becomes a false premise downstream.
B. Three mid-band "sparse cell" exclusions — premise appears FALSE, propose lifting
| exclusion | records (spi / proxy) | weighted carriers |
|---|---|---|
hmrc/state_pension_income_band_50_000_to_70_000 |
287 / 1,158 | 535,141 |
hmrc/self_employment_income_income_band_50_000_to_70_000 |
186 / 649 | 370,233 |
hmrc/private_pension_income_count_income_band_100_000_to_150_000 |
77 / 233 | 142,754 |
Hundreds of in-band carriers is not "too few records for the solver". A plausible history: these were adjudicated pre-#803, when excluding a sibling band silently widened its neighbour (the #792 movers, up to +858%) — i.e. the adjudication may have been reacting to band-edge corruption rather than real sparsity. Their v9 fits were overshoots (+27% to +34%), not support gaps, which also contradicts the sparse-support reason.
Request: re-measure post-#803 and lift if the fits land; the calibration should get these three back.
C. Three thin 500k–1m cells — defensible, revisit with the next spine
dividend_income_income_band_500_000_to_1_000_000 (6–21 records), property_income_count_500_000_to_1_000_000 (2–12), self_employment_income_count_500_000_to_1_000_000 (4–19). Genuinely thin, but not zero; worth re-measuring on the next spine build (the was_wealth pension split landed on main this morning; a fresh spine is building) before renewing them at expiry.
Not touched
The 16 dwp/uc_payment_dist exclusions (uk-data#452) and the rest of the register are out of scope here — though note the v10 calibration measured UC caseload regressing to −25.6% (from −14.5%) with the 16 band exclusions in place and unchanged UC support, i.e. those exclusions removed the upward gradient on UC weights. Worth weighing when uk-data#452's M2 (the #755 pension split) gets its first calibrated measurement.
Approver context: the register entries carry approved_by: juaristi22, expiries 2026-11-25/26.
Activity
juaristi22 commentedon Aug 28, 2026
v11 evidence (spine-j, first spine with the #755 pension-wealth split, same seam/doctrine as v10): the excluded-cell support table is cell-for-cell identical on spine-j (receipt: uk-candidate-eval out/excluded_cell_support_spine_j.json), so the class-B revision case is spine-independent.
One new interaction worth folding into the adjudication:
hmrc/self_employment_income_count_income_band_50_000_to_70_000now overshoots +38.6% (it was within bounds at v10). Its amount sibling is one of the three class-B exclusions — with the amount constraint removed, the solver pushes mass into the band and only the surviving count reference resists. One-sided sibling exclusion distorts the survivor; lifting the three class-B cells would remove the distortion at its source.juaristi22 commentedon Aug 28, 2026
Revision implemented and validated — closing via #810. The register now carries the class-B lift (3 entries back on the calibrated surface), the class-A rewording (total income, ITA 2007 s.23, excluding capital gains, with per-family measured support), and the class-C per-cell support citations.
v12 seam measurement (spine-j, revised 44-entry register, 364 targets bound — receipts
runs/uk-623-first-calibrated/spine-assessment-v12/):hmrc/state_pension_income_band_50_000_to_70_000hmrc/self_employment_income_income_band_50_000_to_70_000hmrc/private_pension_income_count_income_band_100_000_to_150_000All three inside the 25% band — the "lift if the fits land" condition is met. The sibling distortions resolve at the source exactly as predicted:
self_employment_income_count_50_000_to_70_000+38.6% → +0.1%,state_pension_count_50_000_to_70_000+23.5% → +3.0%. Nothing else moves (UC family flat;obr.capital_gains_tax−25.01% → −24.9%, now inside the band); headline loss 0.0297 → 0.0300 while binding three more targets.With this revision the entire hmrc SPI band surface is green —
uk_target_fitblocks on 6 UC-side cells only (#808: the two TCL disability cells; #809: the three composition cells and the COUPLE_WITH_CHILDREN payment band).Merge pull request #810 from PolicyEngine/807-exclusion-revision