Campaign-UK staging producer: archive -> resolved claim-id joins + 14 reckoner attaches - #72
Merged
Conversation
The adjudicated replacement for #32's campaign-UK ingester: a deterministic producer that resolves the frozen 2026-08-02 UK campaign staging against the ingested claims instead of loosening the match contract. Chain (every step closed, raises on 0/2+): archived row construction -> executed uk_run -> t2-collation HMRC change label -> exactly one uk_hmrc reckoner claim -> the strict {claim_id} match form. hmrc_reckoner_t2 resolves (14 rows, collation hints verified equal to DB option strings character-for-character). free_joins (OBR receipts = pe-uk-data calibration surfaces, claims not staged), obr_measures (OBR costings DB, long-tail held), two_child + uprating (Resolution Foundation, long-tail held) are blocked-with-reasons in the module; a new archive family without a disposition fails the produce. ingest_campaign __main__ gains the staged_dir argument it already accepted programmatically. DB ingest deliberately NOT in this commit — it lands after #52 merges so the committed DB advances linearly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mmitted DB produce_campaign_uk resolved all 14 hmrc_reckoner_t2 rows to claim ids (collation hints == DB option strings verbatim) and ingest_campaign attached them: run_id campaign-20260802-reckoner-t2, engine 2.89.2 on the certified populace-uk-2023-dd68c73 bundle, all status constructed. Every result executed a PE current-law baseline while the claims score against hmrc_indexed_baseline_spring_2025 — the cross-baseline view guard holds all 14 at pe_status_effective='constructed', which is the truth of the comparison (PE CY2026 static accrual vs HMRC projected FY direct effects). populations.json regenerated: 270 -> 284 rows (the exporter includes every non-Urban claim with a result). Consistency pins updated deliberately: the provenance pin now lists both country bundles, and the idempotency test gains the stronger property the UK family makes testable — a US re-ingest must leave the UK run's rows untouched (deletion is scoped to staged run_ids). Suite: 235; committed DB byte-stable across the suite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sol's round-1 blocker: the BLOCKED reasons generalized each archive family from its first row. Re-tallied against the frozen archive (verified independently): free_joins = 7 obr revenue_level + 7 uk_dwp benefit_cost + 2 metaless exhibits (the uk_dwp half — DWP benefit- expenditure forecast lines — was omitted entirely); obr_measures = 9 + 1 metaless exhibit; two_child = 2 RF + 1 ukmod poverty_count_change (a REFORM claim — the staged UKMOD family is baseline statistics only) + 1 metaless exhibit; uprating unchanged. Reasons rewritten per-row; two new tests pin the exact compositions AND that every blocked target shape has zero DB claims — a re-frozen archive or a future source staging forces the deliberate re-disposition instead of a silent one. Also the two stale docs: ingest_campaign now describes the uk_resolved flow instead of claiming the UK has no DB ingest; the populations- export docstring names the uk_hmrc reckoner rows among its populations. Suite: 237; committed DB byte-stable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t_meta Sol's round-2 items: - The docstring said 4 metaless exhibits; the per-row total is 5 — free_joins' pair is one construction duplicated. Verified against the archive before rewording. - The composition tally classified "metaless" by missing external_claim_match, never checking the DEFINING property: a refreeze adding exhibit_meta would keep the guards green while making the row ingestible. Meta-bearing exhibit rows now tally under their own key, so that refreeze changes the pinned dicts and forces the re-disposition. - The populations export note (emitted into populations.json) named only the US campaign sources; it now names the UK reckoner family, and the artifact is regenerated (note only — 284 rows unchanged). Suite: 237; committed DB byte-stable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Aug 20, 2026
Rebase completion (the branch forked before the whole UK arc — #43-#48, #52, #71, #72 all landed under it): - uk-deductions-frr (merged today, unknown to this branch) was the one committed lane without a country tag -> UK. - The UK ingests' appended lane metas now carry country explicitly (ingest_uk_externals' five lanes + ingest_uk_deductions' one), so a fresh-feed append passes the new sync_lane_feed guard and never files a UK lane under the app's missing-key US default. - app/public/data copies refreshed from data/ (they had drifted to a 270-row populations.json vs 284) and pinned: new test asserts the committed copies byte-match data/, and a second asserts every committed lane carries US|UK — the two drift classes this rebase surfaced. Suite: 241 python + 3 bun; oxlint + vite build clean; committed DB byte-stable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The adjudicated replacement for #32's campaign-UK ingester (see #32's closing
comment): a deterministic producer that resolves the frozen 2026-08-02 UK
campaign staging against the ingested claims instead of loosening the match
contract.
Chain (every step a closed lookup, raises on 0/2+): archived row construction
-> executed uk_run -> t2-collation HMRC change label -> exactly one uk_hmrc
reckoner claim -> ingest_campaign's strict {claim_id} form. hmrc_reckoner_t2
resolves 14/14; free_joins (OBR receipts = pe-uk-data calibration surfaces,
claims not staged), obr_measures (OBR costings DB, long-tail held on the
storage decision), two_child + uprating (Resolution Foundation, long-tail)
are blocked-with-reasons in the module, and a new archive family without a
disposition fails the produce.
Attached on the committed DB: 14 results (engine 2.89.2, certified UK bundle),
all held at pe_status_effective='constructed' by the cross-baseline guard
(PE current-law baseline vs the claims' HMRC indexed baseline — the honest
label for CY-static vs FY-projected comparisons). populations.json 270 -> 284.
Dual gate: fable review done (this PR); sol pass next.
🤖 Generated with Claude Code