Skip to content

Certified UK artifact carries less than half of admin UC caseload (3.26m vs ~6.7m; £36.9bn vs £75.8bn) #701

Closed as not planned

Description

@MaxGhenis

Summary

The certified UK national artifact under-represents Universal Credit badly: the release policyengine.py is currently re-certifying (populace-uk-2023-dd68c73-4aa4b14-20260619T023711Z) measures 3.26m UC benefit units and £36.9bn UC spend at 2025, against ~6.7m households (2025 average, DWP) and £75.8bn (OBR). The prior certified default (72aeefc-20260611) measures 2.17m and £24.0bn. The 148-target surface those builds calibrated to does not bind UC, so the June rotation wins against enhanced FRS were scored on a surface blind to benefits fidelity.

This is the same defect family just diagnosed in policyengine-uk-data#452 (see the diagnosis comment there), where it is partially fixed: enhanced FRS ≥1.56.6 reaches 6.40m/£77.6bn. Microcosm UK is now the least accurate of the three artifacts on UC.

Measurements

Weighted benefit units with universal_credit > 0 at 2025, policyengine-uk 2.90, annual basis (aggregates only):

artifact UC benefit units UC spend
populace_uk_2023 @ 72aeefc-20260611 (prior certified default) 2.17m £24.0bn
populace_uk_2023 @ dd68c73-20260619 (current certification candidate) 3.26m £36.9bn
enhanced FRS 2023/24, uk-data v1.40.x era 4.19m £51.3bn
enhanced FRS 2023/24, uk-data v1.56.14 (latest) 6.40m £77.6bn
administrative / OBR ~6.7m (2025 avg) → 7.17m (Dec 2025–Feb 2026), DWP deductions statistics Table 1 £75.8bn (OBR)

