PolicyEngine / PolicyEngine/policyengine-scorecard
OBR policy costings (mode 2): Policy Measures Database + EFO 3.17 → PE-UK static counterparts
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- Avg merge
- 6d 12h
- Merged PRs (30d)
- 32
Description
Max's steer (2026-08-16): center PE model development — including PolicyEngine Macro — on the Scorecard. Use it to compute PE counterparts to OBR's published scores first, before adding machinery nothing else uses. This issue is the static half; the macro half is the companion issue linked below.
The population
The 8/2 harvest staged the full OBR Policy Measures Database (~/scorecard-harvest/uk_obr/; access recipe and staging decisions in its NOTES.md): 24,304 rows = every measure × tax head × FY, Budget 1970 → Autumn Budget 2025, certified costings, positive_gain_to_exchequer verbatim; plus EFO March 2026 Table 3.17 (95 rows): OBR's current re-estimated yields of the personal-tax measures (PA/HRT freezes, additional-rate cut, NICs thresholds) — each a one-line policyengine-uk reform.
None of it is in the DB. #48/#51 cover mode 1 (levels/baseline moments; OBR enters as 259 EFO welfare rows). This lane is mode 2 (#4): reform deltas — OBR's certified costing of a measure vs PE-UK's static costing of the same measure.
Precedent to extend, not reinvent
sources/campaign-20260802/uk/obr_measures.jsonl — 10 rows (SB2024 HICBC, employee NICs 2p/4p): reversal legs on the certified 2026 world, with annotations naming the axes — OBR = announcement-baseline vintage, behavioural-adjusted, FY accrual; PE = certified world, static, CY. Those axes are the assumptions-registry entries (#10) and the explained-share material.
Design
- Measure → reform registry (e.g.
data/uk/obr_measure_reforms.yaml): per measure — PMD row key, fiscal event, verbatim OBR description, PE reform spec (parametric dict + start FY),computability∈ {expressible, partial (annotate what's missing), not_expressible (why)}, construction (reversal-on-certified-world, or forward from the announcement baseline when the baseline registry (#13) has it), notes. Human-readable provenance on every row; the registry is itself a Scorecard artifact. - Compute: policyengine.py (latest) managed sims on the certified populace-uk bundle, one reform per measure, per FY in the OBR window; emit GBP aggregates by head where PE can split (income tax / NICs / benefits) so head-level and total rows both join. Every
pe_valuetraces to a saved per-run artifact. - Stage under the campaign ingest contract (
results/uk/staged/*.jsonl:external_claim_matchdescriptor, engine_version, full bundle id, status/construction/run_id/annotations). DB ingest of the PMD claims themselves rides #48's vocabulary (gbp,fy,basis) once it merges — stage first, ingest second, exactly as the US campaign did. - Compare descriptively: ratio bins, never pass/fail;
benchmark_class = different_model(HMRC/HMT costing models) unless assumption-matched; baseline mismatch surfaced per #13; behavioural vs static named on every row.
First families (in order)
- EFO Mar 2026 3.17 — 95 rows, current re-estimates, cleanest joins.
- PMD 2023–2025 events, income tax + NICs + welfare heads (~1,000 rows before computability filtering): AS2023/SB2024 NICs cuts, HICBC, PA/HRT freeze extensions, AB2024 employer NICs, AB2025 measures, two-child limit (joins the pentagon).
- Backfill earlier events as the registry grows.
Gate
Sol-reviewed PR(s), org-side branch (private repo — fork PRs don't run Actions). Descriptive register throughout (#9): no "replication rate", no wins.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with sources/campaign-20260802/uk/obr_measures.jsonl and the staged harvest's NOTES.md to understand the existing precedent and data. Read policyengine.py and the proposed data/uk/obr_measure_reforms.yaml structure, then trace how results/uk/staged/*.jsonl feeds ingestion. Done means the first EFO 3.17 family is computed with saved run artifacts, provenance, and descriptive comparisons under the stated campaign contract.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data-engineering, databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100