Repository navigation
UK local: rerun the 2025 Autumn Budget constituency analysis on the local candidate to find data gaps and per-seat support before Budget day #1241
Description
@vahid-ahmadi, could you take this one?
Summary
We want to publish constituency results for the 28 October 2026 Budget. #1131 leaves open whether they come from Microcosm's local release or from the eFRS constituency weights, as in 2025. Before choosing, we need to know two things for the policies a Budget typically touches:
- how the local candidate behaves at seat level;
- how many survey households sit behind each estimate.
The quickest way to find out is to rerun last year's constituency analysis on the local candidate and on the eFRS, and compare them.
The mansion-tax check on the 11 October candidate shows why this matters:
- owner-occupied homes above £2m in England come from a few dozen survey households;
- all but 3 of the 543 English seats have fewer than 10 such households behind them;
- the eFRS passes the record checks only because it reweights the same households into every seat.
See #1112 and the HVCTS umbrella issue (#1240). Other policies may have the same problem in milder forms, and we'd rather find out now than on the day.
What to run
- Reforms.
- The 2025 Autumn Budget measures in the dashboards: two-child limit repeal, fuel duty freeze extension, rail fares freeze, threshold freeze extension, dividend, savings and property income tax +2pp, student loan repayment threshold freeze, salary sacrifice NIC cap.
- The combined package.
- The HVCTS at £2m and £1.5m.
- Years 2026-27 to 2030-31, or at least 2026-27 and 2029-30.
- Code. Use the 2026 dashboard's pipeline:
PolicyEngine/uk-autumn-budget-dashboard-2026,src/uk_budget_data/pipeline.py,ConstituencyCalculator. Last year's local-area dashboard (PolicyEngine/Autumn-budget-local-area) has the same reforms if that's easier. - Datasets.
- The local candidate: score this exact build:
staged/uk-local-candidate-f100-s42-20261011T200435Z-108c1225inpolicyengine/populace-uk-private.- File:
microcosm_uk_2024_25_local.h5, sha25677456e20bc70d8d9116e47559a44de1226e942b68a3a8ad84dc79f5ddfacfcab. The local run directory isuk-k25-h100000-ngfes-f0.5-u0.0216. - This is not the national dataset
microcosm_uk_2024_25.h5used in UK: main_residence_value stops at about £2.8m (about £3.0m in 2026), so there are no homes in the £3.5m+ surcharge bands #1112, and not the eFRS. If a newer candidate is frozen before you start, use it and record its release id and sha256 in your summary. - The pipeline reads a 650 × N
parliamentary_constituency_weights.h5. Until Microcosm exports its seat assignment in that format (weight-matrix export, PR to be linked), a group-by onconstituency_code_oawithhousehold_weightgives the same seat totals. - policyengine-uk holds
household_idas int32, and Microcosm's clone ids wrap. Join engine output to the H5 by row position, not by id.
- File:
- The eFRS (policyengine-uk-data 1.58.0) with its constituency weights, as the 2025 baseline.
- The local candidate: score this exact build:
- Other constituency analyses. Add any other constituency analysis we published in 2025 or plan for this Budget, for example the two-child-limit comparison with official statistics mentioned in UK: two-page note on how constituency impacts are estimated (draft for the Budget-day analysis) #1131.
What to measure
For each reform, year and seat (and local authority, if cheap):
-
Support:
- distinct survey households whose net income changes, behind each seat estimate;
- effective records among those households;
- the largest single household's share of the seat's total change.
Clones and copies of one survey household count once: use Microcosm's
source_household_id. The eFRS doesn't export a source id, so use an attribute fingerprint for now. -
Disclosure pass rate:
- how many seats pass the rules below;
- how many still pass after secondary suppression against the national and regional totals and against the package's other components.
-
Uncertainty: 90% intervals from resampling survey households with weights held fixed. Report:
- the median relative half-width;
- how many seats have an interval crossing zero.
Say clearly that this understates uncertainty, because calibration isn't re-run.
-
Comparison:
- rank correlation by seat between Microcosm and the eFRS for each reform;
- where they diverge most, as a count of seats and a region, not seat-level values;
- independent benchmarks where they exist, such as official two-child-limit statistics. HMRC income by constituency is a calibration target, so it isn't independent.
-
Data gaps: the reforms and subpopulations with thin support or implausible patterns, and the characteristic each depends on that isn't anchored locally. Examples are property values, investment income, salary sacrifice, student loans and fuel spending. Map each to an existing issue (UK: main_residence_value stops at about £2.8m (about £3.0m in 2026), so there are no homes in the £3.5m+ surcharge bands #1112, UK local build (K=25, 2026-10-06): data-quality defects on the target surface and the spine #1123, UK spine: composition-faithful SPI income draw — bridge predictors and rank-preserving replacement (with-children UC residual) #840, UK spine: housing benefit £2.7bn against OBR £12.1bn — pensioner and supported-accommodation HB missing after the UC migration #867, WS-C deferred adjudications and the reconciliation layer #736, UK: supply the engine's local_authority input from the ladder's local_authority_code, plus council tax follow-ups from policyengine-uk#1855/#1864 and uk-data#482/#484 #953) or file a new one.
Deliverables
- Private: the full seat-level results, unsuppressed, kept in a private repository (for example PolicyEngine/uk-mansion-tax-microdata, or a new private Budget-analysis repo) or locally. Never in a public repository.
- Public summary (a comment on this issue), aggregates only:
- for each reform and year, the count of seats passing and failing the checks;
- the median interval width;
- the Microcosm–eFRS rank correlation;
- the gap list with links.
- A recommendation: which reforms can be published at seat level on Budget day, which only by region or nationally, and which data fixes would change that. This feeds the suppression rule still open in UK: two-page note on how constituency impacts are estimated (draft for the Budget-day analysis) #1131.
Ideally by 20 October, so the findings can shape the frozen candidate build and the dashboard's suppression rules.
Disclosure control: please read before posting anything
Every output here derives from UKDS-licensed microdata (FRS, WAS, LCFS, SPI and others). The UKDS End User Licence (CD137, clause 8, with CD171 §5.2.1) binds every output. This issue and its comments are public, and so are the dashboard repos. Posting here, committing, or uploading CI logs or artifacts all count as publishing.
- Aggregates only. Publish only weighted totals or means over at least 10 distinct survey households (clones and copies count once). Write "<10" for anything smaller.
- No unit-record values. No maximum or minimum, no top-k values, no single household's income, value or weight, and nothing that shows where a distribution ends, for example that a value band is empty.
- No dominant cells. Don't publish a cell where one survey household is more than half of the total.
- No differencing. A new number combined with already-public numbers must not isolate a small group or narrow a unit record. Watch out for:
- two runs under different uprating factors or thresholds;
- a total minus published parts;
- a package minus its other components;
- shares that sum to one with one part hidden;
- before and after totals.
- Support figures in bands. Publish counts of survey households per seat only as
<10,10–29or30+, never exact. - Seat-level values stay private. No seat tables, maps or screenshots in public threads. A map colour is a value: a public map must hatch withheld seats (as in the shareable mode of the PolicyEngine/uk-mansion-tax-microdata dashboard), not colour them.
- CI. In a public repo, don't print unsuppressed outputs in workflow logs or upload them as artifacts.
- Edit history. GitHub keeps edit history for issues and comments, so editing doesn't remove a value; delete and re-post instead.
- Review. When unsure, ask before posting, and have a second person check anything new.
analysis/disclosure.pyin PolicyEngine/uk-mansion-tax-microdata has a validator for result tables.
Links
- UK: two-page note on how constituency impacts are estimated (draft for the Budget-day analysis) #1131 (constituency method note and the open suppression rule), UK local build (K=25, 2026-10-06): data-quality defects on the target surface and the spine #1123 (local build defects), UK: main_residence_value stops at about £2.8m (about £3.0m in 2026), so there are no homes in the £3.5m+ surcharge bands #1112 (high-value homes), the HVCTS umbrella issue (UK: data fixes to model the High Value Council Tax Surcharge (mansion tax) correctly, and the related housing and council-tax gaps #1240).
- High-value housing facts for the UK local calibration: HM Land Registry Price Paid Data, UK HPI, ONS house price statistics by constituency, the National Statistics Postcode Lookup, and the OBR High Value Council Tax Surcharge costing chronicle#343 (Land Registry and house-price facts).
PolicyEngine/uk-autumn-budget-dashboard-2026, and the private PolicyEngine/uk-mansion-tax-microdata (mansion-tax check, disclosure tooling and hex-map prototype).
Activity
vahid-ahmadi commentedon Oct 15, 2026
Status update on the readiness run. No survey data has been read yet, so there are no seat-level or support figures in this comment.
Done
pipeline.py,ConstituencyCalculator), the disclosure layer from Add disclosure control and uncertainty for UK geography outputs policyengine.py#605, and Microcosm's and the eFRS's lineage code, against what the comparison needs: loading the local file, seat assignment, weights, years 2026-27 to 2030-31, the nine 2025 measures, the package, and the HVCTS at £2m and £1.5m.constituency_code_oa,region_code_oaandsource_household_idfrom the H5 by row position (never byhousehold_id, UK clone stages can number identifiers past the 32-bit range policyengine-uk stores #1194), runs every reform, year and seat through the layer with the package and region nesting in one release, applies secondary suppression, and writes the audit and summaries to a private directory outside any repository. It has been checked on synthetic arrays only. It is not in any repository.parent_of,prior_public, and three spellings of the UK regions) skip the nesting and prior-public checks without an error.source_household_iddoesn't name the survey household, so SPI copies and capital-gains clones count separately or the layer refuses the file.Blocked
The data comparison itself. Both the local candidate (
policyengine/populace-uk-private, sha25677456e20…) and the eFRS with its constituency weights are private, and this needs my own Hugging Face access, which isn't set up yet. I'll run the comparison once it is. If a newer candidate is frozen by then, the script records its id and sha256.Ranked risks, before data
How thin a seat gets, without data:
n_eff) and dominance rules are what bind.From most to least urgent:
Gaps between the asks and what landed (relevant to the Budget run)
Finding.suggestedas a component name for package findings and an area otherwise (#24 constituency PR: what the pipeline needs to score the local file and the eFRS through the disclosure layer uk-autumn-budget-dashboard-2026#43).--min-sources 30to test both.🤖 Generated with Claude Code
vahid-ahmadi commentedon Oct 15, 2026
@juaristi22 the comparison has run. Everything below is an aggregate over seats; the seat-level audit stays private.
Setup
uk-local-candidate-f100-s42-20261011T200435Z-108c1225(sha matches the issue).Verdict by reform
Share of affected seats that are reported / approximate / withheld (local ; eFRS), 2029-30
Gaps found
recoverable_parentfindings are left over. A region is withheld while all its seats are published, and the layer suggests nothing. There are a handful on the local file and up to a few dozen per year on the eFRS. Each costs about one more seat, but the dashboard needs a rule for choosing it (uk-autumn-budget-dashboard-2026#43).Suggested next steps before 28 October
recoverable_parentrule and a decision on the package release structure to Make US source stages manifest-driven #43 / Track US geography and local-area source support #48.🤖 Generated with Claude Code
vahid-ahmadi commentedon Oct 15, 2026
@juaristi22 an addendum to the comparison above, after finding 1 of the dashboard #48 review.
The question. Before policyengine-uk-data#597, an SPI copy's clones could carry the stacked id rather than the FRS original's. A check that only asks whether ids collapse clones then counts the copy as a separate survey household. The review said the readiness script has the same gap, and it was right about the script: its check would have accepted a stacked file.
The local file is not affected, so the results above stand. All checks were on the household table, aggregates only:
source_household_id. Only the row id is remapped, and the channel is recorded inhousehold_support_channeland the copy flags.source_household_idin the local file is a raw FRS household id: 100% fall in the set of unflagged eFRS 1.58.1 household ids. None carries a stacking offset.Rerun. The corrected id would be the same vector the run already used, so the 2029-30 local tier shares are unchanged and no verdict changes.
Fix to the script. The private readiness script now adds two checks to the "collapses clones" test. First, every source id must be an unflagged FRS household id. Second, copies must match their original. It passes on this file and refuses a test copy where the SPI copies are given stacked ids. The plain orphan rule would wrongly refuse a sampled file like this one.
🤖 Generated with Claude Code