Skip to content

Add UK high-value housing sources: OBR surcharge costing, ONS house prices by constituency, and Price Paid, UK HPI and NSPL registrations - #349

Merged
juaristi22 merged 4 commits into
mainfrom
issue-343-uk-high-value-housing
Oct 13, 2026
Merged

juaristi22 merged 4 commits into
mainfrom
issue-343-uk-high-value-housing

Conversation

@juaristi22

@juaristi22 juaristi22 commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds the published sources #343 asks for, so Microcosm can build local targets for high-value owner-occupied homes. There are two fact packages (23,003 facts) and four raw-only registrations. Field contracts, licences and parity are in docs/data-sources/uk-high-value-housing.md.

Fact packages

  • OBR costing of the high value council tax surcharge (2 April 2026), obr-hvcts-costing-april-2026: 63 facts for England, typed model_output / source_projection.
    • Table 1.1, estimated properties in scope by band, static, 2028-29 to 2030-31: 71k, 54k, 25k and 15k in 2028-29, 165k in total.
    • Table 1.2, the same post-behaviour: 66k, 53k, 24k and 14k in 2028-29, 156k in total.
    • Table 1.5, the costing, 2026-27 to 2030-31, every line. In 2028-29 the static costing is −£605m and the post-behavioural costing −£400m. The table's own convention applies: negative is a reduction in PSNB.
    • Paragraph 1.13:
      • 40% of liable properties are non-owner-occupied;
      • 14% of affected properties have non-UK resident owners;
      • support-scheme take-up is 75%, carried with the constraint household_net_income < 30000.
  • ONS house price statistics for small areas by parliamentary constituency, year ending March 2026 edition (released 17 September 2026), ons-hpssa-pcon24-year-ending-march-2026: 22,940 facts.
    • Sales counts (Tables 1a to 1e) and median price paid (2a to 2e), for all types and each of the four property types.
    • All 575 England and Wales constituencies, for the years ending March 2023, 2024, 2025 and 2026.
    • Boundaries: July 2024. The workbook's codes are exactly the set in ons-oa21-pcon-jul2024-lookup.

Raw-only registrations. These follow the precedent of #269 and the UK local rents (registration_kind: raw_only): there is no package, alias or bundle entry, and nothing is parsed into facts. None of their bytes is committed: each file entry is marked storage.local: false, and R2 holds the bytes.

  • hmlr-price-paid-data-yearly-august-2026: HM Land Registry Price Paid Data, August 2026 release (published 29 September 2026). It is the 32 yearly files, pp-1995.csv to pp-2026.csv, keyed by year in one manifest.
  • hmlr-price-paid-data-monthly-update-august-2026: the same release's change file, with record status A/C/D.
  • hmlr-uk-hpi-full-file-july-2026: the UK House Price Index full file. It has index (January 2023 = 100), average price and sales by area, month and breakdown. The 317 England and Wales local authorities run from January 1995 to July 2026.
  • ons-nspl-august-2026: the National Statistics Postcode Lookup. It covers 2,729,090 current and terminated postcodes and maps each to oa21cd, lad26cd and pcon24cd, among other geographies.

Code:

  • hmlr joins the UK publishers in R2_COUNTRY_PUBLISHERS, so its keys sit under raw/uk/.
  • chronicle/artifacts.py reads the new storage.local: false marker. inventory-artifacts and publish-raw accept an R2-only entry without a local copy, so both stay valid over db/data on a fresh clone. They still check (and publish-raw uploads) the bytes when a local copy is present. verify-raw checks the R2 object. An entry marked R2-only with no R2 location is an error. Inventory counts gain r2_only_count, and publish counts gain skipped_count.
  • The two packages are registered in the alias table and the UK bundle. - scripts/build_uk_high_value_housing_packages.py writes both packages from the pinned bytes, and every selector it emits is matched against publisher text.

Fixes #343.

Review notes

