Repository navigation
Conversation
anth-volk
force-pushed
the
v2plan/1f-123-region-reference-files
branch
from
October 26, 2026 13:18
3050f02 to
00657f1
Compare
Each file lists every region of one country with its code, label, type, parent, US state, the value that selects its households, and the v1 identifier it replaces. The UK file lists 1,016 regions: the United Kingdom, its four nations (Northern Ireland as country/northern_ireland, replacing country/ni), 650 constituencies and 361 local authorities by ONS code (constituency/E14001063 replaces constituency/Aldershot), each under its nation. The 361 include Ards and North Down (N09000011), which the Public API's own list now carries. The US file lists the United States, 51 states, 436 congressional districts with unchanged codes, and 333 places. The constituency and local-authority rows come from the Public API's own lookup files; the US states, districts and places, and every filter value, match the region registry of PolicyEngine.py 6.7.5. A loader validates each file: unique codes and v1 identifiers, codes that start with their type, and parents that lead to the national region. Nothing reads the files yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ta release Catalog extraction no longer reads PolicyEngine.py's region registry. It takes every region from the checked-in reference file of its country and gives it a dataset and filter from a scoping rule per country and region type: - US national, and UK national: the release's national dataset, no filter. - US states and congressional districts: the release's state and district dataset, a row filter on state_fips or congressional_district_geoid. - UK nations: the national dataset, a row filter on the stored region. - UK constituencies and local authorities: the national dataset, a weight_replacement filter whose field names the release's weight matrix (parliamentary_constituency_weights, local_authority_weights) and whose value is the region's ONS code. The matrix must come from the same release as the dataset, since weights attach to households by position. Extraction fails if the national region would not use the reviewed dataset, a dataset role names no certified dataset or a per-region template, a filtered region has no filter value or a malformed list, or a runnable region sits under one that is left out. Region types without a rule (US places) are left out and counted in the publication evidence. The installed 6.7.5 catalog now publishes 1,503 regions: 488 US and 1,015 UK. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… missing Before it publishes a catalog version that is not stored yet, the publication command checks each region against the certified artifact its filter reads, and stops with a clear error if: - a row filter's column (state_fips, congressional_district_geoid, region) is not a household column of the region's dataset; or - a weight matrix's row count differs from its row lookup, or the lookup has no row for a constituency's or local authority's ONS code. Compute finds a region's matrix row in the same lookup files (constituencies_2024.csv, local_authorities_2021.csv). The artifacts are read from Hugging Face at their pinned revisions with ranged requests, so only HDF5 metadata and the column-name arrays are downloaded: about a minute for the 9.8 GB US file. Pandas fixed and table formats, one frame per year, and policyengine-core files are understood. A read failure names only the artifact and the error type. Versions already stored are not read again, since publication only compares them. The seed workflow's publication step receives the organization secret PE_UK_PRIVATE_HF_READ_TOKEN as HUGGING_FACE_TOKEN, because the UK data repository is private. The release workflow passes it through its existing `secrets: inherit`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A catalog version is identified by its country and PolicyEngine.py version and never changes once published, but its regions now come from the Public API's reference files. Republishing a stored version compared every table, regions included, so a reference file change under an unchanged PolicyEngine.py version (6.7.5 today, whose stored version has the 826 regions of PolicyEngine.py's registry) made the seed job fail. For a stored version, publication now compares every table except regions exactly as before, keeps the stored region rows unchanged, and logs kept_published_catalog_regions with the country, the version and the counts of staged region rows the stored version lacks and of stored rows not staged. A version not yet stored still publishes, and is checked against, the reference-file regions. Region file changes therefore take effect in the next catalog version that is published. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The artifact test now checks that the UK release fixture's artifacts name the placeholder repository example-org/example-uk-data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Catalog publication's data reader imports both, which the project had only through PolicyEngine.py and PolicyEngine Core. They are now direct dependencies, constrained to keep the locked versions (h5py 3.16.0, huggingface-hub 1.12.2). uv.lock, refreshed with `uv lock` (uv 0.13.4, as the release workflow uses), changes only the project's dependency metadata. A test requires every third-party package the reader imports to be a direct dependency. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The seed command configures no logging handler, so Python's last-resort handler printed only the warning's bare event name and dropped the structured attributes. The message now carries the country, the PolicyEngine.py version and both region-row counts; the attributes stay for structured handlers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Republishing a stored catalog version with different content failed with "persisted <country> catalog differs from PolicyEngine.py", even when the difference came from the Public API's own selections, such as a dataset. The error now names the country, the version and the first table that differs (model version, variables, parameter nodes, parameters, parameter values, datasets or regions), and still no row data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Verification reduced every read failure to the artifact's name and the error type, so a structure error such as "household group holds no data frame" reached the operator only as "CertifiedDataReadError". That error, which names only HDF5 entries and counts, now keeps its message; any other failure is still reduced to the name and type, since its text may hold a location. The error class moves to the catalog's errors module so verification can recognize it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The region data check reads stored catalog versions before publication checks the database revision, so on a database without the v2 schema the command failed with "catalog initialization failed unexpectedly" instead of the specific revision error. unpublished_countries now requires the expected Alembic revision first, as publication does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The UK credential document said the catalog publication step reads only UK artifacts, but the same authenticated file system also reads the public US dataset. The weight-matrix lookup comment and the catalog document now say that the certified data release lists no lookup file, so the check uses the Public API's own copies, and that on 2026-10-22 both copies were byte-identical to the files compute downloads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a stored catalog version kept its region rows, the publication evidence still counted the staged regions and reported the staged fallbacks and omissions, so the record kept before a release described regions that were never published. The evidence now counts the stored region rows for such a country, leaves its staged fallback and omitted summaries out, and lists it under kept_regions with the stored and staged region counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a region's parent existed but a region further up its chain did not, the reference file check named the region's direct parent as unknown. It now names the missing code and the region that names it as parent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without HUGGING_FACE_TOKEN, the UK artifact reads failed with "could not read the certified artifact enhanced_frs_2024_25: FileNotFoundError", which gave no sign of the cause. The installed check now stops before any read when a country whose certified data repository is private (the UK) needs checking and the token is unset, with a message naming the variable, never its value. The public US data is still read without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ading Adds tests for errors that had none: an invalid region code and a national region not named after its country; a release manifest without a dataset map or a region-dataset map, without the reviewed default dataset, with a region dataset without a path, and with an artifact without a path, revision or repository; a household entry that is not an HDF5 group. Also covers a weight matrix with a non-array entry, the default Hugging Face file system and its token, a verification error the inspector raises, and the default row lookups. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lookup comment and the catalog document now say only that on 2026-10-22 both copies were checked to be identical in content to the lookups the calculation workers download. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The data reader's docstring and the UK credential document said only HDF5 metadata and column names are downloaded. Reads go through a cache of 1 MB blocks, so they download the blocks holding that metadata, which can include neighbouring bytes; the household arrays are never read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`make test` runs coverage, which writes .coverage (an SQLite database with local paths) and coverage.xml at the repository root; neither was ignored, so a broad `git add` could commit them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The constant holding the environment variable's name is now HUGGING_FACE_CREDENTIAL_VARIABLE, which the hardcoded-password check does not flag, so its suppression is removed. The environment variable stays HUGGING_FACE_TOKEN. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y occur RegionDataVerificationError inherited from CatalogExtractionError, which is raised before any database access, although verification runs after the stored catalog versions are read and reads certified data over the network. It is now its own error, documented as such, and the command still prints its message. A missing HUGGING_FACE_TOKEN is now reported as the existing V2ConfigurationError, the error for absent configuration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Region scoping typed the PolicyEngine.py release manifest as object and read its dataset map, region-dataset map and data package with getattr. A runtime-checkable Protocol now states those three attributes; a manifest without them fails with a message naming them, and their values are still checked where they are read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… release routes them to The Public API now pins PolicyEngine.py 6.10.0. Its UK release certifies no constituency or local-authority weight matrix; it routes both region types to a local-area dataset (microcosm_uk_2024_25_dense) whose households carry constituency_code_oa and la_code_oa. UK constituencies and local authorities are now scoped like US states and districts: a row filter on that column, with the region's ONS code, on the dataset the release routes their type to. Because the national file has no area codes, they never fall back to it; a release that routes no dataset to their type stops publication, naming the region. The weight_replacement scoping, the weight-matrix artifact checks and the row-count reading of weight matrices are removed. No release the Public API can publish uses them: the pinned 6.10.0 release has none, stored 6.7.5 versions keep their regions without being scoped again, and the Public API's local-authority list now has 361 rows while 6.7.5's matrix had 360, so that check would be wrong for 6.7.5 anyway. The installed 6.10.0 catalog now extracts 1,504 regions (488 US, 1,016 UK) and 4 datasets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The catalog fixture's UK reference file now also lists Northern Ireland and Ards and North Down (local_authority/N09000011). The unit tests assert that the local authority is row-filtered on la_code_oa with its ONS code in the local-area dataset the release routes it to, that the UK records no fallback, and that a release routing no dataset to local authorities stops publication naming the region, as for constituencies. These replace, at unit level, master's registry-based test of the UK area regions' dataset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
v2plan/1f-123-region-reference-files
branch
from
October 26, 2026 14:42
00657f1 to
d2f6c4c
Compare
This was referenced Oct 26, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4019
Summary
Catalog publication now reads each country's regions from region reference files checked into the Public API, instead of copying PolicyEngine.py's region registry. This branch is rebased onto #4010's final commits, which include
master, so it targets the PolicyEngine.py release the Public API pins: 6.10.0.The review of the retarget to 6.10.0 and of Ards and North Down found no bugs. Two small additions followed:
unit tests now cover a UK local authority's routed dataset, column and value, that the UK records no fallback, and a release that routes no dataset to local authorities;
the Stage 9 runbook paragraphs are rewrapped.
Reference files.
policyengine_api/data/v2/catalog/region_reference_files/us.csvanduk.csvlist every region's code, label, type, parent, US state, the value that selects its households, and the v1 identifier it replaces:country/nibecomescountry/northern_ireland;constituency/Aldershotbecomesconstituency/E14001063;local_authority/Maidstonebecomeslocal_authority/E07000110;local_authority/Ards and North Downbecomeslocal_authority/N09000011.US codes are unchanged. The national labels are "United States" and "United Kingdom". A loader checks that codes and v1 identifiers are unique, that each code starts with its type, and that every parent leads to the national region.
Scoping from the certified data release. One rule per country and region type takes the dataset from the release manifest's region datasets and sets a row filter:
populace_us_2024populace_us_2024_acs_local)row_filteronstate_fipsorcongressional_district_geoidmicrocosm_uk_2024_25microcosm_uk_2024_25row_filteronregionmicrocosm_uk_2024_25_dense)row_filteronconstituency_code_oaorla_code_oa, value the ONS codeThe UK national file has no area codes. A UK constituency or local authority therefore never falls back to it: a release that routes no dataset to their type stops publication, naming the region.
Verification before publishing. Before publishing a catalog version that is not stored yet, the publication command reads each dataset the filters use from Hugging Face, at its pinned revision, using ranged requests. Only the 1 MB blocks holding HDF5 metadata and column names are fetched. Publication stops if a filter's column is not a household column of its dataset. Errors name only artifacts, tables, columns, codes and counts.
Omitted regions. Region types without a rule are left out and counted in a new
omitted_region_summariesevidence field. Today that is only US places.Stored versions keep their regions. See "Stored catalog versions" below.
Direct dependencies:
h5py>=3.16,<4andhuggingface-hub>=1.12,<2. The locked versions are unchanged;uv.lockchanges only in the project's own metadata.No route, table or migration changes.
/v2/regionsserves whatever the catalog stores.Retargeted to PolicyEngine.py 6.10.0
Earlier versions of this PR scoped UK constituencies and local authorities with a
weight_replacementfilter on the release's weight matrices. That path, its weight-matrix checks and its matrix reading are removed, because no release the Public API can publish uses them:Ards and North Down (N09000011)
Included by the user's decision. The Public API's own local-authority list on
masteralready has it, and the v1 metadata now serveslocal_authority/Ards and North Down. Under 6.10.0 it is row-filtered onla_code_oain the local-area dataset, so it publishes.Whether that column holds rows for N09000011 is not checked. That would need reading the column's values from the private UK dataset, so it stays an open item.
Counts
Sources of codes and labels
policyengine_api/data/constituencies_2024.csvandlocal_authorities_2021.csv. The local-authority list now has 361 rows and matches PolicyEngine.py 6.10.0's 2023 list. A nation is the parent of each, chosen from the first letter of its ONS code (E, S, W, N).congressional_districtsmodule. US FIPS numbers and places come from PolicyEngine.py's public data.Stored catalog versions
kept_regionswith stored and staged counts, and leaves out that country's staged fallback and omitted summaries.When the new regions reach staging and production
Only when a catalog version that is not yet stored is published. Where the deploy of
masterhas already published the PolicyEngine.py 6.10.0 catalog, that version keeps the regions taken from the registry, because a stored version keeps its regions. The reference-file regions then reach staging and production with the next PolicyEngine.py version that is published, by an operator or by the release workflow's seed job. This PR does not publish anything.Open risks
populace_us_2024_acs_localfile (9.8 GB) in 55.5 seconds.la_code_oaholds rows for every local authority, N09000011 included, is not checked.Follow-up
US places stay left out until a place filter's value format is checked and compute accepts places. The certified ACS-local file has a
place_fipshousehold column.Environment variables
HUGGING_FACE_TOKENPE_UK_PRIVATE_HF_READ_TOKEN, listed as available to this repository, with no environment-level secret of the same nameenv:of the catalog publication step only ("Seed and validate the v2 metadata catalog") inseed-v2-database.yml. It arrives throughsecrets: inheritfrom the release workflow's staging and production seed jobs, and directly on manual dispatch. A test checks that the workflow names it only once.V2_DATA_WRITE_DATABASE_URLNot verified: that
PE_UK_PRIVATE_HF_READ_TOKENcan read the UK data release. There has been no live run. If a UK version needs checking and the token is unset, the command stops before reading anything, with a configuration error naming the variable.Suppressions
None added.
What this waits for before merging
Testing
GitHub Actions runs on this branch are cancelled at the user's request. The evidence is these local runs on the tip:
make testset: 3476 passed.RUN_V2_CATALOG_COMPATIBILITY=1: passed;ruff format --check,ruff check,mypyon the configured set,python scripts/run_quality_guards.py,python -m scripts.rules validateandguard,alembic -c alembic-v2.ini check: clean.changelog.d/v2plan-1f-123-region-reference-files.changed.md.🤖 Generated with Claude Code