Skip to content

Count Scottish Child Payment, Healthy Start and the Two Child Limit Payment in government spending - #2366

Merged
MaxGhenis merged 1 commit into
mainfrom
gov-spending-scp-healthy-start-2338
Oct 12, 2026
Merged

MaxGhenis merged 1 commit into
mainfrom
gov-spending-scp-healthy-start-2338

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2338

What and why

scottish_child_payment, healthy_start_vouchers and two_child_limit_payment were in HOUSEHOLD_BENEFIT_VARIABLES but not in GOV_SPENDING_VARIABLES. Households received them, but government spending didn't count them, so gov_balance overstated the public finances by the amount paid.

The issue named the first two. two_child_limit_payment had the same gap. It is zero at baseline, because the regulations were not laid, but it is paid when a reform turns it on (gov.social_security_scotland.two_child_limit_payment.in_effect).

This PR adds all three to GOV_SPENDING_VARIABLES. It also adds a code-health test so the gap can't reopen: every household benefit must be in government spending, or on an explicit, documented NOT_PAID_BY_GOVERNMENT list, which is empty today.

Invariants

  1. Subset with exclusions. Every entry of HOUSEHOLD_BENEFIT_VARIABLES is in GOV_SPENDING_VARIABLES or in NOT_PAID_BY_GOVERNMENT with a reason (tests/code_health/test_household_benefits_in_government_spending.py). A third test there runs the checker on the old list and confirms it reports exactly the three.
  2. Sum identity. gov_spending equals the sum of the distinct GOV_SPENDING_VARIABLES.
  3. Balance identity. gov_balance = gov_tax − gov_spending.
  4. Conservation, at baseline. household_benefits − NOT_PAID_BY_GOVERNMENT = gov_spending − (spending that is not a household benefit: pawhp, other_public_spending_budget_change). "At baseline" means gov.contrib.benefit_uprating is at zero: household_benefits applies that lever and gov_spending doesn't, which predates this PR (see follow-ups).
  5. Metamorphic. Paying a household d more of any of the three payments raises household_benefits and gov_spending by d, lowers gov_balance by d, and leaves gov_tax unchanged.

Invariants 2-5 are Hypothesis properties in tests/test_gov_spending_properties.py. Power: on the old list, the code-health test, both YAML cases (tests/policy/baseline/gov/gov_spending.yaml) and both properties fail. On this branch they pass.

Impact

Real run, 2026, one Microsimulation each. Both runs use the certified enhanced FRS: uk-data 1.58.0, enhanced_frs_2024_25.h5, HF revision 47bbb58d, sha256 5ba399ea…d960b6, verified at load. Main is 3f174d0; this branch is b0e8fb1, a clean tree. The runs went through the heavy lock, one at a time. Script and outputs: ~/reviews/uk-statutory-pay-gov-spending-2026-10-12/ (impact.py, compare.py, runs/).

2026, £bn Main This branch Change
gov_spending 552.208 552.782 +0.574
gov_balance 469.236 468.662 −0.574
universal_credit 83.589 83.589 0
household_benefits 552.579 552.579 0
household_net_income 1,710.908 1,710.908 0
gov_tax 1,021.444 1,021.444 0
  • What the +£0.574bn is. The Scottish Child Payment is £0.520bn and Healthy Start £0.054bn. The Two Child Limit Payment is nil at baseline. In every household, the change in gov_spending equals the sum of the three payments, to within half a penny. This re-measures the issue's ~£0.57bn.
  • Who it reaches. 394 sample households (386k weighted) see gov_balance fall. No household's income changes.

Tests run

  • New: code-health 3 passed; gov_spending.yaml 2 passed; properties 2 passed (45 s). test_aggregation_lists.py passed.
  • CI at this head: all six checks pass. That includes Test, which runs the microsimulation reform-impact fixtures with the HF token.

Review

GPT-6.1 Sol (subfleet run --task review --tier hard) approved head b0e8fb1 with no blocking findings. The review is at ~/reviews/uk-statutory-pay-gov-spending-2026-10-12/review/out_2366.md. It checked the following:

What I did with its non-blocking notes:

  • Invariant 4 only at baseline: qualified above, and a follow-up session is proposed to make gov_spending apply the uprating lever.
  • Cross-test import: left, to keep the approved head. There is precedent in test_state_pension_credit_qualifying_age.py.
  • Healthy Start in Scotland is Best Start Foods: noted. It is government-funded either way.

Interactions

Ownership: no W1 or W3 file is touched.

axiom: n/a: government-spending accounting lists for microsimulation aggregates, not a policy rule.

🤖 Generated with Claude Code

Reproducer: policyengine_uk/tests/code_health/test_household_benefits_in_government_spending.py::test_every_household_benefit_is_government_spending_or_excluded, policyengine_uk/tests/code_health/test_household_benefits_in_government_spending.py::test_exclusions_are_household_benefits_outside_government_spending, policyengine_uk/tests/code_health/test_household_benefits_in_government_spending.py::test_the_check_reports_a_benefit_left_out_of_government_spending, policyengine_uk/tests/policy/baseline/gov/gov_spending.yaml::Scottish Child Payment and Healthy Start vouchers are government spending, policyengine_uk/tests/policy/baseline/gov/gov_spending.yaml::The Two Child Limit Payment is government spending when a reform turns it on, policyengine_uk/tests/test_gov_spending_properties.py::test_government_spending_counts_every_benefit_government_pays

…ayment in government spending

HOUSEHOLD_BENEFIT_VARIABLES listed scottish_child_payment,
healthy_start_vouchers and two_child_limit_payment, but
GOV_SPENDING_VARIABLES did not, so households received them at no cost to
the government and gov_balance was overstated by the amount paid.
two_child_limit_payment is zero at baseline (the regulations were not
laid) but is paid when a reform turns it on.

Adds a code-health test that every household benefit is in government
spending or on an explicit, documented NOT_PAID_BY_GOVERNMENT list (empty
today), YAML cases, and Hypothesis properties: gov_spending is the sum of
its list, gov_balance = gov_tax - gov_spending, household benefits equal
government spending on households, and a pound more of each payment is a
pound more spending and a pound less balance.

Fixes #2338

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

MaxGhenis commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator Author

Hand-off to the UK hub from session local_615fdd79-8fa2-4544-b8ce-67188d179ad6 (started by the UK hub).

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

UK hub (2026-10-12): this PR's head b0e8fb179 is merged unchanged into rollup B, #2380, with #2365, #2366 and #2375. Its one CI run tests all three together on current main. Merging #2380 with a merge commit marks this PR merged. The hub cancelled this PR's own queued runs, which the rollup replaces, to free slots in the starved Actions queue. Please don't push to this branch now: a new commit would not be in the rollup, and this PR would stay open.

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.

Scottish Child Payment and Healthy Start are household benefits but missing from government spending

1 participant