PolicyEngine / PolicyEngine/policyengine-scorecard

Forcing take-up ON zeroes housing_benefit_pensioners — the fullpart denominator is unusable until this is resolved

Open
#128 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
0
Forks
0
Avg merge
6d 12h
Merged PRs (30d)
32

Description

Found by the first real UK compute run (#127, toward #76), on the certified populace-uk-2023-dd68c73-4aa4b14-20260619T023711Z artifact at policyengine-uk 2.89.2.

What happened

compute_uk_counterparts.py runs two sims: baseline (calibrated take-up) and fullpart (take-up forced on, to give the entitled-population denominators the DWP take-up counterparts need). The pipeline's own invariant then aborted:

forcing take-up ON made these values FALL, which is impossible for a
take-up denominator and is how a receipt-gated benefit reads as healthy:
  housing_benefit_pensioners  recipient_count    380,069.49 -> 0.0
  housing_benefit_pensioners  benefit_spending   £2,623,951,195.87 -> 0.0
Do not publish this run.

14 of 30 take-up-sensitive values rose as expected. This one didn't just fail to rise — it went to exactly zero.

Why it matters

The whole point of the fullpart run is to produce entitled denominators so a take-up rate can be computed as recipients / entitled. A denominator of zero does not produce a wrong rate; it produces an undefined one. And the failure mode the guard names is the dangerous version: if this had been left unchecked, a receipt-gated benefit would read as healthy rather than broken.

So no UK take-up counterpart involving pensioner housing benefit can be published until this is understood.

Likely mechanism (hypothesis, not verified)

Forcing would_claim_* / claims_all_entitled_benefits on plausibly migrates pensioner households onto Universal Credit, so the legacy pensioner housing-benefit population empties. If so the zero is arithmetically correct for the world the override creates — and the problem is that the override creates the wrong counterfactual for this benefit, not that the engine miscomputes.

That would make it a question about what fullpart should mean for legacy/UC-overlapping benefits, not a bug to patch. Note the other legacy benefits in the same run (jsa, esa_income, housing_benefit_pensioners) all show 0/1 — they did not rise either. universal_credit shows 1/1. That pattern is consistent with the migration hypothesis and is the first thing to check.

What needs deciding

  1. Confirm or reject the migration hypothesis by inspecting which override flags are set for pensioner HB and where the population goes.
  2. Decide the contract: does fullpart force take-up per benefit (holding legacy/UC routing fixed), or does it force the whole entitlement cascade? The current override does something closer to the latter, and the take-up denominators need the former.
  3. Whichever way, keep the guard. It did its job — this is the run it existed for.

Not blocked on

#127 (the compute route) is independent and honest about this: it publishes nothing, and data/pe/ carries no UK artifact. UK coverage stays at 14 results.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with compute_uk_counterparts.py and the certified UK artifact from the first compute run. Inspect which override flags apply to pensioner housing benefit and where affected households move, then compare the legacy benefits with universal_credit. Done means the migration hypothesis is confirmed or rejected, the fullpart contract is decided, and the existing guard remains in place.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.