Skip to content

Place high-value homes where the Land Registry sees them (#1240) - #1270

Merged
juaristi22 merged 14 commits into
mainfrom
uk-high-value-homes-1240
Oct 15, 2026
Merged

juaristi22 merged 14 commits into
mainfrom
uk-high-value-homes-1240

Conversation

@juaristi22

@juaristi22 juaristi22 commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Delivers the fix-1, 2, 3, 4, 5 and 8 parts of #1240 under María's rulings of 2026-10-13; fixes 6 and 7 stay open on that issue as follow-ups, so this PR does not close it. Based on main at 412f916 (after #1242, the K=15 doctrine, #1256, #1271, #1267, #1282 and #1281 merged; the contract digests are re-pinned on #1281's gate battery, nothing else moved). One PR: seven ordered commits, six for review round 1, one for round 2 and the regeneration of the registers and pins on the current base; the register regeneration lands with the family commit so the first two commits are reviewable but not individually green.

What changes

Feed re-pin (commit 1). The Chronicle pin moves to 735820c (PolicyEngine/chronicle#343 via #349): the OBR April 2026 HVCTS costing note, the ONS HPSSA by 2024 constituency, and three raw-only registrations (Price Paid yearly files, UK HPI full file, NSPL). No existing package moves, so no compiled target changes; the OBR note is vendored for the benchmarks gate.

Land Registry stock and VOA band mix (commit 2). tools/build_uk_high_value_home_stock.py reduces the Price Paid files to the latest non-bulk sale of every dwelling, uprates by local authority and property type HPI to the calendar-2024 average, places sales through the NSPL and the committed England-and-Wales atomic support, and counts dwellings over £1m, £1.5m and £2m (April-2026 prices, deflated with the England index) by constituency, local authority, region and nation. Owner-occupied counts use the census private-sector tenure share rescaled to the OBR control on homes over £2m, with a coverage correction for stock never sold since 1995. Outputs: high_value_home_stock_facts.json (consumer-fact rows under microcosm.derived_fact., 5,430 rows), per-constituency value knots winsorised at £20m, the implied support bound, and a provenance file with the HPSSA parity receipts and the sensitivities (no coverage correction; census share without the control). tools/build_uk_voa_band_mix.py gives cumulative band shares per LSOA from CTSOP1.1.

Derived target family (commit 3). Three contract targets microcosm.high_value_homes.over_1m|over_1_5m|over_2m bind at constituency and local-authority grain for England and Wales (575 seats and 316 authorities active per threshold; the Isles of Scilly and the City of London take the standing support-floor deferral). The fence high_value_home_stock_derived_estimate is adjudicated to 2026-12-31. The metrics read the stored main_residence_value at the dataset period. Census, local references, membership and parity receipts are regenerated.

Diagnostic gates (commit 4). uk_high_value_homes_benchmarks (England owner-occupied homes by surcharge band beside OBR Table 1.1, regional £2m+ shares beside the derived stock, seat rank correlations against the derived stock and VOA band H) and uk_high_value_homes_support (areas by band of distinct source households above £1.5m and £2m, with dominance). Both report-only, in the local diagnostic scope, outside certification. The per-area support table is a candidate artifact that stays in the run directory; shipped details carry counts only.

Per-clone value and band (commit 5). Two nodes after geography derivation, uk.full.property.value and uk.full.property.band (--property-localisation price_paid, the default on the atomic assignment), give every England-and-Wales owner clone its home value off its assigned constituency's sale distribution at the household's weighted rank among its region's owners, move property_wealth by the same amount, and draw the council-tax band from the LSOA's VOA mix at the same uniform. The uniform is keyed on the spine household, so pool clones of one household share it whatever K is. regional_land_values.json moves to the calendar-2024 average so the stored value sits at the dataset period's prices and the engine uprates it once.

Support stage (commit 6). high_value_home_support after regional_property_uprating copies every owner household in the top 5% of its region's value rank six ways at equal weight, each copy carrying high_value_support_copy_index in its lineage; the value node spreads the copies inside the stratum. Mass is conserved exactly (uk_stage_high_value_home_support_mass). The spine fixture moves to 41 stages.

Docs and changelog (commit 7).

Review round 1 (Vahid, 2026-10-14)

  1. Stratum mass (must). The support copies are now ranked beside their root, so the owner mass at or above the stratum is the selected share; a 4,000-household test asserts it (test_support_copies_keep_the_stratum_mass_at_the_selected_share). The stage docstring no longer claims the two ranks agree by construction.
  2. HPSSA parity. The builder now compares category A sales counts and medians by 2024 constituency, fiscal year and property type with the ONS rows in the feed; the receipt (aggregates per year and type) is in the provenance file.
  3. Licence. Every derived resource carries a licence block with the publishers' attribution statements (HM Land Registry OGL v3.0 for Price Paid and the UK HPI, the NSPL's OS and Royal Mail notices with ONS's OGL statement, OGL v3.0 for VOA, census and OBR); the docs restate them. The vendored OBR resource is written by the generic vendoring tool, which carries no licence field; its attribution sits in the stock resources' block and the docs.
  4. OBR reconciliation. The benchmarks gate now sets the derived stock's England private-sector count over £2m beside Table 1.1 (the like-for-like figure) as well as the owner-occupied count; the fence names the coverage correction as the main sensitivity. Whether to scale the derived level to the OBR total is left to María.
  5. Thin cells. The local doctrine's scale rule becomes default_target_loss_scales_with_family_floors: the default rule with a 100-home floor for the high_value_homes/ cells (the support gate's assessment threshold), receipted on the prepared solve; every cell stays bound.
  6. Small cells in shipped details. Bands and regions resting on fewer than ten distinct source households are suppressed in the shipped gate details, with one more cell suppressed when only one would be; the stage gate rounds its survey counts to the nearest ten.
  7. Bands. The band redraw covers owner-occupiers only; renters keep the spine's band.
  8. Parity rationale. The derived family's ledger_only rows carry their own reason.
  9. --built-on is explicit on both builders; the byte-identical claim holds for the same date.
  10. Noted; policyengine-uk#2392 stays the engine-side follow-up.

Review round 2 (Vahid, 2026-10-15)

  1. Shipped regional gap (should). The benchmarks gate still tests the largest regional gap over every region, suppressed ones included, but ships only the largest over the unsuppressed regions (largest_gap in the details), and when the evaluated maximum rests on a suppressed region the failure message names the threshold it exceeds without the value. The evidence summary carries both maxima and the flag; test_benchmarks_gate_keeps_a_suppressed_regions_gap_out_of_what_it_ships pins the three cases.
  2. K (nit). The doctrine's clone count is K=15 (UK_LOCAL_CLONE_COUNT, UK local release: nation-grain doctrine at K=15 and 2,000 epochs, a 100,000-household release path, line-scoped gate exclusions, and the QRF tail surface #1242); the earlier body said K=25 by mistake. The post-merge dense build runs at the doctrine's K=15.

Rebased onto main at c28b453. The registers, parity receipts, spine fixture, coverage manifest and contract digests are regenerated on 71b9b8b (#1271, the last merge touching UK files; #1267 and #1282 touch US and NZ files only): every register regenerates byte-identical, so #1271 moved only the age-band split's four national targets and the engine lock beside this branch, and the derived family's rows are unchanged.

Verification

The full suites below ran on the tree rebased onto the #1242 branch at da026cb (identical to main at 1cfbf7d); Vahid's round-2 check confirms all ten CI jobs green at 0263998 on 121fd4d. On the current head (the UK tree of 71b9b8b, after #1271) the engine-free modules this PR touches or pins plus #1271's new spine and release-identifier modules (53 files, the two pre-existing failures below unchanged), the spine-parity acceptance test, the engine graph, coverage, identifier, birth-month and admission tests, the integration smoke on the 41-stage synthetic spine, ruff and tools/ci_test_plan.py verify ran, not the whole suite; CI runs the rest.

  • Engine-free suite (the 567 files tools/ci_test_plan.py list-job engine-free names): green except two failures that reproduce identically on the base commit with the previous feed and are unrelated to this branch: test_uk_target_references.py::test_childcare_and_bus_references_compile_with_declared_provenance (the pinned DfI NI passenger-receipts value) and test_uk_cgt_projection.py::test_engine_is_reported_unavailable_without_the_uk_extra (the local environment has the UK extra installed).
  • pytest packages/microcosm-build/tests/engine/uk: green (one pre-existing skip).
  • Integration smoke (test_uk_staging_integration.py --run-integration): green. The smoke reports four failed stage-health gates (child benefit take-up, LCFS energy rake, NTS facts, pension credit take-up); they are identical on main's synthetic fixture and non-blocking in smoke mode.
  • tools/ci_test_plan.py verify, ruff check, ruff format --check on every touched file: clean.
  • Both builders rerun byte-identically against the committed resources; the HPSSA seat-sales parity receipts are in the provenance file.
  • Compile-parity receipts: the national and production receipts are unchanged by the re-pin; the local receipt gains 2,673 ledger-only rows (the new family against an incumbent that has none) and nothing else moves.

Disclosure control

Every committed receipt is an aggregate over public data (Land Registry, HPI, NSPL, VOA, census, OBR) or a count; the per-seat support table from the licensed pool is not committed and not copied into the release directory.

After merge

One spine build and one dense build (the doctrine's K=15, 100k households, --inspection-export --staging-local-only); then a register PR on the band-H deferrals and any high_value_homes cells without support, and the #1241 freeze.

🤖 Generated with Claude Code

@vahid-ahmadi

Copy link
Copy Markdown
Contributor

Needs changes before merge: the support split nearly doubles the mass in each region's top value stratum (finding 1). The rest are should-fix items or nits.

@juaristi22, I reviewed the diff against uk-local-doctrine-k25-ngfes at 7636689.

Disclosure verdict first. Most of the 1.27m added lines are seven generated resources:

  • high_value_home_stock_facts.json
  • voa_council_tax_band_mix_lsoa.json
  • high_value_home_value_knots.json
  • local_target_references.json
  • local_target_reference_membership.json
  • the local parity differences file
  • sources.schema.json

I read every one of them. Every committed value is an aggregate of public data: Price Paid, UK HPI, NSPL, VOA CTSOP, census tenure and the OBR note. None of them holds a survey unit record, a per-seat count of survey households, or a survey-derived cell. The 2,673 new parity rows are 3 × (575 + 316) derived targets. The spine parity fixtures that changed are synthetic. The per-area support table (sources_by_area, dominance) only reaches .high_value_home_support.csv in the run directory. assemble_uk_dense_release_dir.py copies named files only, so that table doesn't reach the release directory. The address-level dwelling cache needs --cache-dir and stays out of the repo. So on the committed files, I have no disclosure blocker. Two smaller points on shipped gate details are in finding 6.

Findings

  1. must, uk_runtime/property_localisation.py:285, with the override at :300-302.

    • The problem: rank_rows = ranked & ~is_support drops the support copies' mass from the rank denominator. That is 5/6 of the selected 5%.
      • The unselected owners are then ranked over about 95.8% of the mass, so they spread up into [0.95, 1).
      • The copies then get their own draws in [0.95, 1) on top of that.
    • Synthetic probe: one region, 4,000 owners with equal weight, run through the real select_high_value_support_households and owner_uniforms.
      • Weighted owner mass with u ≥ 0.95: 0.0895 (it should be 0.05).
      • Weighted owner mass with u ≥ 0.99: 0.0174 (it should be 0.01).
      • Without the split, the share above 0.95 is 0.0500.
    • Effect: before calibration, every seat gets about 1.8 times as many £1m, £1.5m and £2m homes as its knots imply. Calibration then has to weight that away against the other local families.
    • Fix: drop & ~is_support, so the copies are ranked too (they tie with their root), and keep the override. I made that one-line change and reran the probe: 0.0500 and 0.0095.
    • Test: test_support_copies_take_a_keyed_uniform_inside_the_top_stratum has two households, so it can't see this. Please add a test over a few thousand households asserting that the weighted mass at or above stratum_lower equals the selected share.
    • Related: the docstring at high_value_home_support.py:17-20 says selection and value rank "agree by construction". They don't quite agree:
      • selection uses spine weights and breaks ties by household_id;
      • the value node uses pool weights and breaks ties with a keyed draw.
      • Worth rewording.
  2. should, tools/build_uk_high_value_home_stock.py:906-909.

  3. should (licence point; your call on the wording).

    • None of the new derived resources or their provenance carries a licence or attribution field: the stock facts, knots, band mix, provenance and obr_hvcts_costing_facts.json.
    • The inputs are Price Paid, UK HPI, VOA CTSOP and census, all OGL v3.0, plus the NSPL, which carries ONS, OS and Royal Mail notices. Each asks for an attribution statement when derived data is published.
    • Please take the exact wording from HM Land Registry's Price Paid guidance on using or publishing the data, and from the ONS NSPL licence page. Put it in a licence/attribution field on each resource and in the docs.
    • This is a repo-wide gap, but this is the first PR to commit Price Paid derivatives.
  4. should (method judgement), the OBR reconciliation.

    • The provenance gives these England counts over £2m at April 2026 prices:
      • private-sector dwellings: about 193k;
      • owner-occupied: about 116k.
    • OBR Table 1.1 counts about 165k properties in scope, across all tenures and including company-owned homes. At the note's 60% owner-occupied share, that implies about 99k owner-occupied.
    • So the bound local family sums about 17% above the OBR-implied figure, and its all-tenure base sits above the OBR all-tenure total.
    • The driver is the coverage correction.
      • It takes the owner-occupied count from about 73k (sold stock only) to 116k.
      • It assumes that dwellings never sold since 1995 follow the sold distribution within each authority.
      • The median authority ratio is 1.54 (tools/build_uk_high_value_home_stock.py:716).
    • Two other things work in the same direction:
      • LA-average HPI uprating of old prime sales;
      • OBR's 60% control being used for its share but not its level, then extended to £1m and £1.5m.
    • Suggestions:
      • have the benchmarks gate compare private_sector_dwellings, not owner-occupied, with Table 1.1;
      • name the coverage assumption as the main sensitivity in the fence text and the PR body.
    • Whether to scale the derived stock to the OBR level is a modelling choice I'd leave open.
  5. should, the thin bound cells.

    • Constituency targets over £2m: 47 are zero and about 230 are under 10 homes. There are 9 zero LA targets.
    • These come from public Price Paid aggregates (fractional, coverage-scaled), but the loss scale is max(|t|, 1). One pool clone carrying a weight of tens to hundreds of households in a seat with a target of about 3 is charged a very large relative miss.
    • initialization.py:55 refuses a nonzero target with no supporting row. The body defers "cells without support" to a register PR after merge.
    • UK: data fixes to model the High Value Council Tax Surcharge (mansion tax) correctly, and the related housing and council-tax gaps #1240 asked for tolerances that reflect the stock's uncertainty. Consider one of these:
      • bind only areas above a floor; the support gate already uses 100 homes;
      • set a loss scale floor for this family before it binds, rather than after.
  6. should, small cells in the shipped gate details.

    • high_value_home_gates.py:480-483 ships england_owner_occupied_by_band_2026, which includes the over-£5m band, plus the frame's regional shares over £2m. Both come from the calibrated pool.
      • The £5m+ band, and the £2m+ share in the northern regions, can rest on very few source households.
      • Please suppress any band or region that rests on fewer than 10 distinct source households. You already have source_household_id in hand.
    • stage_health.py:3386 ships the exact count of source households selected into the stratum.
      • Rounding it, or reporting copies and mass only, would keep it in line with the receipts rule.
  7. should, property_localisation.py:383.

    • localise_bands redraws the band for every England and Wales row from the LSOA's all-dwelling mix.
    • Renters, including social renters, take an identity uniform, so a social tenant in a band-H-heavy LSOA can draw band H. Owners' high-band share is understated by the same amount.
    • Consider drawing owners and renters from tenure-specific parts of the mix, or limiting the redraw to owners.
  8. nit, ledger_compile_parity_local_incumbent_2025_signed_differences.json:36336 onwards.

    • The 2,673 new ledger_only rows reuse the Northern Ireland SPI reason ("a published per-area fact ... Newry, Mourne and Down").
    • These are derived estimates, not published facts. A reason that says so would avoid confusion later.
  9. nit, tools/build_uk_high_value_home_stock.py:189.

    • --built-on defaults to today, so a rerun on another day isn't byte-identical, despite the "rerun byte-identically" claim.
    • Pin it, or say the claim holds for the same --built-on.
  10. note, outside this PR.

    • Moving regional_land_values to the 2024 average means "the engine uprates once", but policyengine-uk still uprates property with GDP per capita (policyengine-uk#2392).
    • So the 2028-29 values the engine sees won't move with the HPI that deflated the thresholds.

What I checked

  • I read the PR body, UK: data fixes to model the High Value Council Tax Surcharge (mansion tax) correctly, and the related housing and council-tax gaps #1240 and the full code diff:
    • the stock builder and the band-mix builder;
    • high_value_home_stock.py, high_value_homes.py, high_value_home_gates.py, high_value_home_support.py, property_localisation.py and household_lineage.py;
    • the population kernels, the terminal and CLI wiring, stage_health and the target weights.
  • I inspected the structure and contents of every generated JSON resource for survey-derived content.
  • Tests: I ran 23 test files covering the touched areas, including the five new high-value-home files and the graph, target, census, battery, contract and chronicle-feed tests. Result: 824 passed, 7 skipped.
  • ruff check and ruff format --check on the 69 touched Python files: clean.
  • Revert check: I replaced the knots interpolation in localise_values with a pass-through, and test_localise_values_interpolates_caps_and_leaves_others_untouched failed. I then restored the file.
  • The probe for finding 1 used the real functions on synthetic data only, before and after the one-line change.
  • What I couldn't check:
    • CI: none is reported on the stacked branch.
    • The integration smoke and the engine suite.
    • Reproducing the builders: that needs the Price Paid, HPI and NSPL downloads.
    • Any real-data run of the gates.

🤖 Generated with Claude Code

@juaristi22
juaristi22 force-pushed the uk-local-doctrine-k25-ngfes branch from 4f824b0 to 5fbf114 Compare October 14, 2026 14:36
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 1: the value node dropped the support copies
from the within-region rank, so the unselected owners spread up into the
stratum and the copies' own draws landed on top, nearly doubling the owner
mass above the stratum (0.0895 for a 0.05 stratum on a 4,000-owner probe).
The copies now rank beside their root, tying on value, so the mass at or
above the stratum is the selected share; a 4,000-household test asserts it
at 0.95 and 0.99. The stage docstring no longer says the selection rank and
the value rank agree by construction: they agree up to ties and up to the
spine-to-pool weight change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, findings 2, 3 and 9. The stock builder now compares
category A residential sales and medians by 2024 constituency, fiscal year
and property type with the ONS HPSSA rows in the feed, and writes the
aggregates (cells compared, median and 90th-percentile relative difference,
share within tolerance) to the provenance file: seat sales match to the
year ending March 2025 and show the registration lag for the latest year.
Every derived resource carries a licence block with the publishers'
attribution statements (HM Land Registry data under the Open Government
Licence v3.0 for Price Paid and the UK HPI, the NSPL's OS and Royal Mail
notices with ONS's OGL statement, OGL v3.0 for the VOA, census and OBR
inputs); the docs restate them. Both builders take an explicit --built-on,
so a rerun reproduces the committed bytes for the same date. The facts
rows are unchanged (same rows_sha256).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 5: the derived cells are fractional,
coverage-scaled aggregates, with hundreds of seats under ten homes over
2 million, and the default scale max(|target|, 1) charged one clone's weight
there as a miss of that many units. The local solve doctrine's scale rule
becomes default_target_loss_scales_with_family_floors: the default rule
with a floor of 100 homes for the high_value_homes/ cells, the support
gate's assessment threshold. The floor lives in target_weights; the prepared
solve carries the scales and a receipt of the rows it raised; the ordered
problem binds them, so the dense node (and the size search and refit that
inherit its scales) solves under them; the doctrine evidence and the rotated
holdout derive the same scales. The dense node still honours the plain
default that the national seam binds without row scales, since the two
rules coincide wherever no floored family has a row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, findings 4 and 6. The benchmarks gate suppresses any
England band or region that rests on fewer than ten distinct source
households in the details it ships, and one more cell when only one would
be, so the total cannot recover it; the gate still evaluates the exact
regional gap. The stage gate rounds its survey counts to the nearest ten.
The OBR leg now sets the derived stock's England private-sector count over
2 million beside Table 1.1, the like-for-like comparison, next to the
owner-occupied count the family binds, and the derived-estimate fence names
the coverage correction as the main sensitivity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 7: the VOA mix counts every dwelling in the
LSOA, so drawing renters from it handed the owners' share of the high bands
to households the value node leaves untouched. The band node now redraws
owner-occupiers only; renters keep the spine's band, and the receipt counts
them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juaristi22
juaristi22 force-pushed the uk-high-value-homes-1240 branch from 7636689 to ee360d8 Compare October 14, 2026 16:47
@juaristi22

Copy link
Copy Markdown
Collaborator Author

Thanks, @vahid-ahmadi. The branch is rebased onto the current uk-local-doctrine-k25-ngfes (3b4f899) and the review lands as six commits on top of the series; the registers, parity receipts, fixture, coverage manifest and contract digests are regenerated on the new base.

  1. Fixed. The copies are ranked beside their root (your one-line change), with the override kept. test_support_copies_keep_the_stratum_mass_at_the_selected_share runs 4,000 equal-weight owners through select_high_value_support_households and owner_uniforms and asserts the mass at or above 0.95 is 0.05 and at or above 0.99 is 0.01 (both within 0.003). The stage docstring now says the two ranks agree up to ties and the spine-to-pool weight change.
  2. Added. The builder compares category A sales counts and medians by 2024 constituency, fiscal year and property type (all plus the four types) with the HPSSA rows in the feed, using the committed support's seat for each transfer's output area. The receipt is in high_value_home_stock.provenance.json under receipts.hpssa: for the years ending March 2023 and 2024 the median seat difference in sales is zero and 99 and 94 per cent of seats are within 0.3 per cent; the year ending March 2026 differs by about 7 per cent at the median (registration lag). Medians agree to within 1 per cent for 98 to 100 per cent of seats except the latest year.
  3. Added. Each of the four stock resources and the band mix carries a licence block: "Contains HM Land Registry data © Crown copyright and database right 2026. This data is licensed under the Open Government Licence v3.0." (Price Paid, UK HPI); "Contains OS data © Crown copyright and database right 2026", "Contains Royal Mail data © Royal Mail copyright and database right 2026" and "Source: Office for National Statistics licensed under the Open Government Licence v.3.0" (NSPL, England and Wales postcodes only); OGL v3.0 for the VOA, census and OBR inputs. docs/uk-full-build-graph.md restates them. The vendored OBR resource is written by the generic vendoring tool, which has no licence field; its attribution sits in the stock resources' block and the docs.
  4. Partly taken. The benchmarks gate's OBR leg now sets the derived stock's England private-sector count over £2m beside Table 1.1 as well as the owner-occupied count, and the fence text names the coverage correction as the main sensitivity. Whether to scale the derived level to the OBR total is María's call; I have left it as a question for her.
  5. Taken, as a loss-scale floor. The local doctrine's scale rule is now default_target_loss_scales_with_family_floors: the default rule with a floor of 100 homes for the high_value_homes/ cells (the support gate's assessment threshold). It is a reviewed addition to the closed scale-rule vocabulary; the prepared solve carries the scales and a receipt of the rows raised, the ordered problem binds them so the dense node (and the size search and refit behind it) solves under them, and the doctrine evidence and the rotated holdout derive the same scales. The national seam keeps the plain default, which the dense node honours because no floored family has a row there. Every cell stays bound.
  6. Fixed. Bands and regions resting on fewer than ten distinct source households are nulled in the shipped details, with one more cell nulled when only one would be so the total cannot recover it (empty cells stay as zero); the gate still evaluates the exact regional gap. The stage gate ships households_selected_nearest_10 and copies_created_nearest_10.
  7. Taken. The band redraw covers owner-occupiers only; renters keep the spine's band. CTSOP1.1 has no tenure split, so tenure-specific mixes are not available.
  8. Fixed. The derived family's ledger_only rows carry a rationale that says they are a derived estimate with no incumbent counterpart.
  9. Fixed. --built-on is required on both builders; the byte-identical claim holds for the same date.
  10. Noted; policyengine-uk#2392 stays the engine-side follow-up.

Verification on the rebased tree: engine-free suite, engine-backed UK suite and the integration smoke, with the two pre-existing failures described in the PR body unchanged. The per-seat support table still only reaches the run directory.

🤖 Generated with Claude Code

@juaristi22
juaristi22 force-pushed the uk-high-value-homes-1240 branch from ee360d8 to 82b7240 Compare October 14, 2026 19:21
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 1: the value node dropped the support copies
from the within-region rank, so the unselected owners spread up into the
stratum and the copies' own draws landed on top, nearly doubling the owner
mass above the stratum (0.0895 for a 0.05 stratum on a 4,000-owner probe).
The copies now rank beside their root, tying on value, so the mass at or
above the stratum is the selected share; a 4,000-household test asserts it
at 0.95 and 0.99. The stage docstring no longer says the selection rank and
the value rank agree by construction: they agree up to ties and up to the
spine-to-pool weight change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, findings 2, 3 and 9. The stock builder now compares
category A residential sales and medians by 2024 constituency, fiscal year
and property type with the ONS HPSSA rows in the feed, and writes the
aggregates (cells compared, median and 90th-percentile relative difference,
share within tolerance) to the provenance file: seat sales match to the
year ending March 2025 and show the registration lag for the latest year.
Every derived resource carries a licence block with the publishers'
attribution statements (HM Land Registry data under the Open Government
Licence v3.0 for Price Paid and the UK HPI, the NSPL's OS and Royal Mail
notices with ONS's OGL statement, OGL v3.0 for the VOA, census and OBR
inputs); the docs restate them. Both builders take an explicit --built-on,
so a rerun reproduces the committed bytes for the same date. The facts
rows are unchanged (same rows_sha256).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 5: the derived cells are fractional,
coverage-scaled aggregates, with hundreds of seats under ten homes over
2 million, and the default scale max(|target|, 1) charged one clone's weight
there as a miss of that many units. The local solve doctrine's scale rule
becomes default_target_loss_scales_with_family_floors: the default rule
with a floor of 100 homes for the high_value_homes/ cells, the support
gate's assessment threshold. The floor lives in target_weights; the prepared
solve carries the scales and a receipt of the rows it raised; the ordered
problem binds them, so the dense node (and the size search and refit that
inherit its scales) solves under them; the doctrine evidence and the rotated
holdout derive the same scales. The dense node still honours the plain
default that the national seam binds without row scales, since the two
rules coincide wherever no floored family has a row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, findings 4 and 6. The benchmarks gate suppresses any
England band or region that rests on fewer than ten distinct source
households in the details it ships, and one more cell when only one would
be, so the total cannot recover it; the gate still evaluates the exact
regional gap. The stage gate rounds its survey counts to the nearest ten.
The OBR leg now sets the derived stock's England private-sector count over
2 million beside Table 1.1, the like-for-like comparison, next to the
owner-occupied count the family binds, and the derived-estimate fence names
the coverage correction as the main sensitivity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 7: the VOA mix counts every dwelling in the
LSOA, so drawing renters from it handed the owners' share of the high bands
to households the value node leaves untouched. The band node now redraws
owner-occupiers only; renters keep the spine's band, and the receipt counts
them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juaristi22
juaristi22 changed the base branch from uk-local-doctrine-k25-ngfes to main October 14, 2026 19:22
@juaristi22

Copy link
Copy Markdown
Collaborator Author

Rebased onto main at 1cfbf7d (the #1242 merge) and retargeted from uk-local-doctrine-k25-ngfes to main. The thirteen commits are unchanged in content; the registers, parity receipts, spine fixture, coverage manifest and contract digests were regenerated on the rewritten doctrine branch tip (da026cb), whose tree is what main now carries, so the suites in the PR body stand for this head.

🤖 Generated with Claude Code

@juaristi22
juaristi22 force-pushed the uk-high-value-homes-1240 branch from 82b7240 to 0263998 Compare October 14, 2026 20:36
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 1: the value node dropped the support copies
from the within-region rank, so the unselected owners spread up into the
stratum and the copies' own draws landed on top, nearly doubling the owner
mass above the stratum (0.0895 for a 0.05 stratum on a 4,000-owner probe).
The copies now rank beside their root, tying on value, so the mass at or
above the stratum is the selected share; a 4,000-household test asserts it
at 0.95 and 0.99. The stage docstring no longer says the selection rank and
the value rank agree by construction: they agree up to ties and up to the
spine-to-pool weight change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, findings 2, 3 and 9. The stock builder now compares
category A residential sales and medians by 2024 constituency, fiscal year
and property type with the ONS HPSSA rows in the feed, and writes the
aggregates (cells compared, median and 90th-percentile relative difference,
share within tolerance) to the provenance file: seat sales match to the
year ending March 2025 and show the registration lag for the latest year.
Every derived resource carries a licence block with the publishers'
attribution statements (HM Land Registry data under the Open Government
Licence v3.0 for Price Paid and the UK HPI, the NSPL's OS and Royal Mail
notices with ONS's OGL statement, OGL v3.0 for the VOA, census and OBR
inputs); the docs restate them. Both builders take an explicit --built-on,
so a rerun reproduces the committed bytes for the same date. The facts
rows are unchanged (same rows_sha256).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 5: the derived cells are fractional,
coverage-scaled aggregates, with hundreds of seats under ten homes over
2 million, and the default scale max(|target|, 1) charged one clone's weight
there as a miss of that many units. The local solve doctrine's scale rule
becomes default_target_loss_scales_with_family_floors: the default rule
with a floor of 100 homes for the high_value_homes/ cells, the support
gate's assessment threshold. The floor lives in target_weights; the prepared
solve carries the scales and a receipt of the rows it raised; the ordered
problem binds them, so the dense node (and the size search and refit that
inherit its scales) solves under them; the doctrine evidence and the rotated
holdout derive the same scales. The dense node still honours the plain
default that the national seam binds without row scales, since the two
rules coincide wherever no floored family has a row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, findings 4 and 6. The benchmarks gate suppresses any
England band or region that rests on fewer than ten distinct source
households in the details it ships, and one more cell when only one would
be, so the total cannot recover it; the gate still evaluates the exact
regional gap. The stage gate rounds its survey counts to the nearest ten.
The OBR leg now sets the derived stock's England private-sector count over
2 million beside Table 1.1, the like-for-like comparison, next to the
owner-occupied count the family binds, and the derived-estimate fence names
the coverage correction as the main sensitivity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 14, 2026
Review of PR #1270, finding 7: the VOA mix counts every dwelling in the
LSOA, so drawing renters from it handed the owners' share of the high bands
to households the value node leaves untouched. The band node now redraws
owner-occupiers only; renters keep the spine's band, and the receipt counts
them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juaristi22

Copy link
Copy Markdown
Collaborator Author

Rebased onto main at 121fd4d (after #1256, the SPI draw, merged). The thirteen commits are unchanged in content; the spine fixture, the release input coverage manifest and the contract digests were regenerated on this head. On it I ran the engine-free modules this PR touches or pins (46 files), the spine-parity acceptance test, the engine graph and release-input coverage tests and the integration smoke, all green; the full suites in the PR body ran on the previous head, whose tree differs from this one only by #1256.

🤖 Generated with Claude Code

@vahid-ahmadi

Copy link
Copy Markdown
Contributor

Fine once the largest regional gap stops exposing suppressed regions (new finding 1). Round-1 finding 1 is fixed; the rest are fixed or settled.

@juaristi22, round 2 at 0263998 (on main 121fd4d). I checked each round-1 point against the code, not only your reply.

Round-1 status

  1. Fixed. property_localisation.py:291 now ranks the copies (rank_rows = ranked). I reran my round-1 probe (4,000 equal-weight owners, real select_high_value_support_households and owner_uniforms): owner mass at u ≥ 0.95 is 0.0500 and at u ≥ 0.99 is 0.0095. The new 4,000-household test covers it, and the docstring is corrected.
  2. Fixed. _hpssa_price_paid_cells and _hpssa_parity compute the comparison, and receipts.hpssa in the provenance file matches your summary: median seat difference in sales of zero for the years to March 2023 and 2024, and about 7% for the latest year. Aggregates only.
  3. Fixed. All four stock resources and the band mix carry a licence block with the Land Registry, OS, Royal Mail and ONS statements, and the docs restate them. The OBR resource relying on the stock block is fine by me.
  4. Partly fixed, by design. The OBR leg now puts the private-sector count beside Table 1.1, and the fence names the coverage correction as the main sensitivity. Whether to scale to the OBR level is still an open decision, and I'm not taking a view on it here.
  5. Fixed. default_target_loss_scales_with_family_floors (100-home floor) reaches the dense node, the size check import, the doctrine evidence and the rotated holdout. The dense node refuses a floors rule without bound scales.
  6. Partly fixed. Bands and regions are suppressed under 10 distinct sources, with complementary suppression, and the stage gate rounds to the nearest 10. One leak is left: see new finding 1.
  7. Fixed for renters. Owners still draw from the all-dwelling mix. CTSOP has no tenure split, so I accept that limit.
  8. Fixed. All 2,673 ledger_only rows carry the derived-estimate rationale.
  9. Fixed. --built-on is required on both builders.
  10. Noted.

New findings

  1. should, uk_runtime/high_value_home_gates.py:430, shipped at :577 and printed at :564.
    • largest_gap_evaluated is the maximum over all regions, suppressed ones included. The derived-stock shares are public.
    • So when the maximum exceeds every shipped gap, it gives one suppressed region's gap and narrows its frame share to a few candidates. The total then constrains the other suppressed region.
    • Fix: ship the largest gap over the unsuppressed regions only. Keep the full maximum for the pass/fail test, and leave the value out of the failure message when it comes from a suppressed region.
  2. nit, PR body. It calls UK local release: nation-grain doctrine at K=15 and 2,000 epochs, a 100,000-household release path, line-scoped gate exclusions, and the QRF tail surface #1242 "the K=25 doctrine" and plans the after-merge dense build at K=25, but UK local release: nation-grain doctrine at K=15 and 2,000 epochs, a 100,000-household release path, line-scoped gate exclusions, and the QRF tail surface #1242's title says "nation-grain doctrine at K=15". Which K is the post-merge build meant to use?

Rebase onto main

  • A range-diff of the original seven commits against round 1 shows only regenerated JSON, contract digests and the target-count assertions moved. No source logic changed.
  • Draw SPI-channel incomes at the FRS twin's conditional rank (#840) #1256's SPI stages run before high_value_home_support in source_stages.json, so the copies inherit the SPI draw. I see no interaction.
  • The files both PRs touch are the regenerated fixture, manifest and contract digests.

Disclosure

  • I checked the six new commits, all thirteen commit messages and the PR body.
  • New committed values are public-data aggregates: the HPSSA parity receipt, the licence blocks and the parity rationale. The spine fixture changes are synthetic.
  • No survey counts or small cells are committed.
  • The per-seat source counts in the evidence summary still only feed the gates in memory. Only the gate details ship.

What I checked

  • CI on 0263998: all 10 jobs pass, including engine-uk, integration-uk and lint.
  • Locally on a fresh venv: 17 test files for the touched areas (high-value homes, property localisation, doctrine, rowwise, target weights, stage health, graph, census, source stages, spine parity, coverage manifest, contract, ledger parity). 639 passed, 5 skipped.
  • ruff check and ruff format --check on the 74 touched Python files: clean.
  • I couldn't check the builders' reruns or a real-data run of the gates.

🤖 Generated with Claude Code

juaristi22 added a commit that referenced this pull request Oct 15, 2026
Review of PR #1270, finding 1: the value node dropped the support copies
from the within-region rank, so the unselected owners spread up into the
stratum and the copies' own draws landed on top, nearly doubling the owner
mass above the stratum (0.0895 for a 0.05 stratum on a 4,000-owner probe).
The copies now rank beside their root, tying on value, so the mass at or
above the stratum is the selected share; a 4,000-household test asserts it
at 0.95 and 0.99. The stage docstring no longer says the selection rank and
the value rank agree by construction: they agree up to ties and up to the
spine-to-pool weight change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 15, 2026
Review of PR #1270, finding 5: the derived cells are fractional,
coverage-scaled aggregates, with hundreds of seats under ten homes over
2 million, and the default scale max(|target|, 1) charged one clone's weight
there as a miss of that many units. The local solve doctrine's scale rule
becomes default_target_loss_scales_with_family_floors: the default rule
with a floor of 100 homes for the high_value_homes/ cells, the support
gate's assessment threshold. The floor lives in target_weights; the prepared
solve carries the scales and a receipt of the rows it raised; the ordered
problem binds them, so the dense node (and the size search and refit that
inherit its scales) solves under them; the doctrine evidence and the rotated
holdout derive the same scales. The dense node still honours the plain
default that the national seam binds without row scales, since the two
rules coincide wherever no floored family has a row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 15, 2026
Review of PR #1270, findings 4 and 6. The benchmarks gate suppresses any
England band or region that rests on fewer than ten distinct source
households in the details it ships, and one more cell when only one would
be, so the total cannot recover it; the gate still evaluates the exact
regional gap. The stage gate rounds its survey counts to the nearest ten.
The OBR leg now sets the derived stock's England private-sector count over
2 million beside Table 1.1, the like-for-like comparison, next to the
owner-occupied count the family binds, and the derived-estimate fence names
the coverage correction as the main sensitivity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 15, 2026
Review of PR #1270, finding 7: the VOA mix counts every dwelling in the
LSOA, so drawing renters from it handed the owners' share of the high bands
to households the value node leaves untouched. The band node now redraws
owner-occupiers only; renters keep the spine's band, and the receipt counts
them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 15, 2026
PR #1270 review round 2, finding 1. The benchmarks gate's regional leg
evaluated its largest gap over every region, suppressed ones included,
and shipped and printed that value. The derived-stock shares are public,
so when the maximum came from a suppressed region the value gave back
that region's frame share, and the total then constrained the other.

The gate keeps the full maximum for its outcome but ships the largest
gap over the unsuppressed regions only, and when the evaluated maximum
rests on a suppressed region the failure message names the threshold it
exceeds without the value. The evidence summary carries both maxima and
the flag; the gate's details carry only the shipped one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juaristi22

Copy link
Copy Markdown
Collaborator Author

Thanks, @vahid-ahmadi. Round 2 is addressed at the new head, rebased onto main at c28b453 (#1271, #1267 and #1282 merged today; only #1271 touches UK files); the registers, fixture, coverage manifest and contract digests are regenerated on it, every register regenerates byte-identical, and the derived family's rows are unchanged.

  1. Fixed. The benchmarks gate keeps the maximum over every region for its outcome but ships only the largest gap over the unsuppressed regions, and when the evaluated maximum rests on a suppressed region the failure message says it exceeds the threshold in a suppressed region, without the value. The evidence summary carries largest_gap_evaluated, largest_gap_shipped and largest_gap_in_suppressed_region; the gate's details carry only the shipped maximum. test_benchmarks_gate_keeps_a_suppressed_regions_gap_out_of_what_it_ships covers the failing, passing and printed cases, and the evidence test checks that the toy pool (both regions suppressed) ships no gap at all.
  2. My mistake. The doctrine is K=15 (UK_LOCAL_CLONE_COUNT, UK local release: nation-grain doctrine at K=15 and 2,000 epochs, a 100,000-household release path, line-scoped gate exclusions, and the QRF tail surface #1242); the body said K=25 from the earlier candidate's pool. Corrected, and the post-merge dense build runs at K=15.

Finding 4 from round 1 (scaling the derived level to the OBR total) stays with María.

Verification on this head: the engine-free modules this PR touches or pins plus #1271's new spine and release-identifier modules (53 files; the two pre-existing failures described in the body unchanged), the spine-parity acceptance test, the engine graph, coverage, identifier, birth-month and admission tests, the integration smoke on the 41-stage synthetic spine, ruff check, ruff format --check and tools/ci_test_plan.py verify. The per-seat support table still only reaches the run directory.

🤖 Generated with Claude Code

juaristi22 and others added 14 commits October 15, 2026 11:37
PolicyEngine/chronicle#349 lands the inputs microcosm#1240 needs: the OBR
April 2026 costing note for the High Value Council Tax Surcharge (63 rows),
the ONS house price statistics for small areas by 2024 constituency to the
year ending March 2026 (22,940 rows), and three raw-only registrations (the
HM Land Registry Price Paid yearly files, the UK HPI full file and the NSPL)
that carry no facts and are read by the stock builder against their
registered sha256 pins. The feed grows from 927,239 to 950,242 rows; no
existing package moves, so no compiled target changes and the vendored facts
only carry the new provenance header.

The OBR note is vendored for the benchmarks gate (`obr_hvcts_costing_facts.json`),
the national references and the spine parity fixture sources are regenerated
on the new pin, and the re-pin doc records the move.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`tools/build_uk_high_value_home_stock.py` reduces the pinned Price Paid
yearly files to the latest non-bulk sale of every dwelling (identity:
postcode, PAON, SAON), uprates each sale by its local authority's and
property type's HPI to the calendar-2024 average, places it through the
NSPL output area and the committed England-and-Wales atomic support, and
counts dwellings over £1m, £1.5m and £2m (April-2026 prices deflated with
the England index) by constituency, local authority, region and nation. The
counts are owner-occupied by the census share of the private-sector stock,
rescaled to the OBR costing note's control on homes over £2m, and corrected
for stock never sold since 1995 by the VOA private-sector stock over the
valued dwellings. The outputs are consumer-fact rows under the Microcosm
derived-fact namespace, per-constituency value knots (winsorised at £20m),
the support bound the knots imply, and a provenance file with the parity
receipts and the sensitivities.

`tools/build_uk_voa_band_mix.py` turns the pinned CTSOP1.1 tables into
cumulative band shares per England-and-Wales LSOA. The loader module
validates every resource against its recorded hashes and the atomic support
pin, and exposes the thresholds, metric names and owner masks the rest of the
build shares (microcosm#1240 fix 2).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The local surface compiles the derived stock beside the Chronicle feed:
three contract targets (`microcosm.high_value_homes.over_1m|over_1_5m|over_2m`,
provider `microcosm`) bind at constituency and local-authority grain for
England and Wales, with no higher control declared, the
`high_value_home_stock_derived_estimate` fence adjudicated to 2026-12-31 and
the generic support-floor deferral on the Isles of Scilly and the City of
London. The frame metrics read the stored `main_residence_value` at the
dataset period for owner households.

`generate_uk_local_target_references.py` takes `--derived-facts`, the
compile-parity and release-cut tools merge the same rows, the full-targets
provenance records the derived resource, and the census, local references,
membership and parity receipts are regenerated on the 735820c pin (575
seats and 316 authorities active per threshold).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two report-only gates on the calibrated pool (microcosm#1240 fix 8):
`uk_high_value_homes_benchmarks` sets England owner-occupied homes by
surcharge band beside OBR Table 1.1, the regional split of homes over £2m
beside the derived stock, and the seat rank correlations against the derived
stock and VOA band H; `uk_high_value_homes_support` counts areas by band of
distinct source households above £1.5m and £2m, with dominance. The per-area
support table is a candidate artifact (`.high_value_home_support.csv`) that
stays in the run directory; the shipped details carry counts only. Both
gates sit in the local diagnostic scope and outside certification.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
After geography derivation, `uk.full.property.value` and
`uk.full.property.band` (`--property-localisation price_paid`, the default on
the atomic assignment) read every England-and-Wales owner clone's
`main_residence_value` off its assigned constituency's uprated Land Registry
sale distribution at the household's weighted rank among its region's owners,
move `property_wealth` by the same amount, and draw `council_tax_band` from
the assigned LSOA's VOA band mix at the same uniform. The uniform is keyed on
the spine household, so every pool clone of one household shares it whatever
K is; high-value support copies take a keyed rank inside the top stratum.
Scotland and Northern Ireland keep the spine's values and bands. The draw is
a typed artifact the band node and the pool consume, the resource digests
enter the size-checkpoint identity and the candidate manifest, and
`uk_support` binds the rewritten columns to the knots' cap
(microcosm#1240 fixes 3 and 4).

`regional_land_values.json` moves from the December-2025 HPI level to the
calendar-2024 average so the stored value sits at the dataset period's prices
and the engine's annual uprating projects it once (fix 5).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The `high_value_home_support` stage after `regional_property_uprating`
copies every owner household in the top five per cent of its region's value
rank six ways at equal weight, each copy carrying
`high_value_support_copy_index` (the lineage the geography identity keys
on), so the few tail households spread across seats once the value node
gives each copy its own keyed rank inside the stratum. Mass is conserved
exactly (`uk_stage_high_value_home_support_mass`). The spine graph, the
kernel tables, the coverage manifest, the operation vocabulary and the spine
parity fixture (41 stages) move with it (microcosm#1240 fix 1).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review of PR #1270, finding 1: the value node dropped the support copies
from the within-region rank, so the unselected owners spread up into the
stratum and the copies' own draws landed on top, nearly doubling the owner
mass above the stratum (0.0895 for a 0.05 stratum on a 4,000-owner probe).
The copies now rank beside their root, tying on value, so the mass at or
above the stratum is the selected share; a 4,000-household test asserts it
at 0.95 and 0.99. The stage docstring no longer says the selection rank and
the value rank agree by construction: they agree up to ties and up to the
spine-to-pool weight change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review of PR #1270, findings 2, 3 and 9. The stock builder now compares
category A residential sales and medians by 2024 constituency, fiscal year
and property type with the ONS HPSSA rows in the feed, and writes the
aggregates (cells compared, median and 90th-percentile relative difference,
share within tolerance) to the provenance file: seat sales match to the
year ending March 2025 and show the registration lag for the latest year.
Every derived resource carries a licence block with the publishers'
attribution statements (HM Land Registry data under the Open Government
Licence v3.0 for Price Paid and the UK HPI, the NSPL's OS and Royal Mail
notices with ONS's OGL statement, OGL v3.0 for the VOA, census and OBR
inputs); the docs restate them. Both builders take an explicit --built-on,
so a rerun reproduces the committed bytes for the same date. The facts
rows are unchanged (same rows_sha256).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review of PR #1270, finding 5: the derived cells are fractional,
coverage-scaled aggregates, with hundreds of seats under ten homes over
2 million, and the default scale max(|target|, 1) charged one clone's weight
there as a miss of that many units. The local solve doctrine's scale rule
becomes default_target_loss_scales_with_family_floors: the default rule
with a floor of 100 homes for the high_value_homes/ cells, the support
gate's assessment threshold. The floor lives in target_weights; the prepared
solve carries the scales and a receipt of the rows it raised; the ordered
problem binds them, so the dense node (and the size search and refit that
inherit its scales) solves under them; the doctrine evidence and the rotated
holdout derive the same scales. The dense node still honours the plain
default that the national seam binds without row scales, since the two
rules coincide wherever no floored family has a row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review of PR #1270, findings 4 and 6. The benchmarks gate suppresses any
England band or region that rests on fewer than ten distinct source
households in the details it ships, and one more cell when only one would
be, so the total cannot recover it; the gate still evaluates the exact
regional gap. The stage gate rounds its survey counts to the nearest ten.
The OBR leg now sets the derived stock's England private-sector count over
2 million beside Table 1.1, the like-for-like comparison, next to the
owner-occupied count the family binds, and the derived-estimate fence names
the coverage correction as the main sensitivity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review of PR #1270, finding 7: the VOA mix counts every dwelling in the
LSOA, so drawing renters from it handed the owners' share of the high bands
to households the value node leaves untouched. The band node now redraws
owner-occupiers only; renters keep the spine's band, and the receipt counts
them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The branch is rebased onto uk-local-doctrine-k25-ngfes at 3b4f899, which
retired the 2023 production parity receipt and moved the national targets.
The national references, the local census, the local references and
membership, the two remaining compile-parity receipts, the data-target
parity register, the spine fixture, the release input coverage manifest and
the release-contract digests are regenerated on it. The derived family's
ledger_only parity rows carry their own rationale (review finding 8).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
PR #1270 review round 2, finding 1. The benchmarks gate's regional leg
evaluated its largest gap over every region, suppressed ones included,
and shipped and printed that value. The derived-stock shares are public,
so when the maximum came from a suppressed region the value gave back
that region's frame share, and the total then constrained the other.

The gate keeps the full maximum for its outcome but ships the largest
gap over the unsuppressed regions only, and when the evaluated maximum
rests on a suppressed region the failure message names the threshold it
exceeds without the value. The evidence summary carries both maxima and
the flag; the gate's details carry only the shipped one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juaristi22
juaristi22 force-pushed the uk-high-value-homes-1240 branch from e851e76 to e1a65e2 Compare October 15, 2026 10:39
@juaristi22
juaristi22 merged commit 5792966 into main Oct 15, 2026
10 checks passed
juaristi22 added a commit that referenced this pull request Oct 15, 2026
uk_council_tax_band_domain runs at the spine's transferred boundary, and the
full build carries that report forward instead of evaluating it again, so a
later step that writes council_tax_band (#1270's band redraw after geography
derivation) was checked by nothing. uk_council_tax_band_domain_terminal is
the same release-blocking check at the terminal phase; a test pins its
parameters to the spine entry's. The release-cut scope owns it, so in the
full build a failure stops the build rather than counting as a local export
exception. Contract mirrors added and five gate digests re-pinned. Vahid's
review, finding 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 15, 2026
uk_council_tax_band_domain runs at the spine's transferred boundary, and the
full build carries that report forward instead of evaluating it again, so a
later step that writes council_tax_band (#1270's band redraw after geography
derivation) was checked by nothing. uk_council_tax_band_domain_terminal is
the same release-blocking check at the terminal phase; a test pins its
parameters to the spine entry's. The release-cut scope owns it, so in the
full build a failure stops the build rather than counting as a local export
exception. Contract mirrors added and five gate digests re-pinned. Vahid's
review, finding 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Oct 15, 2026
#1270 merged first, so this branch regenerates rather than merging the
registers by hand. From the 735820c feed main now pins (the consumer
artifact rebuilt from PolicyEngine/chronicle at 735820c and checked against
its pinned row count and facts digest), the local references, the membership
and the local parity receipt are regenerated: 24,269 active local references,
main's 24,477 less the same 208 small-cell cells, and 1,796 reviewed
exclusions. The scorer's frozen count, the battery pin, the runbook and the
receipts move with them. local_binding_adjudications.json keeps the six
renewals and #1270's high_value_home_stock_derived_estimate entry;
local_targets.py keeps both imports; the parity tool keeps #1270's derived
stock rationale beside the small-cell one. The gate digests, the H2 spine
fixture and the coverage manifest are regenerated. The C1 receipt now says
its twin spines were measured before the rebases, on a shell redraw neither
rebase touches.

This commit sets the tree to the tested merge of the branch and main; the
replayed commits before it resolved conflicts toward the branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants