Repository navigation
Release the 10/8 uk-data batch (15 PRs, relock to policyengine-uk 2.122.2) - #544
Merged
Merged
Conversation
Replace the OBR table 4.9 Housing Benefit target, which is GB DWP-funded spending but was compared with UK-wide modelled Housing Benefit, with DWP Spring 2026 targets for Housing Benefit spending and claims over Pension Credit qualifying age in Great Britain. Targets can now name the countries they cover. The figures under Pension Credit qualifying age are kept but not calibrated: the model pays working-age Housing Benefit to too few records for a target to be met without concentrating it on a handful of them. Stop drawing would_claim_uc for benefit units whose adults have all reached State Pension age, keeping every other unit's draw unchanged. Require policyengine-uk 2.102.5, which lets pension-age families make new Housing Benefit claims (PolicyEngine/policyengine-uk#1901). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
State in the release note that modelled GB Housing Benefit falls to about £8.0bn. Mark the mixed-age classification as an assumption, date the benefit-group equality from 2024-25, and quote the calibrated build's working-age claims. Add a test that the calibrated columns build on the dataset, since the loss matrix skips a target whose column raises, and note that would_claim_uc uses survey-year State Pension age. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FRS CVPAY is the rent a boarder or lodger pays the householder, after deducting any state benefits to help with rent (FRS question CvPay, asked about each person not related to the HRP in the second and later benefit units of a conventional household). frs.py added it to the payer's own property_income. Move the property income calculation into a tested helper, frs_property_income, that keeps SUBRENT and ROYYR1 and drops CVPAY. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of #503: the seeded cases only draw non-negative amounts, so the floor at zero was never active, and every fixture had a unique index while create_frs stacks the adult and child tables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… tenure ROYYR1 holds a property loss as a positive amount flagged by RENTPROF = 2, and the build counted it as income. A loss now counts as zero. SUBRENT was counted only for owner-occupiers, although the FRS asks every household about sub-letting. The tenure restriction is removed. SUBRENT stays as reported whether SUBALLOW says it is before or after allowable expenses; the FRS collects no expense amount. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Negative FRS values are missing-value codes (-1 to -9), not amounts. Flooring the sum let a missing ROYYR1 code cancel the household reference person's SUBRENT, which now matters for renting households too. Floor each amount instead. FRS 2024-25 has no negative codes in either field, so the build is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…flag The create_frs smoke test's fake simulation did not answer the variables the would_claim_uc rule now reads (person_benunit_id, is_adult, is_SP_age), which failed CI with KeyError: 'person_benunit_id'. Pick the claimant-and-partner flag the way the locked policyengine-uk does for Housing Benefit's pension-age route: is_claimant_or_partner where the release defines it, otherwise is_adult as in 2.102.5. Both the would_claim_uc rule and the age-group targets use it. Under 2.102.5 the base FRS is identical to the previous commit's in every column. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TOTCAPB3 (DWP's derived benefit-unit total of savings and investments) for every FRS benefit unit; -1 where missing or negative. Pension Credit counts the claimant's and partner's capital (SPCA 2002 s.5); the WAS household imputation gives FRS Pension Credit reporters a weighted median of 74,300 pounds against the survey's own 300 for those the model then finds not entitled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second-stage QRF draws each SPI-donor person's benefit reports from age, gender, region and incomes, with no view of the benefit unit or of health. Those reports then act as existing claims in policyengine-uk. The take-up anchors, receives_benefits_in_own_right and ssmg_reported were also left as the FRS donor's. On SPI-donor rows, this zeroes the income-related awards (UC, Pension Credit, Housing Benefit, CTR, IS, tax credits, income-related ESA and JSA, SSMG), the out-of-work benefits (contributory ESA and JSA, incapacity benefit, SDA) and Child Benefit, whose only use is the take-up anchor. It then rebuilds the anchors and receives_benefits_in_own_right from the rows' own reports. The zeroed columns stay in the QRF chain, so the values of the reports kept do not change. Also adds hypothesis as a dev extra, for the property tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The FRS build drew each benefit unit's Broad Rental Market Area from rows of lha_list_of_rents.csv.gz within region and LHA category. That file's Scottish, Welsh and Northern Ireland lists are byte-identical copies of English BRMAs' lists, each matched on the April 2019 rate, so those nations' draws ignored their rental markets (#515). Draw instead in proportion to census private-rented households by region, BRMA and the bedroom band matching each LHA category (England and Wales 2021, Scotland 2022, Northern Ireland 2021; Northern Ireland has no bedrooms question, so its weights cover every category). Move the draw to datasets/brma.py, add property tests for it, document sources and validation in storage/BRMA_DATA_SOURCES.md, and remove the list of rents. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efit flag Review of 96672af (subfleet 20261002-011737-spi-514-review): - IIDB, AFCS and bereavement support follow an injury, service or a death, not income, and the QRF drew them at 6.2, 2.4 and 4.6 times the FRS rate by weight. SPI rows now take the donor's own values. - The Child Benefit take-up flag keeps the donor's value: the award does not depend on the replaced incomes and the claim is for the same children. Only the UC and Pension Credit flags are redrawn. - The comment no longer says the model's means test replaces the zeroed income-related reports: in policyengine-uk 2.93.0 housing benefit, CTR, IS, tax credits and income-related ESA and JSA need a report, so SPI rows no longer get them. Evidence is now cited by weight, and Child Benefit counts 16-19 qualifying young people. - One assign_reported_takeup helper serves create_frs and the SPI rows, so the rate and the anchoring rule have one source. The SPI draws no longer depend on which columns are present. - Tests pin the three rule sets, use shuffled, gapped ids and check the rebuilt flags against reports that are not zeroed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e year and the UC redraw Round-2 review of eb14fd0 (subfleet 20261002-041419-spi-514-review-r2, APPROVE): the FRS comparison for ESA (contributory) rested on under 10 records; the take-up rates' year and the stage-two UC redraw had no direct test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An FRS benefit unit is one adult or a couple plus dependent children. The adult table holds the head (UPERSON 1) and any partner (UPERSON 2); any other adult forms and heads their own benefit unit. So adult-table membership is policyengine-uk's is_claimant_or_partner (#1896), which the model otherwise infers from ages and cannot get right for unflagged large-age-gap households (policyengine-uk#2039). - frs.py derives it next to is_parent and rejects a benefit unit without one or two adult records (none in FRS 2020-21, 2022-23, 2023-24 or 2024-25). - SPI records are one-person benefit units, so each is its claimant. - The transfer builder marks the tax-unit head and a joint filer's spouse; the checked-in enhanced_cps_2025.h5 gains the builder's column in place (every other column unchanged). - stack_datasets refuses to stack a person table without the role onto one with it. Cloning, subsampling, uprating and the SPI and CGT donor copies carry whole person tables, so the column follows them. - Tests: examples, Hypothesis properties over generated FRS-shaped households, stacking, cloning, SPI, transfer builder vs checked-in H5, and built-dataset invariants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_frs's smoke test stubs Microsimulation.calculate with plain arrays, so take np.asarray rather than .values, and remove the stub of the deleted lha_list_of_rents.csv.gz. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/brma_households downloads every census and BRMA geography input, checks each against a pinned sha256 (decoded-content hashes for the ONS custom-API batches), and rebuilds storage/brma_private_rented_households.csv byte for byte. Scotland's census ward table is the one manual download, with instructions in the manifest. Area overrides established from official lookups carry dated evidence and are asserted against the polygons so a boundary change fails loudly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Northern Ireland: build each BRMA's private-rented households from NISRA's postcode-district household counts and NI's private-rented share, dropping the ONS Postcode Directory Northern Ireland records, whose LPS end user licence does not clearly allow publishing derived figures. BRMA shares move by 1.5 points on average. - Move the household pick into brma.pick_household_brmas and test it. - Test that every category uses its bedroom band, with spot values; give each region's BRMAs distinct names in the property tests; make the fail-closed test remove a cell rather than skip. - Decode enum regions; assert Scotland's bedroom headers exactly. - Docs: Cardiff Bay and Balloch overrides, centroid wording, what the validation correlates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
clone_and_assign sampled a household's OA by population from anywhere in its country, then wrote the OA's region, LA and constituency onto the household without touching `region`. In release 1.57.4, 88.5% of English households (86% of English weight) carry an OA in a different region from the one the FRS recorded, and the median English LA draws 93% of its weight from households surveyed in another region. policyengine.py groups households by `constituency_code_oa` / `la_code_oa` for its constituency and local-authority impacts and for area-scoped simulations, so every English area was reporting an England-wide mix. assign_random_geography now takes the households' regions and samples within the region (Wales and Scotland are one region each; a household with no region below the country falls back to its country). Collision avoidance draws from the same region. A region with no OAs in the crosswalk, a region that contradicts the country, or an unrecognised region value raises. Called without regions it draws exactly as before: seed 42 reproduces the released `oa_code` column. Adds Hypothesis to the dev extras for the property tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…K 2.107.0 - SPI-synthetic copies get pension_credit_reported_capital = -1: the FRS donor's capital does not belong with SPI-imputed incomes (24 of 152 SPI PC reporters were entitled in build E only because of it). - uprating_factors.csv and uprating_growth_factors.csv get the column with the savings row (policyengine-uk uprates it with the same per-capita GDP index), so uprate_dataset keeps the two in step. - policyengine-uk >= 2.107.0, the first release defining the variable (#2018); core 3.32.12 comes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk#2081 adds the person input uc_is_in_gainful_self_employment (UC Regs 2013 reg 64). Without it the model reads any self-employment income other than zero as gainful self-employment and none as none, so a trader who breaks even, or whose loss this build floors at zero, never gets the minimum income floor, while an employee's small side trade does. Set it from the FRS: true when the main job (EMPSTATI) is self-employment, whatever its profit (ADM H4013, H4054, H4503), and when a side trade's profit is above the person's employment income (ADM H4034). The SPI copy in impute_income re-derives it from its own imputed incomes. Releases of policyengine-uk without the variable skip the column. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The FRS employment_status mapping zipped range(12) with 11 statuses, so
EMPSTATI 11 ("Other inactive" in the UKDS FRS 2024-25 data dictionary) was
unmapped and the fillna fallback made it LONG_TERM_DISABLED. That also put
other-inactive working-age adults into the ESA health-condition and
support-group proxies.
Map the adult codes through an explicit table keyed to the data dictionary,
make child-table rows CHILD, and fail the build on any adult code the table
does not know rather than guessing a status. Every adult in the 2020-21,
2022-23, 2023-24 and 2024-25 releases carries a code from 1 to 11.
Tests cover codes 0-11 exhaustively, Hypothesis properties of the mapping and
the ESA proxies, create_frs end to end for every code and a child row, and
the built datasets. Adds hypothesis as a dev dependency (same pyproject and uv.lock
change as #522 and #525).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SPI income model drew every SPI-synthetic row's six incomes from age, gender and region alone, while the row kept its FRS donor's employment status. Children drew pay, the unemployed and retired drew earnings, and self-employed rows rarely drew a profit. Fit one QRF per earnings group (employee, self-employed, both, neither) on the SPI records in that group, using PAY and the SPI self-employment indicator SEINC_NUM, and draw each FRS row from the group its employment status and recorded earnings put it in. Children keep their own incomes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hypothesis properties for the FRS and SPI group mappings, the training sample allocation, the per-group model's draws and the donor values kept for children, plus a check on a built enhanced FRS. The cache tests write the per-group format. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI build logs are public, so the error now names the unknown codes without per-code counts and reports a total under 10 adults as "fewer than 10". Raised by the microcosm port session; no change on current FRS releases, where every adult has a code from 1 to 11. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under pandas 3, Series.astype(str) keeps NaN as a float, so sorting a set
holding a blank code and another unknown code raised TypeError and hid the
codes. Format from the float codes instead ("0, 12, blank"), which behaves
the same under pandas 2 and 3. Found by the microcosm port session's
differential under pandas 3.0.3.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With SPI incomes drawn by earnings group, the SPI-synthetic rows no longer give pay to children and people out of work. Calibration then met the HMRC counts of income-tax payers with employment income, which are annual and include part-year earners, by moving about 4m people's weight from out of work to employees (32.2m against the LFS's 29.1m for 2024). Nothing tied employment status to an official count. Add national targets for the ONS LFS employee and self-employed levels (MGRN, MGRQ annual averages, 2022-2025), counted from the FRS ILO main-job status. Move the status groups to utils/employment_status.py so the income imputation and the targets share them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A loaded runner tripped Hypothesis's too_slow health check while the properties themselves held. Drop the deadline and that health check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HMRC's counts of income-tax payers with employment income by area are annual, so they include people with pay for part of the year whose FRS status at interview is out of work. Trained on, they held employees at 32m against the LFS target of 29.6m. The area amounts and the national counts by income band still train; the counts stay in the calibration logs as validation targets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflict resolved per runbook A4 step 6: pyproject.toml takes policyengine-uk>=2.107.0 (R sets the final floor); the auto-merged uv.lock is left as merged and reset to main's in R. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved per runbook A4 step 10: datasets/frs.py keeps #514's assign_reported_takeup(...) calls for would_claim_pc and would_claim_uc, keeps #490/#510's comments, and ANDs #490's ~derive_all_claimants_over_state_pension_age(...) term onto the would_claim_uc draw (draw count unchanged); .gitignore takes the union of both sides; uv.lock reset to main's (b45c373), relocked in R. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved per runbook A4 step 12: datasets/frs.py keeps both new functions, #490's derive_all_claimants_over_state_pension_age and #524's derive_is_claimant_or_partner_from_frs_microdata; uv.lock reset to main's (b45c373), relocked in R. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflict resolved per runbook A4 step 13: datasets/frs.py keeps all three new functions, #490's derive_all_claimants_over_state_pension_age, #524's derive_is_claimant_or_partner_from_frs_microdata and #525's derive_uc_is_in_gainful_self_employment. #525's uv.lock edits auto-merged and are reset to main's in R. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved per runbook A4 step 14, both in tests/test_legacy_benefit_proxies.py: (a) the FakeMicrosimulation double keeps #490's person_benunit_id, is_adult and is_SP_age branches and #526's [66] * len(...) state_pension_age; (b) #526's create_single_adult_frs helper drops the lha_list_of_rents.csv.gz read_csv fake, because #516 deleted that file and its fake. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SPI-donor rules redraw would_claim_uc on SPI-synthetic rows, so a unit whose claimant and any partner have all reached State Pension age could get would_claim_uc there even though create_frs (#490) never gives it one. apply_spi_donor_benefit_rules now takes an optional per-benefit-unit mask, uc_pension_age_excluded, and clears would_claim_uc where it is set. Its one pipeline caller always computes the mask on the real target dataset with the same derivation as create_frs and passes it; a test checks that wiring. Integration commit for the 10/8 uk-data release (d833). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#525 needs policyengine-uk 2.122.0 or later (first release with PE-UK #2081). Floors become policyengine-uk>=2.122.0 and policyengine-core>=3.32.13; the dev extras keep a single hypothesis>=6.168.3. The lock changes exactly four packages: policyengine-uk 2.93.0 -> 2.122.2, policyengine-core 3.31.1 -> 3.32.13, hypothesis added (6.168.5), and the package's own entry 1.56.16 -> 1.57.4. uv lock --check passes. Relock commit for the 10/8 uk-data release (d833). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 7, 2026
Merged
…ount (F1) test_full_target_set_available_offline (from #536) asserted at least 30 OBR targets offline. The release combines four member PRs that each replace OBR targets with better sources, which no single PR's CI saw together: #490 swaps obr/housing_benefit for DWP Housing Benefit targets, #510 swaps obr/pension_credit for DWP Pension Credit spend and caseload, #533 swaps the two OBR salary-sacrifice NI relief targets for HMRC's, and #530 merges the two OBR UC targets into obr/universal_credit. That leaves 29 OBR targets (34 on main), so release CI failed with 29 >= 30. The test now checks what it was for: offline, the committed workbooks give exactly the OBR targets that the same workbooks give when served, plus the receipts and NICs names. A broken fallback still fails it. Release-only fix for the 10/8 uk-data release (d833). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
21 of 52 tasks
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.
Release the 10/8 uk-data batch as one data release, expected to be 1.58.0. This branch contains 15 member PRs at their reviewed heads, the planned merge conflict resolutions, the SPI UC pension-age integration (I1), and the dependency relock (R). It lands only on Max's go under d833.
The member PRs' impact estimates were measured separately, under different policyengine-uk versions or development heads. They do not add, and no full build of the combined release has run locally.
Member PRs and exact-head reviews
0812cd1b3c5952a2b4b259ae046baf44dfced8a3cc937e0555d7ead58fc980b41b1959510709b1dbf4d8f95c512ad47b902c2a2bb9c12f8853cce7b8954c225)65656305498b1964ca000ecf1620097eec71c5ec29e1bd7a18a80942cc9014946d2dc8bea7e40b44a1690afaa72595b2d5a847ac6581b692be1fbf147605e63efb57b1dce40df91ea459aa7da9485cc6974fa8cbb90b636fdc06e21195a420a3e0fad7cf0863a6aa540be49dac65cfd73c17ebe82b17eecddeb16e944e0ed00df43f6492344ebbc6b055657c1c5b20c02a2f0d3509fff90cc679f302b8225c0eis_claimant_or_partnerfrom the FRS adult table.5e320ff2140bf2cb2a7ad0c01bc31d5fa71cb766dc2abf7b4cd52b9e63c3631020af6e7e0c79c6da1832adeb2296b53fe5a7d7194e770118aa34d1f8d39371d508c33065e636fd9dcc5f15e750177fa2A4 merge conflict resolutions
.gitignoresides, retaining onelocal_geography_weights.csv.gzline and.brma-cache/; resetuv.lockto main'sb45c373cversion.pyproject.tomlhunk withpolicyengine-uk>=2.107.0, then set the final floor in R; retain the clean auto-merged lock until R.targets/schema.pyhunk withcarry_forward; Calibrate GB universal credit to one OBR total; reach the UC payment top band #530's conflicting hunk repeats the oldercountriesversion.assign_reported_takeup(...), Calibrate Housing Benefit to DWP's GB figures by age group #490/Solve Pension Credit take-up over entitled benefit units #510's comments, and Calibrate Housing Benefit to DWP's GB figures by age group #490's& ~derive_all_claimants_over_state_pension_age(...)exclusion on the base-FRSwould_claim_ucdraw; union.gitignoreand reset the lock to main's.datasets/frs.pyand reset the lock to main's.datasets/frs.py, includingderive_uc_is_in_gainful_self_employment.person_benunit_id,is_adult, andis_SP_agefixture branches and Map FRS EMPSTATI 11 to OTHER_INACTIVE, not LONG_TERM_DISABLED #526's[66] * len(...); remove the obsoletelha_list_of_rents.csv.gzfake reintroduced by Map FRS EMPSTATI 11 to OTHER_INACTIVE, not LONG_TERM_DISABLED #526, as Weight FRS BRMA draws by census private-rented households #516 deletes that file.uv.lockto main's before R.#503, #509, #490, #510, #536, #533, and #517 merged without conflicts. No code choices beyond the A4 rules were needed.
I1: SPI donor UC pension-age exclusion
Apply #490's pension-age exclusion to #514's SPI donor redraw, so a benefit unit whose claimants are all over State Pension age cannot acquire
would_claim_ucthrough that redraw.apply_spi_donor_benefit_rules(dataset, donor_person=None, uc_pension_age_excluded=None)accepts an optional boolean array with one entry per benefit unit. After redrawing take-up flags, it applieswould_claim_uc &= ~uc_pension_age_excludedwhen the array is supplied; withNone, it excludes nothing. The rule function does not construct aMicrosimulation.The sole pipeline caller always computes the mask on the real target dataset with the existing
_all_claimants_over_state_pension_age(target_dataset, year)helper, using the same computation ascreate_frs, and passes it explicitly. The helper loads a one-yearUKMultiYearDatasetcontainer holding a copy of the target, so it evaluates that year's claimant and State Pension age variables without extending the dataset or uprating unrelated household inputs. Example and property tests compute the mask on_people_dataset(...)and pass it in; a caller-wiring test captures the keyword argument so omitting it fails. This keeps synthetic fixtures independent of household uprating inputs and avoids adding a simulation to every donor-rule Hypothesis example.#490's exclusion therefore reaches both UC draws. #510's enhanced-dataset Pension Credit take-up step still supersedes #514's SPI Pension Credit redraw. On policyengine-uk 2.122.2,
claimant_or_partner_variableselectsis_claimant_or_partner, supplied by #524.R: dependency relock
Set the dependency floors to
policyengine-uk>=2.122.0andpolicyengine-core>=3.32.13, retain onehypothesis>=6.168.3requirement indev, and keepbuildandtowncrier>=24.8.0on separate lines. Lock policyengine-uk exactly to 2.122.2, the version covered by the pin analysis, rather than advancing to a later release. #525 requires policyengine-uk 2.122.0 or later.The expected lock changes are exactly four package records:
policyengine-ukpolicyengine-corehypothesispolicyengine-uk-dataR adds
changelog.d/uk-data-batch-relock.changed.md. Together with the 15 member fragments, versioning should produce one 1.58.0 section containing 16 entries; #524's.addedfragment drives the minor bump from 1.57.4.Local validation
The four targeted files passed: 48 passed, 1 skipped (39 warnings) in 120.46 seconds, using the required shared
lockf -k, two workers, and a fresh temporary directory removed afterward. The pension-age example, property, and caller-wiring tests passed; the original synthetic-fixture regression passed unchanged. The dataset-dependent pension-age check skipped because the built dataset was unavailable.uv lock --checkpassed for 162 packages. Ruff formatting passed for 242 files andgit diff --checkpassed. All 15 reviewed heads are included; only the seven expected storage paths differ, with no generated geography output.What publishes after the go
The release branch push publishes no data. The release PR runs PR CI on the combined tree. On Max's go, one merge to main starts versioning and a docs redeploy; versioning commits 1.58.0, and
push.yamlruns the full build and tests. The docs redeploy runs independently and can complete even if the later build tests fail. The hub cancels the duplicatepush.yamlrun on the merge commit at the old version.If the full build and tests pass:
policyengine/policyengine-uk-data-private: one commit writes seven root files: base FRS, enhanced FRS, tiny-base FRS, and tiny-enhanced FRS.h5files;parliamentary_constituency_weights.h5;local_authority_weights.h5; andlocal_geography_weights.csv.gz. It also writesrelease_manifest.jsonat the root and atreleases/1.58.0/, then creates and verifies HF tag1.58.0.policyengine-uk-data-private: overwrite those same seven objects in place, each with version metadata1.58.0. Consumers fetching the HF root files or GCS objects by name receive the new release.Update package versioncommit with version 1.58.0 and one CHANGELOG section. The publish workflow attempts a lightweight git tag1.58.0, which the hub verifies afterward. The gh-pages docs redeploy comes from the merge commit because Weight FRS BRMA draws by census private-rented households #516 and Draw each cloned household's Output Area from its own FRS region #517 changedocs/.HF uploads before GCS. The installed-version manifest certifies
policyengine-uk==2.122.2andpolicyengine-core==3.32.13. Nothing is uploaded to PyPI or to the public HF repo, and no GitHub Release object is created. This batch changes no release-path files. The downstream microcosm#1087, PE-UK #2082, and policyengine.py release follow on their own gates; d778's policyengine.py release pins the then-latest policyengine-uk and core with the new data and certifies that bundle.The release PR carries the member PRs' issue closures because GitHub's handling of their closing keywords when the member heads reach main has not been verified:
Fixes #515
Fixes #504
🤖 Generated with Claude Code