UK wave 1: ONS mid-2023 population estimate source packages, UK countries + England regions (#132) - #137
UK wave 1: ONS mid-2023 population estimate source packages, UK countries + England regions (#132)#137juaristi22 wants to merge 3 commits into
Conversation
…England regions (PolicyEngine#132) Two ledger-source-ingestor packages backing the 108 region-x-age rows of the wave-1 production surface (PolicyEngine#132), built from publisher truth instead of policyengine-uk-data's provenance-unrecorded demographics.csv: - ons-mye-2023-uk-countries: mye23tablesuk.xlsx (MYE2 persons), rows UK/Wales/Scotland/Northern Ireland, 368 facts. - ons-mye-2023-england-regions: mye23tablesew.xlsx (MYE2 persons, 2023 LA boundaries edition), publisher-emitted E12 region rows, 828 facts. Shape: one record set per single year of age (groupby age; all-ages sets are age-totals), rows carry per-row geography overrides, age enters fact identity via row filters mirrored by explicit constraints. Single-age facts at publisher granularity; the fixture's 10-year bands (whose 80_89 is actually 80+) are a populace-side mapping concern. Gates: validate-package clean for both; build-suite green end to end (source cells, records, facts, DB, agent acceptance) with facts spot-verified against the workbooks. Consumer-contract export requires manifest storage.r2 (raw_r2_uri), so the final consumer gate awaits 'ledger publish-raw --root db/data' by a credentialed maintainer; the committed manifests record checksums and retrieval metadata only. The MYE2 digit column headers are text-typed cells the guard contract cannot express (render int-coerces digit expectations, guard compare is raw); the age span is pinned by the guarded 'All ages' and '90+' endpoints instead. Follow-up contract issue to be filed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ns in one artifact (PolicyEngine#132) The mid-2024 UK edition publishes the E12 region rows directly in MYE2, so a single package covers all 13 geographies (1,196 facts at single year of age). Per-edition packages rather than year-templating because ONS restructured the workbook between editions (Wales moved from row 13 to row 345); the vintage-suffixed package-ID convention expects this. Same gates as the mid-2023 pair: validate-package clean, build-suite and agent acceptance green (proven under a disclosed, reverted local storage.r2 sandbox), facts spot-verified against the workbook. Consumer-contract export still awaits 'ledger publish-raw' by a credentialed maintainer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e-1 aliases (PolicyEngine#132) ons-uk-population-projections-2024: the NPP principal projection (uk_ppp) from the 2024-based z1 uk.zip, one record set per year 2024-2029, rows = sex x single year of age (214 per year), 1,284 source_projection facts at calendar-year periods. The national NPP was never blocked by the demographics.csv lineage problem (that concerned the regional family only); policyengine-uk-data itself consumes the 2024-based national file. Later projection years land via the vintage backfill lane. Registers all four packages in SOURCE_PACKAGE_ALIASES (the drift guard that failed CI - unregistered packages/* fail loudly rather than being silently dropped from bundles, per PolicyEngine#78) and updates the year-2023 bundle expectations to the post-publish-raw truth measured by a full local bundle build: 42,895 facts (+3,676), 64 packages, 19 periods, ons by-source 4,922, 59 source tables, geography 1,065. Digit-text guard gap note: NPP year headers and single-age labels are text-typed digit cells the guard contract cannot express; anchored by the guarded Sex headers, the '110 and over' block ends, and the sha-pinned artifact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Source-review outcomes and CI triage (commit Source decisions (reviewed):
CI triage: the red check was not the R2/storage gate — it was the Remaining red, by design: the bundle test's consumer export requires (Counts were verified under locally injected and reverted 🤖 Generated with Claude Code |
Part of #132 (wave 1 also covers the SLC packages, blocked on #131/#136, and the ISC private-school package — this PR does not close the issue).
Lane:
ledger-source-ingestor(.github/ledger-agents.yml) — judgesledger-source-fidelity+ledger-boundary. Paths:packages/**plus thedb/data/**writes thefetch-artifactharness flow prescribes (note for maintainers: the ingestor lane'sallowed_pathsdoesn't listdb/data/**today).What
Two source packages backing the 108 region×age rows of the June production calibration surface, 1,196 facts total, at publisher granularity (single year of age; the fixture's 10-year bands are a populace-side mapping concern):
ons-mye-2023-uk-countriesmye23tablesuk.xlsx(MYE2 persons)ons-mye-2023-england-regionsmye23tablesew.xlsx(MYE2 persons, 2023 LA-boundaries edition)Shape: one record set per single year of age (
groupby_dimension: age; the all-ages sets are age-totals), rows carry per-row geography overrides, and age enters fact identity via row filters mirrored verbatim by explicit constraints (the consumer-contract comparator matchesunit/labelexactly). The YAMLs are machine-generated and uniform (10.9k + 21.4k lines); if a compact templated form is preferred, that belongs with the contract follow-up below.Sources (for review)
mye23tablesuk.xlsx— sha2567ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16mye23tablesew.xlsx— sha25696dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94Both artifacts were fetched twice by independent code paths (manual download, then
uv run ledger fetch-artifact) with byte-identical checksums;provenance_class: census(census-anchored official estimates, mirroring thecensus_pepprecedent).Source decision this PR asks reviewers to ratify
Issue #132 originally framed this family as projections (SNPP/NPP), inheriting policyengine-uk-data's claimed lineage for its committed
demographics.csv. Kickoff findings changed that:_age_80_89band is actually 80+ (a systematic −18% otherwise): median 0.76%, p90 2.14%, max 2.94% — the expected estimates-vs-projections gap, enumerated per-target in the populace consumption gate (Consume Ledger UK facts: uk_target_references, mapping module, and a compile-parity gate populace#622). Top deltas:south_east_age_10_19+2.94%,east_age_10_19+2.86%,west_midlands_age_10_19+2.46%.Projection packages (2022-based NPP
uk.zip, England 2022-based SNPP) remain queued for future-year calibrations, where actuals cannot exist — porting both sources is consistent with the exhaustive-vintage policy; populace picks the active source per calibration year.Gates
validate-package: clean for both packages, zero warnings.build-suite --year 2023: green end to end — source cells, source records, facts, DB build,agent_acceptance.jsonvalid with zero errors (only the standard non-fatalno_concept_alignmentswarning; Axiom alignment is a later step).test_source_files.py,test_ledger_source_cells.py,test_ledger_facts_only.py) pass.Draft because: the consumer-contract export requires
storage.r2(raw_r2_uri) in the manifests. The committed manifests honestly record checksums and retrieval metadata only; the suites were proven green under a locally injected, disclosed, and reverted R2 block. After source review, a credentialed maintainer runsuv run ledger publish-raw --root db/dataand the last gate closes with no package changes.Contract findings for maintainers
_render_valueint-coerces digit-string expectations while_resolve_guard_cellcompares raw — MYE2's text-typed0..89headers can't be expressed asexpected_column_header. The age span is pinned by the guarded non-digit endpoints (All ages,90+) plus the sha-pinned artifact. Follow-up contract-lane issue to be filed.ledger-agents.yml's ingestor lane omitsdb/data/**although the canonicalfetch-artifactflow writes there.🤖 Generated with Claude Code