Skip to content

Add UK source packages for #251 and #253: UC payment indicator × child entitlement crosses (April 2023 to May 2026) and Scotland's council-area household total on the households spec - #252

Merged
juaristi22 merged 4 commits into
mainfrom
issue-251-uc-payment-child-entitlement-crosses
Sep 9, 2026
Merged

Conversation

@juaristi22

@juaristi22 juaristi22 commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add two DWP Stat-Xplore UC_Households source packages, Great Britain, monthly April 2023 to May 2026 (38 months, the latest month in DWP's 18 August 2026 quarterly release), for the joint distribution that the Add UK source packages for #233–#237: UC child-entitlement and nil-award crosses, award-band and Scotland histories, ONS family tables, HMRC Child Benefit, census household composition #239 pairwise crosses cannot identify:
    • dwp-uc-households-family-type-payment-indicator-child-entitlement-april-2023-may-2026: Family Type × Payment Indicator × Child Entitlement, 760 facts (benefit_units).
    • dwp-uc-households-children-payment-indicator-child-entitlement-april-2023-may-2026: Number of Children × Payment Indicator × Child Entitlement, 1,216 joint facts (benefit_units) plus DWP's own Total over Child Entitlement per (month, number of children, payment indicator), 608 facts under the distinct total_benefit_units measure with child_entitlement: all and table_record_kind: total. The Total is the publisher's total: true recode item, not a sum of the joint cells.
  • The observation window extends the issue's April–December 2025 request to April 2023 onward, per the maintainers' direction on 2026-09-08. DWP flags June 2024–February 2026 as revised (r) and March–May 2026 as provisional (p) in this extract; both markers are archived in the response bytes and pinned by a test.
  • Archive the exact request and response: the API echoes the submitted query (database, measure, month and value URIs, total flags) inside the response bytes, which are stored verbatim, sha-pinned in the manifests and uploaded to ledger-raw (raw/uk/dwp/…). Both Yes/No categories, all five family types (including Unknown or missing family type), all eight child-count categories (including Unknown or missing and Not available prior to April 2019) and every literal publisher zero are preserved; no cell is suppressed in the returned cubes, so no row is omitted. DWP's Number of Children axis keeps its publisher meaning (verified declared under-20s), not qualifying children.
  • Requested-versus-returned coverage is checked by a test that compares the echoed recodes and month list against the returned field items and manifest digest. Contemporaneous margins reconcile within disclosure control: |Total − (No + Yes)| ≤ 8 across all 608 triples; the joints re-aggregate to the three Add UK source packages for #233–#237: UC child-entitlement and nil-award crosses, award-band and Scotland histories, ONS family tables, HMRC Child Benefit, census household composition #239 pairwise packages over the nine overlapping months within 6, 9 and 7 households (both extracts sit inside the same DWP release). No source value is rewritten.
  • Rebased over Add UC family type totals from 2023 #250: the 27 April–December months of 2023–2025 in DWP's family-type history overlap the new family-type cross, and summing its four payment × child-entitlement cells per family type lands on each published detail cell within 11 households (135 cells), under the same 15-household tolerance Add UC family type totals from 2023 #250 applies; the published Total is not compared.
  • UK local household counts: file Scotland's council-area total under the households spec, not the tenure spec #253, in the same PR: Scotland's 32 council-area all-occupied-households cells from the pinned NRS Census 2022 UV404 export are filed a second time as the nrs.census2022.uv404.council.households record set on uk.local_geography.households.by_local_authority.v1, mirroring the NRS constituency leg (domain household_count, geography groupby, the publisher's All occupied households row label kept as the evidenced filter). Same artifact, rows, guards and values; the household_count domain keeps the fact and semantic keys distinct from the tenure filing. A consumer now resolves all 361 UK local authorities from one spec, as it already does for the 650 constituencies. No new download, no value change, no reconciliation between legs or grains.
  • No identity migration: no existing fact changes; the NRS tenure package gains a record set and the NISRA package a comment. Vocabulary is unchanged (dwp.uc_benefit_units / dwp.uc_households, benefit_unit, K03000001, period.type: month, filter keys family_type / number_of_children / payment_indicator / child_entitlement).

Chronicle governance

  • Approved Chronicle agent role: ledger-source-ingestor
  • Deterministic checks run:
    • Source-package validation: PASS — 38 record sets / 760 source-backed facts (family type) and 76 record sets / 1,824 source-backed facts (number of children), 0 errors, 0 warnings.
    • Source-cell preservation: committed JSON bytes match the archived responses byte-for-byte; sha256 pinned in manifest and R2 metadata.
    • Consumer-contract validation: PASS — 1,976 detail facts and 608 published Total facts validate; lineage coverage 1.0 and one linked raw R2 artifact per package.
    • Raw-facts boundary validation: Chronicle stores publisher values without aging, imputation or reconciliation; reconciliation exists only as tests.
  • Agent acceptance: valid: true, row_semantic_error_count: 0 for both packages (build-suite).
  • LLM judge verdicts:
    • ledger-source-fidelity: PASS — every emitted value resolves to a cell of the archived response; all 2,584 facts carry source-row and source-cell lineage.
    • ledger-boundary: PASS — the publisher Total is DWP's own total: true item; the margin and pairwise reconciliations exist only as tests and emit no computed fact.

Consumer note

Binding, averaging and any use of the longer history stay in microcosm (#882, PR #883); microcosm's 111 UC references pin exact dimension sets, so none of them can pick up the new three-dimension facts.

Tests

  • uv run chronicle validate-package <alias> --year 2025 for both aliases: valid, 0 errors, 0 warnings (38 record sets / 760 facts; 76 record sets / 1,824 facts).
  • uv run chronicle build-suite <alias> --year 2025 --out … --replace for both: zero stage errors, lineage coverage 1.0, agent acceptance valid with row_semantic_error_count: 0.
  • uv run pytest -q tests/test_dwp_uc_composition_source_packages.py tests/test_source_package_alias_drift.py tests/test_chronicle_suite.py: 43 passed.
  • uv run chronicle validate-package nrs-census2022-uv404-tenure-council-area --year 2022 and its build-suite: 10 record sets / 320 facts, 0 errors, agent acceptance valid with row_semantic_error_count: 0.
  • uv run pytest -q tests/test_uk_local_household_count_legs.py: 3 passed (361 local authorities and 650 constituencies on one spec each; Scotland's 32 cells identical to the tenure filing, sum 2,509,275; 64 distinct fact keys).
  • uv run pytest -q tests/test_chronicle_source_package.py -k 'provenance_class or dwp': 9 passed.
  • uv run pytest -q --ignore=tests/test_chronicle_bundle.py: 866 passed, 1 skipped.
  • uv run pytest -q tests/test_chronicle_bundle.py::test_build_bundle_writes_merged_consumer_contract: 1 passed (bundle 195,193 facts on top of Add UC family type totals from 2023 #250, 169 packages, 164 tables, 177 semantic duplicates and 269 periods unchanged).
  • uv run ruff check: clean; the four modified Python files pass ruff format --check (nine untouched test files fail the repo-wide format check on main as well); git diff --check: clean.

Fixes #251, fixes #253

🤖 Generated with Claude Code

juaristi22 and others added 3 commits September 8, 2026 18:48
…to May 2026

- Two Stat-Xplore UC_Households source packages for chronicle#251, Great
  Britain, one record set per month from April 2023 through May 2026, the
  latest month in DWP's 18 August 2026 quarterly release (the window
  extends the issue's April-December 2025 request at the maintainers'
  direction): family type × payment indicator × child entitlement (760
  facts) and number of children × payment indicator × child entitlement
  (1,216 joint facts).
- The children cube was requested with total: true on the child-entitlement
  recode, so DWP's own Total over child entitlement lands as 608 further
  facts under the distinct total_benefit_units measure, table_record_kind
  total and filters child_entitlement: all, in a .total record set per
  month. Chronicle never sums the joint cells; the Total row omits an
  '== all' constraint because its source column carries the publisher
  label 'Total', which the guard cell pins instead.
- Raw API responses are archived verbatim (the query is echoed inside
  them), sha-pinned in the manifests and uploaded to ledger-raw under
  raw/uk/dwp/. All publisher categories, including the unknown and
  not-available tails and literal zeros, are preserved; no cell was
  suppressed, no month is missing, and no category code changed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Register both aliases in SOURCE_PACKAGE_ALIASES and the sorted
  UK_BUNDLE_SOURCES; add their validate-package/build-suite pairs to the
  harness doc and extend the UC family-type row of the UK source checklist
  (fact counts, the publisher-emitted margin, the r/p revision markers).
- Tests pin the 38-month window, every publisher category and literal
  zero, sample cells at April 2023, April 2025 and May 2026, the echoed
  query against the returned field items and manifest digest, the
  publisher Total as a margin (|Total - (No + Yes)| at most 8), the
  re-aggregation to the three #239 pairwise cubes over April-December 2025
  (gaps at most 6, 9 and 7 within the 15-household disclosure tolerance)
  and agent acceptance with zero row-semantic errors.
- Bundle pins move by the 2,584 new facts (+68 per month for each of the
  38 months); the semantic-duplicate count and period count are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- After rebasing over #250, the 27 April-December months of 2023, 2024
  and 2025 overlap the new cross: summing its four payment x
  child-entitlement cells per family type lands on the published detail
  cell within 11 households (126 of 135 cells differ, disclosure control),
  under the same 15-household tolerance #250 applies. The published Total
  is not compared and no fact is emitted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ouseholds spec

- chronicle#253: the 32 all-occupied-households cells of the pinned NRS
  Census 2022 UV404 council-area export are filed a second time as the
  nrs.census2022.uv404.council.households record set on
  uk.local_geography.households.by_local_authority.v1, mirroring the NRS
  constituency leg (domain household_count, geography groupby, the
  publisher's 'All occupied households' row label kept as the evidenced
  filter). Same artifact, same rows, same guards, same values; the
  household_count domain keeps fact and semantic keys distinct from the
  tenure filing, so nothing collides and nothing is reconciled.
- A consumer now resolves all 361 UK local authorities (296 + 22 England
  and Wales, 11 Northern Ireland, 32 Scotland) from one record-set spec,
  as it already does for the 650 constituencies; tests pin both covers,
  the cell-for-cell identity with the tenure filing and the 2,509,275
  Scotland total. The NISRA header and the UK source checklist drop the
  stale 'a second Scottish package would collide' note.
- Bundle pins move by the 32 facts (nrs, calendar_year:2022, household).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juaristi22 juaristi22 changed the title Add UK source packages for #251: UC payment indicator × child entitlement crosses, April 2023 to May 2026 Add UK source packages for #251 and #253: UC payment indicator × child entitlement crosses (April 2023 to May 2026) and Scotland's council-area household total on the households spec Sep 8, 2026
@juaristi22
juaristi22 marked this pull request as ready for review September 9, 2026 08:28

@vahid-ahmadi vahid-ahmadi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review at fee140f8 (Claude Code, high effort; fresh checkout, full suite: 884 passed, 1 skipped, exit 0 — 17 more than the body's 866 because the bundle test runs here and passes; validate-package on all four touched packages: 0 errors, 0 warnings; ruff check clean at the locked 0.14.10; both artifact shas and sizes match the manifests and are enforced at build).

What checks out

  • Facts are the raw cube cells exactly. Re-walking the [38, 5, 2, 2] and [38, 8, 2, 3] cubes against build_facts(2025) gives 760 of 760 and 1,824 of 1,824 with zero mismatches; the children package splits 1,216 detail benefit_units and 608 total_benefit_units.
  • The Totals are the publisher's. The archived response echoes total: true on the child-entitlement recode and carries a third Total item with no URI; the total record sets sit on their own spec with table_record_kind: total, child_entitlement: all and a guard on the Total label, so a consumer pinning the two named values cannot pick them up. Chronicle sums nothing; the only sums are in tests. |Total − (No + Yes)| is at most 8 in every month.
  • The joints re-aggregate to #239's three pairwise packages over the nine overlapping months within 6, 9 and 7 households, as the tests pin, and the family cross re-aggregates to #250's 135 detail cells within 11.
  • Window and provenance. 38 contiguous months from 2023-04 to 2026-05, June 2026 correctly absent; the r markers on 2024-06 to 2026-02 and p on 2026-03 to 2026-05 are in the archived bytes and pinned exactly; extraction_method records the database, measure, the four field URIs in response order, the month range and the recode total flags, and the test asserts the echoed query equals the declaration. source_url is the REST endpoint, parity with #239.
  • Scotland (#253) is an additional filing, not a replacement: a new nrs.census2022.uv404.council.households record set on the households spec, byte-identical rows to the tenure block, 32 cells summing to 2,509,275 and asserted equal cell-for-cell; 361 local authorities and 650 constituencies now each resolve on one spec. The NISRA change is comment-only.
  • Bundle arithmetic is exact: +2,616 = 760 + 1,824 + 32, with the per-source, per-geography, per-entity and per-month deltas all consistent and no other package moved. The provenance-class line-count test is satisfied.

Question

The family cross's 20-cell monthly sum against #250's published GB Total is off by 16 in two months — October 2023 (−16) and December 2025 (+16), with the rest within ±14 — above the 15-household tolerance #250 quotes for its own Total-versus-detail check. The body explicitly declines that comparison and the test compares only the detail cells, which is the right choice; a 20-cell sum accumulating DWP's cell-level perturbation makes 16 plausible. I recomputed both months from the archived cube and #250's CSV and get the same figures. Worth one sentence in the family package header so the next reader does not treat it as a discrepancy.

Nits

  • Neither header mentions the two-child-limit repeal from 2026-04-06. DWP's definition of child entitlement is a child element in the award, so Yes/No is stable across the window and the repeal changes how many children are paid for, not whether the element exists; one line saying so would pre-empt the question.
  • The Totals carry no source_row_dimensions where #250's did — deliberate and correct here, since the unpivot parser puts each dimension label in the row and a declared all would be compared against the label Total and fail; the children header explains it.
  • tests/test_dwp_uc_composition_source_packages.py:663 uses a naive datetime.strptime, which trips DTZ007 on newer ruff only.

Could not verify

The R2 object at the manifest key, a live Stat-Xplore re-query (the echoed query block is the evidence), and microcosm's claim that its 111 UC references pin exact dimension sets.


Approving. The two crosses give microcosm the joint the pairwise packages could not, and every reconciliation the body claims reproduces.

@juaristi22

Copy link
Copy Markdown
Collaborator Author

@vahid-ahmadi Thanks for the review. Answering the question here rather than pushing; the three comment-only lines are queued for the next revision of these packages (the November 2026 DWP release extends the window), so the PR merges as reviewed.

Question — the 20-cell monthly sum against #250's Total

Reproduced: −16 in October 2023 and +16 in December 2025, the other 25 months within ±14. It is two disclosure-control layers compounding, not a discrepancy:

  • Per family type, the cross's four payment × child-entitlement cells re-aggregate to Add UC family type totals from 2023 #250's published detail cell within 11 (the pinned comparison). Summing those five per-family-type gaps gives the 20-cell-versus-detail gap, which reaches +21 in December 2025 and −17 in October 2023.
  • Add UC family type totals from 2023 #250's own five detail cells differ from its published Total by up to 11; in those two months by −5 and +1.
  • The 20-cell-versus-Total gap is the sum of the two: +21 − 5 = +16 and −17 + 1 = −16. In most months the layers partly cancel, which is why the rest sit within ±14.

The 15 in #250 is the observed bound of a five-cell comparison, not a publisher tolerance, so a 20-cell sum was never expected to meet it. The test therefore compares the finest published grain (the detail cells) and leaves the Total out deliberately; a sentence saying so goes in the family package header at the next touch.

Nits

  • Two-child limit removed from 6 April 2026. DWP's Child Entitlement records whether the award includes a child element at all; the limit capped the number of children the element was paid for, so the Yes/No split is stable across the window and the repeal moves the children-count and award-amount cubes, not this axis. Header line queued with the one above.
  • No source_row_dimensions on the Totals. Deliberate, as the children header records: the unpivot parser puts the Total label in the row's own column, so a declared all would be compared against that label and fail agent acceptance.
  • DTZ007. The repository's ruff configuration selects no DTZ rules (default rule set), so it does not fire at the locked 0.14.10 or on a newer ruff under this configuration; the parse will move to a timezone-aware form when the file is next edited.

@juaristi22
juaristi22 merged commit ec7169b into main Sep 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants