Skip to content

Describe the Microcosm UK pipeline and calibration targets, and update UK validation and capital gains copy - #56

Merged
juaristi22 merged 13 commits into
masterfrom
uk-microcosm-data-pages
Oct 27, 2026
Merged

juaristi22 merged 13 commits into
masterfrom
uk-microcosm-data-pages

Conversation

@juaristi22

@juaristi22 juaristi22 commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Rewrites the UK data pipeline page (/uk/model/data/pipeline) for the Microcosm UK build at microcosm 90ff43f (policyengine-uk 2.162.8). It described the Enhanced FRS build (FRS 2023-24, WAS round 7, constituency and local-authority weight matrices).
  • Fills the UK calibration-targets page (/uk/model/data/calibration), which said target details were available for the US model only. It uses the US page's table, search and level badges, with UK levels.
  • Adds scripts/extract_uk_calibration_targets.py, which builds src/data/ukCalibrationTargets.json from the two UK releases policyengine.py serves.
  • Points the UK validation page to the PolicyEngine scorecard; it described TAXSIM validation, which covers US taxes only.
  • Describes the UK labour supply and capital gains responses on the behavioural responses page, which showed the CBO's US elasticities.

This is a draft until both pages describe one certified build: the next pair, being built on 90ff43f with policyengine-uk 2.162.12 and one unreleased engine change. Once policyengine.py certifies it:

  • the table is regenerated from it;
  • the pipeline page is re-checked against the code it was built from;
  • the footer moves to the commit on main that carries that code, and to its engine version.