Representation: the issue asked Chronicle to confirm these.

  • Price Paid is registered raw-only, as record-level identity, not as facts. Each row is one transfer, and every aggregate the issue lists (latest sale per property, category A, uprated, above a threshold, by area) is Microcosm's computation.
  • Yearly files, not pp-complete.csv.
    • publish-raw uploads through wrangler r2 object put, which refuses files above 300 MiB (MAX_UPLOAD_SIZE in wrangler's source). The complete file is 5,525,539,417 bytes; the largest yearly file (pp-2002.csv) is 239,344,429 bytes.
    • The 32 yearly files of a release are exactly the complete file's rows split by year of transfer. Order-independent row digests by year agree with this release's pp-complete.csv (31,610,742 rows).
  • Monthly revisions: each release is a new pair of registrations under its own directories, pinned by sha256. Chronicle does not apply a change file.
  • The UK HPI is registered raw-only too. Microcosm uses it as an uprating lookup, January 1995 onward, by local authority and property type. That is about two million published cells, beyond the bundle's scale as facts. Its bytes are in R2 only: each monthly full file (35 MB) revises the last, and nothing in Chronicle parses it. The Isles of Scilly (E06000053) have no HPI series, which the doc flags for Microcosm's uprating join.
  • ONS reference years. Only the four years ending March are ported. They are fiscal years and do not overlap. The other 118 rolling years and the lower-quartile tables are not ported. The 60 medians ONS suppresses as [x] emit no fact.
  • OBR paragraph parameters carry 2028-29, the charge's first year, because the note dates none of them. Each record set says so. Tables 1.3 and 1.4 are not ported.

Storage and licences:

  • Price Paid, NSPL and UK HPI bytes are in R2 only, the first registrations of that kind, with .gitignore entries and the storage.local: false marker.
    • Price Paid's address fields are Royal Mail and Ordnance Survey data. HM Land Registry permits them for personal or non-commercial use and for residential price information services, and this repository is public.
    • The NSPL zip is 185 MB, above GitHub's file limit. Its user guide also requires a separate LPS licence for commercial use of Northern Ireland (BT) postcodes.
    • The private ledger-raw bucket holds the bytes for provenance; nothing is redistributed.
    • The doc gives each source's licence and required attribution, including the UK HPI's prescribed HM Land Registry statement, the OBR note's and the ONS workbook's.
  • R2 upload: done. publish-raw uploaded all 37 new artifacts to ledger-raw in the PolicyEngine account. verify-raw then fetched each one back and matched its sha256 and size: 37 of 37 verified.

Parity (all public aggregates):

  • Price Paid rows by year of transfer for this release are tabled in the doc. Every row has 16 fields; record status is A throughout the yearly files, and C and D appear only in the change file.

  • pp-2024.csv has 931,453 rows in this release (763,905 category A). That is not the 881,757 the issue quotes, which matches neither.

  • The ONS seat sums against this release's category A sales of D/S/T/F, by year ending March:

    year ending March Price Paid, this release ONS, 575 seats difference
    2023 873,130 872,848 +282 (0.03%)
    2024 692,752 692,252 +500 (0.07%)
    2025 855,338 853,195 +2,143 (0.25%)
    2026 707,700 659,366 +48,334 (7.33%)

    The gap grows towards the latest year, which fits registrations lodged after ONS's extract.

  • The ONS workbook has no England and Wales total row, so the issue's in-file parity check cannot run. The tests pin the seat sums instead, and check that the four property types partition each seat-year.

Chronicle Governance

  • Approved Chronicle agent roles:
    • ledger-source-ingestor for the packages and registrations.
    • ledger-contract-maintainer for the storage.local manifest field and its handling in chronicle/artifacts.py.
  • Outside the ingestor's allowed paths:
    • chronicle/artifacts.py, chronicle/source_package.py and chronicle/bundle.py (registration, as every package PR does, plus the marker);
    • db/data/**;
    • scripts/build_uk_high_value_housing_packages.py;
    • docs/data-sources/uk-high-value-housing.md, docs/pe-uk-source-checklist.md, changelog.d/343.added.md, .gitattributes and .gitignore;
    • tests/test_issue_343_uk_high_value_housing.py and tests/test_chronicle_artifacts.py;
    • README.md and docs/agent-source-package-harness.md (the marker).
  • Deterministic checks run:
    • validate-package and build-suite for both packages: valid, with 0 agent-acceptance errors and lineage coverage 1.0.
    • Every one of the 22,940 ONS facts equals its workbook cell, checked independently of the package.
    • The full default bundle is valid: 1,030,137 facts after the rebase (main's 1,007,134 plus 23,003), 379 packages and 321 source tables. tests/test_chronicle_bundle.py is re-pinned.
      • No new duplicate keys and no new geography keys.
      • One new warning, publisher wording kept as published: ONS's 'Semi-detached houses' against DESNZ's 'Semi detached' for property_type=semi_detached.
    • On a simulated fresh clone (db/data without any git-ignored bytes), inventory-artifacts over db/data is valid: 408 entries, 0 missing, 35 R2-only. publish-raw skips the 35 R2-only entries. A test checks the same on copies of the four manifests.
    • verify-raw confirms all 37 new R2 objects against their pins.
    • .gitignore covers every uncommitted file, and a test checks it.
  • LLM judge verdicts:
    • ledger-source-fidelity: pending specialist review. Every fact is a publisher cell, guarded by its line text, table title or column header. The tests pin the published values.
    • ledger-contract: pending specialist review. No fact, consumer-contract or identity change. The manifest gains an optional storage.local boolean, and the R2 routing gains a publisher.
    • ledger-boundary: pending specialist review. The OBR values are publisher projections. De-duplication, category filtering, uprating, the owner-occupier adjustment, threshold counts and target binding all stay in Microcosm, as the issue's "Out of scope" lists.

Tests

  • uv run pytest -q (the full suite, run as two parts) on Python 3.13, before the rebase:
    • tests/test_chronicle_bundle.py: 25 passed;
    • everything else: 5,115 passed, 3 skipped.
  • After the rebase and review round one:
    • tests/test_issue_343_uk_high_value_housing.py and tests/test_chronicle_artifacts.py: 63 passed, 1 skipped (the opt-in large-bytes check). With LEDGER_VERIFY_LARGE_RAW=1, all 64 pass.
    • tests/test_chronicle_source_package.py, test_uk_atomic_area_raw_sources.py, test_chronicle_uk_local_2025.py, test_chronicle_boundaries.py and test_chronicle_governance.py: 215 passed.
    • The re-pinned bundle test was not rerun locally (it takes about an hour). The rebase only composed its pins with main's; CI's Chronicle bundle runs it.
  • tests/test_issue_343_uk_high_value_housing.py (18 tests) covers:
    • fact counts and validity;
    • the published OBR values, and that Table 1.5's lines add up;
    • the stated parameters and their constraint;
    • the ONS seat set against ons-oa21-pcon-jul2024-lookup;
    • the property-type partition and pinned seat sums;
    • the suppressed-median count;
    • each raw registration's identity, R2 key and storage.local: false marker;
    • inventory and publish-raw staying valid without the bytes;
    • the yearly files fitting under the wrangler cap;
    • the git-ignore rules;
    • the Price Paid field contract on the monthly file, and the UK HPI header and coverage.
    • With LEDGER_VERIFY_LARGE_RAW=1 it also hashes the uncommitted bytes against their pins. That passes locally on all 35 uncommitted files, 5.8 GB.
  • tests/test_chronicle_artifacts.py adds six tests for the marker:
    • inventory accepts absent R2-only bytes, still checks present ones, and rejects a malformed marker or a missing R2 location;
    • publish-raw skips absent bytes, uploads present ones keeping the marker, and refuses an entry without an R2 location.
  • uv run ruff check chronicle policyengine_chronicle db scripts tests: passed. ruff format --check passes on the new Python files.
  • git diff --check: clean.

🤖 Generated with Claude Code

@vahid-ahmadi

Copy link
Copy Markdown

Automated review pass (Claude Code, high effort), round 1 at 66c47b52

Thanks María. Verdict: good to merge after one should-fix (the raw-artifact tooling now fails on a fresh clone). Every fact I checked matches the publisher's file, and the ONS and HPI files are byte-identical to today's live downloads. The rest are small doc points.

Findings

  1. Should: inventory-artifacts and publish-raw over db/data now fail on every fresh clone.
    • The 33 Price Paid files and the NSPL zip are declared in manifests but, by design, never committed. Both commands treat an absent local file as an entry error (missing_file, chronicle/artifacts.py:1636-1637 for the inventory and :1516-1517 for publish), and both reports are valid only if every entry is (chronicle/artifacts.py:200-202, :263-265).
    • I ran inventory-artifacts --root db/data at this head: 408 entries, 374 valid, and the 34 new R2-only entries all missing_file, so valid: false. Every other entry passes, so this PR is what flips it.
    • README.md:391-395 and docs/agent-source-package-harness.md:19-21 tell contributors and agents to run exactly these commands over db/data. The next person who does so gets 34 errors, and an agent may well try to "fix" them by downloading 5.7 GB.
    • The PR's "inventory-artifacts is valid for all 37" holds only on a machine that has the bytes.
    • Fix: a manifest marker for R2-only bytes (for example storage.local: false) that inventory-artifacts and publish-raw skip locally and leave to verify-raw. If that's too much for this PR, a README line saying to narrow --root to the package directory would do for now.
  2. Should-consider: the UK HPI full file is committed, but nothing builds from it.
    • UK-HPI-full-file-2026-07.csv is 35,012,747 bytes and 151,921 lines, about a third of the PR's line count. It becomes the largest raw CSV in db/data (the previous largest is the 27 MB OA21 parish lookup).
    • Committing isn't wrong: OGL allows it, and big committed packages have precedent (the DWP UC constituency package is 47 MB). But this one is raw-only, and the doc says each monthly release revises earlier months, so each new HPI vintage would add another 35 MB to history.
    • Holding it in R2 only, like Price Paid and NSPL, would keep the repo lean. test_uk_hpi_full_file_header (tests/test_issue_343_uk_high_value_housing.py:523) could skip when the bytes are absent, as the Price Paid field-contract test already does (:494-501). Your call. If it stays, a sentence in the Storage section on why HPI is committed and Price Paid isn't would help.
    • The ONS package YAML (7.4 MB, 254k lines) is in line with existing packages, so no concern there.
  3. Licence attribution gaps in docs/data-sources/uk-high-value-housing.md.
    • :208 gives the UK HPI licence as plain "Open Government Licence v3.0". OGL v3.0 requires an attribution statement, and the doc gives one for Price Paid (:89-91) and the NSPL (:231-233) but not for the HPI. The HPI is the only one of the four raw files that this public repo actually redistributes, so it needs one most. It is a joint HM Land Registry, ONS, Registers of Scotland and LPS product, so the statement should credit all four.
    • The two fact packages have no section in the doc. The PR description says the licences are there, but nothing covers the ONS workbook (the cover sheet asks for "Source: Office for National Statistics", adapted from HM Land Registry data under OGL v3.0) or the OBR note. A short section for each, with licence, vintage and retrieval date, would match the raw-only sections.
  4. Changelog wording, changelog.d/343.added.md:1. It says Price Paid is registered as the "complete file and monthly change file". The registration is the 32 yearly files, and the PR deliberately avoids pp-complete.csv.
  5. Nit, for the Microcosm join: the Isles of Scilly have no UK HPI series. The HPI full file has 317 England and Wales local authorities for July 2026. The NSPL's LAD code list (in the same zip) has 318. The one missing is E06000053 (Isles of Scilly). A Price Paid → NSPL lad26cd → HPI uprating join therefore drops Scilly postcodes unless Microcosm falls back to Cornwall or the South West. One line under "What stays in Microcosm" would flag it.

What I checked

  • Code and contract.
    • The only code changes are hmlr added to the UK R2 publishers and the two aliases and bundle entries. No earlier manifest uses source_id: hmlr, so the routing change moves no existing key.
    • The builder asserts every selector against publisher text. ONS seats must be exactly 575, E14001/W07000 codes, identical across all 10 sheets. The OBR lines are matched by page, prefix and number count.
    • Fiscal years are stamped by opening year, as the builder documents, which matches the bundle's existing fiscal_year: keys: year ending March 2026 → fiscal_year:2025, and OBR 2028-29 → 2028.
    • The re-pinned bundle counts in tests/test_chronicle_bundle.py add up: 63 + 22,940 = 23,003.
  • Tests.
    • tests/test_issue_343_uk_high_value_housing.py: 15 passed, 2 skipped (the two that need the uncommitted Price Paid bytes).
    • tests/test_chronicle_artifacts.py and the source-package tests: 164 passed.
    • Against base a5280e1, the new file fails as it should: the packages and manifests don't exist there.
    • I stopped my local bundle test, which takes about two hours. CI's Chronicle bundle ran it green at this head.
  • ONS constituency workbook.
    • I downloaded the live file from the manifest URL. Its sha256 e5a1d593… is identical to the pinned file.
    • In an independent pass, all 22,940 facts equal their workbook cells. There are 23,000 cells, and the 60 [x] are skipped. Every fact carries constituency / pcon_2024.
    • Spot checks against the live file, median price for the year ending March 2026:
      • Kensington and Bayswater (E14001310): £1,065,000;
      • Cities of London and Westminster (E14001172): £973,000;
      • Chelsea and Fulham (E14001160): £849,000;
      • Hampstead and Highgate (E14001265): £872,500;
      • Merthyr Tydfil and Aberdare (W07000099): £153,000.
    • Also against the live file: detached houses in Kensington and Bayswater £7,250,000, and Chelsea and Fulham detached [x] with no fact. Sales counts: Chelsea and Fulham 1,280, Cities of London and Westminster 1,113.
  • OBR note.
    • obr.uk sits behind a Cloudflare challenge, so I couldn't re-download it to compare hashes. I checked the pinned PDF instead: its metadata says created 2 April 2026, and I read the text.
    • Table 1.1, 2028-29: 71k / 54k / 25k / 15k, total 165k. Table 1.2: 66k / 53k / 24k / 14k, total 156k.
    • Table 1.5: static −605 / −620 / −635 and post-behavioural −400 / −430 / −435 for 2028-29 to 2030-31, and +120 / +155 in 2026-27 and 2027-28. Paragraph 1.15's £0.4bn yield agrees.
    • Paragraph 1.13: 40%, 14% and 75%, with the £30,000 threshold.
    • All match the facts, with value scales ×1,000 and ×£1m.
    • As a sense check, the bands times the charges (£2,500 to £7,500) give about £604m, which matches the £605m static costing.
  • UK HPI.
    • The live file at the manifest URL is byte-identical: sha256 654a5419…, 35,012,747 bytes.
    • England has index 100 in January 2023, confirming the base. July 2026: England index 102.7 (average £293,479), UK 104.5 (£272,611).
  • Price Paid.
    • HEAD on the live URLs gives the pinned sizes: pp-2024.csv 162,424,209, pp-2026.csv 67,147,774, and the monthly file 15,840,574. All were last modified 28 September 2026.
    • These URLs are overwritten each month (the September release is due around the end of October). After that, R2 is the only copy of these bytes, and the doc already says so.
    • The licence notes match HM Land Registry's terms: OGL plus the Royal Mail and OS address-data restriction. Keeping the bytes out of a public repo is the right call.
  • NSPL.
    • The ArcGIS item is "National Statistics Postcode Lookup (August 2026)", and its size, 185,109,467 bytes, matches the pin.
    • I read the zip's directory and the first lines of Data/NSPL_AUG_2026_UK.csv through HTTP range requests. The header has 35 fields, including oa21cd, lad26cd and pcon24cd, so constituencies are on the July 2024 boundaries. The bundled constituency code list is "as at 12_24".
    • The manifest's LPS note on Northern Ireland postcodes matches the user guide's requirement.
  • R2. I couldn't fetch the 37 R2 objects myself (no bucket access here), so for storage I'm relying on your verify-raw report (37 of 37). All 37 manifest keys equal what build_r2_key produces from the pinned sha256, under raw/uk/.
  • Fit with uk-mansion-tax-microdata Establish Arch data foundation #1. The stock-based map there needs Price Paid (latest sale per property), HPI uprating and NSPL geography. All three are now pinned. The ONS constituency facts are sales flows, so they suit validation rather than a stock count. Note that the year ending March 2026 seat sums sit 7.3% below Price Paid because of registration lag, as your parity table shows.

CI at this head: Chronicle bundle, Chronicle checks and Chronicle surface all pass.

juaristi22 and others added 4 commits October 13, 2026 10:34
chronicle#343 sections 3 and 5. obr-hvcts-costing-april-2026 ports Tables
1.1, 1.2 and 1.5 of the OBR's 2 April 2026 costing of the high value council
tax surcharge and three parameters stated in paragraph 1.13, as source
projections for England (63 facts). ons-hpssa-pcon24-year-ending-march-2026
ports sales counts and median price paid by July 2024 constituency and
property type for the years ending March 2023 to 2026 (22,940 facts).
scripts/build_uk_high_value_housing_packages.py writes both from the pinned
bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chronicle#343 sections 1, 2 and 4. HM Land Registry Price Paid Data
(August 2026 release: the 32 yearly files and the monthly change file), the
UK House Price Index full file (July 2026) and the National Statistics
Postcode Lookup (August 2026) are pinned by sha256 and archived in R2, with
no package, alias or bundle entry.

None of their bytes is committed. Price Paid's address fields carry Royal
Mail and Ordnance Survey terms that limit them to non-commercial use, the NSPL
zip is above GitHub's file limit, and each monthly UK HPI full file revises
the last. The yearly Price Paid files stand in for pp-complete.csv, which
wrangler's 300 MiB object-put cap keeps out of publish-raw. hmlr joins the UK
R2 publishers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Field contracts, licences and parity for the raw releases go in
docs/data-sources/uk-high-value-housing.md, and the source checklist gains a
section. The default bundle grows by 23,003 facts and two packages, with one
new publisher-wording warning (semi-detached).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Mark R2-only bytes with storage.local: false. inventory-artifacts and
  publish-raw accept such an entry without a local copy (they still check and
  upload the bytes when present), so both stay valid over db/data on a fresh
  clone; an R2-only entry without an R2 location is an error.
- Keep the UK HPI full file in R2 only, like Price Paid and the NSPL; its
  header test skips when the bytes are absent.
- Give the UK HPI its prescribed attribution, add sections for the OBR note
  and the ONS workbook, flag the Isles of Scilly's missing HPI series, and
  correct the changelog's Price Paid wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@juaristi22
juaristi22 force-pushed the issue-343-uk-high-value-housing branch from 66c47b5 to f41cb29 Compare October 13, 2026 09:49
@juaristi22

Copy link
Copy Markdown
Collaborator Author

Thanks Vahid. I rebased onto main (at 130b95b); the bundle pins are composed with main's: 1,007,134 + 23,003 = 1,030,137. Round one is addressed in f41cb29.

  1. Fresh-clone failure (should). Fixed with the marker you suggested.
    • Each file entry of the four raw-only registrations (35 entries) now carries storage.local: false.
    • inventory-artifacts and publish-raw accept such an entry without a local copy.
      • When the copy is present they still check it, and publish-raw uploads it.
      • An absent copy is reported as r2_only in the inventory and skipped by publish-raw.
      • verify-raw is unchanged and checks the R2 object.
      • The counts gain r2_only_count and skipped_count.
    • An R2-only entry with no storage.r2 location, or a non-boolean local, is an error.
    • On a copy of db/data without any git-ignored bytes, inventory-artifacts --root db/data is valid: 408 entries, 0 missing, 35 R2-only. publish-raw skips all 35.
    • README.md and docs/agent-source-package-harness.md explain the marker, including that a missing R2-only file is not something to fix by downloading.
    • Tests: six in tests/test_chronicle_artifacts.py, plus one in the High-value housing facts for the UK local calibration: HM Land Registry Price Paid Data, UK HPI, ONS house price statistics by constituency, the National Statistics Postcode Lookup, and the OBR High Value Council Tax Surcharge costing #343 module that runs both commands on copies of the four manifests without bytes.
  2. UK HPI committed (should-consider). Moved to R2 only, like Price Paid and the NSPL.
    • The CSV is gone from every commit on the branch, not just from the tip.
    • test_uk_hpi_full_file_header skips when the bytes are absent, and now also pins the Scilly gap.
    • The Storage section and the .gitignore comment give the reason: each monthly release revises the last, and nothing in Chronicle parses it.
  3. Licence attribution.
    • The UK HPI section credits HM Land Registry, ONS, Registers of Scotland and LPS as producers. It quotes the attribution statement HM Land Registry prescribes in About the UK House Price Index. That statement names HM Land Registry only, so I used it verbatim rather than writing a four-way one.
    • New sections cover the OBR note (OBR copyright page, OGL) and the ONS workbook (OGL; adapted from HM Land Registry data; "Source: Office for National Statistics"). Each gives the release, retrieval date, sha256 and size.
  4. Changelog. Now says the 32 yearly files and the monthly change file, and mentions the marker.
  5. Isles of Scilly. Confirmed: E06000053 has no UK HPI series, and the NSPL places 113 postcodes there (94 live). The HPI section and "What stays in Microcosm" flag it, suggesting a fallback to Cornwall (E06000052) or the South West.

While checking the NSPL text I also confirmed one claim the doc made. For all 2,413,799 England and Wales postcodes, live and terminated, NSPL's pcon24cd equals the constituency that ons-oa21-pcon-jul2024-lookup gives through oa21cd. The doc now says so.

Tests after the rebase and this round:

I didn't rerun the hour-long bundle test after the rebase. It only composes pins, and CI's Chronicle bundle runs it.

🤖 Generated with Claude Code

@vahid-ahmadi

Copy link
Copy Markdown

Automated review pass (Claude Code, high effort), round 2 at f41cb29d

Thanks María, re-reviewed at f41cb29d. Verdict: all five round-1 points are fixed and I found nothing new that blocks this. Good to merge once CI has run green at this head (both jobs were still queued when I posted).

Round-1 points

  1. Fresh-clone failure: fixed.
    • In a fresh worktree at this head (no git-ignored bytes), inventory-artifacts --root db/data is valid: true: 408 entries, 0 missing, 35 r2_only (32 yearly Price Paid files, the monthly file, the HPI and the NSPL), 0 checksum mismatches.
    • publish-raw on a copy of that tree, with a stub wrangler that only logs, skips all 35 (skipped_count: 35) and never calls wrangler for them.
    • I ran the edge cases against a copy of the real HPI manifest:
      • a present local copy with the wrong bytes gives checksum_mismatch in both commands, and nothing is uploaded;
      • the marker without storage.r2 gives r2_only_without_r2_location;
      • local: "false" (a string) gives malformed_storage_local;
      • local: true, or no marker, with the file absent still gives missing_file.
    • When a present R2-only file is uploaded, the write-back spreads the existing storage mapping, so local: false survives. Your test pins that.
    • verify-raw is untouched: the diff to chronicle/artifacts.py doesn't reach verify_raw_artifacts.
    • Tests against main's code (130b95b):
    • Nothing else that walks manifests trips on the new entries. The only manifest walkers are inventory, publish-raw and verify-raw (chronicle/artifacts.py), reached through chronicle/harness.py. No source package reads the four raw-only manifests, so bundle building never looks for their bytes. The CI jobs run pytest, ruff and load all, none of which runs these commands over db/data.
    • The README and docs/agent-source-package-harness.md now say a missing R2-only file is not something to fix by downloading. That covers the agent risk I raised.
  2. UK HPI committed: fixed.
    • No commit in 130b95b..f41cb29d has the CSV, nor any Price Paid or NSPL bytes: git ls-tree on all four commits finds no UK-HPI-*, pp-*.csv or NSPL_* path, and git rev-list --objects over the range finds no such blob. The only blobs above 5 MB are the ONS workbook (5.9 MB) and the ONS package YAML (7.4 MB).
    • .gitignore:12 covers it (git check-ignore -v confirms), and test_uncommitted_raw_bytes_are_ignored_by_git passes on a fresh tree.
    • test_uk_hpi_full_file_header skips cleanly with "UK HPI bytes are archived in R2, not committed".
  3. Licence attribution: fixed.
    • UK HPI. HM Land Registry's About the UK House Price Index, section 7 "Republishing data", prescribes exactly the statement you quote, with the year 2020, and gives no separate one for Scottish or Northern Ireland data. Section 1.1 names the four producers you list. Quoting it verbatim was the right call over my four-way suggestion.
    • ONS workbook. The committed workbook's Cover sheet says the statistics "were adapted from data from the HM Land Registry licensed under the Open Government Licence v.3.0" and asks for "Source: Office for National Statistics". The doc matches. (Its Notes block also has "Source: Office for National Statistics, HM Land Registry", if you'd like the joint form too. Optional.)
    • OBR note. obr.uk still serves me a Cloudflare 403, so I read the archived copyright page instead. It allows use and re-use, logos excepted, under the OGL, as the doc says. The PDF itself carries no licence text. The archived page sat at obr.uk/legal-pages/copyright/, and I couldn't check whether the doc's obr.uk/copyright/ link still resolves.
  4. Changelog: fixed. changelog.d/343.added.md now says "the 32 yearly files and the monthly change file", and mentions the marker.
  5. Isles of Scilly: fixed. Flagged under the HPI section (docs/data-sources/uk-high-value-housing.md:218) and "What stays in Microcosm" (:292-295), with the Cornwall (E06000052) or South West fallback.

New findings

None in this PR. One note on something that was already broken on main:

What I checked

CI at this head: Chronicle bundle and Chronicle surface have been queued since 09:49 UTC (run 38379038746) and hadn't started when I posted, so Chronicle checks hasn't run either. The verdict assumes they go green.

@juaristi22
juaristi22 merged commit 735820c into main Oct 13, 2026
3 checks passed
juaristi22 added a commit to PolicyEngine/microcosm that referenced this pull request Oct 14, 2026
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>
juaristi22 added a commit to PolicyEngine/microcosm that referenced this pull request Oct 14, 2026
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>
juaristi22 added a commit to PolicyEngine/microcosm that referenced this pull request Oct 14, 2026
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>
juaristi22 added a commit to PolicyEngine/microcosm that referenced this pull request Oct 15, 2026
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>
juaristi22 added a commit to PolicyEngine/microcosm that referenced this pull request Oct 15, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants