Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/uk-company-cars-316.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The UK spine writes company cars (PolicyEngine/uk-autumn-budget-dashboard-2026#316). A new last stage, `company_cars`, sets six of policyengine-uk 2.165.0's company car inputs for each employee the FRS job record gives a company car (`EXPBEN01`), through four carriers the root stage now writes from the job tab: the list price, drawn within the respondent's CARVAL band from WAS round-8 company cars' prices grown by the engine's CPI index; the fuel (FUELTYP, and HMRC Table 2C's shares where it is unknown); the CO2 figure at HMRC Table 2A's shares among cars that emit CO2, hybrids first into 1 to 50 g/km, which takes a 50-mile electric range; private fuel (EXPBEN03); and capital contributions (CARAMT). SPI-channel rows keep their twin's car only where their drawn EPB is positive, and their `employment_income`, the tape's PAY + EPB + TAXTERM, gives up the engine's car and fuel benefits, capped at EPB (María's ruling of 30 October 2026). No HMRC company car fact is a calibration target; `uk_stage_company_cars_invariants` blocks a release on any invariant break.
1 change: 1 addition & 0 deletions changelog.d/uk-policyengine-uk-2-165-0.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The UK lock moves from policyengine-uk 2.164.2 to 2.165.0 (PolicyEngine/uk-autumn-budget-dashboard-2026#316). 2.165.0 (PolicyEngine/policyengine-uk#2750) models the company car and car fuel benefits in kind from nine person inputs, taxes them through `taxable_employment_income` rather than `employment_income`, and adds the Class 1A NICs on them to `ni_employer`; the inputs default to no car, so a file that sets none of them is unchanged. 2.164.3 and 2.164.4 count `other_investment_income` in `market_income`, `household_market_income`, `hbai_household_net_income` and `capital_income`; the UK spine fills that column (microcosm#1418), so household market and HBAI incomes rise by it where a household holds it. The uprating and bonus-sacrifice pins keep every value, concept coverage gains the nine company car inputs, and the coverage manifest, the H2 spine fixture, the version mentions and the US worker identity's lock digest move with the lock.
12 changes: 6 additions & 6 deletions docs/concept-coverage/policyengine-uk.md

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions docs/uk-company-cars-316.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Company cars (dashboard #316)

Budget 2026 raises every company car appropriate percentage by one point in 2030-31
(Table 6.1 row 86). policyengine-uk 2.165.0 (PolicyEngine/policyengine-uk#2750) taxes
the company car and car fuel benefits, and the Class 1A NICs on them, from nine person
inputs that default to no car, so a file that sets none of them scores the rise at £0.
The `company_cars` stage, the last in the UK roster, sets six of them.

| Input | Where it comes from |
|---|---|
| `company_car_list_price` | The FRS CARVAL band, drawn within it from WAS round-8 company cars' list prices |
| `company_car_fuel_type` | The FRS FUELTYP code; HMRC Table 2C's shares where it is unknown |
| `company_car_co2_emissions` | HMRC Table 2A's shares among cars that emit CO2; zero for an electric car |
| `company_car_electric_range` | 50 miles for a car at 1 to 50 g/km |
| `company_car_capital_contributions` | The FRS CARAMT, where CARCON says the employee contributed |
| `company_car_private_fuel_provided` | The FRS EXPBEN03, on a car that is not electric |

Availability, payments for private use and the 2020 registration flag keep the
engine's defaults: no survey records them.

## Who has a car

The FRS asks each current employee job whether the employer provided a company car
(EXPBEN01) in the last 12 months. The root stage, `frs_spine`, carries each person's
car from their car job with the lowest JOBTYPE, the main job first, so a person has at
most one, as in the engine. The survey asks CARVAL and CARCON of a company van too;
they are taken as the car's.

SPI-channel rows carry their FRS twin's carriers, as they carry every root column.
Their pay is the SPI tape's PAY + EPB + TAXTERM, where EPB is every taxable expense
payment and benefit in kind, so a twin's car is kept only where the row's drawn EPB
is positive.

## The draws

Every draw is keyed on the person's identity, so reordering rows moves none.

- **Fuel.** Petrol is `PETROL`; a hybrid or another fuel is `ALTERNATIVE_FUEL`; an
electric car is `ELECTRIC`; a diesel is `DIESEL_RDE2`, since every new diesel has
met RDE2 since January 2021 and company cars turn over in three to four years (the
diesel supplement moves the baseline only, not the 2030-31 rise). An unknown fuel
draws at HMRC Table 2C's shares.
- **List price.** WAS round 8 (April 2020 to March 2022) records company cars' list
prices to the nearest £1,000. They are grown to the build year by the engine's CPI
index from 2021, and each holder draws within their CARVAL band from the weighted
quantile function of the WAS cars inside it. The open band (£40,001 and over) and
an unknown band draw from the WAS cars of the same fuel class (electric or not). A
cell with fewer than 3 WAS households falls back to all fuel classes, then to a
uniform draw within the band (up to £80,000 for the open band).
- **CO2.** HMRC publishes recipients by CO2 band and by fuel, but no table crosses
them. An electric car emits none. The others are split between 1 to 50 g/km and the
bands above it so that the weighted share at 1 to 50 g/km matches Table 2A's among
cars that emit CO2, hybrids first; the bands above are drawn at Table 2A's shares,
uniformly within each. Every figure in the open band (170 g/km and over) is above
the maximum percentages' thresholds.

## SPI-channel pay

On an SPI-channel row the engine's car and fuel benefits come out of
`employment_income`, capped at EPB (María's ruling of 30 October 2026):

1. Private fuel goes first where its benefit alone exceeds EPB.
2. A car whose benefit still exceeds what is left has its list price scaled down
until it fits, with its contributions dropped. The benefit is the price above the
capped contributions times the appropriate percentage, so the scaling is exact.
3. A car that would need a list price below £5,000 to fit is dropped, and its EPB
stays in pay.

Pay plus the benefits then equals the tape's total on every such row. The SPI
employment income targets read employment income plus `benefits_in_kind`, so they
read the same total as before.

## Measured, not bound

No HMRC company car fact is a calibration target: the stage draws fuel and CO2 to
Tables 2A and 2C, so binding them would be circular. The national build reports the
calibrated file against HMRC's Table 1 (recipients, taxable value, income tax and
NICs), Table 3A (by income range) and Table 4 (by region).
`uk_stage_company_cars_invariants` blocks a release on any record that breaks an
invariant, and on SPI-channel pay off the tape's total.

## Disclosure

The FRS and WAS are UK Data Service safeguarded data. The stage's receipt carries
weighted aggregates, rounded counts and support bands only, and no record's value.
3 changes: 2 additions & 1 deletion docs/uk-isa-subscriptions-1415.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

The `isa_subscriptions` stage gives every adult of the UK spine what they paid
into ISAs in the year, by type, and the per-person ISA balances behind them. It
runs last, on final incomes, and nothing in the spine reads its outputs.
runs on final incomes, after every stage but company_cars, and nothing in
the spine reads its outputs.

| Column | Meaning |
|---|---|
Expand Down
2 changes: 1 addition & 1 deletion packages/microcosm-build/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ us = [
# The UK extra adds the rules engine for local metric generation from a
# Microcosm UK H5. Target tables remain explicit inputs, and the base package
# still does not import policyengine-uk at import time.
uk = ["policyengine-uk>=2.164.2", "microcosm-data>=0.1,<0.2", "h5py>=3", "tables>=3", "openpyxl>=3.1"]
uk = ["policyengine-uk>=2.165.0", "microcosm-data>=0.1,<0.2", "h5py>=3", "tables>=3", "openpyxl>=3.1"]

[project.scripts]
microcosm-build-uk = "microcosm.build.uk_runtime.full_build_cli:main"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@
"grow_isa_subscriptions",
"split_both_type_subscriptions",
"split_household_isa_balances",
# PolicyEngine/uk-autumn-budget-dashboard-2026#316: company cars.
"assign_company_car_fuel_types",
"carve_spi_company_car_benefits",
"classify_company_car_facts_with_reviewed_fence",
"clean_was_company_car_donor",
"draw_company_car_co2_emissions",
"draw_company_car_list_prices",
"convert_bonuses_to_bonus_sacrifice",
"convert_donors_to_target_stock",
"convert_interest_to_structural_mortgage_inputs",
Expand Down
Loading
Loading