Downstream stakes: reform aggregates scale with this caseload. The UC deductions module (policyengine-uk#1815, WPI Economics and JRF-style floor analyses behind it) validates per household but inherits the caseload for every count and cost; on the current certification candidate those aggregates run less than half of admin.

Proposal: UC as the next bound family

The dense/local lane (#495) already named "an independent bound family (UC counts)" as the prerequisite for trusting the K=2 candidate. The national surface needs it first:

  • UC caseload targets (benefit units with any UC, by year): 2025 ≈ 6.7m, 2026 ≈ 7.2m. Derivable from the DWP deductions statistics Table 1 (households with a deduction ÷ published share, monthly Mar 2025–Feb 2026) — the derivation and monthly series are in the policyengine-uk-data fix PR referenced from Dense-arm SSI swap runaway cap at 0.12 × fresh national (#447) #452, which adds the same target there as dwp/uc/households.
  • UC expenditure counterpart (OBR welfare table, £75.8bn 2025-26) — the Scorecard doctrine's OBR-counterpart target; uk-data's stack already carries it and binds at 1.56.6+.
  • Chronicle looks like the right home for the source facts (DWP Stat-Xplore / deductions statistics package), with the surface consuming a target profile, but I'll defer sequencing to the active UK campaign (input-coverage contract, HMRC restoration, FRS spine) rather than propose where it slots.

Happy to implement the source facts and target wiring if useful — the measurement scripts and derivations are reproducible from the #452 thread.

Activity

  1. MaxGhenis commented on Aug 17, 2026

    @MaxGhenis
    ContributorAuthor

    Seam analysis before implementing this — conclusion: the right home for each piece already exists or is owned, so this lands as a hand-off rather than a parallel build.

    Where each piece belongs:

    • Facts → the DWP monthly series belongs alongside the uk_national profile work in chronicle#164 rather than a competing package. Ready to drop in, verified against the staged gov.uk tables: UC benefit units (DWP "households on UC" = benefit units, point in time, derived as deducting households ÷ published share from the deductions statistics Table 1): Apr 2025 6.38m; May–Aug 2025 6.60m; Sep–Nov 2025 6.96m; Dec 2025–Feb 2026 7.17m. OBR UC expenditure counterpart: £75.8bn 2025-26.
    • Consumption seam → Consume Ledger UK facts: uk_target_references, mapping module, and a compile-parity gate #622 (Chronicle references/profile consumption/parity gate) and Calibrate the UK national build from Ledger-backed targets #623 (the missing UK national calibration seam) are exactly where these targets plug in; the rowwise path today binds only the local census-household family. Consume Ledger UK facts: uk_target_references, mapping module, and a compile-parity gate #622's no-silent-gaps requirement already covers the policyengine-uk-data#456 defect class — good.
    • Operations → the profile machinery currently supports identity fact operations only. The two targets need three declared operations: calendar-year average (2025 ≈ 6.7m), latest-plateau selection (2026 ≈ 7.2m), and component sum (if the OBR fact arrives split). These look like early entries for the spec-engine operation vocabulary (RFC: the spec engine — schema for full spec-drivenness (review before build) #698) rather than one-off code.
    • Targets (once the seams land): UC caseload = sum of a UC-receipt indicator at benefit-unit level; UC expenditure = sum of universal_credit. Sums only, entity-explicit — DWP "households" are benefit units, so this avoids the dwellings-vs-households class from policyengine-uk-data#457.

    One question for the calibrate owners: the current loss is capped weighted MAPE with fixed row scales (packages/microcosm-calibrate/src/microcosm/calibrate/solve.py:448-493, scales max(abs(target), 1)). Does the cap flatten gradients for large misses the way policyengine-uk-data#456 documents for its bounded torch.min loss? A UC target starting at 0.45× of truth needs pull throughout the range, not just near the target.

    Happy to turn the facts into a stacked contribution on chronicle#164 or a follow-on PR the moment #622/#623 land — the derivation, source CSVs, and measurement scripts are all reproducible from the policyengine-uk-data#452 thread. Full seam map available on request.

  2. MaxGhenis commented on Aug 17, 2026

    @MaxGhenis
    ContributorAuthor

    Answering my own loss question from the seam comment, after computing the profile: no #456-class defect here.

    relative_error_loss is min(|estimate − target| / max(|target|, 1), cap) with _DEFAULT_TARGET_LOSS_CAP = 10.0 (solve.py:128). Two properties settle it:

    • An undershoot of a nonnegative estimate has scaled miss ≤ 1.0 (maximum at estimate = 0), so it can never reach the cap — a UC target starting at 0.45× of truth keeps full, constant-magnitude gradient the whole way in.
    • The clip only engages beyond an 11× overshoot, where it functions as a guard rather than a shaping term. And unlike uk-data's torch.min sre, the L1 form's gradient does not decay with distance below the cap.

    So the two targets proposed here will pull correctly under the existing loss once the #622/#623 seams land — no calibrate changes needed for this issue.

  3. vahid-ahmadi commented on Aug 20, 2026

    @vahid-ahmadi
    Contributor

    Connecting the #727/#184 review thread to the operations analysis above, because your own monthly figures put a number on what the unresolved basis costs.

    With chronicle#184 merged, the DWP series resolves through _latest_period_selector_match — eligible facts at or before the reference period, then latest wins. Against your listed series (Apr 2025 6.38m; May–Aug 6.60m; Sep–Nov 6.96m; Dec 2025–Feb 2026 7.17m), that means:

    So the gap between "the basis we meant" and "the basis the resolver picks" is roughly 6% on the very target meant to close a −52% caseload miss — and it lands as a default rather than a decision. That's the concrete case for the calendar-year-average operation being a blocking dependency rather than a nice-to-have: allowed_value_operations is ["identity"] today, so the contract literally cannot express the average, and the identity path silently resolves to the December plateau instead of failing closed the way an unrepresentable basis should.

    Two things that would keep this from being rediscovered as an unexplained calibration residual:

    1. Treat RFC: the spec engine — schema for full spec-drivenness (review before build) #698's calendar-year-average operation as the gate on activating dwp.uc.households, not on refining it — until it exists, the honest states are inert (today) or explicitly month-pinned with a note saying December was chosen deliberately.
    2. When the operation does land, the latest-plateau selection you also named (2026 ≈ 7.2m) and the calendar-year average differ by the same ~6% for the same reason, so whichever the calibration binds should carry its basis in the declaration — the two are easy to confuse precisely because both are defensible.

    Agreed with your boundary call on chronicle#184, by the way — turning a published monthly stock into an annual figure would have put consumer semantics in the facts layer, which is exactly what the #166 ruling took out of Chronicle. The basis belongs here; it just needs the vocabulary to say it.

  4. juaristi22 commented on Sep 9, 2026

    @juaristi22
    Collaborator

    Closing as superseded by #882. The missing UC caseload bindings are repaired; expenditure comparability and certified consumer acceptance are explicitly carried forward in the scope-transfer note. This closure consolidates the remaining work and does not claim a passing certified replacement.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions