Repository navigation
Compile the UK local target surface from Chronicle facts: area-grain references, membership, and compile parity #759
Description
Parent: #495 (workstream G of the UK-migration epic #665). Depends on #708 and the machinery merged in #735.
Why
#622 gave the national surface one doctrine-clean path from Chronicle facts to compiled targets: contract + pinned feed + period → typed references and a membership classification, behind two release-blocking compile-parity gates. The local surface has no equivalent, and it is the only missing link in the local lane.
Both ends already exist. Chronicle wave 3 (PolicyEngine/chronicle#134) minted the local facts — 24 packages, ~95.6k facts at constituency and local-authority grain — and local_targets.compute_household_metrics already computes the household side of every metric in build/uk/uk_local_target_census.json (26 metrics across 7 families; 18 at constituency grain, 22 at LA). What is missing is the middle. Nothing compiles fact values into area-grain references, so of the census's ten sources only three are pinned (the OA-ladder household counts) and seven remain documented_unpinned: the local solve can compute its metric columns but cannot bind their targets.
Depends on
- Migrate the UK local-geography and firms contracts out of Chronicle (chronicle#166 ruling) #708 — the
uk_local_geographycontract (25 targets: 4 HMRC income, 8 ONS age bands, 5 UC, 3 equivalised income, 4 tenure, 1 private rent) must land inbuild/uk/as a UK resource first. This issue consumes the resource, not the duck-typed profile objectmetric_names_from_target_profilereads today. - Complete #622: compile the UK target surface from Ledger facts at the 2024-25 line #735 machinery —
target_reference_authoring.py,target_materialization.py,ledger_targets.py(period-token collapse, assertion-policy enforcement, the declared multi-fact operations), the parameterized compile-parity gate ingates.py, andcalibrate/matrix.py's entity collapse.
Scope
- Area-grain authoring. Fan each contract target out over its declared
geography_levels× the ladder's 650 constituencies / 361 local authorities, emitting one reference per (target, area) withledger_selector.geography_levelandgeography_idpinned exactly as the national surface pinscountry/K02000001. Shipbuild/uk/local_target_references.jsonandlocal_target_reference_membership.jsonin the same shapes as the national pair (candidate/active counts, status counts, geography pins, uprating holds), with zero unexplained deferrals. - Geography identity, declared once. One crosswalk between the published area codes carried by the facts and the ladder's area ids, with vintages pinned per layer (PCON24 vs earlier constituency editions, LAD editions, the Scotland and Northern Ireland equivalents). A reference whose area code does not resolve at the declared vintage fails the compile — never a silent drop, never a best-effort match.
- Per-family resolution, signed. Resolve or defer each family with a reason: HMRC income by area, ONS age structure, UC households (plus the constituency-only child-count splits), equivalised income (LA only), tenure (LA only), private rent (LA only).
census_householdsstays ladder-derived — the compile records the artifact sha as its provenance rather than re-minting the values as facts. - Support oracle before binding. Per epic doctrine, run the oracle for each family before it binds. A family whose household-side support cannot carry its target is deferred with the measurement attached, not bound and left for the solver to absorb.
- Compile-parity gate and frozen fixtures. Parameterize the existing parity gate over the local registry against two fixtures: the in-code default metric surface (
metric_names(area_type)with no profile) and the incumbent uk-data local target surface. Every difference enumerated and signed in a committed resource, mirroringledger_compile_parity_*_signed_differences.json. - Fact gaps go upstream. Any family the feed cannot answer is recorded here and requested in Chronicle — never worked around by minting a value microcosm-side.
Out of scope
- Execution-time enforcement of the 7
review_required_before_bindingfences (the UK dense/local epic: rowwise constituency-grain dataset by cloning the national staging pool (US dense-arm analog) #495 increment-4 remainder issue). - The clone pilot (UK dense/local epic: rowwise constituency-grain dataset by cloning the national staging pool (US dense-arm analog) #495 increment 5), the calibrated candidate (increment 6), credibility gates (Port UK local target surface and credibility gates from uk-data #147), publication (Publish a Populace UK local variant with rowwise H5 and long weights #146).
Acceptance
local_target_references.jsoncompiles from a sha-pinned consumer artifact at the declared period, and the membership file accounts for all 25 contract targets × their declared area levels, every deferral signed.- The compile-parity gate is release-blocking, passes on both committed fixtures, and refuses a reference whose geography id or vintage does not resolve.
- The census artifact regenerates with the previously
documented_unpinnedsources either pinned or carrying an explicit signed reason they are not. - No target value enters from any path other than the pinned artifact; ladder-derived values carry the ladder artifact sha.
🤖 Generated with Claude Code
Activity
Adopt the UK local-geography and firms contracts, and the local compi…
Adopt the UK local-geography and firms contracts, and the local compi…
Adopt the UK local-geography and firms contracts, and the local compi…
Adopt the UK local-geography and firms contracts, and the local compi…
Adopt the UK local-geography and firms contracts, and the local compi…
Adopt the UK local-geography and firms contracts, and the local compi…
Merge pull request #795 from PolicyEngine/uk-local-contracts-708-759