Repository navigation
UK: port the remaining uk-data fixes tracked in #1095, engine items included - #1121
Conversation
Automated review pass (Claude Code, high effort) — round 1 at
|
a0f292a to
a8dc66f
Compare
…h no annual-coded award (#1095) From the review of #1121: the repair's threshold is twice the tab's largest annual-coded award, so it moves with each survey year, and a tab with calendar-month awards but no annual-coded award used to repair nothing without saying so. access_fund_annual now refuses that tab, and records the paid awards by period code, the threshold and the repaired count; the root stage carries the record in its checkpoint evidence beside the capital sentinel count. The docstring and changelog describe the 2024-25 repair in aggregate terms. The spec scope names the refusal, and the stage's surfaces are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The commits, where the plan changed during implementation (C5 reads the child tab too; C6 puts one identity-keyed draw on the root stage; B1 mirrors the engine's formula rather than handing the flag to it; B2 leaves the UC take-up population to Max's branch; B4 is rebased on #1081, which merged first), and the measurement: arm E (value-identical LCFS, 7/7 gates), arm B0 (the engine bump empties two sparse UC payment bands; #1107's rollout checks), arm B2 and the head arm, which also takes the West Midlands 12,570 to 15,000 income-tax cell past the 25% bound. Both diagnoses are recorded: the regional bands leave out other investment income, and policyengine-uk 2.122.2's corrections move every award that supported the two UC bands. X defers the cell and Y excludes the bands; replaying the target-fit gate on the head arm's evidence then passes. Review round 1 on #1121: the rebase onto #1081, the battery clock CI tripped on, and R1's access-fund evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks, Vahid. Round 1 is addressed on the rebased head; details by item below. Rebase. The branch is rebased onto main after #1081, and CI's
1. X and the band variable. Agreed, it's a measurement bug, and wider than the regional cells. 47 HMRC targets band on policyengine-uk's
I measured the fix through the calibration's own measure path on the head spine, adding The fix belongs upstream:
I'm drafting a policyengine-uk issue, and X's register entry will link it once it's filed. X keeps the cell bound in calibration and expires on 2026-11-03. 2. Y and the growing class. Kept for this PR. Agreed the class needs a rule rather than one signed entry per sparse band. The options are:
3. B4 and #1081. #1081 merged first, and B4 is rebased on it, so the CVPAY line is now #1081's own The householder's receipt stays uncredited, as #1081's docstring records. policyengine-uk 2.122.2 has no householder-side input for lodger or boarder receipts. It has only the payer's two columns and 4. The bump. Thanks for the list. B0's changelog fragment now carries the forward-year note:
5. The opt-out shortfall. It's expected under #1107's contract (
So the 27.4k shortfall is recorded, not filled, and 6. C2's threshold. Done in
7. C6. Thanks; no change. Still open before merge:
|
The review of #1121 agreed the West Midlands 12,570-15,000 cell fails because policyengine-uk's total_income leaves out other investment income, which its own income_tax charges, and María ruled the fix belongs upstream. pe-uk#2174 now tracks it, and X's register entry names it as what the four-week deferral waits on. The entry's approval, adjudication and dates are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a8dc66f to
980ffef
Compare
The commits, where the plan changed during implementation (C5 reads the child tab too; C6 puts one identity-keyed draw on the root stage; B1 mirrors the engine's formula rather than handing the flag to it; B2 leaves the UC take-up population to Max's branch; B4 is rebased on #1081, which merged first), and the measurement: arm E (value-identical LCFS, 7/7 gates), arm B0 (the engine bump empties two sparse UC payment bands; #1107's rollout checks), arm B2 and the head arm, which also takes the West Midlands 12,570 to 15,000 income-tax cell past the 25% bound. Both diagnoses are recorded: the regional bands leave out other investment income, and policyengine-uk 2.122.2's corrections move every award that supported the two UC bands. X defers the cell and Y excludes the bands; replaying the target-fit gate on the head arm's evidence then passes. Review round 1 on #1121: the rebase onto #1081, the battery clock CI tripped on, and R1's access-fund evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Automated review pass (Claude Code, high effort) — round 2 at
|
| Round-1 item | Status | Evidence |
|---|---|---|
| 1. West Midlands deferral is a band-variable defect | Agreed; link the issue | Confirmed upstream at policyengine-uk 2.122.2. total_income (variables/gov/hmrc/income_tax/total_income.py, cites ITA 2007 s. 23) adds savings_interest_income but not other_investment_income, while taxable_savings_interest_income charges both. It's now filed as policyengine-uk#2174. The X entry in uk/target_fit_reviewed_exclusions.json explains the defect but cites only microcosm#1095. Please add #2174 so the deferral points at the fix that retires it before 2026-11-03. Your 6.15× → 0.92 measurement on the head spine, with the other 119 regional cells moving at most 8%, is a convincing case that the band, not the data, is wrong. |
| 2. Single-household UC band exclusions (Y) | Fine as stated | Kept for this PR. A pooling or minimum-support rule is the right follow-up; worth a tracking item on #1095 so it doesn't stay one signed entry per release. |
| 3. B4 overlap with #1081 | Closed | The branch contains the #1081 merge (a50b9cc0). CVPAY handling is only #1081's frs_property_income; B4 keeps the payer's rent_paid_as_boarder/rent_paid_as_lodger and the shared-rent liability. The uncredited householder receipt is documented in #1081's docstring, and the engine has no householder-side input yet. |
| 4. Engine bump and the 2029 salary-sacrifice note | Closed; one link | The B0 changelog fragment's forward-year note is accurate. It would help to cite policyengine-uk#2173, filed today for exactly this: the fix routes the excess to NI-able earnings only. |
| 5. Child Benefit opt-out shortfall (27.4k) | Closed | Recorded rather than filled, as #1107's contract sets out (pool_shortfall_families, pool_exhausted, default opt_out_charge_share = 1), and obr.child_benefit still fits. |
| 6. Access-fund repair threshold | Closed | d083f8ff5: access_fund_annual (frs_spine.py:1390) refuses a tab that has calendar-month awards but no annual-coded award. Its evidence records paid awards by period code, the threshold and the repaired count, and the root stage carries that in its checkpoint evidence. The tests cover repair, refusal and the evidence record (test_uk_frs_spine.py:1062, :2954-3013), and they pass locally. |
| 7. C6 linked-claim share hand-weighted | Still open (nit) | The reply says "no change", but the round-1 nit was about the weighting, not the rule. frs_spine.py:1353-1362 still computes the linked share from a hand-built gross4 array (weight[linked].sum()). Under the microdf-throughout convention, a MicroSeries over the person rows with household weights would do it. Not blocking. |
Rebase and CI
- The engine-free fix is legitimate. In
test_uk_battery_bindings.py::test_fully_armed_battery_evaluates_gate_for_gate, the fixed register clock predated X's approval, so X read as not yet in force. Moving the clock forward is what the test's note asks. It passes locally. - New: conflicts with main. Main has moved by Add Axiom graph adapter surfaces and simulate.rules_by_ref@1 (NZ v0, G1) #1118 and Add the liquid financial assets concept, schema version 2 (NZ v0, G3a) #1120 (the NZ hub: Axiom adapter and the liquid financial assets concept).
git merge-treeshows two conflicts, both in generated files:docs/concept-coverage/policyengine-uk.mdandpackages/microcosm-frame/tests/golden/concept-coverage/policyengine-uk.json. Regenerate them after merging main; nothing hand-written conflicts. - CI at this head:
wheelspassed.engine-free(3.13, 3.14),lintandselect-countrieswere still pending when I checked.
980ffef to
c098fdc
Compare
…h no annual-coded award (#1095) From the review of #1121: the repair's threshold is twice the tab's largest annual-coded award, so it moves with each survey year, and a tab with calendar-month awards but no annual-coded award used to repair nothing without saying so. access_fund_annual now refuses that tab, and records the paid awards by period code, the threshold and the repaired count; the root stage carries the record in its checkpoint evidence beside the capital sentinel count. The docstring and changelog describe the 2024-25 repair in aggregate terms. The spec scope names the refusal, and the stage's surfaces are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review of #1121 agreed the West Midlands 12,570-15,000 cell fails because policyengine-uk's total_income leaves out other investment income, which its own income_tax charges, and María ruled the fix belongs upstream. pe-uk#2174 now tracks it, and X's register entry names it as what the four-week deferral waits on. The entry's approval, adjudication and dates are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The commits, where the plan changed during implementation (C5 reads the child tab too; C6 puts one identity-keyed draw on the root stage; B1 mirrors the engine's formula rather than handing the flag to it; B2 leaves the UC take-up population to Max's branch; B4 is rebased on #1081, which merged first), and the measurement: arm E (value-identical LCFS, 7/7 gates), arm B0 (the engine bump empties two sparse UC payment bands; #1107's rollout checks), arm B2 and the head arm, which also takes the West Midlands 12,570 to 15,000 income-tax cell past the 25% bound. Both diagnoses are recorded: the regional bands leave out other investment income, and policyengine-uk 2.122.2's corrections move every award that supported the two UC bands. X defers the cell and Y excludes the bands; replaying the target-fit gate on the head arm's evidence then passes. Review round 1 on #1121: the rebase onto #1081, the battery clock CI tripped on, and R1's access-fund evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c098fdc to
bdffbe2
Compare
…h no annual-coded award (#1095) From the review of #1121: the repair's threshold is twice the tab's largest annual-coded award, so it moves with each survey year, and a tab with calendar-month awards but no annual-coded award used to repair nothing without saying so. access_fund_annual now refuses that tab, and records the paid awards by period code, the threshold and the repaired count; the root stage carries the record in its checkpoint evidence beside the capital sentinel count. The docstring and changelog describe the 2024-25 repair in aggregate terms. The spec scope names the refusal, and the stage's surfaces are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review of #1121 agreed the West Midlands 12,570-15,000 cell fails because policyengine-uk's total_income leaves out other investment income, which its own income_tax charges, and María ruled the fix belongs upstream. pe-uk#2174 now tracks it, and X's register entry names it as what the four-week deferral waits on. The entry's approval, adjudication and dates are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The commits, where the plan changed during implementation (C5 reads the child tab too; C6 puts one identity-keyed draw on the root stage; B1 mirrors the engine's formula rather than handing the flag to it; B2 leaves the UC take-up population to Max's branch; B4 is rebased on #1081, which merged first), and the measurement: arm E (value-identical LCFS, 7/7 gates), arm B0 (the engine bump empties two sparse UC payment bands; #1107's rollout checks), arm B2 and the head arm, which also takes the West Midlands 12,570 to 15,000 income-tax cell past the 25% bound. Both diagnoses are recorded: the regional bands leave out other investment income, and policyengine-uk 2.122.2's corrections move every award that supported the two UC bands. X defers the cell and Y excludes the bands; replaying the target-fit gate on the head arm's evidence then passes. Review round 1 on #1121: the rebase onto #1081, the battery clock CI tripped on, and R1's access-fund evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bdffbe2 to
692e8b7
Compare
…h no annual-coded award (#1095) From the review of #1121: the repair's threshold is twice the tab's largest annual-coded award, so it moves with each survey year, and a tab with calendar-month awards but no annual-coded award used to repair nothing without saying so. access_fund_annual now refuses that tab, and records the paid awards by period code, the threshold and the repaired count; the root stage carries the record in its checkpoint evidence beside the capital sentinel count. The docstring and changelog describe the 2024-25 repair in aggregate terms. The spec scope names the refusal, and the stage's surfaces are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review of #1121 agreed the West Midlands 12,570-15,000 cell fails because policyengine-uk's total_income leaves out other investment income, which its own income_tax charges, and María ruled the fix belongs upstream. pe-uk#2174 now tracks it, and X's register entry names it as what the four-week deferral waits on. The entry's approval, adjudication and dates are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The commits, where the plan changed during implementation (C5 reads the child tab too; C6 puts one identity-keyed draw on the root stage; B1 mirrors the engine's formula rather than handing the flag to it; B2 leaves the UC take-up population to Max's branch; B4 is rebased on #1081, which merged first), and the measurement: arm E (value-identical LCFS, 7/7 gates), arm B0 (the engine bump empties two sparse UC payment bands; #1107's rollout checks), arm B2 and the head arm, which also takes the West Midlands 12,570 to 15,000 income-tax cell past the 25% bound. Both diagnoses are recorded: the regional bands leave out other investment income, and policyengine-uk 2.122.2's corrections move every award that supported the two UC bands. X defers the cell and Y excludes the bands; replaying the target-fit gate on the head arm's evidence then passes. Review round 1 on #1121: the rebase onto #1081, the battery clock CI tripped on, and R1's access-fund evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Automated review pass (Claude Code, high effort) — round 3 at
|
| Item | Status |
|---|---|
| Link pe-uk#2174 from X | Done. The register reason, the receipts and test_uk_battery_bindings.py (assert "pe-uk#2174" in deferral.reason) all cite it. X expires 2026-11-03. |
| Regenerate concept coverage against main | Done. Regenerated on the new concept schema (d824f5e97d58), with 285 inputs and 40 covered. The branch merges cleanly into main. |
| Cite pe-uk#2173 in B0's note | Open (nit 2). |
| Y's sparse-band class needs a rule | No tracking item on #1095 yet. Worth one line so it doesn't stay one signed entry per release. |
| C6 hand-weighted share | Open (nit 3). |
#1086 / P checked
[tool.uv] conflictspairs every US-installing extra with every UK-installing extra. The US-installing extras aremicrocosm-build[us],microcosm-data[us]andmicrocosm-frame[policyengine]; the UK-installing ones are each package's[uk].- No other
pyproject.tomlin the workspace installs an engine. - CI installs one extra per lane (
--extra us,--extra uk), which the conflicts allow. APPROVED_UV_LOCK_SHA256is re-pinned at P and again at B0.
Tests run locally at 692e8b7b (fresh worktree, uv sync --all-packages --locked, the engine-free environment)
test_engine_core_pins.py: 14 passed.- All 18 engine-free test files this PR touches: about 1,220 passed, 7 skipped, 0 failed.
ruff check .: clean.ruff format --check: none of the PR's files would be reformatted.- CI at this head is green: lint, wheels, select-countries, engine-free, engine-us and engine-uk (each on 3.13 and 3.14), and integration-uk.
Still before merge (from the description, and unchanged)
- The signed-difference entries for the net-new columns (C5, C6, B2–B5) and for B1's mechanism change. The drafts are still outside the repo.
- A calibration of this head, the national build and the certifier. The receipts' head arm was built as
65a08ddb6with both UC bands bound; the Y replay reuses those weights.
…1095) #1089 (2fe7d8b) moved the SPI Table 3.6 employment, self-employment and private-pension amounts by total-income band to HMRC's band growth (hmrc.itl_2026.total_income_growth_by_total_income_band) by editing the generated uk/target_references.json, which it also re-serialised with literal pound signs. The population contract still declared the flat OBR average-earnings, per-capita mixed-income and private-pension indices for the three targets, so regenerating from feed 825406f gave e8f829... against the committed bf7549..., and the feed-gated test_committed_surfaces_regenerate_from_pinned_feed[national] failed on main (CI skips it without the licensed feed). The contract now declares the band-growth index, with notes saying so, for the three targets, and both generated resources are regenerated: the references equal the committed ones as parsed JSON (only the encoding returns to the generator's), and the membership report, which still recorded the flat-index uprating for the 39 references, now records the band factors (-2.3% for 15,000-20,000, +0.3% for 20,000-30,000). Compiled values are unchanged: the three lowest employment bands stay at GBP 17.7bn, 47.5bn and 172.5bn, and the national compile parity regenerates and passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vahid's should-fix on #1100: retiring the access_fund input-mass exclusion left the period-code defect it recorded with no active record. The FRS weeklyises ACCSSAMT from the reported amount and its period code ACCSSPD, and an access-fund award is paid per academic year or term. On the 2024-25 tab the 16 awards' calendar-month amounts run up to the size of a whole annual award, so an award read as monthly can annualise to more than ten times every annual-coded award; #1089 had to sign an exclusion when calibration took such a household to the weight bound. access_fund_annual reads ACCSSPD: a calendar-month award (code 5) that annualises to more than twice the largest annual-coded award (code 52) on the tab is read as its per-period amount, ACCSSAMT x 52/12. On the 2024-25 tab that repairs fewer than 10 awards and leaves large but plausible monthly amounts as reported, as it does the awards with no period code. A tab without the ACCSSPD column refuses. The spec names the rule, the test and H2 fixtures carry ACCSSPD, and the coverage manifest and H2 fixture are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es (#1095) The rest of uk-data#486 on microcosm. The LCFS donor's G018 and G019, household counts of adults and children by the survey's age-18 split, were renamed to the engine's person flags is_adult and is_child, and the recipient materialised those engine flags and summed them per household. policyengine-uk#1896 deprecates both flags. The predictors are now household_adult_count and household_child_count, in the same positions of the predictor list, and the recipient counts its members from age (18 and over, under 18), which is exactly the engine's 2.100.0 rule, so the values and the seeded forest are unchanged; the stage no longer asks the engine for the two flags. The lcfs_consumption notes were a plain YAML scalar containing " #890", which YAML reads as a comment, so 642 characters were dropped at load and from source_stages.json; the notes are now single-quoted and gain a sentence on the counts. Coverage manifest and H2 fixture regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ar-2025 window (#1095) DWP's benefit expenditure and caseload tables give each fiscal year its own measure (expenditure_2024, expenditure_2025), so calendar_year_window read the two years as two one-year series and refused the window; #1100 dropped the row for that reason. A window selector can now declare source_measure_id_by_opening_year, mapping each overlapping year to its measure: a fact matches only its own year's measure, and the declared measures form the window's one series. The map's form is checked when the reference is built; its years are checked when the window resolves, so a compile that restamps the reference to another period (the 2023 parity receipt) defers it like any reference without facts. dwp.hb.amount_pension_age binds the line "Housing Benefit over Pension Credit qualifying age" at 3/12 of the FY2024-25 outturn (6,851.0m) plus 9/12 of the FY2025-26 forecast (7,114.7m), 7,048.8m, on housing_benefit over benefit units whose eldest adult is 66 or over in Great Britain households. It has its own dwp_benefit_expenditure family, which allows source projections. The national references, the membership report and the 2025 parity receipt gain the row and nothing else. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The spine never wrote is_blind, so every person took policyengine-uk's default False. A person is now blind where their own FRS tab records SPCREG1 = 1, registered blind or severely sight impaired with the local authority: registration follows the consultant ophthalmologist's certificate the engine's is_blind names. The adult and child tabs ask the same question, so children are read too; partial-sight registration (SPCREG2) is not read (uk-data#523). FRS 2024-25 has 29 registered adult records (57.3k at gross4 design weights) and fewer than 10 child records. On policyengine-uk 2.100.0 the TV licence concession, the Disabled Students' Allowance condition, the Council Tax Reduction non-dependant exemption and the Tax-Free Childcare age limit and higher amount read it. person.is_blind joins the export-surface allow-list (gates.json and its mirrored constant) and the graph's root booleans. Regenerated: source_stages.json, the H2 spine fixture (synthetic SPCREG1 on adults and children), the coverage manifest's source-manifest pins and the mirrored gate digests. The net-new-column adjudication is drafted for signature. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1095) uc_is_in_startup_period was never set, so the engine's default False applied the Universal Credit minimum income floor from the first assessment period of every self-employed claim. Port uk-data#527's rule (UC Regs 2013 reg 63 as substituted by SI 2019/1152): a self-employed person (EMPSTATI 3/4, a held self-employed JOB row, or nonzero SEINCAM2) is in a start-up period when the benefit unit's UC claim (UCSTART, month/day/year) or the first self-employed job (SEJBLONG, main job first) began less than 12 calendar months before INTDATE; a year-round trader's new self-employed job that is not a business is a new engagement and does not date the trade. UC records with no linked claim date (288 of 2,402 FRS 2024-25 UC benefit units) draw their claim recency, keyed on the benefit unit, at the GROSS4 share of linked self-employed claimants inside the window (0.324). The draw is declared on frs_spine as assign_binary_from_rate, and the stage notes now name it as the root's one identity-keyed draw: only this stage reads the raw claim, interview and job dates. UCSTART is kept as read before numeric conversion, and missing raw date columns refuse. SPI-redrawn rows keep the flag only while their status or imputed self-employment income still shows self-employment. At design weights 222 person records (488.2k) hold it, 96 (208.3k) in UC benefit units, no child. person.uc_is_in_startup_period joins the export allow-list and the graph's root booleans and SPI rewrites. Regenerated: source_stages.json, the H2 spine fixture (synthetic INTDATE, UCSTART, job dates, SAMESIT and SDEMP, and UC rows), the coverage manifest's source pins and the mirrored digests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…side (#1095) The remaining #1095 items read inputs policyengine-uk added after 2.100.0 (pe-uk#1896, #1946, #2018/#2070, #2006, #1940/#1904, #2140), so the UK extras of microcosm-build, microcosm-data and microcosm-frame require >=2.122.2, and the UK fork of the lock moves to policyengine-uk 2.122.2 with core 3.32.19. Under #1086's per-country pins the US fork does not move: the extras that install policyengine-us keep core 3.32.5, so the certified US default still loads and the US lane runs on the engine it was built with. Re-derived on the new lock, no data change: the uprating pin stamp (values unchanged), the policyengine-uk concept coverage (285 inputs, 40 covered), the concept mapping reviewed against 2.122.2 (targets unchanged; the Child Benefit notes quote the documentation that datasets export registered claims; the liquid financial assets reason names the person-level stocks car_list_price and lifetime_isa_balance, and Universal Credit's household capital split by claimant and partner count beside its Lifetime ISA source), the H2 fixture's numerical dependency, APPROVED_UV_LOCK_SHA256 and the CGT stages' declared dependency. policyengine-uk 2.112.0 replaced the male and female State Pension age parameters with the timetable by date of birth, so the UC take-up population reads the cohort's whole-year age from that timetable (66 for 2024 and 2025) and refuses a year where none exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
is_severely_disabled_for_benefits counted any Attendance Allowance and any Armed Forces Compensation Scheme payment. It is now the tax credit severe disability condition (CTC Regs 2002 reg 8, WTC Regs 2002 reg 17) read from the categories the stage derives: DLA care at the highest rate, PIP daily living at the enhanced rate, or higher-rate Attendance Allowance (uk-data#494). That is policyengine-uk's own formula since #1946, and an engine-lane test checks the stored flag against it category by category. FRS code 8 cannot separate Armed Forces Independence Payment, so AFCS no longer counts. The incumbent's coverage manifest marks the flag required, so the spine keeps storing it rather than handing it to the formula. Regenerated: the stage notes in source_stages.json, the coverage manifest's source pins and the H2 fixture's stage record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk#1896 defines is_claimant_or_partner and is_hbai_dependent_child and infers both from ages when a dataset does not supply them. Every FRS person is on the adult table or the child table: the adult table holds each benefit unit's head and any partner (uk-data#524), the child table its HBAI dependent children (uk-data#486), so the spine writes adult-table membership and its complement. The existing claimant derivation already refuses a benefit unit without one or two adult records. Both join the export allow-list and the graph's root booleans. Regenerated: source_stages.json, the H2 fixture, the coverage manifest's source pins and the mirrored gate digests. The UC take-up population's move to the engine's rule is left to Max's uk-take-up-per-person-spa branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk#2018 and #2070 add pension_credit_reported_capital: 0 or more replaces every capital source in Pension Credit's assessable capital, and the default -1 leaves the household proxy. The UC capital coherence stage now writes it beside uc_reported_capital from the same final capital: FRS TOTCAPB4 for the survey units, the capital redraw for SPI-channel units, and the named unavailable sentinel -1 where none is recorded (uk-data#513). Like UC's override it replaces property too; the engine issue about that is held for María's go. It joins the export allow-list and the stage's graph cells. Regenerated: source_stages.json, the H2 fixture, the coverage manifest's source pins and the mirrored gate digests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk#2006 adds liable_for_share_of_household_rent, rent_paid_as_boarder and rent_paid_as_lodger. The spine ports uk-data#512's rule for the first: a later benefit unit of a shared household (HHSTAT 2) is liable where its adults report a rent share (SRENTAMT), it reports Housing Benefit (HBOTHAMT) or a linked UC record carries a housing element (UCHOUSEL); conventional households are left out. CVPAY, the rent a boarder or lodger pays the householder, is recorded on the payer and was counted as the payer's property income; it now feeds rent_paid_as_boarder (CONVBL 1) or rent_paid_as_lodger, and leaves property_income by the same line #1081 removes (coordination with Max owed). FRS 2024-25 at gross4: 103 shared households (319.9k) hold 178 liable later units (615.9k); 43 adult records (138.4k) pay the householder, fewer than 10 as boarders; 806.7m a year leaves property income. The three columns join the export allow-list; regenerated: source_stages.json, the H2 fixture (synthetic HHSTAT, CONVBL, HBOTHAMT and UCHOUSEL), the coverage manifest's source pins and the mirrored gate digests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#1095) policyengine-uk#1940 adds has_mixed_age_couple_pension_credit_saving, the SI 2019/37 saving for a couple entitled as that couple on 14 May 2019. Its default formula reads the older member's birth date from age and the model year, and microcosm holds ages fixed, so each later model year would drop another protected cohort (uk-data#519). The Pension Credit take-up stage already materializes the engine once on the post-SPI receipts at the frame's survey-year period; it now asks for the saving in the same call and stores it, so the entitlement it redraws take-up on and every later model year read the same answer: a mixed-age couple whose older member was born by 5 February 1954, reporting Pension Credit or pension-age Housing Benefit without an income-related legacy benefit, and no Universal Credit. The stage declares the stored output and a second materialize operation; the column joins the export allow-list and the stage's graph cells. Regenerated: source_stages.json, the H2 fixture, the coverage manifest's source pins and the mirrored gate digests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…leave out other investment income (#1095) The head arm (65a08ddb6) blocks on hmrc.spi_region.income_tax_by_region_12570_15000@E12000005 at +27.4% (target 55.1m, design 339.2m) beside the two UC payment bands. The regional cells slice on policyengine-uk's total_income, which leaves out other_investment_income although income_tax charges it as savings interest. Fewer than 10 SPI records whose income is mostly other investment income sit in this band with their whole tax, so the cell's design value is 6.1 times its target (6.0 times before these ports; every other region's cell 0.6-1.1 times). Banded on total income including other investment income, it falls in line with the other regions. The solver pulled the cell to +8.9% with the engine-free ports; policyengine-uk 2.122.2 lands it at +23.6% and B3-B5 at +27.4% (a counterfactual arm with CVPAY back in property income lands at +25.4%). It is deferred four weeks in the target-fit register, approved on 2026-10-06, while the band variable is corrected. The entry would be stale before B3, where the cell fits at +23.6%, so it lands after B5. The two UC bands still block the national artifact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dwp/uc_payment_dist/SINGLE_annual_payment_26_400_to_27_600 and COUPLE_NO_CHILDREN_annual_payment_24_000_to_25_200 each rest on fewer than 10 FRS households. The same spine under policyengine-uk 2.100.0 keeps every supporting award in its band; 2.122.2 moves all of them out through corrections, not data changes: the published LHA rates move awards to neighbouring bands, the 2019 mixed-age couple saving keeps couples who report Pension Credit off UC, and Carer Support Payment counts as unearned income. Both bands sit at -100% on arms B0, B2 and head, so they join the uk-data#452 measure exclusions beside their siblings, approved on 2026-10-07 and expiring with the class on 2026-11-26. Replaying the target-fit gate on the head arm's evidence without the two bands passes, with the West Midlands deferral in force. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h no annual-coded award (#1095) From the review of #1121: the repair's threshold is twice the tab's largest annual-coded award, so it moves with each survey year, and a tab with calendar-month awards but no annual-coded award used to repair nothing without saying so. access_fund_annual now refuses that tab, and records the paid awards by period code, the threshold and the repaired count; the root stage carries the record in its checkpoint evidence beside the capital sentinel count. The docstring and changelog describe the 2024-25 repair in aggregate terms. The spec scope names the refusal, and the stage's surfaces are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review of #1121 agreed the West Midlands 12,570-15,000 cell fails because policyengine-uk's total_income leaves out other investment income, which its own income_tax charges, and María ruled the fix belongs upstream. pe-uk#2174 now tracks it, and X's register entry names it as what the four-week deferral waits on. The entry's approval, adjudication and dates are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The commits, where the plan changed during implementation (C5 reads the child tab too; C6 puts one identity-keyed draw on the root stage; B1 mirrors the engine's formula rather than handing the flag to it; B2 leaves the UC take-up population to Max's branch; B4 is rebased on #1081, which merged first), and the measurement: arm E (value-identical LCFS, 7/7 gates), arm B0 (the engine bump empties two sparse UC payment bands; #1107's rollout checks), arm B2 and the head arm, which also takes the West Midlands 12,570 to 15,000 income-tax cell past the 25% bound. Both diagnoses are recorded: the regional bands leave out other investment income, and policyengine-uk 2.122.2's corrections move every award that supported the two UC bands. X defers the cell and Y excludes the bands; replaying the target-fit gate on the head arm's evidence then passes. Review round 1 on #1121: the rebase onto #1081, the battery clock CI tripped on, and R1's access-fund evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
692e8b7 to
05b8f07
Compare
|
Thanks, Vahid. Rounds 2 and 3 are addressed: #1143 has merged, and this PR is rebased onto it with the fixes ( Round 3
Round 2
Before merge
|
|
Calibration of this head (arm head-r3). Built locally from
The receipts in |
#1086 is settled: each country has its own policyengine-core pin (option 2), which landed on its own as #1143. This PR is the policyengine-uk bump that follows it: B0 moves only the UK side of the lock. C1 can still be cherry-picked on its own.
Before merge: a calibration of this head, which is queued. After merge, as for #1100: the signed-difference entries for the net-new columns (C5, C6, B2–B5) and for B1's mechanism change, whose drafts stay outside the repository until signed, then the national build and the certifier.
Summary
This ports every remaining unblocked item on #1095. It covers:
On the locked engine (C1–C6)
uk/target_references.json. The contract now declares the band-growth index, so regenerating reproduces the committed references. The compiled values are unchanged.household_adult_countandhousehold_child_countand are counted fromage, so they no longer read the engine's deprecatedis_adultandis_child. The stage notes are now quoted in full. The imputation is value-identical (see Measurement).dwp.hb.amount_pension_ageis bound at the calendar-2025 window: 3/12 of FY2024-25 (£6,851.0m) plus 9/12 of FY2025-26 (£7,114.7m), £7,048.8m.calendar_year_windowgains the selector keysource_measure_id_by_opening_year.is_blindfrom the FRS blind registration question (Set is_blind from the FRS blind registration flag (SPCREG1) policyengine-uk-data#523), on the adult and child tabs alike.uc_is_in_startup_periodfrom the FRS claim and trade start dates (Set the UC start-up period from the FRS claim and business start dates policyengine-uk-data#527).On policyengine-uk 2.122.2 (B0–B5)
APPROVED_UV_LOCK_SHA256.car_list_priceandlifetime_isa_balance, and Universal Credit's split of household capital by claimant and partner count.is_claimant_or_partnerandis_hbai_dependent_childcome from the adult and child tables (Supply is_claimant_or_partner from the FRS adult table policyengine-uk-data#524, Supply is_hbai_dependent_child from the FRS and move targets and imputations off the deprecated is_child/is_adult policyengine-uk-data#486).pension_credit_reported_capitaltakes the same recorded capital asuc_reported_capital(Use the FRS benefit-unit capital for Pension Credit's capital test policyengine-uk-data#513).liable_for_share_of_household_rentfollows Mark the benefit units that share their household's rent policyengine-uk-data#512's rule.CVPAYbecomes the payer'srent_paid_as_boarderorrent_paid_as_lodger. UK FRS spine: stop counting lodgers' rent and property losses as property income; sub-letting rent for every tenure #1081, which merged first, already leaves it out ofproperty_income.Calibration registers (X, Y)
The diagnoses are under Measurement.
From the review (R1, rounds 2 and 3)
np.averageover the linked rows with thegross4household weights. It is not a microdfMicroSeries, because microdf reaches an environment only with an engine and the FRS spine runs in the engine-free lane.Where this departs from the plan
is_blindfor children.uk-take-up-per-person-spabranch.Measurement
Each arm was built and calibrated locally on Chronicle 825406f. The control is A9, main's code. The arms predate the rebase onto #1081, so their spines lack its property-income rules.
uk_target_fitfails on two UC payment bands that hold no benefit unit under policyengine-uk 2.122.2: singles at £26,400–27,600 and childless couples at £24,000–25,200.obr.child_benefitcalibrates to 0.0%.hmrc.spi_region.income_tax_by_region_12570_15000@E12000005) fails at +27.4%. It was +8.9% on arm E and +23.6% on B0.total_income, which leaves outother_investment_incomealthoughincome_taxcharges it.total_incomeincludes other investment income. That fix belongs upstream:total_incomecites ITA 2007 s. 23, which counts all income charged to income tax.Full numbers are in
experiments/1095-uk-data-ports-2-receipts.md.Testing
e3e3d881f:engine-freelane's 509 test files: 14,929 passed and 133 skipped, with the same two environmental failures;engine-uklane's 40 test files, run in full: 170 passed. Its Add the liquid financial assets concept, schema version 2 (NZ v0, G3a) #1120 liquid-asset test had failed on 2.122.2 since the previous rebase.test_batched_scoring_matches_whole_pool_policyengine_usfailed on both Pythons. It's a Maryland child-care rate lookup under policyengine-us 2.2.1 on core 3.32.19. With the per-country pins (Give each country its own policyengine-core pin (#1086) #1143), a US install from the new lock resolves core 3.32.5, andtest_us_post_export_scoring.pypasses there (4 tests). The lock-level test passes on this head.ruff checkandruff format --checkpass on all changed Python files.tools/ci_test_plan.py verifyandtools/graph_acceptance_burndown.py --verifypass.Receipts:
experiments/1095-uk-data-ports-2-receipts.md.🤖 Generated with Claude Code