Two-country catalog: UK seven-source harvest, campaign PE results, baselines registry (#13), descriptive register (#9) - #32
Closed
MaxGhenis wants to merge 5 commits into
Closed
Conversation
…vocab - baselines table + baseline_key on external_scores/pe_results/pe_exhibits; ReformRef.baseline_key() derives from the baseline descriptor (claim-id hashing unchanged — additive projection). Registry curated in scorecard_db/baselines.py; runners fail loudly on unregistered worlds. - comparisons view exposes claim/PE baseline labels and pe_status_effective: comparable across different baselines can never render as plain agreement. - DiagnosisClass.methodological_difference (descriptive semantics); pe_gap/external_issue now REQUIRE a citable action_link — the CPSP erratum diagnosis cites its vendored NOTES anchor. - Metric/UnitConcept UK extensions (COLLATION UK worklist item 1): gbp family, exchequer_impact, unclaimed_expenditure, revenue/expenditure levels+changes, policy_parameter_level, taxpayer/percentile/average-tax families, income-distribution family (median/mean/share/gini/S80S20), poverty_threshold, persistent_poverty_rate, IFS/RF reform-distribution family; STANDARD_CONDITIONS UK keys (fy, basis, equivalisation, …). - poverty_count + persistent_poverty_rate join the permanent-holdout set. - platform/urban/solo ingests record the baseline actually executed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… routing) Seven adapters over vendored gzipped staging (sources/harvest-uk-2026-08-02; raw downloads stay outside, pinned by manifests): obr 25,425 · dwp 1,952 · hmt 1,368 · hmrc 987 · ukmod 1,392 · jrf 300 · ifs 268 · resolution_foundation 70 Full accounting against the 33,943 staged rows: 31,762 ingested + 2,090 admin outturns routed to Ledger staging (data/ledger/uk_admin_outturns .jsonl — OBR EFO outturn columns 133, DWP BECL outturns 102, HMRC outturn/provisional statistics 1,855; deterministic pre-agreed fact ids) + 89 deliberate drops tallied in lane notes (88 JRF MIS budget cells, 1 RF price-index row) + 2 JRF rounded/unrounded twins merged with rounding-consistency assertions. Load-bearing decisions: - period = FY START year everywhere, re-derived from verbatim fy labels (fixes DWP FYE end-year keying and the 1999/00→1900 staging defect); - OBR measures database: policy_ref world per measure title × 84 fiscal events; workbook-order reconstruction of component runs, 4.9 welfare-cap sections, 4.11 parent lines, and the Mar-2026/Nov-2025 EFO vintage split — all condition axes the staging had dropped; - consumed_as_target only on lines populace-UK literally consumes, read from policyengine-uk-data this session (obr.py receipts/CT/NICs/4.9 welfare; BECL expenditure for the five exact-line benefits; SPI-family projections seed_source via the shared SPI 2023-24 base; DWP UC admin and PC take-up per the staged verified notes; HB take-up held out as the live comparator for policyengine-uk#1813); - IFS Green-Budget options ride the registered non-current-law baseline world ifs_2cl_fp_removal_rolled_out (#13); - HMRC ready-reckoner lines are policy worlds slugged identically to the campaign runs' join keys. Tests: 42 new (tests/test_uk_ingest.py). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sources/campaign-2026-08-02/ vendors the 2026-08-02 run files (full bundle provenance; npz arrays and logs stay outside) and scorecard_db/ingest_campaign.py joins them to existing claims by exactly-one-match DB queries: uk_reckoner 23 · uk_free_joins 25 · uk_obr_measures 10 · uk_uprating 6 · tpc 14 · pwbm 2 · cpsp 8 · jct_obbba 1 · cbo_free_joins 88 = 177 - Every result records the baseline actually executed (#13); the TPC option legs make the view guard observable (claim baseline Senate Title VII vs PE current_law — labels exposed, never plain agreement). - Reckoner deltas recomputed from vendored run+baseline aggregates and cross-checked against the campaign's own collations before landing; HMRC RR world slugs gained their tax_section (the same line title exists under VAT and IPT). - The campaign's DWP free-join legs turn out to anchor FY2025-26 cells (the runner selected staged END-year ints): results attach to the claims the values identify, with the vintage caveat annotated. - OBR measure reversals anchor to the dominant component row with the N-row component-sum anchor named (OBR decomposes measures by head). - April-2026 uprating parameter checks land comparable (PE tree matches RF to their stated precision); the LCWRA new/existing split and data-driven LHA stay not_computed with the check's own notes. - CPSP levels carry methodological_difference diagnoses (descriptive register; populace#593 EHS sub-channel cited). - AFA floor ambiguity lands as two constructions on one claim. - Two-child-limit family (calibrated + entitlements take-up + abs-line continuity pair) → 11 pe_exhibits rows, reform two_child_limit_removal vs registered pre_ab2025 baseline (direction explicit). Tests: 17 new (tests/test_campaign_ingest.py); suite 160 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
data/scorecard.db rebuilt from scratch: urban → platform → solo → diagnoses → harvest → uk → campaign. 74,032 claims across 16 sources, 8,767 PE results, 531 exhibits (solo take-up attribution restored + two-child family), 19 diagnoses, 12 registered baselines, zero unregistered. Ledger staging file: 2,090 UK admin outturn facts. scorecard_db/README.md documents the UK population, the campaign results population, the baselines registry, and the full rebuild order (solo + diagnoses steps now included — they were silently omitted from the previous rebuild, which is why pe_exhibits was empty). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Main gained PRs #24-#30 while this branch built (day-1 US campaign attach, reform-validation registry population, exhibit_meta routing, baseline moments, CI). Reconciliation: - scorecard_db/ingest_campaign.py (main's) stays canonical for the US families and now records the executed baseline per #13; the UK side this branch built moves to scorecard_db/ingest_campaign_uk.py, reading the raw runs vendored under sources/campaign-20260802/uk_runs/. The campaign's staged UK descriptor files are deliberately superseded (docstring says why: strict-subset coverage, under-determined reckoner descriptors) except the two-child pentagon attachments, which land translated (3 rows, pre_ab2025 executed baseline). - db.py unifies on main's SQL-constant/preparer architecture, extended with baseline_key across scores/results/exhibits; the registry gains pre_obbba_current_law (reform-validation's CBO Dec-2024 option baseline — caught by the deliberate-registration gate). - Free-join skip attachments dedupe per claim (Self assessment carries identical 3.4/3.8 values); pentagon rows use their own run-id namespace so ingest_campaign's committed-DB provenance checks hold. - data/scorecard.db regenerated via the full documented order (urban → platform → solo → diagnoses → harvest → reform_validation → uk → campaign → campaign_uk) + populations export + app feeds; ruff format applied repo-wide (the new CI gate). Suite: 200 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 17, 2026
MaxGhenis
added a commit
that referenced
this pull request
Aug 19, 2026
…ce-only) (#70) The seven-source UK harvest staging (33,943 rows: obr/dwp/hmt/hmrc/ifs/ ukmod/rf/jrf — manifests, notes, compressed staged output) and the compute campaign's UK run records existed only machine-local and on the #32 branch; the architecture adjudication (dual review) identified them as the genuinely perishable asset independent of which ingest architecture lands. This PR is data preservation only: no schema, no DB, no ingest code — the long-tail lanes that consume it come per-lane after the foundation decision. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Aug 19, 2026
* Baselines registry + descriptive-register gate (issues #13, #9) The two architecture-neutral schema layers from #32, extracted and hardened as the prerequisite the UK-foundation adjudication called for — main's vocabulary (Metric/UnitConcept/STANDARD_CONDITIONS) untouched. Registry (#13): baselines table + baseline_key on external_scores / pe_results / pe_exhibits, stamped by the shared preparers; curated in scorecard_db/baselines.py (15 worlds); register_baselines fails loudly on any key in data the registry doesn't describe — extending it is a deliberate act. It fired twice while landing this: on RV's pre_obbba_current_law (as #32 documented) and on pre_obbba_law from today's #31 T26-0009 re-parse — a world introduced hours ago, now registered with its distinct-from-pre_obbba_current_law rationale stated (equivalence is a future deliberate act, never assumed). Comparisons-view guard: a comparable result whose executed baseline differs from the claim's renders pe_status_effective='constructed'. Hardened beyond #32 (the adjudication's null-hole finding): claims' baseline_key is backfilled by exact projection from each row's own reform_json (never inference); legacy results keep NULL — the executed baseline is provenance we don't have — and the view downgrades those to 'baseline_unvalidated' wherever the claim's world is not current law (the null world's key is injected into the view SQL so the guard works on unseeded files). On the committed DB: 42,610 claims -> 12 in-use worlds, zero unregistered, zero retroactive status shifts. Gate (#9): DiagnosisClass.methodological_difference joins the taxonomy; db.diagnose raises for pe_gap/external_issue without a citable action_link. It caught main's CPSP erratum diagnosis missing its citation (the erratum NOTES anchor — ported from #32's fix). Suite: 179 tests (14 new: registry, guard both branches, gate, migration). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Gate round: end-to-end guard, strict backfill, executed-baseline stamps All five review blockers: 1. Producers stamp executed baselines — campaign/platform/urban/solo results and exhibits carry current_law (verifiably what those runs executed; the jct expiry-reversal's negation stays documented in its construction); reform-validation stamps per scoring mode via two new deliberately-registered worlds: pre_obbba_expiry_2026 (isolated runs' shared pre-OBBBA expiry baseline, per the l0 note) and jcx_stack_position (the position-varying stacked family, position in the construction string — registered honestly as a family so stacked runs are non-NULL and can never render plain agreement against any single-world claim). Committed DB re-ingested: 783 stamped results (603/144/36), 8,590 legacy NULLs preserved as-is. 2. Guard end-to-end: export_populations mirrors the #13 view guard per result (status + status_effective + claim/result baseline labels; summary counts by effective status); the app renders effective status in the pill/filter and badges per-release downgrades. 3. Migration backfill is strict: _legacy_claim_baseline_key projects exactly (missing key / JSON null -> current_law) and fails loudly on {} / [] / false / non-string policy / non-object reform_json; baseline_key() validates a nonempty string slug. 4. Committed artifacts honor the #9 gate: the CPSP erratum diagnosis rewritten through db.diagnose with its citation, and the NOTES.md erratum got an anchorable heading so the fragment resolves. 5. Registry provenance corrected against the vendored sources: JCX-29 = SFC substitute (JCX-30/31 the manager's pair); the pre-2025-tariffs world is keyed by TPC (161) + PWBM (22), not Tax Foundation; Senate Title VII cites the vendored T25-0209/T25-0215. Tests: 189 (backfill projection + 6 malformed-descriptor cases + reopen idempotency + producer non-NULL for campaign and RV + exporter downgrade both branches). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Per-(chain, provision) stack worlds; accurate tariff citation The reviewer proved the jcx_stack_position family key laundered 36 distinct executed worlds into one hash — and that the claimed mitigation was false (the construction string carried no position; the buildi chain visibly moves through different baselines per position). Now: stacked runs stamp one registered world per (chain, provision) — {policy: obbba_stack_below, chain: f0af251|jcx_producer, provision: id} — enumerated deliberately from the canonical provision map (36 entries; the family entry is disavowed and its unreferenced registry row removed), and the construction gains the chain position (:stack_posNN:). The RV test now pins per-world counts (f0 chain = 2 results per provision, producer chain = 6) instead of entrenching the collapse. Registry: 51 worlds, zero unregistered, zero effective-status shifts. Also: the pre-2025-tariffs provenance now states exactly where the baseline is explicit (T25-0366's 11 manifest rows) vs assigned from the documented workbook verification (T26-0010/0112/0113). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Raw-chain ordinals; convergent registry seeding Round-3 findings: (1) the position token was stamped on isolated results and counted scored-row ordinals — f0's CDCC is raw chain position 17, after the unscored senior-deduction link that demonstrably feeds its baseline. Stacked constructions now carry chain_posNN as the RAW ordinal (unscored links counted); isolated rows carry no token — their baseline is the shared expiry world. (2) register_baselines was not convergent: an in-place upgrade would keep the disavowed jcx_stack_position row. The seeder now prunes registry rows no longer defined — refusing loudly if data still references them (disavowal must re-key first) — with upgrade regression tests both ways. Stale comments describing the removed family corrected. 191 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Pin raw-ordinal facts in tests; last stale family comment Per the round-4 non-blocking notes: a test now asserts f0's CDCC carries chain_pos17 (the raw ordinal past the unscored senior link) and that no isolated result carries a position token; the one remaining comment describing the removed jcx_stack_position family is corrected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Closing per the two-model adjudication (fable + sol independent cold-reads, both HIGH confidence): the uk/* adapter stack was chosen as the UK foundation, and this PR's durable contributions were extracted rather than merged wholesale. Credit ledger — what this PR contributed to what shipped:
Adjudication records: the two independent verdicts and the sequenced plan are in the #48 thread; #48 merged today as the foundation with this PR's schema layers already under it. 🤖 Generated with Claude Code |
MaxGhenis
added a commit
that referenced
this pull request
Aug 19, 2026
… reckoner attaches (#72) Deterministic resolution of the frozen 2026-08-02 UK campaign staging against the ingested claims (the adjudicated replacement for #32's ingester): archived construction -> executed uk_run -> t2-collation HMRC change label -> exactly one reckoner claim -> ingest_campaign's strict {claim_id} form. 14/14 resolved and attached (engine 2.89.2, certified UK bundle) — the first UK PE results on the committed DB, all held at pe_status_effective='constructed' by the cross-baseline guard. populations.json 270 -> 284. The four unresolvable archive families are blocked with per-row-accurate, machine-pinned dispositions (compositions + zero-claims-per-target tests), so a re-frozen archive or a future source staging forces a deliberate re-disposition rather than a silent drift. Dual gate: fable + sol, three rounds (r1 validated all 14 mappings; r2/r3 tightened the dispositions to per-row accuracy and the defining exhibit_meta property). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
Completes the two-country catalog: the seven-source UK harvest ingested with the Ledger routing rule, the campaign's UK compute batch joined as PE results, the baselines registry (#13), and the descriptive-register gate (#9). Reconciled on top of this week's main (PRs #24–#30): main's
ingest_campaignstays canonical for the day-1 US families; this branch adds its UK sibling and the schema layer both now share.Report
Claims in DB: 74,237 across 66 sources (regenerated via the documented order: urban → platform → solo → diagnoses → harvest → reform_validation → uk → campaign → campaign_uk). The eight UK sources this PR adds:
UK full accounting — 33,943 staged rows = 31,762 ingested + 2,090 routed to Ledger staging (data/ledger/uk_admin_outturns.jsonl: HMRC outturn/provisional 1,855 · OBR EFO outturn columns 133 · DWP BECL outturns 102, deterministic pre-agreed fact ids for the populace/Ledger lane) + 89 deliberate drops tallied in lane notes (88 JRF MIS budget cells, 1 RF price-index row) + 2 JRF rounded/unrounded twins merged with rounding-consistency assertions.
Campaign UK results joined — 65 PE results via
scorecard_db/ingest_campaign_uk.py, every one recording the baseline actually executed (#13): uk_reckoner 23 · uk_free_joins 23 · uk_obr_measures 10 · uk_uprating 6 · two_child_pentagon 3. Plus 11 two-child-limit pe_exhibits (calibrated + entitlements-basis worlds + abs-line continuity pair) against the registeredpre_ab2025baseline, and 8methodological_differencediagnoses on the CPSP level rows (populace#593 cited). Two honest uprating skips (LCWRA new/existing split, data-driven LHA) landnot_computedwith the tree-check's own notes. DB totals after everything: 9,438 pe_results, 535 exhibits, 19 diagnoses, 13 registered baselines, zero unregistered.Tests: 200 green (
uv run --with pytest pytest tests/ -q, the CI gate): +12 schema (registry, view guard, diagnose gate, migrations), +42 UK adapters (FY normalization, ledger routing, full accounting, verified consumed sets), +17 UK campaign joins, alongside main's new reform-validation/campaign/export/moments suites.ruff format --checkclean.Schema (#13, #9)
baselinesregistry table +baseline_keyon external_scores / pe_results / pe_exhibits, carried through the shared SQL constants/preparers so main's single-transaction ingests record it too; curated in scorecard_db/baselines.py (13 worlds — the deliberate-registration gate caught reform-validation'spre_obbba_current_lawduring the merge, exactly as designed). Claim-id hashing unchanged.comparisonsview exposes claim/PE baseline labels +pe_status_effective: comparable across different baselines can never render as plain agreement (observable on TPC's Senate-Title-VII claims).DiagnosisClass.methodological_difference(strictly descriptive);pe_gap/external_issuenow require a citableaction_link—db.diagnoseraises otherwise.poverty_count+persistent_poverty_ratejoin the permanent-holdout set.UK ingest decisions worth review
1999/00→1900 staging defect).seed_sourcevia the shared SPI 2023-24 base; HB take-up stays held out as the live comparator for policyengine-uk#1813.Notes / follow-ups
🤖 Generated with Claude Code