Repository navigation
UK #1326: 2023-24 Scottish property income by NSND band (project tool, not for merge) - #1327
juaristi22 wants to merge 4 commits into
Conversation
A project tool for one external request, not for main. It reads a released UK national file and its build's national target registry and writes private outputs outside the repository: - a one-year back-cast that inverts policyengine-uk's own forward uprating, with a guard against the engine's silent zeros for earlier periods; - a bounded reweight to the SPI 2023-24 facts the build binds (UK property income counts and amounts by band; Scottish taxpayers and total income by band), holding each region's households; - Release 1 (the ten requested bands) and Release 2 (four bins aligned to the 2023-24 Scottish rate thresholds), with distinct records, effective records and source-bootstrap intervals per band, and restricted and public versions with hierarchical suppression; - an illustrative 1p on the Scottish rates charged on property income, with and without the finance-cost reduction following. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@juaristi22 thanks, this is my review at Close, with one disclosure fix before anything goes out. The definitions match the Scottish Government's request, the back-cast is an exact inverse of the engine's forward step, the reweight is gentle, and the 1p reform is the right shape for the April 2027 power. One thing has to change before the public tables are sent: the public record counts let a reader rebuild a withheld band's exact count by subtraction (item 1). The rest are "should" items, mostly about what we claim in the release note and which engine we run. What I ran. A fresh clone at the head,
Findings
Disclosure overall. With item 1 fixed, the rules are a reasonable minimum for aggregates from EUL microdata sent to a government body: 10 distinct records, the dominance check, secondary suppression over total → bins → bands, and the cautious assumption that the 1p costing reveals the total. I found no route to microdata. Licensed outputs are refused inside a git tree, What looks right
🤖 Generated with Claude Code |
From Vahid's review at c4cddcd: 1. Public tables show a band's record count only when the band is published, so a thin band's count can't be rebuilt from its bin. 2. The headline counts taxpayers with taxable property income; landlords wholly under the property allowance are counted beside it in the restricted and private tables. 3. The private audit carries each band before and after the reweight, and the release note says what is calibrated and what is a test. 4. The tool refuses policyengine-uk older than 2.134.4. 5. SPI-channel rows that keep their FRS person's values are keyed by that person; the manifest counts them and any FRS person also hosting tape records. 6. A reweight that doesn't converge, or misses a fact or region total by more than 0.5%, stops the run. 7. The bootstrap resamples FRS households and tape records across all Scottish persons. 8. The back-cast lists the inputs it leaves at the file's year, and the round-trip test compares every column. 9. Read-back facts are checked against HMRC's printed SPI 2023-24 tables (Tables 3.7 and 3.11, shipped as a CSV). 10. The relief variant must reproduce the engine at zero on the file. 11. The costing marks rates-only as the headline and the relief variant as a sensitivity; the release note says static, 2023-24, no response. 12. The release note footnotes PA as £12,570. 13. Two records over 85% also withhold a cell. 14. The manifest moves to private/, a release note goes with each version, and the text helper is shared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On 6cba5d71, meeting Scotland's total income by band (Table 3.11) moved weight onto a few very high-income records. Scotland's untargeted investment, employment and pension income all moved away from the published table, and with the UK property facts it took 13% off Scottish taxable property income. Reweighting to UK property income by band and Scottish taxpayer counts by band keeps every untargeted Scottish check at or better than the back-cast. With fewer facts the misses reach zero before the divergence stops shrinking, so the search can end at the iteration limit with the facts met. The limit rises to 20,000; the run accepts a stop there when every miss is within --max-miss, and refuses any other unconverged stop. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@vahid-ahmadi thanks, this was a thorough review. Everything is addressed in
Tests: the 23 engine-free and 4 engine tests pass locally, and so do |
Not for merge. This is the data work for one external request (#1326), kept on its own branch. It adds a project tool and its tests. Nothing in the build changes.
What it does
python -m tools.uk_scotland_property_income --h5 … --registry … --out …reads a released UK national file and the national target registry of the build that produced it. It writes private outputs outside the repository, and refuses any output directory inside a git working tree. It runs these steps from #1326:refuse_earlier_periodstops that before any engine call.backcast.py). It inverts the engine's own forward step: each input is divided by the growth inuprating_indices.yamlthatapply_single_year_upratingwould multiply it by, and household weights move by ONS population growth.registry.py,measures.py,rake.py).uprating_factor. They are checked against HMRC's printed Tables 3.7 and 3.11 (spi_2023_24_published.csv), and the run stops on a mismatch.uk_population_targets.json:total_income_after_loss_relief;bands.py,release.py).reform.py). The reform addsdeltato every Scottish rate ontaxable_property_income_after_allowances. The headline keeps the finance-cost reduction at 20%; the sensitivity raises it bydeltaas well. Each run first checks that the sensitivity at zero reproduces the engine on the file.Validation
Tests:
engine_free/uk/test_uk_scotland_property_income.py(23 tests) covers:engine/uk/test_uk_scotland_property_income_engine.py(4 tests): the back-cast round-trips every column through the engine's ownextend_single_year_dataset; the earlier-period guard; the reform adds exactlydeltatimes the Scottish property slice and nothing elsewhere; the relief variant matches the engine at zero.tools/ci_test_plan.py verifyandruff check .pass.A run on the 19 Oct national release (
6cba5d71, H5810ba980…), at1552cdc8bunder policyengine-uk 2.134.4, took about 8 minutes:Scottish total income and income tax by band are no longer targets, and both improve. That suggests matching Scottish taxpayer counts moves Scotland's income distribution the right way. Scotland's untargeted investment, employment and pension income also stay at or better than the back-cast.
The quantity the outturn can test is the Scottish property split, which no fact binds. The reweight moves its Scottish total by under 2%, and the private audit shows each band before and after.
All outputs are licensed and stay local. Nothing from them is in this PR beyond the run-level diagnostics above.
Open
net_incomedoesn't deduct trade-loss relief, which moves the NSND bands. UK: 2023-24 property income of Scottish taxpayers by NSND band — the back-cast, reweight, disclosure and engine steps the analysis needs #1326 A5 named 2.130.1; this needs a decision there.restricted/.Refs #1326. Relates #1145, #1276, #1287, #1324.
🤖 Generated with Claude Code