Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/public/data/lanes.json
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,17 @@
"running": false,
"updated": "2026-08-19",
"note": "7 claims"
},
{
"id": "obr-policy-effects",
"source": "OBR",
"area": "published economic effects of policy",
"mode": 2,
"country": "UK",
"stage": "ingested",
"running": false,
"updated": "2026-08-20",
"note": "266 claims"
}
]
}
11 changes: 11 additions & 0 deletions data/lanes.json
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,17 @@
"running": false,
"updated": "2026-08-19",
"note": "7 claims"
},
{
"id": "obr-policy-effects",
"source": "OBR",
"area": "published economic effects of policy",
"mode": 2,
"country": "UK",
"stage": "ingested",
"running": false,
"updated": "2026-08-20",
"note": "266 claims"
}
]
}
82 changes: 82 additions & 0 deletions scorecard_db/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,85 @@ this ingest mints is marked publication.registry =
"populace_reform_validation" — that marker is the idempotency contract
(re-ingest deletes and recreates exactly these claims, never the harvest
claims it attaches results to).

## 2026-08-20 population: OBR published policy effects (UK)

Fourth UK population and the external half of the Macro entry point
(issue #55): 266 claims from OBR's own published estimates of what
fiscal policy does to the ECONOMY, harvested by
`sources/obr-policy-effects/adapter.py` and ingested by
`ingest_obr_policy_effects` (chain position: after `uk_deductions`,
before the campaign attaches).

```bash
PYTHONPATH=. python -m scorecard_db.ingest_obr_policy_effects data/scorecard.db
```

Four families on four new metrics — `gdp_level_effect` (151),
`cpi_inflation_effect` (36), `supply_side_impact` (19) and
`decisions_effect_on_borrowing` (60). The first and third are
deliberately distinct metrics: a package's effect on the actual-GDP path
is not one measure's supply-side scoring, and
`decisions_effect_on_borrowing` (PSNB) is likewise kept apart from
`revenue_change` and `cash_requirement_change` (PSNCR).

**Units.** Three of the four quantities look like "percent" and are not
one thing, so each carries its own unit concept:
`percent_of_real_gdp` (a deviation in the LEVEL of real GDP),
`percentage_points` (the AB2025 package's effect on CPI inflation) and
`percent_of_potential_gdp` (briefing paper No.10's supply-side
scorings); borrowing is `gbp`. The mapping is validate-THEN-map: the
adapter's staged unit label must equal the one the metric carries or the
ingest raises, so a mislabeled row can never be stored as a different
quantity.

**Baselines.** These claims are NOT scored against `current_law`. OBR
measures a package as a deviation from that EFO round's PRE-MEASURES
forecast — a distinct named world per round — and briefing paper No.10
chapter 2 splits the counterfactual KIND further: tax and welfare
measures against a legislated-parameter counterfactual, DEL and
regulatory measures against the pre-existing activity/spending baseline.
March 2026 Table B.1 states its own counterfactual in its title (the
November 2025 Budget forecast). Each row carries the world and kind as a
`ReformRef.baseline` descriptor with `conditions["baseline_policy"]`
mirroring it, a locator travels with the claim, an event whose baseline
does not match its round raises, and all eleven (round, counterfactual)
worlds are registered in `baselines.py`. Defaulting to `current_law`
would have let a PE result computed against current law read as
comparable.

**Publication.** Provenance is per vendored artifact, so each round's
claims carry their own release date and dated URL (2023-11-22,
2024-03-06, 2024-10-30, 2025-11-26, 2026-03-03) rather than one generic
`obr.uk/publications/` stamp — and the March 2026 rows carry the
publication date, not the Wayback capture.

All 266 are `held_out`: nothing in pe-uk-data or policyengine-uk is
fitted to a macro-effect path — they are what the Macro members get
scored against. `basis` is `forecast` on every row (its repo-wide
meaning); how the effect was scored rides in
`conditions["scoring_method"]` (`post_behavioural` | `supply_side`).

Two identity decisions this population forced:

- **`conditions["decomposition"]`.** The October 2024 workbook prints
the AB2024 package twice — chart 2.A by expenditure component, 2.B by
measure/channel — so both publish a `total` and a
`demand_multipliers`. The decomposition is therefore identity-bearing,
not provenance, and is keyed off (fiscal_event, sheet): the sheet id
alone will not do, since C2.A is by-channel in the Nov 2023 and Mar
2024 workbooks.
- **The supply-side horizon, per scoring round.** Briefing paper No.10's
Table 2.1 states its year in words ("the impact on potential output in
the fifth year of our forecast"), never as a digit — and the paper
re-states scorings made at five EARLIER fiscal events, so "our
forecast" is each measure's own round. `_BP10_HORIZON` resolves the
symbol per event (2027-28 for March 2023 through 2029-30 for March
2025); the note rides verbatim in `conditions["horizon_note"]` and
`conditions["horizon"]` names the symbol. Period is claim identity, so
one shared horizon would have been 19 wrong claims.

Table B.1's nested rows keep the `aggregate_level`/`parent` guard the
OBR welfare lines use, so no consumer summing borrowing effects by FY
double-counts. PE counterparts are step 3 of #55 and are not computed
here.
195 changes: 195 additions & 0 deletions scorecard_db/baselines.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,201 @@
"with two-child limit and family premium removal fully rolled "
"out' (sources/harvest-uk-2026-08-02/uk_ifs).",
),
# --- OBR published policy effects (#55) ---------------------------
# OBR does NOT score a package against "the law in force" in the
# abstract: it scores against that EFO round's PRE-MEASURES forecast
# — a distinct, named world per round, which also fixes the economic
# determinants the effect is measured off. Two rounds' pre-measures
# worlds are different worlds, so a PE result computed against
# current law is NOT comparable to these claims unless it says so.
# Briefing paper No.10 chapter 2 splits the counterfactual KIND, so
# the kind is a descriptor key rather than a blurred single world:
# policy_parameters the measures' pre-announcement legislated
# parameters (tax and welfare measures, and every
# package-level chart)
# del_activity the pre-existing DEL activity/spending level —
# a departmental programme's counterfactual is
# the activity already assumed, not a parameter
# regulatory the pre-existing regulatory baseline (the
# National Planning Policy Framework as it stood)
# Only the (round, kind) pairs the data actually keys are registered;
# the registry is a record of decisions, not a cross-product.
(
{
"policy": "obr_pre_measures_spring_budget_2023",
"counterfactual": "policy_parameters",
},
"obr_pre_measures_spring_budget_2023__policy_parameters",
"OBR's pre-measures March 2023 forecast, the world the "
"Spring Budget 2023 package and its individually scored measures "
"are measured against; counterfactual kind: the measures' pre-announcement legislated parameters.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_spring_budget_2023",
"counterfactual": "del_activity",
},
"obr_pre_measures_spring_budget_2023__del_activity",
"OBR's pre-measures March 2023 forecast, the world the "
"Spring Budget 2023 package and its individually scored measures "
"are measured against; counterfactual kind: the pre-existing DEL activity/spending baseline.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_autumn_statement_2023",
"counterfactual": "policy_parameters",
},
"obr_pre_measures_autumn_statement_2023__policy_parameters",
"OBR's pre-measures November 2023 forecast, the world the "
"Autumn Statement 2023 package and its individually scored measures "
"are measured against; counterfactual kind: the measures' pre-announcement legislated parameters.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_autumn_statement_2023",
"counterfactual": "del_activity",
},
"obr_pre_measures_autumn_statement_2023__del_activity",
"OBR's pre-measures November 2023 forecast, the world the "
"Autumn Statement 2023 package and its individually scored measures "
"are measured against; counterfactual kind: the pre-existing DEL activity/spending baseline.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_spring_budget_2024",
"counterfactual": "policy_parameters",
},
"obr_pre_measures_spring_budget_2024__policy_parameters",
"OBR's pre-measures March 2024 forecast, the world the "
"Spring Budget 2024 package and its individually scored measures "
"are measured against; counterfactual kind: the measures' pre-announcement legislated parameters.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_autumn_budget_2024",
"counterfactual": "policy_parameters",
},
"obr_pre_measures_autumn_budget_2024__policy_parameters",
"OBR's pre-measures October 2024 forecast, the world the "
"Autumn Budget 2024 package and its individually scored measures "
"are measured against; counterfactual kind: the measures' pre-announcement legislated parameters.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_autumn_budget_2024",
"counterfactual": "del_activity",
},
"obr_pre_measures_autumn_budget_2024__del_activity",
"OBR's pre-measures October 2024 forecast, the world the "
"Autumn Budget 2024 package and its individually scored measures "
"are measured against; counterfactual kind: the pre-existing DEL activity/spending baseline.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_spring_statement_2025",
"counterfactual": "policy_parameters",
},
"obr_pre_measures_spring_statement_2025__policy_parameters",
"OBR's pre-measures March 2025 forecast, the world the "
"Spring Statement 2025 package and its individually scored measures "
"are measured against; counterfactual kind: the measures' pre-announcement legislated parameters.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_spring_statement_2025",
"counterfactual": "regulatory",
},
"obr_pre_measures_spring_statement_2025__regulatory",
"OBR's pre-measures March 2025 forecast, the world the "
"Spring Statement 2025 package and its individually scored measures "
"are measured against; counterfactual kind: the pre-existing regulatory baseline.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_pre_measures_autumn_budget_2025",
"counterfactual": "policy_parameters",
},
"obr_pre_measures_autumn_budget_2025__policy_parameters",
"OBR's pre-measures November 2025 forecast, the world the "
"Autumn Budget 2025 package and its individually scored measures "
"are measured against; counterfactual kind: the measures' pre-announcement legislated parameters.",
"policy_ref",
"sources/obr-policy-effects/source.json (baseline_key) plus the "
"per-row baseline / baseline_counterfactual / baseline_locator "
"the adapter emits from the vendored workbooks; descriptor "
"stamped by scorecard_db/ingest_obr_policy_effects.py "
"(_baseline_descriptor).",
),
(
{
"policy": "obr_november_2025_budget_forecast",
"counterfactual": "policy_parameters",
},
"obr_november_2025_budget_forecast__policy_parameters",
"The OBR's November 2025 Budget forecast — the counterfactual "
"March 2026 Table B.1 names in its own title ('Total effect of "
"Government decisions SINCE the November 2025 Budget'). A "
"post-measures world, deliberately not a pre-measures one.",
"policy_ref",
"EFO March 2026, Annex B Table B.1 title, vendored at "
"sources/obr-policy-effects/raw/efo_march2026_annex_tables.xlsx; "
"descriptor stamped by "
"scorecard_db/ingest_obr_policy_effects.py (_baseline_descriptor).",
),
(
{"policy": "pre_ab2025"},
"pre_ab2025",
Expand Down
Loading
Loading