Repository navigation
Emit NRS's council tax bands by 2022 data zone - #421
Conversation
Add the workbook's columns G to N, dwellings in council tax bands A to H, beside nrs_dwellings_total in both record sets of nrs-dwellings-data-zone-2025. They take the total's shape: unit count, aggregation sum, a number cell and the row-5 header, line break included, as a guard. The package round-trips byte for byte through yaml.safe_dump(sort_keys=False, allow_unicode=True, width=88), so the measures were set by loading and dumping it; no row changes. A test checks that the eight bands add up to the total in all 7,392 zones of both sheets. The merged bundle gains 118,272 dwelling facts at existing geography, period and entity keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review of 1d72f0a I checked the 16 new measures against the NRS workbook (downloaded again from the manifest's Nit
Checked and fine
CI at 1d72f0a: Verdict: the emitter matches the source. One optional nit. 🤖 Generated with Claude Code |
Vahid's review of 1d72f0a: nothing pinned the 16 new header guards, so a loosened or removed guard would only show once a shifted column broke the band sum. For each sheet and band, the test puts the next band's header in the band's row-5 cell and expects that band's selector to fail on its column header. The workbook is parsed once per session and shared with the band-sum test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks, Vahid. Nit 1 is in 78d4c27.
The workbook is parsed once per session and shared with the band-sum test, so the 16 cases add about 30 s. All 17 pass locally. 🤖 Generated with Claude Code |
… young people facts Main gained #421 (chronicle#419): 118,272 dwelling facts in the existing NRS data zone package. The only conflict is the merged bundle's pins, which now carry both: facts 2,180,756 + 33,641 = 2,214,397, chronicle#419's calendar-year increments beside this PR's period increments, and its dwellings beside this PR's people and firms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chronicle main 80a3482 (PolicyEngine/chronicle#421) brings NRS's dwellings by council-tax band A to H for each 2022 data zone at December 2024 and 2025 (118,272 rows), which the Scottish conditioned support reads from the next commit on. It also brings what Chronicle merged since 6475380: PolicyEngine/chronicle#415's UK land-value inputs (326,495 rows), which nothing reads yet; PolicyEngine/chronicle#413's raw-only registrations, no rows; and PolicyEngine/chronicle#414, which writes the bundle one package at a time with the same rows. The feed has 2,030,062 rows, and its row contract and schema digest are unchanged. The merge tree is the pull request head's, so the artifact was built from the head. No compiled value moves on either surface: both reference files and both compile-parity receipts are byte-identical. The national membership moves its feed label and the matched-fact counts of the nine MHCLG council-tax stock targets, whose selectors also match the council-tax rows #415 adds; every candidate resolves to the same fact and value. The local membership moves its feed label and the 1,263 DESNZ constituency keys, whose derived keys hash the feed identity. The vendored resources and the DESNZ constituency resource carry the same rows under the new feed identity, the census and the validation register restate the pin, and the H2 fixture moves the contract hashes of the 19 stages that bind vendored resources. The high-value home stock's inputs are unchanged, so it is not rebuilt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The conditioned-support tool now reads NRS's dwellings by council-tax band for each 2022 data zone at December 2024 from the pinned UK feed (record set nrs.dwellings_data_zone_2025.2024, PolicyEngine/chronicle#421) instead of parsing the registered workbook. It streams the feed and checks the whole file against the pin. It refuses a row of that record set that is not a zone's total or band, a zone without all nine, and bands that miss the total. The provenance records the feed read and a fingerprint of the counts, and the Scottish band columns' source names the record set and that fingerprint. The facts equal the workbook's bands in all 7,392 zones; they come from the same bytes (5d61db5f). So the Scottish support's arrays are unchanged, and only the eight band columns' source moves (a8ca096b, 1,607,718 bytes). England and Wales and Northern Ireland rebuild byte for byte, and every receipt is unchanged. The tool's Chronicle block names #421's merge, where the five raw-only registrations pin the same bytes. The facts are streamed rather than vendored: their 66,528 rows would make a resource of over 80 MB. As for the high-value home stock, a feed-gated test checks on each re-pin that the feed still carries the facts the supports were built from, and the re-pin runbook says to rebuild them if not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Closes #419.
This emits the eight council tax band columns of NRS's dwelling estimates by 2022 data zone. They feed the Scottish band weights in PolicyEngine/microcosm#931's geography-first draw. In the meantime, PolicyEngine/microcosm#1519 reads them straight from the registered workbook bytes; it can vendor these facts once this merges.
The measures. Both record sets,
nrs.dwellings_data_zone_2025.2024andnrs.dwellings_data_zone_2025.2025, gain eight measures besidenrs_dwellings_total, in its shape: unitcount, aggregationsum, expected cell typenumber, and a header guard on row 5.Council Tax band:\nAnrs_dwellings_band_anrs.dwellings_band_aCouncil Tax band:\nBnrs_dwellings_band_bnrs.dwellings_band_bCouncil Tax band:\nCnrs_dwellings_band_cnrs.dwellings_band_cCouncil Tax band:\nDnrs_dwellings_band_dnrs.dwellings_band_dCouncil Tax band:\nEnrs_dwellings_band_enrs.dwellings_band_eCouncil Tax band:\nFnrs_dwellings_band_fnrs.dwellings_band_fCouncil Tax band:\nGnrs_dwellings_band_gnrs.dwellings_band_gCouncil Tax band:\nHnrs_dwellings_band_hnrs.dwellings_band_hThe guards match the header cells exactly, line break included. Each
source_column_idis a slug (council_tax_band_a…). The SLC, Gambling Commission and CTAXBASE packages do the same for headers that contain a line break.How the file was edited. 265fb7e committed no generator for this package, and none exists elsewhere. The file round-trips byte for byte through
yaml.safe_dump(sort_keys=False, allow_unicode=True, width=88). So the measures were added by loading it, setting both record sets' measures and dumping it again. The diff is the 16 measure blocks (208 lines); no row changed.The workbook is unchanged: sha256
5d61db5faf7e81451d838e5d394b8e0682bbf501341c1220aea4a78082ceb033, 1,223,284 bytes.The check.
test_scottish_data_zone_council_tax_bands_sum_to_each_zone_totalbuilds the package's facts and checks four things:nrs.dwellings_totalin every zone;Size. 118,272 new facts (7,392 zones × 8 bands × 2 sheets), kept on both sheets as the issue asks; the 2024 sheet alone would be 59,136. The bundle grows by 5.7%. The CI bundle step peaked at 3.4 GiB for 1.74M facts on 5 Nov.
Bundle test counts. I built single-source bundles of
nrs-dwellings-data-zone-2025at bundle year 2023 from main's package and from this branch's. They show:by_source.nrsandby_entity.dwelling: +118,272;calendar_year:2024andcalendar_year:2025: +59,136 each;tests/test_chronicle_bundle.pynow expects:fact_countand the row count: 2,062,484 → 2,180,756;nrs: 359,094 → 477,366;dwelling: 590,264 → 708,536;calendar_year:2024andcalendar_year:2025: +8 × 7,392 each.Chronicle Governance
ledger-source-ingestorchronicle validate-package nrs-dwellings-data-zone-2025, at--year 2025and--year 2023. Both are valid: 18 measures, 14,784 rows and 133,056 source records, with no errors or warnings.chronicle build-suite nrs-dwellings-data-zone-2025 --year 2025is valid. It gives 133,056 facts, lineage coverage 1.0, and every agent-acceptance check passes. Its one warning,no_concept_alignments, is also raised by main's version of the package.chronicle validate-factsandvalidate-source-cellson its output are valid, with no missing labels, lineage or provenance.validate_consumer_fact_contractin the new test.ledger-source-fidelity: pendingledger-contract: not applicable (no schema, identity or contract change)ledger-boundary: pendingTests
Run locally (Python 3.14.8):
uv run pytest -q tests/test_chronicle_uk_local_2025.py -k council_tax_bands_sum: passed.-k 'council_tax_bands_sum or band_header_guards': 17 passed. The new cases aretest_scottish_data_zone_band_header_guards_reject_drift, one per sheet and band. Each puts the next band's header in the band's row-5 cell and expects that band's column-header guard to fail.uv run ruff checkon the touched test files: clean.chronicle validate-package,build-suite,validate-factsandvalidate-source-cellsruns and the single-source bundles described above.Left to CI: the full surface suite and
tests/test_chronicle_bundle.py.Disclosure note
Every new fact is a published NRS area aggregate. Nothing comes from survey records.
🤖 Generated with Claude Code