Skip to content

Re-measure the hmrc SPI band exclusions: three 'sparse cell' premises fail on spine-i (hundreds of in-band carriers) #807

Closed

Description

@juaristi22

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

  1. juaristi22 commented on Aug 28, 2026

    @juaristi22
    CollaboratorAuthor

    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_000 now 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.

  2. juaristi22 commented on Aug 28, 2026

    @juaristi22
    CollaboratorAuthor

    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/):

    lifted cell v12 fit
    hmrc/state_pension_income_band_50_000_to_70_000 +22.2%
    hmrc/self_employment_income_income_band_50_000_to_70_000 +18.5%
    hmrc/private_pension_income_count_income_band_100_000_to_150_000 +23.3%

    All 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_fit blocks on 6 UC-side cells only (#808: the two TCL disability cells; #809: the three composition cells and the COUPLE_WITH_CHILDREN payment band).

  3. added a commit that references this issue on Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions