Skip to content

Evaluate claims_all_entitled_benefits per benefit unit - #1831

Merged
MaxGhenis merged 16 commits into
mainfrom
claims-all-per-benunit
Oct 22, 2026
Merged

MaxGhenis merged 16 commits into
mainfrom
claims-all-per-benunit

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Aug 28, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2393

Evaluate claims_all_entitled_benefits independently for each benefit unit in hand-entered situations, keep main's result on data-built simulations, and keep calculator take-up and survey reporters-only defaults for Council Tax Reduction (CTR) and Housing Benefit (HB).

Root cause

Main's formula is add(benunit, period, SEVEN).sum() < 1, where SEVEN is the seven reported means-tested benefits (Child Tax Credit, Working Tax Credit, Universal Credit, HB, income-based JSA, Income Support and income-related ESA). The .sum() totals those reports over the whole simulation and broadcasts one value to every benefit unit:

This PR first replaced the simulation-wide .sum() with a per-family test everywhere. On data-built simulations, every non-reporting survey family then turned true: 54,276 benefit units on the Enhanced FRS. would_claim_CTC, would_claim_WTC and would_claim_IS are reported | claims_all_entitled_benefits, and child_tax_credit_pre_minimum and working_tax_credit_pre_minimum are gated by take-up only. So review r6 found tax credits leaking on 2024 survey data:

  • tax_credits rose from £156m to £6,151m;
  • tax credits fed the tax credit award, the CTR and HB means tests, the 2024 Winter Fuel Payment benefit test and household net income.

2025 and 2026 matched main only because tax credits stop paying on 5 April 2025 (gov.dwp.tax_credits.active).

Fix

claims_all_entitled_benefits returns false for every family when built_from_data(simulation), and the per-family test otherwise. The flag has five readers: would_claim_CTC, _WTC, _IS, would_claim_housing_benefit and would_claim_council_tax_reduction. All five get main's survey value from the flag itself, so no reader needs its own gate for it:

  • Hand-entered situations: keep the per-family rule, including in multi-benefit-unit households.
  • Dataset-supplied flag: a claims_all_entitled_benefits column in a dataset still overrides the formula, as on main.
  • CTR and HB: keep their own data-built gates under the rulings below, so they stay reporters-only even then.

The alternative, gating the three legacy would_claim_* formulas, would leave the published flag itself at 54,276 true values on survey data.

Behaviour and rulings

  • Hand-entered situations: a family reporting under £1 across the seven is assumed to claim everything it is entitled to, tested per benefit unit. CTR and HB keep main's claims_all_entitled_benefits | positive_report rule per benefit unit. Vahid's three 2026 calculator probes receive £1,800, £1,800 and £633.96 CTR without reports or take-up inputs.
  • Data-built simulations: the flag is false for every family, so Child Tax Credit, Working Tax Credit and Income Support take-up follow reported claims, as on main. CTR is reporters-only under d1390, and HB under Max's d1455 ruling of 19 October 2026. Explicit situation or dataset take-up inputs override these defaults. The calibrated CTR take-up column remains uk-data#448; this interim gate needs no data release.
  • CTR, Pension Credit and Child Benefit are outside the seven: a family reporting only Pension Credit still has the flag set in a hand-entered situation.

Intended differences from main on data-built simulations

  • CTR and HB: reporters-only (d1390, d1455). On survey data this matches main, because main's flag is already false for every family there.
  • A dataset in which no family reports any of the seven, such as a zero-reporter MOCK dataset or a one-row hypothetical dataset. Main's simulation-wide sum is then under £1, so main sets every family true; this PR sets them false. Survey data always has reporters, so survey runs see no difference.
    • Such a household can differ only in a year when tax credits (to 5 April 2025) or Income Support (to 31 March 2026, gov.dwp.income_support.active) still pay, and only if it reports none of the seven but is entitled.
    • Review r6 found that policyengine.py's budget-contract wrapper.policy builds one-row datasets for 2025 and later. Those contract cases have not been re-read against this condition.
  • The four unsupported core-builder overwrite routes (PolicyEngine/policyengine-core#627, open) were already misclassified as data. They now also get reporters-only CTC, WTC and IS take-up, not just reporters-only CTR and HB. No supported caller reaches them (see below).

Data-source detection

built_from_data covers UK Simulation, Microsimulation, core simulations over the UK system, clones, branches and UK build_from_situation rebuilds. All 20 supported routes are pinned with synthetic pytest coverage.

Known limitation: in core 3.33.2, directly calling SimulationBuilder.build_from_dict on an existing data-built object leaves stale source flags and the old dataset, with no reliable situation marker. The four unsupported overwrite routes (core overwrite, its clone, its new branch, and UK overwrite via the core builder) stay misclassified as data: 20 of 24 routes are correct. core#627, which is open, is the right place to fix them. Use UK's supported build_from_situation. The helper and the dataset guidance document this. No population-size, ID-type or weight heuristic was introduced.

Tests

  • Reproducer for r6's leak: test_data_built_nonreporters_get_no_tax_credits is r6's MOCK probe. A non-reporting lone parent (child 5, £12,000 earnings, North West private renter) and a non-reporting working pensioner sit beside a family that reports Child Tax Credit and CTR, in 2024. On data, every flag is false and only the reporter claims Child Tax Credit. The lone parent gets no tax credits and no tax credit award, and is not on a Winter Fuel Payment relevant benefit. Entered by hand, the same families keep the per-family flag [True, True, False]. It fails on 94d5ebe32 (the data-built flag is [True, True, False]) and passes at the head.

  • Property: test_data_built_takeup_equals_reported_only covers MOCK data in 2024 and 2026, for one to three families with any subset of the seven reports and CTR. On data:

    • every take-up flag that reads claims_all_entitled_benefits equals the family's own report;
    • tax credits, CTC, WTC, Income Support, HB, CTR, both means-test incomes, the tax credit award, the Winter Fuel Payment benefit test and household net income equal the same data with those reported-only flags as explicit inputs.

    It fails on 94d5ebe32 and passes at the head.

  • Microdata: test_survey_takeup_follows_reports_in_microdata now asserts main's survey value: the flag is false for every family in 2024 and 2026, and CTC, WTC and IS take-up equal reports. It runs only with the certified dataset; round 7 ran it on certified 1.58.1, where it passes at the fix and fails on 94d5ebe32.

  • Earlier tests in this PR (unchanged):

    • the per-benefit-unit class;
    • the CTR property (no non-reporter gets CTR on data without an explicit claim flag);
    • the MOCK reporters-only CTR and HB tests;
    • the hand-entered HB test;
    • the 20 data-source routes.
  • Hypothesis timing (928a82d7d): both take-up properties now suppress only HealthCheck.too_slow, as 123 of the repo's other 150 Hypothesis test files do. Their examples and every other check are unchanged. On a saturated host (load 170–240), one input draw stalled for 4.9 s in the CTR property and one for 11.8 s in the tax credit property, between simulations. The check allows 30 s over the first ten inputs. The CTR property failed once in a parallel batch during round 7, with no traceback printed. That run's cause can't be recovered, so this removes a measured candidate, not a confirmed cause.

Impact on certified Enhanced FRS 1.58.1

Round 7 ran 2024, 2025 and 2026 default-law Microsimulations, sequentially and aggregates only. It compared main 60b09a4e5 with the fix f56cfc50c, using the same locked environment and the dataset read in place (SHA-256 056e80fd8e9151d78f432a25cde863340baee81304c6216a37fb575ce8563784, matching certified_dataset.yaml).

All 32 vectors are byte-identical (SHA-256) to main in each of the three years. The vectors are the union of r6's lists plus three:

  • the flag and all five would_claim_*;
  • CTR, HB, CTC, WTC, Income Support, UC, Pension Credit, income-based JSA, income-related ESA, Child Benefit and the benefit cap reduction;
  • tax credits and the tax credit award;
  • Winter Fuel Payment, winter fuel allowance and its relevant-benefit test;
  • PAWHP (both variables) and its relevant-benefit test;
  • the HB and CTR applicable incomes, household benefits, household net income and HBAI household net income;
  • CTC and WTC pre-minimum.
Vector 2024 (main = fix) 2025 (main = fix) 2026 (main = fix)
council_tax_reduction (£m) 1,935.847 1,986.907 2,031.565
housing_benefit (£m) 8,029.939 8,587.222 8,922.628
tax_credits (£m) 155.975 0.000 0.000
tax_credit_award (£m) 260.032 0.000 0.000
child_tax_credit (£m) 65.502 0.000 0.000
working_tax_credit (£m) 17.434 0.000 0.000
income_support (£m) 154.672 123.955 0.000
winter_fuel_payment (£m) 381.016 1,696.783 1,679.283
pension_age_winter_heating_payment (£m) 19.145 190.004 197.377
household_net_income (£m) 1,592,895.633 1,658,129.501 1,706,643.077
claims_all_entitled_benefits true (benefit units, unweighted) 0 0 0
would_claim_CTC / _WTC / _IS true (unweighted) 118 / 40 / 60 118 / 40 / 60 118 / 40 / 60
would_claim_housing_benefit / _council_tax_reduction true (unweighted) 2,146 / 7,072 2,146 / 7,072 2,146 / 7,072

Sums use household or benefit-unit weights as the variable's entity requires, in float64. r6 measured 2024 tax_credits at £6,150.836m on 94d5ebe32; the fix returns it to main's £155.975m. Main's 2024 hashes equal r6's main hashes.

origin/main 9d81a5dfa has since been merged (97bc6b874, clean). None of its commits changes claims_all_entitled_benefits or its five readers, and 928a82d7d changes test settings only, so the impact was not rerun. On a dataset where some family reports one of the seven and no column supplies the flag, main's flag is false for every family. Main's CTR and HB take-up, flag | report, is then the report, which is exactly this PR's data-built rule. So the identity holds by construction, and it was measured above. Absolute totals at later main commits can differ on both sides alike.

Disclosures from review r6

  • Income Support YAML: in legacy_award_readers/income_support_take_up_and_person_awards.yaml, the non-reporting lodger's benefit unit now carries claims_all_entitled_benefits: false; this was not disclosed before. In that hand-entered case another member reports Income Support. On main, that report switched the flag off for every family. Under the per-family rule the lodger's flag would be true, and so would its would_claim_IS (reported | claims_all_entitled_benefits), which the case expects to be false. The input keeps the case on its subject, capital sharing.
  • "193 removed" overstated the change against main. An earlier hand-off comment counted 193 removed compensating flags. Those lines had been added earlier in this PR, so main never had them. Against main, the PR adds 3 would_claim_council_tax_reduction: true inputs and 6 claims_all_entitled_benefits: true inputs (12 and 9 lines in total, counting output assertions), all in the new ctr_takeup.yaml (its explicit-override and calculator cases), plus the lodger input above.
  • core#627 is open and is the right place to fix the four unsupported core-builder routes.

Validation

At 97bc6b874 (main merged) and 928a82d7d:

  • Format: uvx ruff format --check . passes on 1,920 files.
  • YAML: round 7's 19 paths (CTR, HB, Income Support, legacy award readers, tax credits, Winter Fuel Payment, PAWHP, winter heating income and the winter fuel allowance reforms) pass: 932 cases.
  • This PR's module: at 97bc6b874, all 17 runnable example tests pass (-n 4), and both properties pass serially (CTR 32 inputs, tax credits 12). At 928a82d7d, the tax credit property passes serially (12 inputs); the CTR property passed all 23 inputs it reached before a 500 s guard (no failure).
  • Main's new data-built modules: test_disable_simulated_benefits.py and test_tax_credits_pension_credit_passport_properties.py show 48 passed and none failed before the guard.

The host ran at load 70–240 throughout, so suites ran in timed slices. Run-level results for the flaky-test check are in the hand-off comment. CI at the head runs the full suite.

Independent final-head review and CI remain for the hub; this build job does not review or merge its own work.

Reproducer: policyengine_uk/tests/test_claims_all_entitled_benefits.py::test_data_built_nonreporters_get_no_tax_credits, policyengine_uk/tests/test_claims_all_entitled_benefits.py::test_data_built_takeup_equals_reported_only, policyengine_uk/tests/test_claims_all_entitled_benefits.py::TestPerBenefitUnit::test_one_reporter_does_not_switch_off_the_other_benefit_unit, policyengine_uk/tests/test_claims_all_entitled_benefits.py::test_ctr_is_zero_for_every_nonreporter_without_an_explicit_claim_flag, policyengine_uk/tests/test_claims_all_entitled_benefits.py::test_mock_data_takeup_is_reporters_only

axiom: n/a: survey take-up assumptions and vectorisation, with no statutory policy rule change.

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits August 28, 2026 07:12
The formula summed its seven reported-benefit columns across the whole
simulation (.sum() < 1), so in microdata the flag was False for every
benefit unit whenever any benefit unit reported any of them, and
would_claim_council_tax_reduction collapsed to FRS reporters only.
Housing benefit, income support and the tax credits are unaffected:
their own already-claiming eligibility gates carry the reporters-only
behaviour independently of this flag.

Refs PolicyEngine/policyengine-uk-data#448.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…path

Review findings on the previous commit: the docstrings, test module
docstring and changelog fragment said "reports any" where the formula
tests the combined reported amount < £1, and the test named for
single-benefit-unit semantics actually built two benefit units. Both
now match the code: documentation states the threshold, and a genuine
one-benefit-unit situation covers the calculator path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@MaxGhenis

MaxGhenis commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator Author

Ruling (Max, 2026-10-12, cos d1390): reporters only. This PR's per-benefit-unit fix lands with council tax reduction kept explicitly to families who report it, until a calibrated would_claim_council_tax_reduction column lands in the data (PolicyEngine/policyengine-uk-data#448). The UK hub adopted this PR (it has no live owner session). A hub job is merging main, making the CTR reporters-only rule explicit, re-measuring the impact and getting a review.

@MaxGhenis
MaxGhenis marked this pull request as ready for review October 13, 2026 02:27
@MaxGhenis

MaxGhenis commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator Author

Ready for hub handoff at 4f1cf4700c88e83d3e90960b8dfccd3d03229f94; current main 1d3abecef443d3a142640bb2f6b0567f2004103c is merged. The PR body now states d1390, the calibrated-column end state uk-data#448, and fresh 2026 impact.

Tests: focused Python/property 9 passed; paired national CTR YAML 6 passed; formatting and lint pass. Two real enhanced-FRS simulations and all source/dataset/identity/flag checks pass. New-head CI run 38335603604 is in progress (YAML/lint/evidence/docs/Python 3.12 smoke pass; four Python shards running, Python 3.11/3.13/3.14 smokes queued as of 02:32Z). Previous head's complete full suite passed.

Impact: CTR amounts and recipients exactly unchanged in UK/England/Scotland/Wales. HB +£749.855384m, +180,511 weighted recipient benefit units; household net income +£749.855374m. All 670 HB changes are new awards to nonreporters whose corrected family flag turns true. Other 21 measured payments are exactly unchanged on every record. Full dataset: 54,142 nonreporting units without a CTR data flag receive zero CTR; zero per-family flag mismatches. Dataset SHA256 5ba399ea5ab9a6c7d4e9aaf6c623080beb34d9ad5f330f6244dbad72b8d960b6. Both full SHAs, country/recipient/HNI tables and the HB exception are in the body.

Please dispatch the independent GPT-6.1 Sol review at 4f1cf4700c88e83d3e90960b8dfccd3d03229f94 through the hub, as adopt-common requires. No in-job review is used as final approval. Review and final CI remain open; this build job does not merge.

Progress, reproducible aggregate evidence, HANDOFF.md, and the one-line handoffs.jsonl are in /Users/maxghenis/.subfleet/worktrees/20261012-202021-adopt-uk1831-r5/.job/ for hub copy-out. Recovery bundle is verified; author history preserved; local runs stayed in the foreground and no datasets/survey records were pushed.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Independent review (GPT-6.1 Sol, UK hub): REQUEST_CHANGES at 4f1cf4700, pending a ruling from Max. The per-benefit-unit fix is correct, CTR meets d1390, impact accounting reconciles, and final-head CI passed. The one blocker is a take-up methodology choice, not a code defect. The fix turns on Housing Benefit for 670 non-reporting families (+£749.9m, +180.5k recipient benefit units in 2026). That is now queued for Max as d1455: keep it, or make HB reporters-only like CTR until a calibrated claim flag exists. Once he rules, the hub sends a small job to implement the chosen behaviour, update the HB docs and takeup.yaml (finding 2), and add the pensioner test. Then it re-reviews and lands.

VERDICT: REQUEST_CHANGES
Head reviewed: 4f1cf47

  1. [blocker] would_claim_housing_benefit.py:14 — Housing Benefit needs a separate take-up ruling. The increase follows mechanically from the existing OR gate and the pension-age new-claim route in housing_benefit_eligible.py:79. However, it activates full HB take-up for eligible survey non-reporters. The documented Enhanced FRS design followed reported claims, and the original fix commit assumed HB would remain unaffected.

    The diagnostic confirms 670 new awards, all to HB non-reporters whose family flag switches false → true: +£749.855384m and +180,511 weighted recipient benefit units. This is (b), a take-up methodology choice, alongside a valid flag bug fix; d1390 explicitly resolves CTR only.

    Max must choose whether Enhanced FRS HB automatically pays eligible families reporting under £1 across the seven benefits, or retains reporters-only take-up until an explicit calibrated HB claim flag is available, while preserving the per-benefit-unit fix. Record that ruling and test the selected behavior with an eligible non-reporting pensioner beside a reporting family.

    The headline totals move toward DWP benchmarks: model UK recipients rise 1.228m → 1.408m, compared with 1.4469m GB claims in March 2026; spending rises £8.456bn → £9.206bn, compared with DWP’s £12.9bn FYE2026 expenditure estimate, which uses Spring Forecast figures. Audited 2024–25 HB spending was £14.677bn. DWP caseload, expenditure estimate, audited accounts.

    That direction is encouraging but does not validate automatic take-up: geography, periods, UC migration and omitted supported/temporary accommodation prevent a matched comparison.

  2. [should-fix] housing-benefit.ipynb:31 — Durable HB documentation contradicts this head. It still says Enhanced FRS take-up follows reported claims. takeup.yaml:2 repeats that assumption. Update both to the ruled behavior.

The per-benefit-unit fix itself is correct. In claims_all_entitled_benefits.py:23, removing .sum() preserves one result per family and the existing seven-benefit/£1 rule. The old reduction let unrelated families determine a BenUnit attribute, contrary to its documented family meaning.

CTR satisfies d1390. would_claim_council_tax_reduction.py:16 defaults solely to reporters; its comment names d1390 and links uk-data#448. The aggregates show identical amounts and recipient status on every record, with zero CTR for all 54,142 non-reporting units without an override.

Tests cover separate/shared households and all seven reports in test_claims_all_entitled_benefits.py:71. The property at line 202 checks zero claim flag and all three CTR outputs; ctr_reporters_only.yaml:1 pairs entitled non-reporters’ zero defaults with positive explicit-flag awards. No assertions were weakened or new skips/xfails introduced. The microsimulation test remains present and was explicitly deselected locally.

Impact accounting reconciles: the live body includes both full SHAs and dataset hash; its country tables match comparison.json. HB is the sole changed payment among 22; HNI rises £749.855374m, leaving a £10.29 aggregate rounding residual. Final-head CI passed.

Read-only static review; no tests or microsimulation run independently.

@vahid-ahmadi vahid-ahmadi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs changes before merge. The per-benefit-unit fix is right, but the new CTR default turns Council Tax Reduction off for every household entered without reports, which is every calculator household.

@MaxGhenis, I reviewed this at head 4f1cf4700.

  1. must: calculator households lose all CTR (variables/gov/local_authorities/council_tax_reduction/would_claim_council_tax_reduction.py:16-19).

    • On main, a household with no reports has claims_all_entitled_benefits true, so would_claim_council_tax_reduction is true and CTR is paid. With this PR the default is council_tax_benefit_reported > 0 alone, so a household with no reports gets £0 unless the caller sets the flag.

    • Probe, 2026, single adult, private rent £8,000, council tax £1,800, no earnings, no roles or reports. I ran the branch, then the same tree with the two changed variable files restored from main 1d3abecef:

      Household CTR main CTR branch Net income change
      70, North West £1,800.00 £0 −£1,800.00
      70, Wales £1,800.00 £0 −£1,800.00
      30, Scotland £633.96 £0 −£633.96
    • On the enhanced FRS this changes nothing, because main's simulation-wide .sum() already made claims_all_entitled_benefits false for every family. The body's own figure shows it: 54,276 family flags change with the per-unit fix. That is why the survey CTR table is identical. The cost lands on households entered by hand instead.

    • The PR adds 193 would_claim_council_tax_reduction: true fixture lines to keep existing expectations. That is the same effect, seen in the fixtures.

    • The d1390 comment is about survey take-up. It doesn't say calculator households should stop getting CTR, and the body and changelog don't mention it.

    • Fix: keep claims_all_entitled_benefits | reported_ctr as the formula default, and get reporters-only on survey runs from the data side. That could be a would_claim_council_tax_reduction column in the dataset (the end state in uk-data#448) or an interim column set from council_tax_benefit_reported. This is not a one-line revert. With the per-unit fix, restoring the OR on its own would turn on CTR for those 54,276 survey families, as happened with HB. So the OR can only come back together with a uk-data release that supplies the column, sequenced with this PR like the HB ruling.

    • If reporters-only for every input is really what is meant, it needs its own explicit ruling and a line in the changelog. The app and API would then have to send the flag.

  2. should: hold the merge until the Housing Benefit ruling is in and applied. The +£749.9m HB from 670 new non-reporter awards is still open as d1455 in the 13 October comment. Whichever way it goes, housing-benefit.ipynb and gov/dwp/housing_benefit/takeup.yaml still say enhanced FRS take-up follows reported claims, and need to match the ruling. Calculator households are not affected here, because a single benefit unit's sum was already per unit.

  3. nit: the docstring says "the seven means-tested benefits the formula checks" (claims_all_entitled_benefits.py:9-17). The list matches the seven _reported variables at lines 27-33. It might be worth saying that CTR, Pension Credit and Child Benefit are not among them, so a family reporting only Pension Credit still counts as claiming everything.

  4. nit: main has moved 115 commits since your last merge (1d3abecef). git merge-tree against current main (714b1438c) is clean. CI at this head is green on every job (YAML, the four Python shards, lint, fix evidence, docs and the smoke imports).

Repo process: the .fixed.md fragment fits. Reproducer: and axiom: lines are present, and Fix evidence passes. No file overlaps with #1820, #1855, #1864, #2184, #2187, #2189, #2193 or #2382.

What I checked

  • Read the full body, the three comments and the whole diff against 1d3abecef.
  • Ran the 14 changed YAML files: 207 cases passed. Ran the 11 changed pytest files with -m 'not microsimulation': 54 passed, 1 deselected. I did not run the enhanced FRS microsimulation test, because I have no access to the data on this machine.
  • Restored main's .sum() in claims_all_entitled_benefits.py. TestPerBenefitUnit::test_one_reporter_does_not_switch_off_the_other_benefit_unit then fails, so the reproducer catches the bug.
  • Ran the household probe in finding 1 on the branch and on main's two variable files.
  • ruff check and ruff format --check on the 13 changed Python files: clean.
  • Take-up is a modelling assumption, not a statutory rule, so I had no legislation to check it against. I did not re-derive the survey figures in the body.

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

@vahid-ahmadi, addressed each point at 94d5ebe3291b8c2b259e12e71dc751cf87ab3a57:

  1. Calculator CTR: hand-entered situations now use main's claims_all_entitled_benefits | positive_report rule per benefit unit. All three probes are committed in ctr_takeup.yaml: £1,800 / £1,800 / £633.96, without reports, claimant roles or take-up inputs. Data-built simulations separately stay reporters-only under d1390 until uk-data#448. Removed the 187 compensating YAML input flags and Python fixture setup; the 193-line count also included six deliberate occurrences in explicit-override tests, which are retained. The survey property now uses MOCK data rather than treating hand-entered situations as survey runs.

    Core 3.33.2 records no reliable marker for direct in-place core-builder overwrites, so we used the hub's authorized fallback: all 20 supported routes are pinned and pass; the four unsupported SimulationBuilder.build_from_dict overwrite routes remain documented limitations (helper docstring and PR body). UK's build_from_situation rebuilds correctly. .job/CORE_ISSUE.md drafts the upstream issue for the hub to file; no ID/weight heuristic was added.

  2. HB ruling: Max's d1455 decision (19 October) is implemented: data-built HB defaults to reporters-only, like CTR; situations keep main's per-family rule. MOCK tests prove £0 for an entitled non-reporter, a positive reporter award, and explicit overrides. The hand-entered pensioner keeps £8,000 HB. The HB notebook and takeup.yaml now describe this split. Full-suite verification also exposed a cap-only fixture that supplied a £30,000 pre-cap HB award without stating that it was claimed. That fixture now explicitly claims its supplied HB award; all cap/exemption assertions are retained.

    Re-measured sequentially on certified uk-data 1.58.1, SHA256 056e80fd8e9151d78f432a25cde863340baee81304c6216a37fb575ce8563784, current main 42c01db91 versus model-source head fb0937710. The final head differs only by the cap-test fixture correction. HB spending is £8.922627540bn and weighted recipient benefit units 1,252,043.699 on both trees: £0 / 0 change, so the prior +£749.9m / +180.5k effect is gone. CTR, HNI and all 22 measured payments have identical award/recipient vectors. All 59,068 HB non-reporters and 54,142 CTR non-reporters get zero awards. The CTR PR effect remains zero as in round 5; absolute totals differ with refreshed main/data, not an isolated PR effect.

  3. Seven-benefit nit: documentation explicitly excludes CTR, Pension Credit and Child Benefit, including the Pension Credit-only example. Three regressions pin those exclusions.

  4. Merge main: restored verified round-6 merge 38755ca26, then merged current fetched main 42c01db91 cleanly in fb0937710. Author commits/history preserved.

Validation:

  • YAML: the full suite passes (3,846 cases).
  • Python: the full local run was cut off by a host power loss after 3,429 passed and 92 skipped. Its one failure, a benefit-cap fixture, is fixed in 94d5ebe32, and that module passes 26/26.
  • CI: it runs the full suite at the head. An independent review follows.

The exact per-benefit-unit reproducer fails with main's .sum() restored (AssertionError) and passes with the fix. The PR body contains the new impact/provenance and retains Reproducer: / axiom:. No self-review or merge was performed; the hub owns final-head independent review and CI follow-up.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Aggregate impact on certified data: pass

Base 9d81a5dfa8 against head 48ea5868e1, both on enhanced_frs_2024_25.h5 (policyengine-uk-data 1.58.1, sha256 056e80fd8e91), fiscal years 2025-26 to 2031-32. Each year is a full microsimulation run on each side.

Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 0 (thresholds in report_spec.yaml; a flag does not fail the job).

Workflow run and full report

Notes

  • In the years a figure from fewer than 10 records is suppressed (spending.disabled_students_allowance), every total containing it, and the decile incomes, are rebuilt from their other components, so no published total includes it. Those totals are marked †. A change is withheld where the two sides leave out different figures and can't be lined up.

Moves flagged for review

None.

Spending by benefit and service

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed

Caseloads

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed

Household net income by decile

No household's net income changes in any year.

No change in any year: receipts by tax head; government balance, each component counted once; model totals; components the model counts twice; household income totals; population; poverty rates; people in poverty; inequality; mean household net income in each side's own deciles; standard reform costings (change in gov_balance); standard reforms: change in each reform's target.

Checks failing on both base and head (1)
  • VAT is never negative (sign:vat): 2025-26: 76 units below zero, a weighted £-54,797,972 in total; 2026-27: 76 units below zero, a weighted £-56,271,349 in total; 2027-28: 76 units below zero, a weighted £-57,609,146 in total
Counted-once check

Each of 84 components was raised by £1 per unit in 2026-27, and every head of its totals was read household by household: its own head must rise by exactly £1, no other tax head may move, no other benefit may rise, and the model's own total must move by what its heads moved. A head that breaks a rule is measured again twice: with every other head held at its baseline value, and with every other head held at its value after the first £1 while the component rises again. It fails where either still shows the response. 0 failed; 0 were skipped.

Provenance
Side Commit Runtime Environment hash Partition hash Time
base main 9d81a5dfa8 uk 2.146.2 (files 582dff2713e2), core 3.33.2, py 3.13.17 aarch64 6a24b7ff580b f210f83d5be4 1569.28s
head #1831 merged into main 48ea5868e1 uk 2.146.2 (files c0c5c29f3cae), core 3.33.2, py 3.13.17 aarch64 6a24b7ff580b f210f83d5be4 1554.95s

Dataset: hf://policyengine/policyengine-uk-data-private/enhanced_frs_2024_25.h5@2526edbbb687a3b54dbb11272e5389e4b62d2ac2, sha256 056e80fd8e9151d78f432a25cde863340baee81304c6216a37fb575ce8563784 (verified on both sides), policyengine-uk-data 1.58.1.

Receipts by tax head: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Income tax £299.29bn £319.01bn £336.47bn £351.62bn £367.17bn £385.29bn £403.59bn
National Insurance (employee and self-employed) £52.58bn £54.94bn £56.75bn £58.48bn £60.62bn £62.57bn £65.03bn
National Insurance (employer) £152.64bn £159.18bn £164.14bn £168.73bn £176.11bn £181.72bn £188.90bn
Employer NI change borne by capital £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Employer NI change borne by consumers £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Capital gains tax £12.62bn £13.06bn £13.55bn £14.04bn £14.54bn £15.09bn £15.65bn
Student loan repayments £7.83bn £8.12bn £8.35bn £8.56bn £8.79bn £9.04bn £9.38bn
VAT £253.71bn £260.53bn £266.72bn £273.14bn £279.83bn £286.71bn £293.71bn
Change in VAT from its baseline £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
VAT on private school fees £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Fuel duties £24.53bn £24.64bn £26.64bn £26.69bn £26.42bn £25.76bn £26.35bn
Alcohol duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Tobacco duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Vehicle excise duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
TV licence fee £4.28bn £4.43bn £4.44bn £4.46bn £4.48bn £4.51bn £4.53bn
Council tax £49.56bn £52.45bn £55.78bn £59.39bn £62.98bn £66.74bn £70.70bn
High value council tax surcharge £0.00bn £0.00bn £0.00bn £0.48bn £0.49bn £0.51bn £0.52bn
Northern Ireland domestic rates £0.55bn £0.58bn £0.61bn £0.63bn £0.67bn £0.70bn £0.73bn
Business rates £31.73bn £31.73bn £31.73bn £31.73bn £31.73bn £31.73bn £31.73bn
Stamp duty land tax (own purchases, and corporate until the £10.06bn £10.56bn £10.98bn £11.40bn £11.81bn £12.23bn £12.64bn
Land transaction tax (Wales) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Land and buildings transaction tax (Scotland) £0.01bn £0.01bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn
Unspecified tax change borne by capital £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Unspecified tax change borne by consumers £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Wealth tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Wealth tax excluding the main residence £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Land value tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Carbon tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Spending by benefit and service: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
State Pension £122.15bn £126.64bn £127.57bn £129.47bn £133.29bn £137.24bn £141.32bn
Pension Credit £6.68bn £7.07bn £7.06bn £7.13bn £7.26bn £7.39bn £7.49bn
Winter Fuel Payment £1.70bn £1.68bn £1.59bn £1.58bn £1.57bn £1.55bn £1.52bn
Pension Age Winter Heating Payment (Scotland) £0.19bn £0.20bn £0.20bn £0.21bn £0.21bn £0.22bn £0.22bn
Universal Credit £78.81bn £83.11bn £84.93bn £86.69bn £87.61bn £89.03bn £90.35bn
Housing Benefit £8.59bn £8.93bn £9.19bn £9.34bn £9.61bn £9.87bn £10.15bn
Council Tax Reduction £1.99bn £2.03bn £2.08bn £2.13bn £2.18bn £2.23bn £2.29bn
Employment and Support Allowance (income-related) £2.12bn £2.18bn £2.23bn £2.28bn £2.33bn £2.39bn £2.45bn
Employment and Support Allowance (contribution-based) £5.22bn £5.36bn £5.49bn £5.62bn £5.76bn £5.90bn £6.04bn
Jobseeker's Allowance (income-based) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Jobseeker's Allowance (contribution-based) £0.29bn £0.30bn £0.30bn £0.31bn £0.32bn £0.33bn £0.33bn
Income Support £0.12bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Working Tax Credit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Child Tax Credit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Incapacity Benefit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Personal Independence Payment £27.05bn £28.19bn £28.94bn £29.64bn £30.37bn £31.11bn £31.87bn
Disability Living Allowance £7.52bn £7.83bn £8.04bn £8.24bn £8.44bn £8.65bn £8.86bn
Attendance Allowance £8.71bn £9.08bn £9.32bn £9.55bn £9.78bn £10.02bn £10.26bn
Carer's Allowance £4.50bn £4.69bn £4.81bn £4.93bn £5.05bn £5.17bn £5.29bn
Carer Support Payment (Scotland) £0.31bn £0.32bn £0.33bn £0.34bn £0.35bn £0.36bn £0.36bn
Carer's Allowance Supplement (Scotland) £0.00bn £0.04bn £0.04bn £0.04bn £0.04bn £0.04bn £0.04bn
Severe Disablement Allowance £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn
Industrial Injuries Disablement Benefit £0.51bn £0.52bn £0.53bn £0.54bn £0.56bn £0.57bn £0.59bn
Armed Forces Compensation Scheme £0.61bn £0.62bn £0.64bn £0.65bn £0.67bn £0.69bn £0.70bn
War Widow's or Widower's Pension £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Child Benefit £16.23bn £16.91bn £17.32bn £17.73bn £18.16bn £18.60bn £19.04bn
Scottish Child Payment £0.50bn £0.52bn £0.53bn £0.55bn £0.56bn £0.57bn £0.58bn
Two Child Limit Payment (Scotland, counterfactual) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Healthy Start vouchers £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn
Maternity Allowance £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Statutory Maternity Pay £3.32bn £3.41bn £3.49bn £3.57bn £3.66bn £3.75bn £3.84bn
Statutory Paternity Pay £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Statutory Sick Pay £1.13bn £1.16bn £1.19bn £1.22bn £1.25bn £1.28bn £1.31bn
Sure Start Maternity Grant £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn
Bereavement Support Payment £0.67bn £0.69bn £0.70bn £0.72bn £0.74bn £0.76bn £0.78bn
Tax-Free Childcare £0.55bn £0.56bn £0.57bn £0.58bn £0.60bn £0.61bn £0.59bn
Extended childcare entitlement £2.66bn £3.14bn £3.23bn £3.30bn £3.38bn £3.47bn £3.55bn
Universal childcare entitlement £3.32bn £3.59bn £3.69bn £3.78bn £3.88bn £3.99bn £4.08bn
Targeted childcare entitlement £0.57bn £0.60bn £0.62bn £0.63bn £0.65bn £0.66bn £0.67bn
Care to Learn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Childcare Grant £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Parents' Learning Allowance £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn
Adult Dependants' Grant £0.06bn £0.06bn £0.04bn £0.04bn £0.04bn £0.04bn £0.04bn
Travel Grant £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed
16 to 19 Bursary Fund £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
NHS spending £204.68bn £205.46bn £206.22bn £207.04bn £207.96bn £208.89bn £209.79bn
State education spending £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn
Transport subsidy spending £25.15bn £25.25bn £25.34bn £25.44bn £25.55bn £25.67bn £25.78bn
Cost-of-living support payment £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Energy Bills Rebate £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Energy Price Guarantee subsidy £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Basic income £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Disability basic income £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Other public spending budget change £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Caseloads: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
State Pension 11,308k 11,208k 10,906k 10,812k 10,860k 10,908k 10,955k
Pension Credit 1,491k 1,489k 1,478k 1,459k 1,459k 1,457k 1,453k
Winter Fuel Payment 7,092k 7,011k 6,601k 6,517k 6,493k 6,381k 6,254k
Pension Age Winter Heating Payment (Scotland) 806k 807k 807k 805k 809k 812k 816k
Universal Credit 6,371k 6,379k 6,409k 6,420k 6,395k 6,387k 6,371k
Housing Benefit 1,254k 1,252k 1,254k 1,240k 1,245k 1,247k 1,249k
Council Tax Reduction 3,186k 3,211k 3,224k 3,245k 3,264k 3,280k 3,293k
Employment and Support Allowance (income-related) 187k 188k 188k 189k 190k 190k 191k
Employment and Support Allowance (contribution-based) 722k 724k 727k 730k 733k 737k 740k
Jobseeker's Allowance (income-based) 0k 0k 0k 0k 0k 0k 0k
Jobseeker's Allowance (contribution-based) 67k 67k 68k 68k 68k 69k 69k
Income Support 25k 0k 0k 0k 0k 0k 0k
Working Tax Credit 0k 0k 0k 0k 0k 0k 0k
Child Tax Credit 0k 0k 0k 0k 0k 0k 0k
Incapacity Benefit 0k 0k 0k 0k 0k 0k 0k
Personal Independence Payment 3,581k 3,595k 3,608k 3,623k 3,639k 3,655k 3,671k
Disability Living Allowance 1,296k 1,301k 1,306k 1,311k 1,317k 1,323k 1,329k
Attendance Allowance 1,701k 1,708k 1,714k 1,721k 1,729k 1,736k 1,744k
Carer's Allowance 1,038k 1,042k 1,046k 1,050k 1,055k 1,059k 1,064k
Carer Support Payment (Scotland) 71k 72k 72k 72k 73k 73k 73k
Carer's Allowance Supplement (Scotland) 0k 72k 72k 72k 73k 73k 73k
Severe Disablement Allowance 4k 4k 4k 4k 4k 4k 4k
Industrial Injuries Disablement Benefit 137k 138k 139k 139k 140k 140k 141k
Armed Forces Compensation Scheme 94k 94k 94k 95k 95k 95k 96k
War Widow's or Widower's Pension 0k 0k 0k 0k 0k 0k 0k
Child Benefit 8,136k 8,165k 8,185k 8,215k 8,249k 8,282k 8,314k
Scottish Child Payment 352k 354k 355k 356k 357k 358k 357k
Two Child Limit Payment (Scotland, counterfactual) 0k 0k 0k 0k 0k 0k 0k
Healthy Start vouchers 200k 201k 202k 203k 204k 204k 205k
Maternity Allowance 0k 0k 0k 0k 0k 0k 0k
Statutory Maternity Pay 334k 335k 336k 338k 339k 341k 342k
Statutory Paternity Pay 0k 0k 0k 0k 0k 0k 0k
Statutory Sick Pay 182k 183k 183k 184k 185k 186k 186k
Sure Start Maternity Grant 26k 26k 26k 27k 27k 27k 27k
Bereavement Support Payment 98k 98k 99k 99k 100k 100k 101k
Tax-Free Childcare 1,017k 1,028k 1,028k 1,033k 1,034k 1,038k 1,023k
Extended childcare entitlement 665k 671k 675k 677k 682k 686k 687k
Universal childcare entitlement 986k 989k 992k 997k 1,002k 1,013k 1,015k
Targeted childcare entitlement 119k 120k 120k 121k 121k 122k 121k
Care to Learn 0k 0k 0k 0k 0k 0k 0k
Childcare Grant 0k 0k 0k 0k 0k 0k 0k
Parents' Learning Allowance 98k 99k 99k 100k 100k 100k 101k
Adult Dependants' Grant 18k 18k 12k 13k 13k 13k 13k
Travel Grant 0k 0k 0k 0k 0k 0k 0k
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed
16 to 19 Bursary Fund 0k 0k 0k 0k 0k 0k 0k
Cost-of-living support payment 0k 0k 0k 0k 0k 0k 0k
Energy Bills Rebate 0k 0k 0k 0k 0k 0k 0k
Energy Price Guarantee subsidy 0k 0k 0k 0k 0k 0k 0k
Basic income 0k 0k 0k 0k 0k 0k 0k
Disability basic income 0k 0k 0k 0k 0k 0k 0k
Government balance, each component counted once: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Government receipts, each component once £899.38bn £939.24bn £976.18bn £1,009.38bn £1,045.66bn £1,082.60bn £1,123.48bn
Government spending £536.24bn † £550.45bn † £556.57bn † £563.61bn † £572.15bn † £581.38bn † £590.55bn †
Government balance, each receipt once £363.15bn † £388.79bn † £419.62bn † £445.77bn † £473.51bn † £501.23bn † £532.93bn †
Benefits in household_benefits but not in gov_spending £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Model totals: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
gov_tax £902.51bn £942.37bn £979.31bn £1,012.51bn £1,048.79bn £1,085.73bn £1,126.61bn
household_tax £496.17bn £522.66bn £548.45bn £570.64bn £592.85bn £617.30bn £644.01bn
pre_budget_change_household_tax £488.34bn £514.54bn £540.10bn £561.60bn £583.57bn £607.75bn £634.11bn
gov_spending £536.24bn † £550.45bn † £556.57bn † £563.61bn † £572.15bn † £581.38bn † £590.55bn †
household_benefits £536.24bn † £550.45bn † £556.57bn † £563.61bn † £572.15bn † £581.38bn † £590.55bn †
gov_balance £366.28bn † £391.92bn † £422.75bn † £448.90bn † £476.64bn † £504.36bn † £536.06bn †
Components the model counts twice: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
corporate_sdlt, counted again inside expected_sdlt £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn £3.13bn
Household income totals: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Household market income £1,657.06bn £1,719.25bn £1,771.68bn £1,821.99bn £1,872.88bn £1,930.99bn £2,001.98bn
Household net income £1,657.86bn † £1,706.28bn † £1,737.91bn † £1,772.02bn † £1,808.10bn † £1,849.73bn † £1,901.48bn †
Household net income (HBAI definition) £1,466.42bn £1,513.06bn £1,545.11bn £1,578.08bn £1,612.09bn £1,651.12bn £1,701.58bn
Population: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
People 69,514k 69,778k 70,036k 70,316k 70,626k 70,944k 71,249k
Benefit units 35,247k 35,381k 35,512k 35,654k 35,811k 35,972k 36,127k
Households 31,167k 31,285k 31,401k 31,526k 31,665k 31,808k 31,944k
Poverty rates: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone 15.9% 15.0% 15.5% 15.6% 15.7% 15.8% 15.8%
Absolute poverty, before housing costs: children 23.7% 20.9% 21.6% 21.4% 21.6% 21.8% 21.7%
Absolute poverty, before housing costs: working-age adults 13.8% 13.4% 14.0% 14.1% 14.2% 14.3% 14.3%
Absolute poverty, before housing costs: pensioners 13.7% 13.2% 13.3% 13.5% 13.6% 13.7% 13.7%
Absolute poverty, after housing costs: everyone 21.1% 20.6% 21.3% 21.5% 21.9% 22.2% 22.3%
Absolute poverty, after housing costs: children 32.1% 30.3% 30.9% 31.1% 31.7% 32.3% 32.5%
Absolute poverty, after housing costs: working-age adults 19.6% 19.4% 20.2% 20.4% 20.8% 21.0% 21.0%
Absolute poverty, after housing costs: pensioners 12.8% 12.6% 12.6% 13.1% 13.4% 13.4% 13.4%
Relative poverty, before housing costs: everyone 16.9% 16.4% 16.5% 16.6% 16.6% 16.7% 16.7%
Relative poverty, before housing costs: children 25.6% 23.5% 23.2% 23.2% 23.2% 23.2% 23.2%
Relative poverty, before housing costs: working-age adults 14.4% 14.4% 14.6% 14.8% 14.9% 15.0% 15.0%
Relative poverty, before housing costs: pensioners 15.0% 14.9% 14.4% 14.7% 14.3% 14.3% 14.6%
Relative poverty, after housing costs: everyone 21.7% 21.3% 21.4% 21.5% 21.6% 21.9% 22.0%
Relative poverty, after housing costs: children 33.0% 31.6% 31.0% 31.1% 31.3% 31.6% 32.0%
Relative poverty, after housing costs: working-age adults 20.0% 20.0% 20.3% 20.4% 20.6% 20.8% 20.9%
Relative poverty, after housing costs: pensioners 13.7% 13.1% 12.8% 13.0% 12.7% 12.9% 13.2%
People in poverty: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone 11,056k 10,435k 10,856k 10,960k 11,091k 11,220k 11,234k
Absolute poverty, before housing costs: children 3,560k 3,141k 3,261k 3,253k 3,298k 3,334k 3,335k
Absolute poverty, before housing costs: working-age adults 5,862k 5,735k 6,068k 6,164k 6,235k 6,314k 6,321k
Absolute poverty, before housing costs: pensioners 1,634k 1,559k 1,527k 1,543k 1,558k 1,572k 1,579k
Absolute poverty, after housing costs: everyone 14,663k 14,366k 14,907k 15,144k 15,491k 15,755k 15,874k
Absolute poverty, after housing costs: children 4,809k 4,556k 4,676k 4,719k 4,835k 4,939k 4,994k
Absolute poverty, after housing costs: working-age adults 8,333k 8,326k 8,775k 8,931k 9,122k 9,275k 9,329k
Absolute poverty, after housing costs: pensioners 1,521k 1,484k 1,456k 1,493k 1,533k 1,541k 1,551k
Relative poverty, before housing costs: everyone 11,780k 11,464k 11,523k 11,660k 11,708k 11,832k 11,879k
Relative poverty, before housing costs: children 3,840k 3,538k 3,506k 3,524k 3,542k 3,554k 3,565k
Relative poverty, before housing costs: working-age adults 6,154k 6,160k 6,356k 6,464k 6,530k 6,636k 6,628k
Relative poverty, before housing costs: pensioners 1,786k 1,766k 1,661k 1,673k 1,636k 1,643k 1,686k
Relative poverty, after housing costs: everyone 15,110k 14,866k 14,956k 15,109k 15,280k 15,513k 15,696k
Relative poverty, after housing costs: children 4,948k 4,756k 4,684k 4,715k 4,771k 4,840k 4,916k
Relative poverty, after housing costs: working-age adults 8,531k 8,560k 8,793k 8,917k 9,054k 9,187k 9,257k
Relative poverty, after housing costs: pensioners 1,631k 1,551k 1,479k 1,477k 1,455k 1,486k 1,523k
Inequality: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Gini coefficient, equivalised HBAI income before housing costs 0.3074 0.3052 0.3066 0.3072 0.3078 0.3084 0.3095
Mean household net income in each side's own deciles: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Decile 1: mean household_net_income per household £17,700 † £17,996 † £17,934 † £17,991 † £18,328 † £18,506 † £18,680 †
Decile 2: mean household_net_income per household £28,323 † £29,102 † £28,705 † £28,983 † £29,330 † £29,734 † £30,317 †
Decile 3: mean household_net_income per household £34,629 † £35,807 † £36,445 † £37,019 † £37,221 † £37,811 † £38,492 †
Decile 4: mean household_net_income per household £39,334 † £40,803 † £41,758 † £42,693 † £43,435 † £44,025 † £44,926 †
Decile 5: mean household_net_income per household £44,861 † £46,156 † £47,079 † £47,439 † £48,027 † £49,181 † £50,036 †
Decile 6: mean household_net_income per household £47,925 † £49,329 † £50,288 † £51,174 † £52,167 † £52,953 † £54,205 †
Decile 7: mean household_net_income per household £56,319 † £57,568 † £58,473 † £59,423 † £60,149 † £61,621 † £62,893 †
Decile 8: mean household_net_income per household £69,267 † £70,356 † £71,672 † £72,810 † £74,351 † £75,797 † £77,578 †
Decile 9: mean household_net_income per household £79,648 † £81,992 † £83,192 † £84,486 † £86,056 † £87,570 † £90,645 †
Decile 10: mean household_net_income per household £117,618 † £120,489 † £122,421 † £124,552 † £126,802 † £129,073 † £131,887 †
Standard reform costings (change in gov_balance): head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp £6.21bn £6.50bn £6.70bn £6.90bn £7.11bn £7.34bn £7.62bn
Raise higher rate by 1pp £3.54bn £3.82bn £4.05bn £4.27bn £4.49bn £4.76bn £4.96bn
Raise personal allowance by ~800GBP/year £-3.83bn £-3.96bn £-4.03bn £-4.10bn £-4.19bn £-4.29bn £-2.02bn
Raise child benefit by 25GBP/week per additional child £-2.00bn £-1.76bn £-1.64bn £-1.54bn £-1.44bn £-1.34bn £-1.24bn
Reduce Universal Credit taper rate to 20% £-20.54bn £-21.10bn £-21.45bn £-21.88bn £-21.95bn £-22.32bn £-22.79bn
Raise Class 1 main employee NICs rate to 10% £11.06bn £11.51bn £11.83bn £12.14bn £12.47bn £12.81bn £13.29bn
Raise VAT standard rate by 2pp £25.01bn £25.68bn £26.29bn £26.92bn £27.58bn £28.26bn £28.95bn
Raise additional rate by 3pp £2.83bn £3.07bn £3.27bn £3.47bn £3.67bn £3.91bn £4.23bn
Raise the Universal Credit standard allowance by 10% £-3.04bn £-3.17bn £-3.24bn £-3.32bn £-3.37bn £-3.42bn £-3.47bn
Raise the State Pension by 10% £-7.81bn £-8.07bn £-7.99bn £-8.11bn £-8.36bn £-8.66bn £-9.02bn
Standard reforms: change in each reform's target: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp: change in income_tax £6.36bn £6.65bn £6.86bn £7.07bn £7.28bn £7.52bn £7.80bn
Raise higher rate by 1pp: change in income_tax £3.55bn £3.83bn £4.06bn £4.28bn £4.50bn £4.77bn £4.97bn
Raise personal allowance by ~800GBP/year: change in income_tax £-3.96bn £-4.10bn £-4.19bn £-4.26bn £-4.36bn £-4.47bn £-1.77bn
Raise child benefit by 25GBP/week per additional child: change in child_benefit £2.34bn £2.15bn £2.03bn £1.92bn £1.82bn £1.71bn £1.59bn
Reduce Universal Credit taper rate to 20%: change in universal_credit £20.53bn £21.09bn £21.44bn £21.87bn £21.95bn £22.32bn £22.78bn
Raise Class 1 main employee NICs rate to 10%: change in national_insurance £11.33bn £11.79bn £12.13bn £12.44bn £12.78bn £13.13bn £13.62bn
Raise VAT standard rate by 2pp: change in vat £25.01bn £25.68bn £26.29bn £26.92bn £27.58bn £28.26bn £28.95bn
Raise additional rate by 3pp: change in income_tax £2.83bn £3.07bn £3.27bn £3.47bn £3.67bn £3.91bn £4.23bn
Raise the Universal Credit standard allowance by 10%: change in universal_credit £3.04bn £3.17bn £3.25bn £3.32bn £3.37bn £3.43bn £3.47bn
Raise the State Pension by 10%: change in state_pension £10.72bn £11.23bn £11.37bn £11.62bn £12.08bn £12.54bn £13.07bn

MaxGhenis and others added 5 commits October 20, 2026 18:11
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claims_all_entitled_benefits is now false for every family on data-built
simulations, and is still tested per family in hand-entered situations.

Main summed the seven reported benefits over the whole simulation, so on
survey data the flag was false everywhere. Tested per family on data, every
non-reporting survey family turned true. would_claim_CTC, _WTC and _IS read
the flag, and tax credits pre-minimum is gated only by take-up, so tax credits
leaked into CTR and HB means tests, tax credit awards and the 2024 Winter Fuel
Payment benefit test (review r6). The gate sits in the flag, so every reader
keeps main's survey value, and a dataset-supplied flag still overrides it.

Tests: review r6's MOCK reproducer, which fails on 94d5ebe; a property test
that on data every take-up flag reading the flag equals the family's own
report, and every downstream output equals explicit reported-only take-up;
the microdata test now checks main's survey value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clean merge. The only file both sides changed is
test_benefit_cap_specified_benefits_properties.py: this branch's
capped_family claim flag and main's three LCWRA wrapper tests touch
separate hunks, and both are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both properties now suppress Hypothesis's too_slow check, as most of the
repo's property tests do. On this host at load 170-240, one draw stalled for
4.9 s in the CTR property and one for 11.8 s in the tax credit property,
between simulations. The check allows 30 s over the first ten inputs. Every
example and every other check is kept.

Round 7 saw the CTR property fail once in a parallel batch, and no traceback
was printed. That run's cause cannot be recovered, so this removes one
measured candidate rather than a confirmed one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Hand-off from the UK hub build job (round 7b): head 928a82d7dd5a5cf370760c8b625cbc4b7b3f7915

Pushed 94d5ebe32..928a82d7d as a fast-forward. No history was rewritten.

  • f56cfc50c (round 7) fixes r6's tax credit leak. claims_all_entitled_benefits is false for every family on data-built simulations, which is main's survey result, and is tested per family in hand-entered situations. It also adds the reproducer test_data_built_nonreporters_get_no_tax_credits and the property test_data_built_takeup_equals_reported_only.
  • 97bc6b874 merges main 9d81a5dfa. The merge is clean, and no merged commit changes the flag or its five would_claim_* readers.
  • 928a82d7d makes both take-up properties suppress Hypothesis's too_slow check only.

CI at the head: all 17 checks pass, including Python shards 1–5, YAML and Fix evidence. Aggregate impact against main 9d81a5dfa for 2025-26 to 2031-32 shows no change in any year.

Impact for 2024–2026 (round 7, certified 1.58.1): all 32 vectors are byte-identical to main in each year. In 2024, tax_credits is £155.975m, back from r6's £6,150.836m. The impact was not rerun, because the merge does not touch take-up.

Reproducer: this round re-ran it against a git archive of 94d5ebe32. It fails there with the data-built flag [True, True, False], and passes at the head.

Flaky test (test_ctr_is_zero_for_every_nonreporter_without_an_explicit_claim_flag): it did not fail in any run this round. At host load 34–240 the module does not fit one 10-minute foreground call, so each run was split into timed pieces:

  • Serially at the head: the CTR property passed 30 generated + 2 explicit inputs, the tax credit property passed 10 + 2, and the other 17 tests passed.
  • Three -n 4 runs at the head: each split the properties' generated inputs into seeded slices of the committed test (32 CTR and 12 tax credit inputs per run, plus the explicit examples), alongside the module's other tests. All passed: 96 + 36 generated inputs and 51 example tests.
  • Earlier, at 97bc6b874: both properties passed alone, serially.

The cause of round 7's single failure can't be recovered, because its traceback was never printed. With deadline=None, Hypothesis's too_slow check fails a test when input draws over its first 10 inputs exceed 30 s, and fails it without a counterexample. Measured on this host with GC excluded, single draws stalled for up to 9.6 s (CTR) and 17.5 s (tax credit) under -n 4. 928a82d7d therefore suppresses only that check, as 123 of the repo's other 150 Hypothesis test files do. That removes a measured candidate, not a confirmed cause.

Other checks: ruff format --check passes. 932 YAML cases pass in round 7's directories, including CTR, HB, IS, tax credits, WFP and PAWHP. The fix-evidence checker passes on the updated body.

Open for the hub:

  1. The independent final-head review at 928a82d7d. None was run in this job.
  2. Check policyengine.py's budget-contract one-row datasets (2025 and later) against the one intended data-built difference: a dataset in which no family reports any of the seven benefits.
  3. A follow-up issue, not filed and not found by search. child_tax_credit_pre_minimum and working_tax_credit_pre_minimum are defined_for take-up only. This is main's behaviour, not this PR's change.
  4. core#627 (open) for the four unsupported overwrite routes.

The PR body is updated. Evidence is in the job's .job/ folder: HANDOFF.md, PROGRESS.md, and flaky/ logs with Hypothesis observability summaries.

@MaxGhenis
MaxGhenis added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 025887b Oct 22, 2026
19 checks passed
@MaxGhenis
MaxGhenis deleted the claims-all-per-benunit branch October 22, 2026 12:12
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Merged by the UK hub (session local_8e19f9d5, Opus 5.5) as 025887b8f at 12:12Z on its merge gates (adopted under d1280). One merge-queue enqueue, pinned to head 928a82d7dd5a5cf370760c8b625cbc4b7b3f7915.

  • Change: claims_all_entitled_benefits is evaluated per benefit unit in hand-entered situations, and is false for every family on data-built simulations. That keeps the reported-only take-up defaults on survey data and closes review r6's P1, a 2024 tax-credit leak of £156m → £6,151m.
  • Review: GPT-6.1 Sol r8 APPROVE at this exact head (~/reviews/uk-hub/reviews/uk1831/REVIEW_1831_R8.md). It verified the reproducer against 94d5ebe32 and confirmed suppressing HealthCheck.too_slow is legitimate. Its one P3 (input-line counts in the body) is corrected.
  • Tests: 39 take-up and provenance tests, 932 YAML cases, ruff clean; 17/17 checks. The merge queue re-tests against current main.
  • Impact: none in 2025-26 to 2031-32 (Aggregate impact on certified eFRS 1.58.1); all 32 vectors match main in 2024–2026.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Evaluate claims_all_entitled_benefits separately for each family

2 participants