Sources

  • Pipeline copy: PolicyEngine/microcosm main at 90ff43f9575fb5ae5c0c4389ba4790ab4ade5722 (the merge of microcosm#1373), which locks policyengine-uk 2.162.8. The files read at that commit:
    • uk/source_stages.json (49 stages);
    • uk/gates.json (81 gates: 79 release-blocking, 2 diagnostic) and the gate scopes in uk_runtime/calibration_run.py;
    • uk_runtime/national_doctrine.py, uk_runtime/local_doctrine.py and uk_runtime/graph_calibration.py (solver settings);
    • uk/uk_atomic_area_supports.provenance.json (small areas).
  • Serving: policyengine.py 6.11.1 (b14ee554): src/policyengine/data/bundle/manifest.json and countries/uk/regions.py.
  • Calibration table: the pair policyengine.py 6.11.1 serves, built at microcosm 67ee2ddf3 with policyengine-uk 2.151.0:
    • national microcosm-uk-2024-25-national-20261025T091414Z-a6299504: its calibration_diagnostics.json sha256 (e61a60a1…) matches the bundle manifest;
    • local area microcosm-uk-2024-25-dense-20261026T105309Z-c9df4b86: its diagnostics sha256 (44ab1c29…) matches that release's manifest, whose H5 matches the bundle.

What changed, by page

Pipeline (src/data/ukPipelineStages.ts, src/components/data/DataPipeline.tsx)

  • The shared spine has seven stages: FRS base; high incomes; wealth and property; spending and travel; benefits and take-up; gains, pensions and loans; spine checks.
  • Then the fork:
    • national file: national calibration, national gates, national dataset;
    • local-area file: copies and areas, localisation, joint solve, size selection, refit, local gates, local-area dataset.
  • Each stage gives its sources (with vintages and UK Data Service study numbers), methods, solver settings, gates, publication, and how policyengine.py serves UK and nation results (national file) versus constituency and local-authority results (local-area file, with its own weights).
  • DataPipeline.tsx gets the UK intro and branch labels. A UK-only ScrollBox makes the wider UK flow and the stage tables scroll inside their own box on phones. For the US it renders its children unwrapped, so US output is unchanged.
  • PolicyEngine certifies both files of a release together, and the page says so for the local-area file too.
  • The intro says both files are built from survey microdata licensed through the UK Data Service, the SPI Public Use Tape included, so they are available only to licensed users and are not public downloads. Every study label names the UK Data Service.
  • The overview keeps imputation (what gives records their characteristics) apart from calibration (how many households each record represents).
  • The intro is short and links microcosm.institute. A small footer names the Microcosm commit, linked to GitHub, and the policyengine-uk version.
  • PipelineStage gains national-sub-1 to national-sub-4 rows. The UK uses row 1 (national gates, beside the joint solve) and row 4 (national dataset, beside the local-area dataset), and the national line runs straight through rows 2 and 3. Rows are evenly spaced: the 25px pull-up of the first sub-row, which the US needs for its taller final-dataset box, applies only when the national row holds a final dataset. For the US the national halves stay empty, as before.

Calibration (src/views/data/UkCalibrationPage.tsx, src/views/data/CalibrationPage.tsx, src/data/ukCalibrationTargets.json)

  • 152 rows covering 24,303 targets, the union of both files:
    • the national file's 1,268 targets;
    • the local-area file's 24,303: all the national ones, 31 more above constituency level, and 23,004 constituency, local-authority and Scottish BRMA cells.
  • Level badges: UK, GB, England and Wales, nation (named when there is only one), region, constituency, local authority, Scottish BRMA.
  • Value column: the row's single UK target. Failing that, GB, then England and Wales, then a lone nation.
  • Every row names its publishers, including NRS, NISRA, DfC (NI), DfI (NI) and NITHC. Notes say how Microcosm transformed a published value: calendar-year windows, uprating index, rescaling to published controls, 52 × weekly amounts.
  • High-value homes, and from 90ff43f the constituency energy split, read "Microcosm derivation from open data".
  • CalibrationPage.tsx changes only its non-US branch, so the US page is unchanged.

Validation (src/views/data/ValidationPage.tsx)

  • UK only: PolicyEngine compares its UK estimates with published figures, such as official statistics and other models' estimates, and the page links the UK view of the scorecard (policyengine.org/scorecard?country=uk). The US page is unchanged.

Behavioural responses (src/components/theory/BehavioralResponses.tsx, src/data/elasticities.ts)

  • UK only, labour supply: the model is static on labour supply unless a reform turns the response on by setting policyengine-uk's two elasticities. The cards show the values PolicyEngine uses when it does: income −0.05 and substitution 0.25, the CBO's central estimates as in PolicyEngine's UK behavioural responses report. A reform then changes employment income by the substitution elasticity times the change in the net-of-tax marginal wage plus the income elasticity times the change in household net income, each change capped at 100%. A note gives the OBR model's ranges by group and says it runs only when an analysis calls it, while policyengine.py uses the two elasticities. This replaces the CBO presets and the decile table, which policyengine-uk does not have. The intro no longer links the US methodology post, and the illustrative chart uses the central values.
  • UK only, capital gains section: realised gains scale by ((1 − t₁)/(1 − t₀))^ε with policyengine-uk's default retention-rate elasticity of 1.0 (Advani, Lonsdale and Summers 2024), 0.5 and 2.0 as sensitivities, and an optional separate 1.4 (the OBR's) for Business Asset Disposal Relief gains. Setting the elasticity to 0 gives a static costing. The US section is unchanged.

Extractor (scripts/extract_uk_calibration_targets.py, scripts/test_extract_uk_calibration_targets.py)

  • Runs locally only, because the release diagnostics are open to UK Data Service licence holders only. Only the derived JSON is committed.
  • Validation follows the style of Rewrite the US data pipeline and calibration pages for the Microcosm default release #49's extractor. It checks:
    • schema 8, household weights, record and target totals, unique names;
    • five-field citations with URLs (repository paths only for Microcosm derivations);
    • known geography ids and local levels, units, value operations and uprating indices.
  • Whitelist: each target is reduced to its value, period, citation, geography, unit, filter variable names and transformation notes before grouping. assert_clean() refuses forbidden keys in the output.
  • Labels come from a strict table keyed by row key, and an unlabelled row stops the extraction. Labels for the two new rows expected in the 90ff43f release are already in place; the script lists labels that no row used.
  • The script refuses releases built with a policyengine-uk version other than the one the Pipeline page names (ukPipelineSource in src/data/ukPipelineStages.ts), so a regeneration can't pair the table with a different engine version from the page's. The release files don't record the Microcosm commit, so matching that is a manual step.

