Repository navigation
Lock policyengine-uk 2.145.0, follow its bus fares and bind thin target rows - #1333
juaristi22 wants to merge 10 commits into
Conversation
|
@juaristi22 thanks, this is my review at Verdict. The 2.141.1 step is sound. I checked every variable policyengine-uk removed or renamed between 2.134.4 and 2.141.1 (the old What I ran
Findings
What looks right
🤖 Generated with Claude Code |
c11ac14 to
1599324
Compare
Only policyengine-uk moves (2.134.4 to 2.139.2); policyengine-core stays at 3.33.3, which still meets its floor. Nothing the build writes is renamed, removed, re-typed or moved between entities. Re-derived as #1308's lock commit did: the uv lock and APPROVED_UV_LOCK_SHA256, the engine pin, the uprating pins' version stamp (every pinned value is unchanged), the concept mapping's engine version, the floors in the three pyproject files and the stage manifests, the coverage manifest, the H2 fixture, and the version-only texts. The concept coverage goes from 302 to 308 inputs: unused_pension_annual_allowance (2.134.5), pension_annual_allowance_taxable_lump_sum_death_benefits and pension_contributions_via_salary_sacrifice_pre_2015 (2.135.6), war_widows_pension_reported (2.135.7), and the two property secured-debt inputs (2.136.1). The liquid-asset reason follows 2.136.1: uc_reported_capital defaults to -1 and, set, is a unit's complete capital; benunit_reported_capital replaces the financial sources only, and property is valued apart and shared across the household's claimants and partners. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pital 2.135.0 gives Universal Credit and Housing Benefit a cap each and removes is_benefit_cap_exempt and its parts. The ESA support-group test reads Housing Benefit's specified-benefit exemption, which follows the stored group for this tenant on income-related ESA, and the UC relationship diagnostic lists both schemes' exemption flags. 2.136.1 values UC property apart (property_sources at 90% less secured debt) and shares it across every claimant and partner in the household, whatever their unit records; a recorded uc_reported_capital is a unit's complete capital and consumes its own share. Every unit on the build's spines records a figure, so nothing is counted twice there. The three engine tests that place units on the -1 sentinel now expect the new shares, and the stage's texts and notes describe the rule. The receipt counts any unit left on the sentinel beside a unit that records the household's property, the one case the engine would count twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The FRS spine summed benefit codes 6 and 9 into bsp_reported. Code 9 is War Widow's or Widower's Pension, which rises with CPI, while Bereavement Support Payment's rates are frozen. policyengine-uk 2.135.7 gives the pension its own input (pe-uk#2382), so code 9 now goes to war_widows_pension_reported and bsp_reported keeps code 6 (#1222). The new column goes wherever bsp_reported goes: the spine's outputs, the graph's stage cells, the SPI fill and rewrite columns, and the reports an SPI-channel row restores from its FRS twin, with the benefit coherence gate checking it. The source manifest, the H2 fixture and the gate digests re-derive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk's dataset uprating projects both recorded capital figures, uc_reported_capital and pension_credit_reported_capital, by GDP per head, as it does financial capital. From 2.139.1 it projects other residential property by house prices, while non-residential property and owned land stay on GDP per head. So the other residential property in a recorded figure grows faster than the engine's own projection of it: by the OBR indices the engine carries, 1.5% faster by 2025 and 2.0% by 2026 from a 2024 base. The stage's module text and its spec note say so; the source manifest and the H2 fixture re-derive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk 2.142.0 carries pe-uk#2536, the fix for pe-uk#2523. It adds defined_benefit_pension_share and the defined-benefit input amount, estimates unused annual allowance carried forward when none is supplied, uses one definition of relevant UK earnings, uprates water and sewerage charges by country with a Scottish Water series, and derives the UC benefit cap's earnings threshold from the national living wage. The lock goes straight there, with no stop on 2.141.6 to 2.141.9, whose water uprating overstates Scottish bills (Vahid's review of #1333). policyengine-core stays at 3.33.3. The floors, APPROVED_UV_LOCK_SHA256, the engine pin, the uprating pins' stamp (the values do not change), the concept mapping's engine_version, the concept coverage (308 to 310 inputs), the coverage manifest, the source manifest, the H2 fixture and the cited versions re-derive. unused_pension_annual_allowance is now a formula, so it leaves the input list; defined_benefit_pension_share, is_full_year_category_a_director and salary_sacrifice_returned_to_income join it and stay at their defaults. employer_pension_contributions.py says why the defined-benefit share stays unset, and salary_sacrifice.py which way leaving the pre-2015 input at nil leans (Vahid's review of #1333, findings 3 and 6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From policyengine-uk 2.136.1 a benefit unit on the -1 sentinel takes its own share of its household's property, which a unit recording the property beside it already holds, so the engine would count it twice. The stage's receipt counted such units for UC only; it now counts them for UC or Pension Credit, since a unit that reports UC records no UC share but may still record Pension Credit property. The UC capital gate now refuses any such unit, so the argument that every unit on the spine records a figure stays checked if a later survey year reaches the sentinel (Vahid's review of #1333, finding 4). The gate's notes and digests re-derive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ipt lines (#1331) The NTS bus stage declares fare_cap_regime: England's £2 single-fare cap outside London, whole in the 2023 and 2024 survey years and absent in 2022, with a penny's tolerance. The stage reads the single-ticket share on the cap years only, because the FRS 2024-25 base year sits under that cap; 2022 stays in the band and trip fit. The ticket receipt adds fare-mix lines for England outside London: before the cap, the share of point-of-use boardings above £2 and their mean fare; under it, the share paid at £2. A line reads <10 when it, or its complement, rests on fewer than 10 unweighted boardings or 10 distinct households. The receipt now also weights each boarding by the full trip weight. It divided the household weight W2 out for the person-level sums and never multiplied it back, so every diary household counted alike in its shares and fares. No stage output read the receipt. The test donor and the H2 fixture's donor now spread every region over every survey year, so the cap years hold London donors. Receipts Part M has the engine-free readings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
María's rule of 2026-10-21: a target row is never left out because its cell rests on fewer than ten records; only a measured distortion of the calibration keeps it out. The floor of ten governs what is published. - The support floor drops only rows no source household carries (the solver's initialiser refuses those). Its floor must be 1, so a count floor cannot come back through the register. The benefit-cap amount bands join its scope. - The per-row exclusions that rested on thin support alone retire: the eleven benefit-cap amount bands and the HMRC £500k to £1m dividend and property-income-count rows. Rows with zero support, and those out for measured frame gaps, stay. - A bound row that fewer than ten source households carry keeps its model figures in the build on every line, as BRMA rows' have since the #1305 review. uk_withheld_rows counts every row. The national gate kernel blanks thin rows in its evidence, restates the manifest's losses over the published rows and refuses a report that names a thin row. The national fit gate decides on the published rows and counts the withheld ones, and every parity-evidence producer states its withheld set, so a missing one fails closed. The certifier skips withheld rows, the Orrery size summary publishes no all-row total, and no run forwards an epoch's loss. The four-household seam fixture and the three-household toy graph would withhold every row, so those pipeline tests lower the count to one or publish every row, and the withheld path has its own tests, including a national seam whose only row is thin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
María's ruling of 2026-10-21 replaces the calendar-year basis of 2026-09-10: the 2025 England and London fare-receipt rows move from 2024-25 as the engine's model year does. Each area's BUS0415a quarter-end index is in force from the start of the quarter it closes and is day-weighted over 6 April to 5 April, as policyengine-uk reads gov.dft.bus.local_bus_fares_index (fiscal_year_blend, PolicyEngine/policyengine-uk#2546). London and England outside London move by their own series and England's receipts move as their sum, as the engine prices each area by its own index. On the June 2026 release England's factor is 1.0763 (1.0570 on the calendar basis) and London's 1.0000086. The bus parity receipt also ties each area's factor to the engine's index ratio (its measurement year over its benchmark year), and the engine test holds the tie within 0.1% at the locked engine. The target references are unchanged; the membership and the national compile-parity receipts re-derive from the pinned feed, the two fare rows only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk 2.145.0 carries pe-uk#2536 (the fix for pe-uk#2523) and pe-uk#2546 (bus fares follow the BUS0415a index by area and fiscal year). Since 2.142.0 it also stacks capital gains on taxable income across the higher and additional bands and sets the annual exempt amount where it saves the most tax (2.143.0), gives Northern Ireland's Local Housing Allowance its own freeze and percentile parameters (2.143.0), and adds PIP points inputs, from which it derives a category only when none is supplied (2.144.0). policyengine-core stays at 3.33.3. The floors, APPROVED_UV_LOCK_SHA256, the engine pin, the uprating pins' stamp (the values do not change), the concept mapping's engine_version, the concept coverage (310 to 311 inputs: pip_dl_points, pip_m_points and local_bus_uncapped_single_fare join at their defaults, and the two PIP categories become formulas that the supplied categories still set), the coverage manifest, the source manifest, the H2 fixture and the cited versions re-derive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6ca0b4b to
e214ff3
Compare
Part of #1095. #1332 has merged, so this PR now targets main. Implements #1331 with the window decision (b).
The lock goes from 2.134.4 straight to 2.145.0. That release carries PolicyEngine/policyengine-uk#2536 (the fix for PolicyEngine/policyengine-uk#2523) and PolicyEngine/policyengine-uk#2546 (bus fares from the published fares index). It does not stop on 2.141.6 to 2.141.9: those grow every country's water bills by Ofwat's series, and only #2536 gives Scotland its own series and holds Northern Ireland flat.
Summary
Lock and re-derived surfaces
uv.lock, the three>=floors andAPPROVED_UV_LOCK_SHA256move to 2.145.0; policyengine-core stays at 3.33.3.engine_version, the concept coverage, the coverage manifest, the source manifest, the H2 fixture and the cited versions re-derive. The engine has 311 inputs (310 at 2.142.0):pip_dl_points,pip_m_pointsandlocal_bus_uncapped_single_farejoin, and the two PIP categories become formulas that the supplied categories still set.uc_reported_capitalof 0 or more is a unit's complete capital.What the releases after 2.142.0 bring
Engine inputs: written or left at the default
war_widows_pension_reportedis written (below).unused_pension_annual_allowanceis a formula from 2.142.0, so it is no longer an input: the engine estimates carry-forward from the five previous years.defined_benefit_pension_share(2.142.0). The engine counts a defined-benefit arrangement's input as its contributions timesdefined_benefit_input_per_contribution, which is 1, so the share would change the annual allowance only for net-pay contributions at 75 and over.employer_pension_contributions.pysays so.pension_contributions_via_salary_sacrifice_pre_2015: the FRS records no start date, so all salary sacrifice counts in threshold income (FA 2004 s. 228ZA(6)). That overstates threshold income for arrangements made before 9 July 2015, and so the taper and the charge's reach, in any comparison with HMRC;salary_sacrifice.pysays so.pip_dl_pointsandpip_m_points(2.144.0): the FRS records the award's components, not the assessment's points, and the categories are supplied.local_bus_uncapped_single_fare(2.145.0): the engine's fitted fare table prices cap changes; drawing person-level fares from NTS donors is outside UK bus fares: keep in step with the engine's per-year fares, take the single-ticket share from cap-regime years, and check cap savings against NTS fares paid #1331.pension_annual_allowance_taxable_lump_sum_death_benefits: no source.other_residential_property_secured_debtandnon_residential_property_secured_debt: they reach UC only for a unit without a recorded capital figure, and every unit on the spine records one.is_full_year_category_a_director(2.141.7): it applies to 2022-23 National Insurance only.salary_sacrifice_returned_to_income: a legacy input the engine documents as never computed.Two benefit caps and UC capital (2.135.0, 2.136.1)
is_benefit_cap_exemptand its parts. The ESA support-group test reads Housing Benefit's specified-benefit exemption, and the UC relationship diagnostic lists both schemes' flags.War Widow's Pension (#1222)
war_widows_pension_reported(2.135.7, Give War Widow's Pension its own CPI-uprated variable ahead of freezing BSP policyengine-uk#2382), andbsp_reportedkeeps code 6. A new FRS spine test pins the split; the old mapping fails it.Bus fares (#1331)
gov.dft.bus.local_bus_fares_index. London and England outside London move by their own series, and England's receipts move as their sum. On the June 2026 release England's factor is 1.0763 (1.0570 on the calendar basis) and London's 1.00001.fare_cap_regime(England's £2 cap outside London, whole in 2023 and 2024) and reads the single-ticket share on those years only, because the FRS 2024-25 base year sits under the cap. 2022 stays in the band and trip fit. Outside London the share of fare-paying boardings paid at the point of use moves from 0.70 (2022 to 2024 pooled) to 0.73.<10. The 930 receipts doc, Part M, has the readings.Thin target rows (María's rule of 2026-10-21)
Not in this PR
benefit_cap_reductionadds the UC and Housing Benefit reductions, and from 2.141.3uc_benefit_cap_reduction_after_flooris the amount a UC award actually loses. Rebinding the cap rows to it changes the population contract, so it is a follow-up (an issue to be filed).What moves
Measurement
Tests
Run locally; CI runs on this PR now that #1332 has merged.
tools/spec_engine_coverage.py --checkpasses (42,184 of 42,184 fields).🤖 Generated with Claude Code