Repository navigation
Set UK road-fuel and energy levels in the LCFS stage on a calendar-2024 basis (#1113) - #1167
Conversation
…ith a diagnose tool (#1113) The national solve was closing three level gaps by moving weights. obr.vat reads +24.7 percent at design weights and +24.1 percent calibrated on #1121's head calibration (policyengine-uk 2.122.2), against the 25 percent bound: the engine divides household VAT by microdata_vat_coverage (0.38, a constant since January 2023), and the frame's raw household VAT is about 46 percent of the OBR receipts (policyengine-uk#1996). The ONS 04.5.1 and 04.5.2 rows sit below the stage's DESNZ volume at QEP prices on every aligned basis (gas below unit cost alone), and fitting them cut electricity 8.6 percent, gas 18.9 percent and the gas-connected share from 84.5 to 78.9 percent. A re-solve of the 2026-09-30 problem with the rows masked changed no other row's fit (98.5 against 98.4 percent within 10 percent). The three rows join the measure-exclusion register on María's 2026-10-08 ruling (VAT until the engine factor is split; the energy rows as a published-source residual, with DESNZ volume at QEP prices kept as the level), windowed to 2027-01-08. tools/diagnose_uk_consumption_taxes.py keeps them measured on any H5 the engine loads, against the values the run's contract registry declares, beside the fuel and energy composition the rows pulled. The twelve COICOP division columns become a named view beside the LCFS rename map so the tool imports them rather than copying them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The LCFS diary records about a quarter less road fuel than ONS household spending, and binding the OBR cars receipts closed that gap by moving weight onto fuel-buying households. A declared level_road_fuel step after the fuel flag now scales petrol and diesel by one factor, so their prior-weighted total equals ONS Consumer Trends COICOP 07.2.2 for calendar 2024 (the year of the DESNZ pump prices the donor uprating uses) less the donor's own c72213 other-fuels share. The drawn mix and each household's relative spend are kept. - lcfs_consumption reads ons_household_expenditure_facts.json, now its declared consumer (re-vendored; values unchanged). - The uk_stage_lcfs_consumption_road_fuel_level stage-health gate recomputes the level from the vendored row and checks that the factor reproduces it; the licensed donor's other-fuels share is bounded at 5%. - Petrol and diesel join the levelled columns, so they carry no committed support bound (regenerated from the pinned LCFS tabs). - The existing litres audit runs after the step, so its frame litres at DESNZ pump prices describe the levelled frame. - Mirrors: operation schema and kind, stage_health parameter vocabulary, spine gate scope, gate-battery digests and entry lists, coverage manifest. The graph parity fixture is regenerated once at the end of the series. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The LCFS diary covers two weeks, so about a third of car-owning donors record no fuel purchase, and the chain reproduced that zero share among the households the fuel flag marks as buying petrol or diesel (34.3% at prior weights on #1121's head). Over a year such a car is refuelled; binding the OBR cars row had moved weight off those households to compensate. A declared redraw_zero_road_fuel step, between the fuel flag's zeroing and the level step, redraws a flagged household whose chain draw is zero from the donor's distribution among households with positive road fuel, on the chain's predictors. A weighted regime-gated QRF draws the total, positive by construction, then the petrol share of it, which keeps diesel-only and mixed households. The quantiles are keyed on the household id (predict_from_uniforms), so a household's draw doesn't depend on row order. Positive chain draws are kept, and the level step then rescales the total. - The receipt records the flagged zero share before and after, the mean among positive households before, the redrawn mean and mix, and the model's regimes. Its two fits add fit-weight records. - The uk_stage_lcfs_consumption_road_fuel_incidence gate checks the declared rule, seed, salt and trees; that no flagged household is left at zero and no unflagged one carries fuel; and the total's positive-only regime. It fails if the chain's zero share passes one half, which would point at the chain rather than the diary. - The end-to-end stage test's synthetic donor now has one-car diaries with no purchase, so the redraw runs there, and the stage's receipts pass both road-fuel gates. - Mirrors: operation schema and kind, stage_health parameter vocabulary, spine gate scope, gate-battery digests and entry lists, coverage manifest, seed pin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#1113) The contract declares ons.household_road_fuel_expenditure: ONS Consumer Trends COICOP 07.2.2 (fuels and lubricants for personal transport), calendar year, household scope, with value_expression "petrol_spending + diesel_spending". It resolves to GBP 35.099bn for 2025. Its notes cover the other motor fuels and lubricants the class carries and the measure doesn't (0.4% on the LCFS diary), and why its design-weight gap is the engine's 2024-to-2025 uprating, since the stage levels the columns to the 2024 row. obr.fuel_duties_cars moves to the measure-exclusion register, still measured on every evaluation. Its gap breakdown: - The OBR cars line includes business-paid car fuel. ONS 07.2.2 at DESNZ pump prices implies about GBP 13.5bn of duty, 7% under it. - With the level step in place, the engine's fuel_duty reads -9.9% against it (-8.1% on DESNZ divisors; policyengine-uk#2169 A). Binding it would move weight onto fuel buyers to stand in for business use. This commit is the only one that changes if the OBR cars row is kept bound instead. - National references regenerated: 1,232 active, with 7 no_fact_at_or_before_period and 16 signed excluded unchanged. The local census is unchanged. - Both compile-parity receipts gain the row as ledger_only. - tools/diagnose_uk_consumption_taxes.py measures the new row beside the held-out ones. The register census and the contract and reference counts are re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chain draws COICOP 04 (housing, water and fuel) and 07 (transport) as whole diary totals, while the stage re-levels the energy and road fuel inside them. Electricity and gas move to DESNZ volume at QEP prices, and petrol and diesel to ONS 07.2.2, so the totals no longer contained their own parts: 2.7% of households had energy above their COICOP 04 total. PE-UK's explicit energy VAT base (policyengine-uk#2166) can only take energy out of the generic base if the totals hold it. A declared recompose_from_remainder step runs after the levelling steps. Each total keeps its own chain draw, less the chain's draws of the parts the stage re-levels, and adds the levelled parts back: - housing_water_and_electricity_consumption: its draw, less the drawn electricity and gas, plus the levelled electricity and gas; - transport_consumption: its draw, less the drawn petrol and diesel, plus the levelled petrol and diesel. The drawn parts are kept right after the support clip, before any step touches them. A remainder floors at zero where the parts outgrow the total: 2,056 and 1,240 of 63,956 households on the head-r3 spine, about GBP 1.0bn and 0.3bn. The chain draws each part after, and conditional on, its total, so the remainder is the chain's own split. Drawing the remainders as chain targets of their own (the plan's first version) over-drew the vehicle-purchase tail of transport: 10 to 13% above the donor in-sample, and GBP 27bn on the spine. The chain and its targets are unchanged, and output columns are unchanged. On the head-r3 spine, consumption across the twelve divisions moves -0.7% (GBP 979.0bn to 972.3bn): - housing -3.4%, as DESNZ x QEP energy (GBP 47.9bn) replaces the drawn electricity and gas (GBP 54.7bn); - transport +0.2%, as the levelled fuel (GBP 36.9bn) replaces the chain's fuel draws (GBP 28.7bn), including those zeroed for households without a fuel car. - The chain's domestic-energy target is the diary's electricity plus gas, so the liquid and solid fuels of COICOP 04.5, which have no column of their own, stay inside the housing remainder at the diary's level. The receipt records their published ONS 04.5.3 and 04.5.4 spend beside it (CY2024, vendored rows): GBP 1.55bn. - The uk_stage_lcfs_consumption_recomposed_totals gate checks each total against its declaration. It requires no negative remainder and no household below its components. The remainder must equal the draw less the drawn parts plus the floored mass, and the total must equal the remainder plus the parts. It also recomputes the uncarried ONS spend from the vendored rows. - The two totals leave the committed support bounds (regenerated); the gate holds them instead. - Mirrors: operation schema and kind, spine gate scope, gate-battery digests and entry lists, coverage manifest, source-stage pins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The audit scales each fuel's all-road-user HMRC litres by the all-fuel OBR cars share (58.3%), giving petrol x1.30 and diesel x0.37. Diesel is mostly vans and lorries, so those per-fuel ratios mislead; only the total ratio compares like with like. The receipt now says so in per_fuel_ratio_basis until a per-fuel cars benchmark exists (DESNZ sub-national road fuel by vehicle and fuel, requested in PolicyEngine/chronicle#322). The plan's quarterly 04.5.x and 07.2.2 vendoring is dropped: no code would read those rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lcfs_consumption stage now sets the levels of electricity, gas, petrol and diesel, the gas connection and the fuel incidence, so calibration should barely move them. Before this series, the bound rows moved them a lot: gas fell 19% through the weights and the gas-connected share 84.5% to 78.9%. uk_diagnostics gains a report-only consumption_drift block, computed from the calibration's initial and final weights on the frame's own columns: - totals: electricity, gas, domestic energy, petrol, diesel, and consumption across the twelve COICOP divisions; - shares: gas-connected households, fuel-buying households, and flagged fuel-car households without fuel. Each value carries design, final, change and relative change. The block is omitted for a frame without the consumption columns. The typed schema (UKConsumptionDrift, UKDriftValue) is optional and forbids undeclared fields, as the rest of the UK extension does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PE-UK projects each household spend column from the H5's year, 2024, with
calendar-year growth, and Microcosm's calibration uprates the same values to
the calendar-2025 window, so both read every column as calendar-2024 prices.
Two of the stage's levels were on FY2024-25 instead:
- energy: DESNZ volume and QEP prices for FY2024-25;
- bus fares: the yield per fare-paying boarding from FY2024-25 receipts and
journeys.
Each column would then have needed its own basis to be projected correctly.
Instead every column now sits on calendar 2024, so none does:
- Energy is priced at QEP's calendar-2024 averages paid and levelled to the
DESNZ Energy Trends volume over the four quarters of 2024, both vendored
beside the fiscal rows. The level now takes a calendar or fiscal year.
- Each area's FY2024-25 bus yield is re-priced to calendar 2024 by its fares
index:
- London and England outside London: DfT's quarterly local bus fares
index, calendar-year mean over fiscal-year mean;
- Scotland: its calendar-year index, taking the fiscal year as three
quarters of 2024 and one of 2025;
- Northern Ireland: England's index.
The factors are 1.000 for London (fares held flat), 0.965 for England
outside London (the fare cap rose in January 2025), 0.988 for Scotland and
0.982 for Northern Ireland. The bus pricing gate checks them.
- The diary columns (CPI-uprated to 2024) and road fuel (ONS 07.2.2 for 2024)
were already on calendar 2024.
The uk_stage_lcfs_consumption_basis gate holds every level-setting step to
calendar 2024: the donor uprating's target year, the energy prices' and the
DESNZ level's periods, the bus prices' year and the road-fuel level's period.
A step whose receipt is absent fails.
On the head-r3 spine all seven lcfs stage-health gates pass. Energy moves
+1.7% (GBP 47.9bn to 48.8bn) and bus fares -2.1%; fuel and the diary columns
don't move. PE-UK can then project every column from the H5's year with no
basis of its own. It still has to project energy: an energy price index from
2024 in place of the uk-data assumption that bills are stored at FY2026-27
prices.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
experiments/1113-consumption-tax-levels-receipts.md is the receipt the register entries cite. It holds: - the commit list; - microcosm#1121's head calibration; - the measurements that put the levels in the stage (energy volumes and sources, road fuel, the VAT factor); - the masked re-solve of the 2026-09-30 problem; - the stage-only development run on the head-r3 spine, where all seven lcfs stage-health gates pass, with the in-sample check that moved the recomposed totals off chain-drawn remainders. One changelog fragment per change. The charter-H2 graph parity fixture and the national remeasure follow Group B (PolicyEngine/chronicle#322), whose feed re-pin moves the fixture again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#323) (#1113) The artifact is chronicle main at the #323 merge: 352,549 rows (825406f's 344,402 plus 8,147), consumer_fact.v4 with an unchanged schema. It brings ONS Consumer Trends by COICOP division and class, with the national and domestic totals, and DESNZ road transport fuel consumption by vehicle type and fuel. - No existing value moved. Every 825406f row is byte-identical except the seven Consumer Trends series already in the feed. #323 restates their 217 rows on ONS's domestic concept (territory role; price-basis, seasonal-adjustment, unit, sheet and concept dimensions), under new keys with the same values. - The national and local reference files are byte-identical. The electricity, gas and road-fuel targets resolve to the same values through the new keys, which is all the national membership records beside the feed label. - The three compile-parity receipts are unchanged. - The vendored resources carry the same rows under the new feed identity. The Consumer Trends resource names the domestic concept, and the road-fuel target's note says why no national bridge applies: ONS splits the tourism adjustment by no class. - The charter-H2 fixture moves at the branch head, after the stage changes that follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stage receipt gains a report-only division_capture block. For each of the twelve COICOP divisions it sets the prior-weighted frame total against ONS Consumer Trends for the uprating's target year (calendar 2024), less the classes a household diary does not record: 02.3 narcotics, 04.2 owner-occupiers' imputed rent and 12.6.1 FISIM. - The divisions are on ONS's domestic concept. Consumer Trends publishes the tourism adjustment for the total only, so only the twelve together are also compared on the national concept (NAT0). International students' tuition has no published split either, and stays in the domestic gap of division 10. - The Consumer Trends resource vendors the 0CN totals and divisions and the three out-of-survey classes for 2023 to 2025 (42 to 93 rows). - Nothing is gated on it. The engine-free stage test has no uprating step, so it checks the block is absent there; a unit test checks the arithmetic against the vendored rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The litres audit's per-fuel benchmark is now HMRC's clearances of that fuel times the cars share of its UK road use, from DESNZ sub-national road transport fuel consumption by vehicle type and fuel (PolicyEngine/chronicle#322), for the uprating's target year. Within one fuel the ktoe cancel, so no conversion factor enters. - For 2024 cars burn 97.8% of road petrol and 39.2% of road diesel; the OBR cars share of fuel duty receipts applied one share to both, which A8 labelled. The OBR-based total stays on the receipt beside the new one. - desnz_road_fuel_by_vehicle.json vendors the UK rows for 2022 to 2024 (30 rows), and the lcfs_consumption stage declares it as an artifact. - Report-only, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fixture moves once, at the branch head, for every stage change above. - The bundle gains the lcfs_consumption steps: redraw_zero_road_fuel, level_road_fuel and recompose_from_remainder. It also gains the calendar-2024 energy and bus-fare parameters, the ONS and DESNZ artifact roles, and the updated source and notes text. - The synthetic LCFS donor gains c72213, the other motor fuels whose donor share level_road_fuel nets from ONS 07.2.2. It is added after the positional columns, so no other synthetic value moves. - In the graph JSON only stage_contract_sha256 moves: for lcfs_consumption and for the ten stages that declare a vendored resource the 1ee7dfe re-pin restamped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The receipts gain B1 to B3 and the fixture commit, plus the stage-only run at B3: all seven lcfs gates pass, and the Group A figures hold. - Division capture: the frame's twelve divisions are 72.8% of ONS's survey scope for 2024, against 58.5% for the donor's own diary. Housing reads 1.059, GBP 8.0bn of its excess being D1's energy level. Furnishings read 1.251: the frame draws 66% more per household than the donor. - Litres audit: petrol reads 1.011 of its cars benchmark and diesel 0.709. The total is 0.894, against 0.951 on the OBR cars share. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Automated review pass (Claude Code, high effort) — round 1 at
|
Vahid's round-1 pass on #1167 found nothing blocking. This takes its three should-fixes and two nits. María ruled on the first two on 2026-10-10. - The electricity and gas exclusions named the FY2024-25 basis the stage left on 2026-10-09. Their reasons now name calendar 2024 and quote that year beside 2025: ONS is 0.88 of the stage's electricity level and 0.76 of its gas level. The 2025 ratios were already calendar-year. María approved the restatement; each adjudication records it and keeps the decision's date. - The bound road-fuel row's notes record the 0.4% scope offset: the target is all of 07.2.2, and the stage levels to it less the donor's other-fuels share. María ruled that it stays recorded and is not scaled into the target. - The same notes size the domestic concept as far as ONS allows: non-residents' spending in the UK and residents' spending abroad, which Consumer Trends publishes for total spending only and by no class. - The stage notes say policyengine-uk applies the fiscal 2024-25 rules to model year 2024, a quarter after the calendar-2024 prices, and that the diary's 07.2.2 has no line for vehicle electricity. - The stage notes feed source_stages.json, the coverage manifest and the H2 fixture bundle, which are regenerated. No stage contract hash or gate digest moves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Round 1 addressed at 3523109, one commit on top of Should
Nits
policyengine-uk knock-ons. Noted for the national remeasure, which has not run yet. It will re-read the ONS row at design weights and the VAT coverage. The Verification at 3523109: 870 tests pass across the register, contract, source-stage, LCFS stage, stage-health, coverage, gate, country-spec and |
Independent adversarial review (Claude Code) at
|
María's independent review of #1167 at 3523109 found the diary columns a quarter past the calendar-2024 basis the PR claims, a gate that could not see it, and gate and register texts describing rows that no longer bind. Stage behaviour: - The diary spend columns (twelve divisions and bus fares) are carried on the engine's CPI index from the April-to-March 2023-24 diary year to calendar 2024: uprate_donor_columns gains a fiscal_year_bridge and a per-column from_window. The step is 1.0186, not the full year's 1.025. Income predictors keep the full-year step to the FRS 2024-25 incomes. - consumption_basis reads each diary column's declared window and the bridge weights, not an assumed period type. - transport_consumption is recomposed around the priced bus fares as well as the levelled petrol and diesel, so it holds every levelled part. - The housing and transport totals keep their committed support bounds, so the terminal support gate holds the emitted totals. The recomposed_totals check guards the declaration and the receipt; its sums are identities. - The division capture and the litres audit record why they have no figures when a published row is missing for the year; they no longer raise. The litres audit falls back to the OBR cars share. A stale vendored resource still fails. - The Consumer Trends target selectors pin the price basis, concept and seasonal adjustment chronicle#323 added. Texts restated to what the stage and the calibration now do: - gates.json: the energy level is calendar 2024; no bound row or release-blocking check holds calibrated domestic energy, the VAT base or fuel duty since D1 to D3, and the notes say so; what road_fuel_level and recomposed_totals can and cannot catch. - The signed exclusions for obr.fuel_duties and COICOP 04.5 no longer say the rows that replaced them bind. - The four measure-exclusion reasons give design-to-final moves and the masked-arm comparison separately, and say the four rows were masked together on the 2026-09-30 problem. - The bound road-fuel row's notes give the engine-growth part of its design-weight gap: about +2.3% on policyengine-uk 2.122.2, scope included. - The stage notes record the fuel flag's known residual, the Northern Ireland bus index proxy, and that the housing remainder holds only part of the diary's other fuels. - The three exclusions that tracked #1113, which the PR closes, now track the follow-up issue #1207, and the two energy rows retire on its reconciliation. Regenerated: source_stages.json, the coverage manifest, the gate digests, the LCFS support bounds, the national references and membership, and the H2 fixture (only lcfs_consumption's contract hash moves). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1113) The review asked that the scripts behind the receipts live in the repository, as docs/evidence/uk-a16-v20 does. - scripts: the M2/M3 desk measurements, the M4 masked re-solve, and the stage-only run with its per-tree runner. - outputs: aggregates only. The household dumps and solved weight vectors stay out, and sanitize_outputs.py drops the stage's donor_floor receipt, which records exact donor minima. - The stage runs include main's stage on the same spine. A re-run redraws most households, so that run, not the spine's stored columns, is what a change is compared with. - M1's volume figures have no saved script; the README says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Corrects what the adversarial review found wrong in the receipts: the -0.8% on consumption was re-run drift against the stored spine, the diary columns were not on calendar 2024, the housing remainder holds only part of the diary's other fuels, and the masked re-solve masked the four rows together on the 2026-09-30 problem. - Adds the round's measurements on the head-r3 spine against main's stage: consumption -0.3% (GBP 969.6bn to 966.8bn), the ten diary divisions -0.7%, housing GBP 172.1bn and transport GBP 182.4bn. All seven lcfs gates pass. - Adds the bound road-fuel row's desk reading at design weights: about +2.3% on policyengine-uk 2.122.2. - Records the decisions the review asked to see written down, and the follow-up issue #1207 that takes the open items. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The independent adversarial review above is addressed at Should fix
Minor
Interaction with #1198 and #1145. Agreed, and the PR body now carries the merge-order steps. One new observation. The housing total now contains the energy columns, and a small number of households carry extreme electricity and gas values. Values of that size predate this PR, and nothing bounds the energy columns themselves. #1207 carries it, with the furnishings over-draw and the other open items. Verification at |
Re-review (Claude Code) at
|
| # | Status | Note |
|---|---|---|
| 1 Diary basis | Fixed | The 12 divisions and bus declare from_window: fiscal_year with the 0.75/0.25 bridge. consumption_basis fails a missing window, a missing column or wrong weights (stage_health.py:2702-2725). Income predictors keep the full step, which is consistent. |
| 2 #1207 | Fixed | #1207 is open, the three exclusions track it, and the retire conditions are reworded. |
| 3 Stale text | Mostly fixed | gates.json 333/888, the signed exclusions, energy_pricing.py and the stage notes are fixed. Leftovers are in item 7 below. |
| 4 Support bounds | Fixed | Housing and transport carry main's bounds again, and uk_support applies them. |
| 5 EV flag | Answered | Accepted: the recipient has no fuel type, so the flag is the only zero-emission identity. One residual isn't recorded: the rate is the car-stock ZEV share applied per household. Battery-only households are a smaller share of vehicle-owning households, because many EV households also run a combustion car, so the flag likely over-designates no-fuel households. |
| 6 Bus in transport | Fixed | UK_LCFS_RECOMPOSED_PARENTS nets and restores bus, and the end-to-end test checks fuel + bus. |
| 7 Consumption figure | Fixed | Base 969.58, then 971.44 (+0.19%) before this round and 966.76 (−0.29%) now. The ten divisions move −0.68%, and the bridge alone is −0.62%. |
| 8 Exclusion bases | Fixed | The figures match m4_report.json. |
| 9 Bound-row gap | Fixed | pe-uk 2.122.2 carries both fuels at −2.691% for 2025: 36.887 × 0.97309 = 35.894 against 35.099, which is +2.26%. So the calibration moves weight away from fuel buyers. |
| 10 Parity scope | Fixed | |
| 11 Scripts | Fixed | receipts.json hashes match. M1 has no script, as the README says. |
| 12 Nits | Mostly fixed | The p537 split matches the derivation masks, and the selectors pin all three dimensions. Minor item 1 below has a new fail-open in the diagnostics. |
New
- Two disclosure-control items have gone to the author separately.
- Hardening: the sanitiser
docs/evidence/uk-consumption-taxes-1113/scripts/sanitize_outputs.py:28drops onlydonor_floor.stage_dev_run.py:145also copiessupport_clipentries, and those carrydonor_minanddonor_max. The block is empty today only because the named columns don't exist. Add both keys toDROPPED, or drop the block.
Minor
- The diagnostics now fail open on bad data, not only on a missing year.
DiagnosticUnavailableErroralso covers ambiguous or duplicate rows (lcfs_consumption.py:616,:753), so a data-integrity error is recorded as "unavailable". And a resource vendored at the pin but missing the year quietly drops the litres audit to the uniform OBR share; only the receipt notes it. - The recomposed totals carry an uprating residue.
- Parents: take the CPI bridge (×1.0186).
- The parts netted from them: stay at their own factors. Drawn energy isn't uprated. Petrol and diesel take the litre-based spending proxies (diesel ×0.898).
- Residue: the remainders keep about 0.019 × drawn energy (roughly £1bn in housing) and the fuel factor gaps (roughly £1.7bn in transport) on the committed totals. So the totals aren't strictly on one basis.
- Fix: rescale each drawn part by parent factor ÷ part factor before netting, or record the residue.
- UK consumption-tax levels: open items after #1167 #1207's R1 acceptance contradicts its own desk figure. It expects levelled road fuel to move under 2% from design to final, but the bound row reads +2.3% at design, so fitting it moves road fuel about 2.2%.
- Nits.
consumption_basischecks the declared window and weights, but not that the receipt'sfactorequalsafter / (0.75 · before + 0.25 · following), though both are recorded.- Stale text remains:
- the
uncarried_spenddocstring (lcfs_consumption.py:1305-1307, "stay inside the housing remainder"); - binding notes saying 04.5 is "bound per fuel" and that
obr.fuel_duties_carsis "Bound at FY2024-25"; donor_uprating.py:3.
- the
- Per-division movement: the bridge is a uniform −0.62%, but divisions move from −1.4% to +2.2% from re-run noise. That matters when reading
division_capture. - Local paths: the scripts and output
spinefields carry local absolute paths.
No tests were weakened and no counts were edited to match. The count changes follow the code.
Taken in #1145 at María's direction, #1167 having merged. - Hardening: the evidence sanitiser drops donor_min and donor_max beside donor_floor and keeps only the spine file's name; the committed outputs and scripts carry no machine-local paths (the scripts read the inputs root from PE). - Minor 1: an ambiguous or duplicate vendored row is a data fault and fails closed as a plain ValueError; only a missing year is recorded as a report-only diagnostic being unavailable. - Minor 2: the recomposition receipt records each parent's uprating residue, the parent's factor against each netted part's, weighted; not corrected. - Nits: the consumption-basis gate holds each bridged column's recorded factor to after / base; the uncarried_spend and donor_uprating docstrings and the obr.fuel_duties_cars and 04.5 binding notes say what the rows are now (measured, not bound); the evidence README says the per-division movement between runs is redraw noise around the uniform bridge. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Main re-pinned the Chronicle feed to 1ee7dfe (352,549 rows) and merged #1167, #1087 and #1099 among 87 commits. On the merged tree: the PRIS resource is re-vendored from the new pin (44 rows unchanged), the target references, membership and both national compile-parity receipts are regenerated against it (1,245 active references: main's 1,232 plus the 13 SPI property amounts), the release input coverage manifest and the H2 fixture are re-derived, the gate-battery and certification part digests move with the merged gates.json, and the count pins follow. The commits below this one keep the surfaces they were measured with. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Summary
Closes #1113. Also covers item 3 of #1123. The UK LCFS stage now sets household road fuel and domestic energy at their published levels, at calendar-2024 prices, instead of leaving the calibration weights to reach them. The rows whose gap is not a weight question become measured diagnostics. This follows María's rulings of 2026-10-08 (D1–D3), plus two of 2026-10-09: the ONS road-fuel row is bound, and every LCFS spend column sits on one calendar-2024 basis.
obr.vat,ons.household_electricity_expenditure,ons.household_gas_expenditureandobr.fuel_duties_carsmove to the measure-exclusion register. They are still measured on every evaluation, and the entries expire 2027-01-08. The contract binds a new household-scope row in their place:ons.household_road_fuel_expenditure(ONS Consumer Trends 07.2.2, calendar 2025, measured as petrol plus diesel spend). The class also carries other motor fuels and lubricants, so the row reads about 0.4% low from scope alone; the binding notes record that offset.consumption_driftshows the rest. That follows from D1–D3, and the gate and register notes say so.redraw_zero_road_fuelgives every flagged fuel-car household a positive fuel spend;level_road_fuelscales petrol and diesel to ONS 07.2.2 for 2024, less the donor's other-fuels share;recompose_from_remainderwrites housing around the levelled electricity and gas, and transport around the levelled petrol and diesel and the priced bus fares.road_fuel_incidence,road_fuel_level,recomposed_totalsandconsumption_basis. The last reads each diary column's declared window. The housing and transport totals also keep their committed support bounds, which the terminal support gate applies to the emitted frame.uk_diagnostics.consumption_drift: the levelled totals and shares at design and final weights;division_capturein the stage receipt: each COICOP division against ONS Consumer Trends;1ee7dfe(UK consumption-tax facts: Consumer Trends for every COICOP division, and road fuel by vehicle type and fuel (PolicyEngine/microcosm#1113, PolicyEngine/microcosm#1123) chronicle#322 via Expand UK consumption-tax expenditure and road fuel facts chronicle#323, 352,549 rows), which brings Consumer Trends by division and DESNZ road fuel by vehicle type and fuel. The re-pin moves no compiled target value on either surface and leaves the three compile-parity receipts as they were. The new road-fuel row adds one ledger-only row to each national receipt.Receipts, findings and rulings are in
experiments/1113-consumption-tax-levels-receipts.md. The measurement scripts and their aggregate outputs are indocs/evidence/uk-consumption-taxes-1113/.Why the levels belong to the stage
On #1121's head calibration (policyengine-uk 2.122.2, 1,167 rows):
obr.vatreads +24.7% at design weights, against a 25% bound. Its level is the engine'smicrodata_vat_coveragefactor (0.38, with no recorded derivation; policyengine-uk#1996), not a weight question.obr.fuel_duties_carsreads −34.5% at design weights. It is a fiscal-year duty total that includes business use of cars. The LCFS diary records about a quarter less road fuel than ONS, and a third of fuel-car households show no fuel purchase in the two-week diary.On the 2026-09-30 national problem (1,090 rows, before this PR's stage levels), a re-solve with the four rows masked together left the other 1,086 rows fitting no worse: 98.5% within 10%, against 98.4%. No arm masks one row alone.
Stage-only measurements
These re-run
lcfs_consumptionon #1121's head-r3 spine (63,956 households). All seven lcfs stage-health gates pass. A re-run redraws most households, so the comparison is with main's stage re-run on the same spine, not with the spine's stored columns.Not in this PR
#1207 collects these open items, under the two deferral registers #736 and #796. The three measure exclusions that are not VAT track it.
obr.vat. That waits until policyengine-uk splits its VAT factor (policyengine-uk#1996).Merge order with #1198 and #1145
942a1fa, which descends from this PR's1ee7dfe.942a1faand regenerates the membership, coverage manifest and fixture.desnz_road_fuel_by_vehicle.json; a mechanical merge would leave it on the old pin.Testing
7f235941c, a check ran after every commit: each loads the UK spec, has a current release-input coverage manifest, and has current gate digests mirrored inmicrocosm-data. The review commits pass the same check.3ed090d03failtest_h2_uk_spine_parityon their own.🤖 Generated with Claude Code