Disclosure control

  • Target values only. Every value is a published official statistic or a Microcosm transformation of one, and none derives from licensed microdata.
  • Only target values are read from the release files. The JSON and the page carry no fit figures, and a test checks both.
  • The pipeline page carries only code parameters, counts of stages, gates, targets and areas, and statistics their publishers state.
  • No figure derives from the SPI Public Use Tape, and nothing is copied from build receipts, evidence files, docs or run directories.
  • An independent disclosure-control review of the diff, the JSON, this description and the note on Fix the UK model pages: pipeline, calibration, validation, behavioural responses, and rules #51 ran before anything was pushed. Its findings are addressed in these commits. The review-round changes and replies had their own review before they were pushed or posted.

Verification

  • bun run test: all 16 files passed at 7b9c449 (178 tests, in Vahid's round-1 run). The touched test files re-ran after each later change.
  • bun run lint: clean. bun run build: passes. eslint and tsc --noEmit re-ran on the files changed after those runs.
  • Extractor: uv run --no-project --with pytest pytest scripts/test_extract_uk_calibration_targets.py passes 61 tests. One more test, which needs the licensed files, confirms the committed JSON is exactly what the script extracts from them.
  • Layout, with next dev in headless Chromium at 375 px and 1440 px (re-run after the review changes, including validation and behavioural responses):
    • UK pipeline and calibration pages: no page-level horizontal overflow in any state (every stage, every opened table, a search), and no console errors. At 375 px the UK flow and tables scroll inside their own box.
    • US pipeline and calibration pages, compared with master: identical text and element geometry, and no console errors.

Merge order

Follow-ups

  • Once policyengine.py certifies the next pair: regenerate src/data/ukCalibrationTargets.json from it, re-check the pipeline page against the code it was built from, and move the footer to the commit on main that carries that code and to its engine version.
  • PolicyEngine's UK behavioural responses article (policyengine.org/uk/research/behavioural-responses) still gives −0.7 as the capital gains default. Its update is step 7 of Adopt CenTax’s retention-rate elasticity of 1.0 as the default for UK CGT modelling policyengine.py#602.
  • Rules pages: draft Show UK programmes from policyengine-uk's registry, and UK terms on the Rules hub #57 builds the UK coverage tracker from policyengine-uk's programme registry (programs.yaml) and uses UK terms on the Rules overview.
  • The Overview page's comparison data (data/comparisons/artifacts.yaml and transparency.yaml) still name the Enhanced FRS (policyengine-uk-data) as the UK dataset, as the US entries still name the Enhanced CPS.

🤖 Generated with Claude Code

Maria Juaristi and others added 4 commits October 27, 2026 12:24
scripts/extract_uk_calibration_targets.py builds src/data/ukCalibrationTargets.json
from the national and local-area releases that policyengine.py serves. Their
diagnostics are licensed, so the script runs locally and only the JSON is
committed. It checks the national diagnostics' sha256 against the bundle
manifest, and the local-area diagnostics' against that release's manifest,
whose H5 must match the bundle's.

Each target is reduced to whitelisted fields (value, period, citation,
geography, unit, filter variable names, transformation notes) before
grouping, and assert_clean() refuses forbidden keys in the output. Rows key on
measure concept and filter variable names; a row without an entry in the
LABELS table stops the extraction.

This JSON comes from the pair policyengine.py 6.11.1 serves (national
a6299504, local area c9df4b86): 24,303 targets in 152 rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The UK page said calibration targets were available for the US only. It now
renders src/data/ukCalibrationTargets.json with the US page's table, search
and level badges, using UK levels: UK, GB, England and Wales, nation, region,
constituency, local authority and Scottish BRMA. It shows target values only.

CalibrationPage.tsx changes only its non-US branch, so the US page is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The UK pipeline page described the Enhanced FRS build (FRS 2023-24, WAS round
7, constituency and local-authority weight matrices). It now follows the
Microcosm UK build at microcosm 90ff43f (policyengine-uk 2.162.8): the 49-stage
spine, then the national file and the 150,000-household local-area file, their
calibration and gates, publication, and how policyengine.py serves national and
area results. Steps new at 90ff43f are marked as such.

DataPipeline.tsx gets the UK intro and branch labels, and a UK-only ScrollBox
so the wider UK flow and the stage tables scroll inside their box on phones.
The US renders as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The UK calibration page renders every JSON row, with header counts, level
badges and values from the JSON and no fit figures. The UK pipeline page has
none of the Enhanced FRS pipeline's stale phrases, and names the Enhanced FRS
only as the previous default or a reference. The US pages are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
policyengine-model Ready Ready Preview Oct 27, 2026 5:19pm UTC

Request Review

PolicyEngine certifies both files of a Microcosm UK release together, the
national file and the local-area file. The pipeline page said the certificate
covered the national file only and that constituency and local-authority
results were not certified.

The UK overview now keeps imputation (what gives records their
characteristics) apart from calibration (how many households each record
represents). The high-income and size-selection stages link Microcosm's
imputation and L0 working papers instead of explaining the methods at length,
and the national calibration stage notes that the calibration paper is in
preparation. A stage link may now point to an external page; the US stages'
links are internal and render as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From María's review of the preview:
- The intro says the UK model runs on Microcosm UK and links
  microcosm.institute, without the version history.
- The commit and policyengine-uk version move to a small footer linked to
  GitHub. The page no longer separates this build from the pair
  policyengine.py serves, so the "new at 90ff43f" markers go.
- The working-paper links leave the stages, since the intro links the
  institute. So do the FRS block's sentence on pooling, the publication-tag
  sentences and the release_certification.json detail.
- The national branch gets a National gates stage with the National dataset
  below it, as the local branch has.

PipelineStage gains national-sub-1 and national-sub-2 rows, drawn in the left
half of the local sub-rows with the same number. For the US those halves stay
the empty spacer they were.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juaristi22 and others added 2 commits October 27, 2026 13:38
The first sub-row was pulled up 25px, which the US layout needs because its
national row ends in a taller final-dataset box. On the UK page that left the
national gates and the joint solve almost touching the boxes above them. The
pull-up now applies only when the national row holds a final dataset.

The national dataset shared a row with size selection and refit, and its
taller box pushed the local gates down. It now sits in the bottom row beside
the local-area dataset, and the national line runs straight down to it.
National rows can sit beside any of the four local sub-rows. For the US those
halves stay the empty spacer they were.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ital gains response

The UK validation page described TAXSIM validation of federal and state
income tax, which covers US taxes only. It now says PolicyEngine compares its
UK estimates with published figures, and links the UK view of the PolicyEngine
scorecard.

The behavioural responses page showed the CBO's US capital gains elasticities
for the UK too. The UK section now describes the response PolicyEngine applies
by default: realised gains scale with the retention rate at an elasticity of
1.0 (Advani, Lonsdale and Summers, 2024), with 0.5 and 2.0 as sensitivities,
and an optional separate 1.4 for Business Asset Disposal Relief gains. The US
pages are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@juaristi22 juaristi22 changed the title Describe the Microcosm UK pipeline and list the UK calibration targets Describe the Microcosm UK pipeline and calibration targets, and update UK validation and capital gains copy Oct 27, 2026
The UK page showed the CBO's US labour supply presets, including a
substitution table by income decile, which policyengine-uk does not have. It
also described an elasticity of taxable income framework and linked the US
methodology post.

The UK page now says the UK model is static on labour supply by default (both
elasticities 0). When users set them, a reform changes employment income by
the substitution elasticity times the change in the net-of-tax marginal wage,
plus the income elasticity times the change in household net income, each
change capped at 100%. It notes that policyengine-uk's OBR labour supply model
runs only when an analysis calls it, and that policyengine.py uses the two
elasticities. The illustrative chart is labelled with the values it uses, and
the UK copy spells "labour". The US page is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The UK cards showed the policyengine-uk defaults, which are 0. They now show
the values PolicyEngine uses when it turns the response on: an income
elasticity of -0.05 and a substitution elasticity of 0.25. These are the
CBO's central estimates, as in PolicyEngine's UK behavioural responses report,
which the source line links. The text says the model is static unless a reform
turns the response on, and the illustrative chart uses the same values. The
OBR note now gives that model's ranges by demographic group and says it
currently models hours worked only. The US page is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vahid-ahmadi

Copy link
Copy Markdown

@juaristi22 round 1, at 7b9c449b3.

Verdict: the pipeline description matches microcosm closely, and the targets I checked match. Two must items before this leaves draft: the page says "certified" about a build that has no certified release, and it doesn't say the datasets are licensed and not public.

I checked against microcosm main (7d45c0c). Its only change since 90ff43f is an NZ docs line, so 90ff43f is still current for the UK. Paths below are under packages/microcosm-build/src/microcosm/build/.

Findings

  1. must: "certified" is used for the 90ff43f build, but no certified release exists at that commit, and as it stands one would probably fail the release cut.

    • The intro says "Two files are calibrated from that spine and certified together" (src/components/data/DataPipeline.tsx:148). Both dataset stages say "PolicyEngine certifies it together with..." (src/data/ukPipelineStages.ts:224, :328). The footer dates the whole page to 90ff43f (src/views/data/PipelinePage.tsx).
    • The served pair was built at 67ee2ddf3 with policyengine-uk 2.151.0, as the calibration page itself says. 90ff43f is 125 commits later. It also includes the LCFS excise step (#1381, merge f6a790cf0), which 67ee2ddf3 does not.
    • This week a verification cut on microcosm #1405, which carries that step through main, was refused at the terminal phase by uk_degenerate_release_surface. The reason was constant household.beer_draught_share and household.cider_draught_share.
    • That gate is one of the 19 release-cut gates (uk_runtime/calibration_run.py:169). uk/degenerate_reviewed_exclusions.json has no entry for either column. The stage writes each share as the published ratio, so the column is constant by design (uk/gates.json, notes on uk_stage_lcfs_consumption_excise_quantities).
    • Suggest: say plainly that the page describes the code at 90ff43f, and that the files currently served come from the earlier 67ee2ddf3 build. Or keep the word "certified" to the served pair only. The "Alcohol, tobacco and gambling duty inputs" detail (ukPipelineStages.ts:103) describes inputs that are not in the served files.
  2. must: the pipeline page does not say the data are licensed, or that the datasets are not public.

    • The page names microcosm_uk_2024_25.h5 as "policyengine.py's UK default dataset" (ukPipelineStages.ts:224), and also names the local-area file (:328). It lists UK Data Service study numbers (FRS SN 9563, SPI SN 9422, WAS SN 7215, LCFS SN 9603, ETB SN 8856, NTS SN 5340). All six match uk/spec/sources.yaml.
    • It never says these are licensed studies. A reader could assume pip install policyengine gets them the file. In fact the bundle manifest at policyengine.py b14ee554 points to hf://policyengine/populace-uk-private/..., which is a private repository.
    • The "SPI Public Use Tape" name also reads as public, but it is a UK Data Service licensed study.
    • The calibration page already handles this well for fit figures (src/views/data/UkCalibrationPage.tsx:227-228). Please add one similar sentence to the pipeline intro, for example: "The source surveys are licensed through the UK Data Service, and the Microcosm UK files are available only to licensed users; they are not public downloads."
  3. should: the calibration table and the pipeline page describe different builds, and in at least one place they disagree.

    • The table is from 67ee2ddf3 (policyengine-uk 2.151.0). The pipeline page is 90ff43f (2.162.8). The pages sit next to each other and show different versions.
    • Concrete case: the Winter Fuel Payment row is noted "Calendar-year window of fiscal-year figures" in src/data/ukCalibrationTargets.json. At 90ff43f it is "Bound at FY2025-26's fact alone, María's ruling of 2026-10-26", with no window (uk/uk_population_targets.json:3139).
    • The pipeline page also states the 3/12 + 9/12 window as a general rule (ukPipelineStages.ts, National calibration details), with no mention that exceptions exist.
    • You have regeneration down as a follow-up. Until then, the pipeline page should say which build each page describes.
  4. should: the release-cut summary leaves out the gate that blocks today. "The 19 release-cut gates cover input coverage, target and export surfaces, parity..., take-up, support, category values and a weights audit" (ukPipelineStages.ts:215). Two of the 19 gates aren't in that list: uk_degenerate_release_surface (no constant, all-zero or all-null columns) and uk_nonnegative_columns (uk_runtime/calibration_run.py:169-170). Please add "no constant or negative columns". The count of 19 is right (calibration_run.py:158-185).

  5. nit: "beat the pinned Enhanced FRS on their common target surface" (ukPipelineStages.ts:210). This is accurate: the rule is candidate_loss < incumbent_loss (uk_runtime/candidate_score.py:692). But it is an in-sample comparison of calibration loss. "Has a lower calibration loss than the pinned Enhanced FRS on the targets both files carry" avoids it reading as a general accuracy claim. The local-area stage already says it makes no out-of-sample claim, which is good.

  6. nit: hard-coded colours. The level badges (UkCalibrationPage.tsx:97-99 and on) and the new UK blocks in BehavioralResponses.tsx use hex values (#dbeafe, #5A5A5A, #E2E8F0). That copies the existing US code (CalibrationPage.tsx:38), so it isn't a regression. Tokens would be better if you touch these again.

What matched

Pipeline parameters checked against microcosm at 90ff43f:

  • 49 stages (uk/source_stages.json).
  • 81 gates: 79 release-blocking and 2 diagnostic (uk/gates.json).
  • National solve: 1,500 epochs, learning rate 0.02, seed 0, weight ratio 10, loss cap 10, family_equal, no L0 (uk_runtime/national_doctrine.py:34-41).
  • Local solve: 2,000 epochs (uk_runtime/local_doctrine.py:145), learning rate 0.15 (uk_runtime/graph_calibration.py:81), 15 copies (local_doctrine.py:162), 150,000 households (:212), λ 0.0216 (uk_runtime/full_build_cli.py:669).
  • 188,880 / 46,363 / 3,780 small areas (uk_runtime/geography_sources.py:145-148).
  • The 7 seam, 7 local and 2 diagnostic gate scopes (calibration_run.py:68-96).

Targets spot-checked against uk/uk_population_targets.json for geography, publisher and binding:

  • OBR income tax (:1994): UK, EFO March 2026 receipts. Matches.
  • OBR SDLT (:2238): calendar_year_window_scaled_by_ratio, matching the row's "scaled by a published ratio" note.
  • OBR Child Benefit (:2415): UK. Matches.
  • OBR TV licence fee (:3071): UK. Matches.
  • OBR Winter Fuel Payment (:3103): England and Wales filter, matching the value's geography. The window note differs (finding 3).
  • ONS UK population (:7217): UK total, mid-2025. Matches.
  • DfT local bus journeys (:16822 onwards): English regions only, so no single value. Matches the row's blank Value.

I did not check the values themselves against the source tables. The extractor reads them from the release diagnostics, which I can't open.

Prose is neutral and quantitative, in British English and sentence case. The labour supply defaults match policyengine-uk (both elasticities 0 unless turned on). The capital gains text matches gov/simulation/capital_gains_responses/elasticity.yaml (1.0, with 0.5 and 2.0 as sensitivities) and badr_elasticity.yaml (1.4, OBR).

What I ran

  • Fresh clone and bun install --frozen-lockfile.
  • bun run test: 16 files, 178 passed. bun run lint: clean. bunx tsc --noEmit: clean. bun run build with a token: passes.
  • uv run --no-project --with pytest --with pyyaml pytest scripts/test_extract_uk_calibration_targets.py: 59 passed, 1 skipped (the test that needs the licensed files).
  • next start, with headless Chrome screenshots of /uk/data/pipeline and /uk/data/calibration at 1440 px. I looked at both. The layout is fine. The footer says 2.162.8 and the calibration box says 2.151.0.
  • I did the neutrality and design checks myself, not with the plugin agents.

Skimmed only: src/data/ukCalibrationTargets.json (4,788 lines, generated; I read the header and listed all 152 row keys and labels), the body of scripts/extract_uk_calibration_targets.py (I read none of its 1,026 lines; I ran its tests), and the 375 px layouts. I didn't run the extractor on release files, and didn't check the merge with #49 or #51.

🤖 Generated with Claude Code

juaristi22 and others added 3 commits October 27, 2026 17:02
…ow copy

The UK pipeline intro now says both files are built from survey microdata
licensed through the UK Data Service, the SPI Public Use Tape included, so
they are available only to licensed users and are not public downloads.
Every study label names the UK Data Service.

The national calibration detail says a few targets bind to one year's
figure instead of the calendar-2025 window, such as the Winter Fuel
Payment. The release-cut summary adds the constant and negative column
checks. The incumbent comparison is described as a lower calibration loss
than the pinned Enhanced FRS on the targets both can be scored on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The extractor reads ukPipelineSource.modelVersion from
src/data/ukPipelineStages.ts and stops when the releases were built with
another policyengine-uk version, so a regeneration cannot pair the table
with a different engine version from the page's. The release files do not
record the Microcosm commit, so matching ukPipelineSource.commit stays a
manual check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… every release-cut check

Most OBR forecasts and HMRC Income Tax liabilities figures take the
3/12 + 9/12 window. Other fiscal-year figures are held at one year, such as
the OBR alcohol, tobacco and gambling duties at 2024-25 and the Winter Fuel
Payment at 2025-26, so "a few" understated them. Those duties are also
measured at 2024, so the detail now says most targets are measured at 2025.

The release-cut summary now covers all 19 gates. It adds stage coverage,
parity of the compiled targets with a signed reference, administrative
totals and Universal Credit's coherence with capital.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@juaristi22

Copy link
Copy Markdown
Collaborator Author

@vahid-ahmadi thanks. Round 1 is in 8badda5 and e5a7c64 (page copy) and 56c003a (extractor).

  1. "Certified" for a build with no certified release. Agreed: nothing at 90ff43f is certified, and you're right that the release cut would refuse it. uk_degenerate_release_surface refused the first dense attempt of that pair on the same two draught-share columns. The next pair is being built on 90ff43f with policyengine-uk 2.162.12 and one unreleased engine change, and it has to pass the same release cut before policyengine.py can certify it. This PR stays in draft until a pair is certified. Then:

    • the targets are regenerated from it;
    • this page is re-checked against the code it was built from, including the duty inputs you point to, which that pair carries;
    • the footer moves to the commit on main that carries that code, and to its engine version.

    So "certified together" will be true of the build the footer names before this merges. I haven't added a sentence about the build served today, because by merge the page and the served files will be the same build.

  2. Licensing. The intro now says both files are built from survey microdata licensed through the UK Data Service, the SPI Public Use Tape included, so they are available only to licensed users and are not public downloads. Every study label now names the UK Data Service, and a test checks both.

  3. Two builds on neighbouring pages.

    • The JSON's Winter Fuel Payment note is right for 67ee2ddf3. The extractor takes each row's notes from its targets' value operations, so regenerating from the new pair drops the window there.
    • The national calibration detail no longer states the window as a general rule. Most OBR forecasts and HMRC Income Tax liabilities figures take it. Other fiscal-year figures are held at one year, such as the OBR alcohol, tobacco and gambling duties at 2024-25 and the Winter Fuel Payment at 2025-26.
    • The extractor now refuses releases built with a policyengine-uk version other than the one the Pipeline page names, so a regeneration can't pair the table with a different engine from the page's. The release files don't record the Microcosm commit, so matching it stays a manual step, which the PR body lists.
  4. Release-cut summary. It now covers all 19 gates. As well as "no constant or negative columns", it adds four checks it also left out: administrative totals, stage coverage, parity of the compiled targets with a signed reference, and Universal Credit's coherence with capital.

  5. Enhanced FRS comparison. It now reads "have a lower calibration loss than the pinned Enhanced FRS on the targets both can be scored on".

  6. Colours. Left as they are for now.

    • The badge colours have no token equivalents. The tokens have no blue, and no light green or amber tints for badge pairs.
    • The two greys in the UK behavioural blocks are exactly text.secondary and border.light. But the Tailwind theme maps only the primary and grey scales, so using those tokens there would mean inline styles inside class-styled blocks that the US shares. That is better done for the whole file at once.

Checks: vitest on the two UK test files passes (24 tests), and the extractor tests pass (61 passed, 1 skipped: the test that needs the licensed files). eslint and tsc --noEmit are clean.

🤖 Generated with Claude Code

@vahid-ahmadi

Copy link
Copy Markdown

@juaristi22 round 2, at e5a7c6435.

Verdict: round 1 must 2 and both shoulds are fixed. Must 1 is only half fixed: waiting for a certified pair deals with the build, but "certified together" stays wrong even then, because policyengine.py certifies only the national file. Please keep this in draft.

Round 1 items

  1. must, "certified" at 90ff43f: still open, in a new form. Holding the PR in draft until a pair at the footer's commit is certified is fine for the build question. It isn't one yet: microcosm #1411 (the signed draught-share exclusions) is still an open draft, so nothing at 90ff43f has passed the release cut. The certified UK release that policyengine.py main (1e76104) serves today is still microcosm-uk-2024-25-national-20261025T091414Z-a6299504 with policyengine-uk 2.151.0 (src/policyengine/data/bundle/manifest.json:37, :107, :112).
    But the wording has a second problem that a new pair won't fix. policyengine.py's docs/regions.md:112-113: "The certificate covers the national dataset only: receipts for runs on the local-area file are uncertified." Certification vets the local-area release and pins its bytes, but does not certify it. Three places still say otherwise:
    • src/components/data/DataPipeline.tsx:148: "calibrated from that spine and certified together";
    • src/data/ukPipelineStages.ts:224 and :328: "PolicyEngine certifies it together with the local-area file" / "with the national file";
    • ukPipelineStages.ts:228: "the policyengine-uk version they are certified for".
      Suggest: "PolicyEngine certifies the national file. policyengine.py checks the local-area file and pins its bytes, but results on it are not certified." We raised the same point on microcosm.institute #85.
  2. must, licensing: fixed. The intro now says both files come from UK Data Service licensed microdata, SPI included, and are not public downloads (DataPipeline.tsx:149-151). All six study labels name the UK Data Service, and there is a test for both. This matches policyengine.py, whose UK bundle points at the private policyengine/populace-uk-private repository.
  3. should, two builds on neighbouring pages: fixed for now. The window detail (ukPipelineStages.ts:191) matches microcosm main (7d45c0c). In uk/uk_population_targets.json, 23 OBR targets use the calendar window. The seven that don't are the five alcohol, tobacco and gambling duties and fuel duty at FY2024-25, and the Winter Fuel Payment at FY2025-26. On the HMRC side, only the five hmrc.itl.* targets use the window. The extractor's engine check (scripts/extract_uk_calibration_targets.py:42-43) is a good guard. The new pair is being built with 2.162.12, so the footer's 2.162.8 has to move before you regenerate, or the extractor will refuse it. Matching the commit is still a manual step, as the PR body says.
  4. should, release-cut summary: fixed. ukPipelineStages.ts:215 now matches all 19 ids in UK_NATIONAL_GATE_SCOPE (uk_runtime/calibration_run.py on microcosm main), including uk_degenerate_release_surface, uk_nonnegative_columns and uk_uc_capital_coherence.
  5. nit, Enhanced FRS wording: fixed (:210).
  6. nit, colours: left as they are, fine for this PR.

New findings

None besides the reframed must 1.

What I ran

Fresh clone at e5a7c6435: bun run test (16 files, 179 passed), lint and tsc --noEmit clean, the extractor tests (61 passed, 1 skipped), and bun run build with a token. next start plus a headless Chromium screenshot of /uk/data/pipeline at 1440 px, which I looked at. The new licence sentence renders in the intro. The footer still reads 90ff43f with 2.162.8.

🤖 Generated with Claude Code

@juaristi22
juaristi22 marked this pull request as ready for review October 27, 2026 17:53
@juaristi22
juaristi22 merged commit 397cdc4 into master Oct 27, 2026
2 checks passed

This branch was successfully deployed

1 active deployment
Preview — e5a7c643 Deployed Oct 27, 2026 by vercel[bot]
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