Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
232eac6
Record #1121's head calibration in its receipts (#1095)
juaristi22 Oct 9, 2026
18d1fa5
Set UC gainful self-employment from the FRS main job and earnings (#1…
juaristi22 Oct 9, 2026
3b41d61
Mark children placed by a local authority from the FRS foster links (…
juaristi22 Oct 9, 2026
533703f
Keep loss-making landlords in the CGT residential signal (#1095)
juaristi22 Oct 9, 2026
d026554
Draw UC take-up over the units the engine can pay UC to (#1095)
juaristi22 Oct 9, 2026
6dd8dac
Count property in UC and Pension Credit recorded capital (#1095)
juaristi22 Oct 9, 2026
c5f3582
Solve Pension Credit take-up over Great Britain and draw newly entitl…
juaristi22 Oct 9, 2026
d04ab10
Rebase SPI savings interest and its band targets by GDP per head (#1095)
juaristi22 Oct 9, 2026
14ae2c3
Scope the PIP daily-living caseload rows to England and Wales (#1095)
juaristi22 Oct 9, 2026
6f4c3bc
Bind obr.council_tax to the Great Britain receipts row (#1095)
juaristi22 Oct 9, 2026
e1ee7f0
Make OBR's NICs total a diagnostic beside the class rows (#1095)
juaristi22 Oct 9, 2026
b85d5a4
Bind the salary-sacrifice relief bands by income tax rate class (#1095)
juaristi22 Oct 9, 2026
a2e5adb
Read the UC award bands in whole pence (#1095)
juaristi22 Oct 9, 2026
e3ac4a5
Keep the PIP daily-living caseload rows as diagnostics on obr.pip (#1…
juaristi22 Oct 10, 2026
a7e5bc5
Retire the West Midlands low-band income-tax deferral (#1095)
juaristi22 Oct 11, 2026
cf42d8a
Add the third ports PR's receipts (#1095)
juaristi22 Oct 11, 2026
887d36d
Address review round 1 on the stage ports (#1095)
juaristi22 Oct 11, 2026
0495c4f
Move savings interest by its history, then the dataset projection (#1…
juaristi22 Oct 11, 2026
2792b21
Hold the rate-class allocation to the engine's earned income tax (#1095)
juaristi22 Oct 11, 2026
c38e370
Regenerate the compile-parity receipts for the savings-interest targe…
juaristi22 Oct 11, 2026
78ea6b6
Keep the West Midlands low-band income-tax deferral (#1095)
juaristi22 Oct 11, 2026
7b17c1d
Record review round 1 in the receipts (#1095)
juaristi22 Oct 11, 2026
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
3 changes: 3 additions & 0 deletions changelog.d/1095-cgt-loss-making-landlords.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Loss-making landlords keep the CGT residential stock signal (microcosm#1095). #1081 counts a letting loss (`RENTPROF` 2) as zero `property_income`, and the CGT residential split read `property_income > 0` as one of its two signs that a gainer holds residential property. So landlords whose letting made a loss lost the sign, and the split's stock shift moved residential gains away from them.

The UK spine now carries an internal flag, `reports_rent_from_other_property`, which holds wherever `ROYYR1` is positive, at a profit or a loss. The CGT stages read it alongside household residential property value and property income. A redrawn SPI row drops its FRS twin's flag, since its property income is an SPI donor's. It is not an engine input, and the release boundary drops it.
3 changes: 3 additions & 0 deletions changelog.d/1095-council-tax-gb-receipts.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
`obr.council_tax` now binds OBR table 4.1 row 15, total council tax receipts (the sum of the England, Scotland and Wales rows), over Great Britain's households (microcosm#1095). It previously bound row 19, total net council tax receipts. Row 19 adds Northern Ireland domestic rates, the council tax accruals adjustment and the high-value council tax surcharge, which no household's council tax carries: £1.34bn, 2.7% of the calendar-2025 window. The target moves from £50.12bn to £48.77bn. `obr.domestic_rates` stays held.

Chronicle stamps the row K02000001, since OBR's table is UK-wide. A new exact-id geography pin keeps it there: the generator's substring rule would otherwise read "scotland" in the concept and pin Scotland. The country legs keep their own nations' pins.
3 changes: 3 additions & 0 deletions changelog.d/1095-looked-after-children.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The UK spine now sets policyengine-uk's `is_looked_after_by_local_authority` for children placed in foster care (microcosm#1095). The FRS 2024-25 question instructions put foster children under 16 in the carer's benefit unit. They make a foster child aged 16 or over a separate benefit unit where a local authority maintenance allowance covers them, so one who stays in the carer's unit has no such allowance and is not marked. Nothing set the flag before, so the engine counted them as the carer's own children in its child tests: Universal Credit's child element and youngest-child rule, Child Tax Credit, Pension Credit, Tax-Free Childcare, extended childcare, the Working Tax Credit childcare element and the legacy benefits.

The `frs_relationships` stage sets the flag for a child-table member under 16 whose household-grid code toward an adult in their own benefit unit is foster child (5), or toward whom that adult records foster parent (9). It follows the relationship code alone: few such children are recorded, and the carer's local-authority fostering allowance (`ALLOW3`) covers fewer still.
5 changes: 5 additions & 0 deletions changelog.d/1095-ni-total-diagnostic.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
OBR's total National Insurance contributions (`obr.ni`, table 3.8 row 12) is now a diagnostic beside the three bound class rows, `obr.ni_employee`, `obr.ni_employer` and `obr.ni_self_employed` (María's ruling of 9 October, microcosm#1095; uk-data#537 drops the row). The engine's `total_national_insurance` is the sum of its class columns, and at the calendar-2025 window OBR's total sits about 1.8% above the three class rows.

The binding note had put the gap down to Class 1A and 1B alone. It is wider than that. OBR's total is a cash figure while the class rows are accrued, and it carries statutory-payment recoveries, Class 1A, 1B and 3, and settlements, none of which any household carries.

The exact FY2025-26 forecast (£200.08bn) is retained on `obr.ni_employee` and never fitted. The incumbent row `obr/ni` moves from mapped to excluded.
7 changes: 7 additions & 0 deletions changelog.d/1095-pension-credit-take-up.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Pension Credit take-up now follows uk-data#510 (microcosm#1095):

- Each component band's residual rate is solved over Great Britain, which DWP's take-up rates cover, and drawn for every entitled non-reporter, Northern Ireland's included. Before, Northern Ireland's units entered the solve, so the rate held UK-wide rather than in Great Britain.
- A benefit unit with no entitlement that does not report Pension Credit claims at DWP's Savings Credit-only caseload take-up, 37% in FYE 2024, on the same draw (new contract key `pension_credit_newly_entitled`). Before, such a unit never claimed, so a reform or a later year that entitled it paid it nothing.
- Entitlement is read at the release's calibration year, as uk-data reads it. The frame is stamped with its survey year, so policyengine-uk projects its incomes, pensions and capital to that year as it does the released file. The UK engine adapter gains a `dataset_period` argument for this. The mixed-age saving is still evaluated at the survey year, and the entitlement read takes it as stored.

SPI-channel reporters stay anchored, since `spi_benefit_coherence` makes their reports coherent; uk-data draws them instead. The stage gate measures each band in Great Britain and fails a receipt measured over any other scope. By channel, the receipt also records the stage's Pension Credit assessable capital and deemed income, and its Guarantee and Savings Credit entitlement.
5 changes: 5 additions & 0 deletions changelog.d/1095-pip-caseload-scope.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
The two PIP daily-living caseload rows, `dwp.pip.daily_living_standard_claimants` and `dwp.pip.daily_living_enhanced_claimants`, are now England-and-Wales diagnostics beside `obr.pip` (uk-data#490, microcosm#1095). DWP has reported PIP for England and Wales only since executive competence moved to the Scottish Government on 1 April 2020, and Chronicle stamps its January 2025 caseload K04000001. Under the Great Britain default pin the rows matched no fact, so they were dormant.

Scoped to England and Wales, the rows resolve to 1.283m standard-rate and 1.608m enhanced-rate claimants, and a calibration fits both within 0.1%. But fitting them pushes the heaviest support family's weight from 1,061 to 1,241 times the positive median, over the `uk_weight_ratio` limit of 1,151. So they leave the fit. Each is a diagnostic reference on `obr.pip`, pinned to its exact January 2025 fact: checked, and never fitted. Diagnostic references now accept a fact dated by month.

The contract holds 388 targets and 1,229 active references.
14 changes: 14 additions & 0 deletions changelog.d/1095-recorded-capital-property.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Universal Credit and Pension Credit recorded capital now include property (uk-data#495, microcosm#1095). policyengine-uk replaces every capital source with a recorded figure of 0 or more and takes it as countable. The FRS benefit-unit capital (TOTCAPB4) counts accounts and assets but no property, so the engine assessed no unit on its household's second homes, buy-to-let property, other buildings or land.

`uc_capital_coherence` now records each capital as the financial carrier plus the unit's share of its household's countable property. The shares follow the engine's own proxies:

- Universal Credit counts other residential and non-residential property, shared by the unit's claimants and partners (`is_uc_claimant`);
- Pension Credit counts those and owned land, shared by the unit's members at or over Pension Credit qualifying age.

A dependant owns none, and the carrier's -1 sentinel passes through to both.

A unit that reports Universal Credit keeps its receipt, and records the carrier alone for Universal Credit. DWP assessed its capital to pay it. The property is imputed without that receipt, since the WAS file has no Universal Credit column, and it is shared over every claimant or partner in the household, so a parent's property would land partly on an adult child's claim. Another unit of its household keeps its own share where it records a carrier. A unit on the -1 sentinel takes the engine's household residual, which includes the share the reporter does not record.

`uc_reporter_redraw` screens SPI units on the carrier plus the property share, so a drawn reporter does not land on a unit whose property is over the capital limit. It screens an FRS unit that reports Universal Credit on its carrier alone, so that unit stays in the training set. The `uk_uc_capital_coherence` gate re-derives both capitals from the carrier, the declared shares and the reporter rule, within £0.01 plus one float32 step, and now checks Pension Credit capital too.

policyengine-uk 2.122.2 does not uprate `uc_reported_capital`, so its property share stays at survey-year values in later model years. `pension_credit_reported_capital` uprates by GDP per head.
11 changes: 11 additions & 0 deletions changelog.d/1095-salary-sacrifice-rate-bands.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
The three HMRC salary-sacrifice income tax relief bands now bind: basic, higher and additional rate, from Table 6.1 for 2024-25 (uk-data#533, microcosm#1095). They had been held out of the fit since microcosm#1069, because their band test compared adjusted net income with after-allowance thresholds and ignored the Scottish bands.

The measure resolver gains a declared rate-class allocation. One counterfactual simulation per substitution pair returns the sacrifice to pay, as uk-data does, and is cached. Each person's relief is the rise in tax on `earned_taxable_income`, bracket by bracket, under their rest-of-UK or Scottish schedule (`pays_scottish_income_tax`). The schedule is read from the simulation's own fiscal-year parameters, so the Scottish bands are the ones in force from 6 April. The brackets group as follows:

- a bracket taxed below 30% is basic;
- the schedule's top rate is additional, where a higher rate sits below it;
- the rest are higher, so the Scottish advanced rate counts as higher.

A contribution that straddles a boundary is relieved at each rate, and the personal allowance taper lands in the brackets the extra pay reaches. The three bands sum to the change in the engine's `earned_income_tax` for every person, and the measure refuses if they stop doing so. The resolver's receipt records the gap to the change in `income_tax` (for example, dividends pushed into the higher dividend band). A binding that declares anything other than the exact allocation is refused. uk-data's worked examples at 2025 reproduce exactly: £454 basic and £692 higher, Scotland's £349.02 and £981.96, and £6,000 all higher where the taper applies.

policyengine-uk puts the Scottish top-rate threshold at £112,570 rather than the statutory £125,140 (pe-uk#2130), so it files some advanced-rate relief as additional. The Table 6.2 all-rates total (£8.8bn) becomes a diagnostic on the higher-rate band, since the bands carry the same relief. The three measure exclusions that held the bands out, due to expire on 25 November, are retired.
3 changes: 3 additions & 0 deletions changelog.d/1095-savings-interest-index.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The 13 HMRC SPI savings-interest band targets now reach the 2025 calibration year in two legs (uk-data#541, microcosm#1095, María's ruling of 9 October). They move to the dataset's year, 2024, by ONS household interest income, the index of the variable's history. From there they move by GDP per head, the index policyengine-uk's dataset projection grows `savings_interest_income` with. The SPI donors take the same path: the stage rebases them to 2024 by the history index, and the engine projects the frame to 2025.

The band targets' 2023-24 to 2025 factor moves from 1.182 to 1.192. The donor rebase is unchanged. An engine lockstep test holds every indexed SPI component's rebasing index, and every HMRC SPI amount family's projection index, to the engine's projection table, and names savings interest's history index apart.
12 changes: 12 additions & 0 deletions changelog.d/1095-uc-award-band-edges.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
The four UC payment-distribution families now read DWP's monthly award bands in whole pence (uk-data#530, microcosm#1095).

**Band edges.** DWP publishes the bands as "£0.01 to £100.00", "£100.01 to £200.00", up to "£2,400.01 to £2,500.00", with each band starting a penny above its predecessor's top. Each binding now declares `band_semantics: whole_pence_upper_closed`, so a band is the upper-closed interval (label lower − £0.01, next label lower − £0.01] × 12, compared in whole pence. The half-open reading was float-fragile on those edges:

- an award of a penny a month could fall below the bottom band;
- £100.01 a month (£1,200.12 a year) stayed in the bottom band, because 100.01 × 12 rounds just above 1,200.12.

The semantics are opt-in, and an unknown value is refused. The other 28 banded bindings keep the half-open reading.

**The top band stays unbound.** `band_upper_bound` closes the last bound band at £2,500.00 a month, so it never absorbs the separately published "£2,500.01 or over" category. Binding that category was measured and left out. With it unbound, the calibration holds 2.6 times DWP's count of lone parents in it and 2.0 times its count of couples with children, and reaches OBR's Universal Credit total. Bound to DWP's counts, the total falls 5.6% short, and couples without children have no household in the band. The awards below the top band are too low for DWP's counts and OBR's total to fit together.

The generator now counts the fan-out facts it leaves unnamed, rather than declaring 12. The pinned feed leaves 8: one "No payment" and one "or over" fact for each of the four family types. The declared 12 counted eight overlapping "or over" facts, which an earlier feed carried.
10 changes: 10 additions & 0 deletions changelog.d/1095-uc-gainful-self-employment.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
The UK spine now sets policyengine-uk's `uc_is_in_gainful_self_employment` (uk-data#525, microcosm#1095). Nothing set it before, so the engine's own rule applied: any nonzero `self_employment_income` counted as gainful self-employment. Because the spine floors losses at zero, a trader at a loss or breaking even never met the Universal Credit minimum income floor, while an employee with a small side trade did. The input's only reader is `uc_mif_applies`.

The rule follows UC Regs 2013 reg 64(a), which asks whether the person carries on a trade as their main employment, and DWP's Advice for Decision Making. ADM starts from hours (H4031) but lets earnings outweigh them (H4034). A person is in gainful self-employment when either holds:

- their main job is self-employed (`EMPSTATI` 3 or 4), whatever its profit, since a trade at a loss or breaking even is still carried on (H4013, H4054, H4503);
- their side trade's profit (`SEINCAM2`) is above zero and above their employment income (`INEARNS`).

SPI-channel rows keep their donor's employment status but take new imputed pay and profit, and the draw does not read the status. So after the redraw they take the earnings route alone: a profit above zero and above pay. The main-job route returns when the SPI draw follows employment status (uk-data#529, microcosm#840).

The flag is fixed at the survey year's incomes. Uprating reprices pay and profit by different indices, so in a projected year a flagged side trade can earn less than the job, or the reverse, and the flag does not follow.
8 changes: 8 additions & 0 deletions changelog.d/1095-uc-take-up-population.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
The Universal Credit take-up draw now runs over the benefit units policyengine-uk can pay Universal Credit to (uk-data#486, uk-data#524, microcosm#1095). These are units with a UC claimant or partner (`is_uc_claimant`) aged 18 or over and under Pension Credit qualifying age. Before, the draw took any unit with a member aged 18 to under State Pension age. That included a pensioner unit whose only younger member was an 18- or 19-year-old dependant. A dependant is neither claimant nor partner, so the engine never pays such a unit Universal Credit, yet the contract rate was spread over it.

The draw, its SPI-channel redraw in `spi_benefit_coherence` and the `uk_take_up_signal` gate share one helper, so all three use the same population. Both stage manifests declare it as `any_uc_claimant_aged_18_under_pension_credit_age` with `role_column: is_uc_claimant`, and the code refuses a manifest that says otherwise. The take-up contract's population text for Universal Credit is re-signed; the rate is unchanged.

The qualifying age is the State Pension age the engine's timetable sets for the cohort reaching it in the build year. That equals the engine's Pension Credit qualifying age at 2024 and 2025. The engine lockstep test compares the population with `is_uc_eligible`, with reported capital set to zero, for one-person units aged 14 to 90. It names the two engine cases the population does not mirror:

- 16- and 17-year-old claimants under the UC Regs 2013 reg 8 exceptions, whom the engine includes;
- mixed-age couples keeping Pension Credit under the SI 2019/37 saving, whom it excludes.
15 changes: 10 additions & 5 deletions docs/uk-income-anchors-280.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,15 @@ membership carries the uprated value with its receipt.
January of the calibration year, the instants the SPI donor rebasing already
uses. Employment income follows `obr.average_earnings`, self-employment
`obr.per_capita.mixed_income`, dividends and property `obr.per_capita.gdp`,
private pensions `obr.private_pension_index`, savings interest
`ons.household_interest_income`; the state pension follows
private pensions `obr.private_pension_index`. Savings interest takes two
legs (microcosm#1095): `ons.household_interest_income`, the index of its
history, to the dataset's year, then `obr.per_capita.gdp`, the index the
engine's dataset projection applies, to the calibration year (1.1420 x
1.0438 = 1.1920 on policyengine-uk 2.122.2). The state pension follows
`gov.dwp.state_pension.new_state_pension.amount`, the rate the engine pays
(203.85 to 230.25 a week, 1.1295). On policyengine-uk 2.98.0 and 2.100.0 the
2023 to 2025 factors are 1.1067, 1.0344, 1.0826, 1.0877 and 1.1819. The compile
2023 to 2025 factors are 1.1067, 1.0344, 1.0826, 1.0877 and, for household
interest alone, 1.1819. The compile
reads the values from the vendored `hmrc_uprating_engine_pins.json` (the six
parameters at every 1 January 2019 to 2026, written from the installed engine
by `tools/pin_uk_uprating_engine_values.py`, whose `--check` refuses drift), so
Expand Down Expand Up @@ -195,8 +199,9 @@ before this stage the spine, like the enhanced FRS, carried no record above

Two uprating conventions sit side by side by design. The national SPI amount
rows move by the engine's own component indices (earnings, mixed income, GDP
per head, the private-pension index, household interest, the new State
Pension rate), because each row is one income component and the engine uprates
per head, the private-pension index, the new State Pension rate, and for
savings interest household interest to the dataset's year and GDP per head
after it), because each row is one income component and the engine uprates
that component by that index: the target and the model then agree on what
"2025 employment income" means. The regional Table 3.11 rows are totals and
tax by band with no component split, so no engine index applies; they move by
Expand Down
Loading
Loading