Repository navigation
Pre-Budget certified release: rebuild on policyengine 6.2.6, model-conditional expected value, dashboard - #30
Merged
Merged
Conversation
b31137e corrected the [^hb-gc-passport] footnote in docs/pilot/E-fiscal-tables.md and docs/MODEL_V2_PILOT.md by hand, but HB_GC_CAVEAT still carried the old wording, so the renderer no longer reproduced the committed tables and both footnote tests failed. Take the committed text as the source of truth, update the two asserted strings, and re-render: the output equals the committed file byte for byte. No number changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A certified-bundle build records certified: true (datasets.provenance), so the results and scenario provenance tests asserted the wrong thing: they required certified is False. They now check the flag against what the build recorded: true only with the registry's certification_bundle for the dataset and matching model/core versions; false, with the uncertified reason and no bundle, for the historical pilot. A unit test exercises both branches, since the committed files predate the model key. The dashboard's replication line no longer assumes an uncertified pair: it names the certifying policyengine.py bundle when the file says certified. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
triple-lock-build --pre-budget --uncertainty-ruling a writes an interim certified file on today's committed inputs and says so: - a top-level release block (also in provenance): stage pre-budget, the OBR March 2026 forecast, April 2027's provisional August 2026 CPI leg, the expected value withheld until the binding C2 score on the 28 October 2026 Budget inputs, and Max's recorded d955 ruling (c); - uncertainty_ruling and the mean-path provenance keep ruling a (the scenario-only execution, no requested_ruling) and add release_stage, interim and recorded_ruling c: an interim release under (c), not a new d955 ruling; - expected_value_omission.reason reads "Withheld pending the post-Budget binding score", not "d955 scenario-envelope ruling", and the assumptions strip quotes it. --pre-budget refuses any ruling but a (CLI and pipeline.build, before any job), --scenario, --mean-path-scenarios and --uncertainty-handoff, and refuses once CPI_PERIOD or the central forecast no longer describe the pre-Budget inputs, so the label cannot go stale. The dashboard shows a pre-Budget banner while release.stage is pre-budget, and the scenario envelope no longer says the recorded ruling omits an expected value in that case. RESULTS_SCHEMA.md documents release; REBUILD.md adds the interim step before the binding rebuild. A results-file check verifies the labels whenever a file carries a release block. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drives pipeline.build with --pre-budget on the adapter's fake-engine handoff fixture. Only PolicyEngine- and git-bound steps are stubbed; EV.build, the mean paths, coverage, redaction, assumptions and benchmarks run for real, and the post-build verifiers from test_results accept the file. An assembly error on this path can no longer first appear after the build's model jobs. Also covers the unlabelled direct-(a) shape and every --pre-budget refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After the post-Budget inputs are committed (CPI_PERIOD 2026 SEP) and before the binding rebuild replaces it, a committed pre-Budget file must fail only the documented stale-results test. The results check now reads the file's own release block; the assembly test still proves the build derives it from config. RESULTS_SCHEMA.md lists provenance.release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dashboard: a scenarios-only file (ruling a, no expected value) now leads the Budget impact tab with one scenario-envelope headline read from the file: the central forecast, the OBR wedge, the paired +/-0.5pp earnings mean paths (2034-35 and 2039-40, gross and net) and the April 2017 replay, with a drop-down line on the earnings asymmetry when the paired differences show it. The envelope is no longer rendered twice, Methodology no longer prints "unavailable", and the intro, backtest note, limitations and path text keep expected-value wording out of a scenarios-only release. Tests: pytest branches on the file's own state. The historical-publication proof and the historical estimator run on the pilot's exact pinned bytes (archived under tests/fixtures/historical-publication once a certified build replaces them); the paired-ageing tests read the paired draws from the same historical file when the committed one omits an expected value; assumptions tests follow the population treatment the runs record; a weight key may hold a label or a check, never a number. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
triple-lock-build --pre-budget now accepts --uncertainty-ruling b as well as a. Under (b) the release block says the expected value is shown as model-conditional: the primary forecast model failed the pre-registered C1 screen, and the binding C2 score and a new release follow the 28 October Budget. The recorded ruling stays (c); interim: true; not a new d955 ruling. Only in this pre-Budget (b) build, expected_value.build skips the 40-slot paired Microcosm subsample and records the omission (release.paired_sensitivity, expected_value.paired_sensitivity). Every other build, including the binding (c) build, still runs it; expected_value.build refuses to omit it for any other ruling. The assumptions strip says the Microcosm cross-check comes with the post-Budget release. Same 160-slot design and cached runs as the (a) build: 0 new jobs. Dashboard: with a pre-Budget (b) file the Budget impact tab leads with the distribution across the simulated paths (expected saving ± its Monte Carlo error, middle 80%, spread strips and the yearly spread chart, labelled model-conditional), then the scenario envelope and its dot chart. The central forecast appears once (scenario card), the Microcosm comparison box is dropped, and the banner explains the model-conditional label. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he Microcosm cross-check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cted value Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…own paths Max on #30 (13 Oct): show the distribution and expected value as provisional under the recorded ruling (c), not (b): the original primary passes the pre-registered C2 screen in the dry run on current data (test A suspended: 4 of 6 terminal, 80% annual). triple-lock-build --pre-budget --uncertainty-ruling c runs the primary through the model-conditional route, checks its path design and specs and both mean-path specs are byte-identical to data/pilot/c2-dry-run, and records the dry run's C2 provenance (run_kind dry_run, expected_value_authorized false) with provisional labels. The paired Microcosm cross-check runs in full. Dashboard: provisional banner and card, dry-run sentence on the Methodology tab, no repeated envelope. Tests and REBUILD/RESULTS_SCHEMA updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The provisional (c) file carries the 40 paired runs on the C2 dry run's design, which has an explicit identical-rates stratum; the pilot's pinned draws move to their own test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Microcosm cross-check triple-lock-build --pre-budget --uncertainty-ruling c on policyengine 6.2.6 / Enhanced FRS 1.58.0, the 40 paired Microcosm runs included. Expected saving unchanged at £11.1bn gross / £7.9bn net in 2039-40; on the same 40 paths Microcosm gives £0.7bn more gross and £0.1bn more net. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…2023 The sensitivity dataset was populace_uk_2023 (June 2026), labelled Microcosm. Pin Microcosm's UK national release instead: microcosm_uk_2024_25.h5 at microcosm-uk-2024-25-national-20261002T230158Z-5c6b3f68 (sha256 aa31bdf6...), uncertified under the 6.2.6 bundle (built with policyengine-uk 2.100.0). Its calibration targets are all for 2025, so it anchors ageing in 2025. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Microcosm's 64-bit ids arrive wrapped to 32 bits in policyengine-uk, so the record-order guard failed although the order is the same. Compare in the model's type and require the ids to stay distinct there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream's birthday draw hashes policyengine-uk's person ids. Microcosm's 64-bit ids arrive wrapped to 32 bits, so hashing the survey's ids gave other birthdays and 495 records changed State Pension type. With the model's ids the draw matches policyengine-uk's months_since_last_birthday for every record on Microcosm, and is unchanged on the Enhanced FRS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Built at e089a0f: Enhanced FRS figures are unchanged; the 40 paired runs now use microcosm_uk_2024_25 instead of populace_uk_2023. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
UK hub FYI for the pre-Budget release: the uk-data age top code, and a change coming in the next uk-data batch.
|
- Drop the Microcosm cross-check from every tab (it stays in results.json) and the pre-Budget banner (its release block stays in the file). - Shorten the intro and the text on every tab; How to read these figures is four lines, including that ages above the top code of 80 are spread by ONS shares. - The scenario envelope is one table: Scenarios and sensitivities. - Households with lower income -> Households worse off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f share as 100 squares Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…io bars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…art, paths guide, one-switch rule chart, collapsible replay, Methodology tables in dropdowns and grouped limitations Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…urce links, joined explainers, one switchable chart and new headline cards on Forecast paths, clearer path picker, 'current law' label Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every link in the dashboard's content is underlined (main a); the On this tab navigation and the site header and footer are not. The replication line now names only the policyengine.py version, falling back to the model and data when no version is recorded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ath, sources as short points, styled hover tips on the headline cards, leads that say what each part shows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- SERIES in lib/colors.js gives each concept one colour on every tab: triple lock darkest teal, Burnham plan mid teal, gross dark / net light teal, earnings dark teal, CPI amber, 2.5% floor pale grey, bands, average, median, OBR central, offsets, highlight, error. A test fails on raw hex. - Methodology in four sections: How we model it, What we use, Our assumptions, Limitations (one scannable list); groups-of-paths and best-distribution dropdowns and Full wording removed. - How our costing compares and If the plan had started earlier are one-box collapsible sections (CollapsibleSection), opened by their links. - Pension amounts and gaps per year (formatAnnualFromWeekly, x52 as policyengine-uk's WEEKS_IN_YEAR); started-earlier pension as a comparison card. - Header and page title name the Burnham plan vs the triple lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ecile ticks 1-10 Example pensioners: pensioner buttons, three cards (State Pension under each rule, income change with what made up the lower pension, share made up from unrounded figures), and one panel switching between an item-by- item waterfall and each year, with The numbers and How to read this as joined footers. The by-group table moves into its chart's panel as The numbers; income deciles show 1-10 with one axis label. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tral note, DWP first, neutral wording The headline card shows the expected saving without the Monte Carlo error in the value and notes that it is provisional until the Budget; the note on why the OBR central forecast saves little sits under the yearly chart; the comparison panel opens on DWP; scenario names and the earnings-shift note come from the file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… household and triple-lock tabs - The four example paths have the same names on every tab; the Distributional tab opens on the OBR central forecast and labels its figures 'on this path'. - How the triple lock works comes second. - 'Years the rules differ' becomes 'Pension below the triple lock'. - Plain, neutral wording: no 'ratchet', 'losing' or code words; one phrasing for the Housing Benefit and council tax reduction caveat. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…parison titles, 'points' not 'pp', plain past-forecast test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ll on phones BoxTitle gives each chart or table box its title and one line saying what it shows, and a test fails if a box heading lacks one. The site header hides two nav links below the small breakpoint so the page fits 390px. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ets from the path's rows; no year-by-year table on Forecast paths Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the household figures are calculated; one header layout for every chart box Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rd; its notes as five bullets with the replayed-vs-paid list Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Root cause: the chart used ChartFrame's grow mode (left from its old card layout), which set only a min-height, so the 100%-height chart measured 0 tall inside the panel and drew nothing. ChartFrame now always sets an explicit height, and a test clicks every view switch on every tab and checks each chart frame has one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the line where it matters Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wn; headline card with one detail line, the error on hover and a short Budget note Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ette test also blocks raw primary colours on data marks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-earlier box; the selected path's line moves into 'What each path is' Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ged) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vahid-ahmadi
marked this pull request as ready for review
October 15, 2026 15:05
This was referenced Oct 15, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Update, 15 Oct: the cross-check now runs on Microcosm's UK release
The 40 paired runs in the 14 Oct update used
populace_uk_2023, the June file the repo has labelled "Microcosm". They now use Microcosm's UK national release:microcosm_uk_2024_25.h5atmicrocosm-uk-2024-25-national-20261002T230158Z-5c6b3f68(SHA-256aa31bdf6…). Everything else stays on the certified 6.2.6 bundle and Enhanced FRS 1.58.0.datasets.py,config.py). Microcosm is pinned by tag and SHA-256 and is uncertified under 6.2.6, because its release declares compatibility with policyengine-uk 2.100.0 only. Its ageing anchor is 2025, since all 1,168 of its calibration targets have period 2025.populace_uk_2023stays registered for the pilot scripts.demography.py, please review. Microcosm's person, household and benefit-unit IDs are 64-bit, and policyengine-uk holds them as 32-bit, so they wrap. The order is the same, and no IDs collide after wrapping._same_order, with a test).EligibilityChangedrefused the run. With the model's IDs, the draw matches policyengine-uk'smonths_since_last_birthdayfor every Microcosm record, and it is unchanged on the Enhanced FRS (whose IDs fit in 32 bits).Results, 2039-40 (£bn)
populace_uk_2023In 2034-35 the paired difference is +0.31 gross and +0.13 net.
microcosm_uk_2024_25.check_assumptions.pypasses, and the dashboard test, lint and build pass.git_dirtyfalse.model-v2; then merge main intomodel-v2and send model-v2: certified bundle, engine port and guarded rehearsal #24 to main.Update, 14 Oct: Max's answers applied
triple-lock-build --pre-budget --uncertainty-ruling cruns the primary through the model-conditional route, then checks that its path design and specs, and both mean-path specs, are byte-identical to the committed C2 dry run (data/pilot/c2-dry-run). It refuses if they differ or if the dry-run primary fails C2. The file records the dry run's C2 provenance (run_kind: "dry_run",expected_value_authorized: false,provisional: true).test_ageing_validationpinned the pilot's paired draws; it now reads the committed file's draws, and the pilot pins have their own test.check_assumptions.pypasses, and the dashboard test, lint and build pass.model-v2; then merge main intomodel-v2and send model-v2: certified bundle, engine port and guarded rehearsal #24 to main.The original description follows. Where it differs from the update above, the update applies.
@MaxGhenis this PR collects all of our pre-Budget work on top of
model-v2(merged up to bf0e6ee): a certified rebuild, its results and the dashboard changes. Nothing is merged. Below: what we did, the decisions that are yours, and the runs still to do.Supersedes #27 and #28; this branch contains both, so they can be closed once this one is settled.
What we did
--pre-budgetrelease mode (from Pre-Budget release mode: scenarios-only certified build, clearly labelled #28):releaseblock and shows a dashboard banner;--pre-budget: shows a model-conditional expected value now. The banner says the primary failed C1, and that the binding C2 score and a new release follow the 28 Oct Budget.pre_budget and ruling == "b"). It is recorded asexpected_value.paired_sensitivity.status: "omitted". The normal and binding builds are unchanged, and a test covers that.tests/fixtures/historical-publication/). Assumptions tests follow the recorded population treatment.check_assumptions.py: passes;Results (UK, £bn, 2039-40, gross / net)
Against the uncertified pilot (E both, kept), central gross is −1.3% and net is +7.3%. Most of that comes from the HB passport fix and the 1.58.0 Housing Benefit and Pension Credit data. GB coverage against DWP: pension-age HB is now +3–11% (pilot +71–86%), and PC claims +13–40% (pilot +30–63%). The State Pension bill is about 15% below DWP.
Decisions for you
Method
Dashboard
getExpectedValuereturns null because it requires the Microcosm sensitivity estimates, so the summary and the expected saving show "unavailable". With the scenarios-only file, it renders the envelope block twice.Code
pre_budget and ruling == "b"Microcosm skip, and thereleaseblock inRESULTS_SCHEMA.mdandREBUILD.md.model-v2, then model-v2: certified bundle, engine port and guarded rehearsal #24 to main. Close Fix #24 CI: render the HB passport footnote from the renderer #27 and Pre-Budget release mode: scenarios-only certified build, clearly labelled #28.Runs still to do
🤖 Generated with Claude Code