diff --git a/chronicle/jurisdictions/uk/__init__.py b/chronicle/jurisdictions/uk/__init__.py index 69004986..f7ee1678 100644 --- a/chronicle/jurisdictions/uk/__init__.py +++ b/chronicle/jurisdictions/uk/__init__.py @@ -1,9 +1,5 @@ """United Kingdom Chronicle target loaders.""" -from chronicle.targets.loaders import ( - load_hmrc_targets, - load_obr_targets, - load_ons_targets, -) +from chronicle.targets.loaders import load_hmrc_targets -__all__ = ["load_hmrc_targets", "load_obr_targets", "load_ons_targets"] +__all__ = ["load_hmrc_targets"] diff --git a/chronicle/source_package.py b/chronicle/source_package.py index 605122a8..9382c98a 100644 --- a/chronicle/source_package.py +++ b/chronicle/source_package.py @@ -295,6 +295,8 @@ "voa-council-tax-stock-by-lad-2025": Path("voa/council_tax_stock_by_lad_2025"), "obr-efo-receipts-march-2026": Path("obr/efo_receipts_march_2026"), "obr-efo-expenditure-march-2026": Path("obr/efo_expenditure_march_2026"), + "obr-efo-economy-march-2026": Path("obr/efo_economy_march_2026"), + "obr-efo-aggregates-march-2026": Path("obr/efo_aggregates_march_2026"), "ons-national-balance-sheet-land-2025": Path( "ons/national_balance_sheet_land_2025" ), diff --git a/chronicle/targets/loaders.py b/chronicle/targets/loaders.py index 22db451b..f7d37ffb 100644 --- a/chronicle/targets/loaders.py +++ b/chronicle/targets/loaders.py @@ -7,8 +7,6 @@ from db.etl_cps import load_cps_targets from db.etl_hmrc import load_hmrc_targets from db.etl_medicaid import load_medicaid_targets -from db.etl_obr import load_obr_targets -from db.etl_ons import load_ons_targets from db.etl_snap import load_snap_targets from db.etl_soi import load_soi_targets from db.etl_soi_credits import load_soi_credits_targets @@ -26,8 +24,6 @@ "load_cps_targets", "load_hmrc_targets", "load_medicaid_targets", - "load_obr_targets", - "load_ons_targets", "load_snap_targets", "load_soi_targets", "load_soi_credits_targets", diff --git a/db/cli.py b/db/cli.py index 4a82cf64..782a8167 100644 --- a/db/cli.py +++ b/db/cli.py @@ -143,20 +143,6 @@ def cmd_load(args): load_cbo_targets(session, years=years) print(f"Loaded CBO projections for years: {years or 'all available'}") - if args.source == "obr" or args.source == "all": - from .etl_obr import load_obr_targets - - years = [int(y) for y in args.years.split(",")] if args.years else None - load_obr_targets(session, years=years) - print(f"Loaded OBR projections for years: {years or 'all available'}") - - if args.source == "ons" or args.source == "all": - from .etl_ons import load_ons_targets - - years = [int(y) for y in args.years.split(",")] if args.years else None - load_ons_targets(session, years=years) - print(f"Loaded ONS projections for years: {years or 'all available'}") - def cmd_stats(args): """Show database statistics.""" @@ -322,8 +308,6 @@ def main(): "bls", "cps", "cbo", - "obr", - "ons", "all", ], help="Data source to load", diff --git a/db/data/obr/efo_aggregates_march_2026/efo_aggregates.xlsx b/db/data/obr/efo_aggregates_march_2026/efo_aggregates.xlsx new file mode 100644 index 00000000..ebc9c5ca Binary files /dev/null and b/db/data/obr/efo_aggregates_march_2026/efo_aggregates.xlsx differ diff --git a/db/data/obr/efo_aggregates_march_2026/manifest.yaml b/db/data/obr/efo_aggregates_march_2026/manifest.yaml new file mode 100644 index 00000000..43dc8164 --- /dev/null +++ b/db/data/obr/efo_aggregates_march_2026/manifest.yaml @@ -0,0 +1,18 @@ +source_id: obr +package_id: obr-efo-aggregates-march-2026 +dataset: obr_obr-efo-aggregates-march-2026 +source_page: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ +table: 'EFO March 2026 fiscal supplementary tables: aggregates' +files: + 2026: + filename: efo_aggregates.xlsx + source_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + sha256: f9eee880e9f39cc8c86d288a803a032b735fea5f9bbd1532f26bfca898a669d9 + size_bytes: 231008 + fetched_at: '2026-08-19T00:00:00+00:00' + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/obr/obr-efo-aggregates-march-2026/2026/f9eee880e9f39cc8c86d288a803a032b735fea5f9bbd1532f26bfca898a669d9/efo_aggregates.xlsx + uri: r2://ledger-raw/raw/obr/obr-efo-aggregates-march-2026/2026/f9eee880e9f39cc8c86d288a803a032b735fea5f9bbd1532f26bfca898a669d9/efo_aggregates.xlsx diff --git a/db/data/obr/efo_economy_march_2026/efo_economy.xlsx b/db/data/obr/efo_economy_march_2026/efo_economy.xlsx new file mode 100644 index 00000000..4b69c853 Binary files /dev/null and b/db/data/obr/efo_economy_march_2026/efo_economy.xlsx differ diff --git a/db/data/obr/efo_economy_march_2026/manifest.yaml b/db/data/obr/efo_economy_march_2026/manifest.yaml new file mode 100644 index 00000000..11010eb5 --- /dev/null +++ b/db/data/obr/efo_economy_march_2026/manifest.yaml @@ -0,0 +1,18 @@ +source_id: obr +package_id: obr-efo-economy-march-2026 +dataset: obr_obr-efo-economy-march-2026 +source_page: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ +table: 'EFO March 2026 detailed forecast tables: economy' +files: + 2026: + filename: efo_economy.xlsx + source_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + sha256: fde1de4bc5424dcf16c7b5c42eb75a35198e347f54db47690e95ede7541db510 + size_bytes: 483251 + fetched_at: '2026-08-19T00:00:00+00:00' + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/obr/obr-efo-economy-march-2026/2026/fde1de4bc5424dcf16c7b5c42eb75a35198e347f54db47690e95ede7541db510/efo_economy.xlsx + uri: r2://ledger-raw/raw/obr/obr-efo-economy-march-2026/2026/fde1de4bc5424dcf16c7b5c42eb75a35198e347f54db47690e95ede7541db510/efo_economy.xlsx diff --git a/db/data/ons/families_households_2025/manifest.yaml b/db/data/ons/families_households_2025/manifest.yaml index f66420ad..7d662b55 100644 --- a/db/data/ons/families_households_2025/manifest.yaml +++ b/db/data/ons/families_households_2025/manifest.yaml @@ -2,7 +2,7 @@ source_id: ons package_id: ons-families-households-2025 dataset: ons_ons-families-households-2025 source_page: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds -table: 'Families and households in the UK 2025, Table 7: households by type' +table: 'Families and households in the UK 2025, Tables 5 and 7: household size and households by type' files: 2025: filename: familiesandhouseholdsuk2025.xlsx diff --git a/db/etl_obr.py b/db/etl_obr.py deleted file mode 100644 index 2ed11875..00000000 --- a/db/etl_obr.py +++ /dev/null @@ -1,313 +0,0 @@ -""" -ETL for OBR (Office for Budget Responsibility) projections. - -Loads UK fiscal and economic projections from OBR's Economic and Fiscal Outlook. -Data source: https://obr.uk/efo/economic-and-fiscal-outlook-march-2024/ -""" - -from __future__ import annotations - -from sqlmodel import Session, select - -from .schema import ( - DataSource, - Jurisdiction, - Stratum, - StratumConstraint, - Target, - TargetType, - init_db, -) - -# OBR projections data (5-year forecast, 2024-2029) -# Source: OBR Economic and Fiscal Outlook, March 2024 -# https://obr.uk/efo/economic-and-fiscal-outlook-march-2024/ -# GDP and budget figures in billions of GBP -# Rates as percentages -OBR_DATA = { - # Fiscal Year 2024-25 - 2024: { - # GDP and public finances (billions GBP) - "gdp": 2_791_000_000_000, # £2.791 trillion - "total_receipts": 1_139_000_000_000, - "total_managed_expenditure": 1_226_000_000_000, - "public_sector_net_borrowing": 87_000_000_000, - "public_sector_net_debt": 2_654_000_000_000, - # Economic indicators (percentages) - "real_gdp_growth": 0.8, - "unemployment_rate": 4.2, - "cpi_inflation": 2.8, - "rpi_inflation": 3.9, - "bank_rate": 4.8, - # Employment (thousands) - "employment": 33_100_000, - }, - 2025: { - "gdp": 2_929_000_000_000, - "total_receipts": 1_207_000_000_000, - "total_managed_expenditure": 1_296_000_000_000, - "public_sector_net_borrowing": 89_000_000_000, - "public_sector_net_debt": 2_783_000_000_000, - "real_gdp_growth": 1.9, - "unemployment_rate": 4.3, - "cpi_inflation": 2.2, - "rpi_inflation": 3.2, - "bank_rate": 4.1, - "employment": 33_200_000, - }, - 2026: { - "gdp": 3_066_000_000_000, - "total_receipts": 1_273_000_000_000, - "total_managed_expenditure": 1_349_000_000_000, - "public_sector_net_borrowing": 76_000_000_000, - "public_sector_net_debt": 2_893_000_000_000, - "real_gdp_growth": 2.0, - "unemployment_rate": 4.1, - "cpi_inflation": 1.8, - "rpi_inflation": 2.8, - "bank_rate": 3.6, - "employment": 33_400_000, - }, - 2027: { - "gdp": 3_199_000_000_000, - "total_receipts": 1_337_000_000_000, - "total_managed_expenditure": 1_399_000_000_000, - "public_sector_net_borrowing": 62_000_000_000, - "public_sector_net_debt": 2_985_000_000_000, - "real_gdp_growth": 1.8, - "unemployment_rate": 4.0, - "cpi_inflation": 1.8, - "rpi_inflation": 2.8, - "bank_rate": 3.4, - "employment": 33_500_000, - }, - 2028: { - "gdp": 3_331_000_000_000, - "total_receipts": 1_399_000_000_000, - "total_managed_expenditure": 1_456_000_000_000, - "public_sector_net_borrowing": 57_000_000_000, - "public_sector_net_debt": 3_070_000_000_000, - "real_gdp_growth": 1.7, - "unemployment_rate": 4.0, - "cpi_inflation": 2.0, - "rpi_inflation": 3.0, - "bank_rate": 3.3, - "employment": 33_600_000, - }, - 2029: { - "gdp": 3_464_000_000_000, - "total_receipts": 1_459_000_000_000, - "total_managed_expenditure": 1_512_000_000_000, - "public_sector_net_borrowing": 53_000_000_000, - "public_sector_net_debt": 3_148_000_000_000, - "real_gdp_growth": 1.7, - "unemployment_rate": 4.0, - "cpi_inflation": 2.0, - "rpi_inflation": 3.0, - "bank_rate": 3.3, - "employment": 33_700_000, - }, -} - -SOURCE_URL = "https://obr.uk/efo/economic-and-fiscal-outlook-march-2024/" - - -def get_or_create_stratum( - session: Session, - name: str, - jurisdiction: Jurisdiction, - constraints: list[tuple[str, str, str]], - description: str | None = None, - parent_id: int | None = None, - stratum_group_id: str | None = None, -) -> Stratum: - """Get existing stratum or create new one.""" - definition_hash = Stratum.compute_hash(constraints, jurisdiction) - - existing = session.exec( - select(Stratum).where(Stratum.definition_hash == definition_hash) - ).first() - - if existing: - return existing - - stratum = Stratum( - name=name, - description=description, - jurisdiction=jurisdiction, - definition_hash=definition_hash, - parent_id=parent_id, - stratum_group_id=stratum_group_id, - ) - session.add(stratum) - session.flush() - - for variable, operator, value in constraints: - constraint = StratumConstraint( - stratum_id=stratum.id, - variable=variable, - operator=operator, - value=value, - ) - session.add(constraint) - - return stratum - - -def load_obr_targets(session: Session, years: list[int] | None = None): - """ - Load OBR projections into database. - - Args: - session: Database session - years: Years to load (default: all available 2024-2029) - """ - if years is None: - years = list(OBR_DATA.keys()) - - for year in years: - if year not in OBR_DATA: - continue - - data = OBR_DATA[year] - - # UK public finances stratum - budget_stratum = get_or_create_stratum( - session, - name="UK Public Finances", - jurisdiction=Jurisdiction.UK, - constraints=[("sector", "==", "public")], # Government sector - description="UK public sector finances", - stratum_group_id="obr_budget", - ) - - # Budget targets - budget_vars = [ - ("gdp", TargetType.AMOUNT), - ("total_receipts", TargetType.AMOUNT), - ("total_managed_expenditure", TargetType.AMOUNT), - ("public_sector_net_borrowing", TargetType.AMOUNT), - ("public_sector_net_debt", TargetType.AMOUNT), - ] - - for var_name, var_type in budget_vars: - if var_name not in data: - continue - - # Check for existing target - existing = session.exec( - select(Target).where( - Target.stratum_id == budget_stratum.id, - Target.variable == var_name, - Target.period == year, - Target.source == DataSource.OBR, - ) - ).first() - - if existing: - continue - - session.add( - Target( - stratum_id=budget_stratum.id, - variable=var_name, - period=year, - value=data[var_name], - target_type=var_type, - source=DataSource.OBR, - source_url=SOURCE_URL, - is_preliminary=year > 2024, - ) - ) - - # UK Economy stratum for macro indicators - economy_stratum = get_or_create_stratum( - session, - name="UK Economy", - jurisdiction=Jurisdiction.UK, - constraints=[], # Whole economy, not a subset - description="UK macroeconomic indicators", - stratum_group_id="obr_economy", - ) - - # Economic rate targets - rate_vars = [ - "real_gdp_growth", - "unemployment_rate", - "cpi_inflation", - "rpi_inflation", - "bank_rate", - ] - - for var_name in rate_vars: - if var_name not in data: - continue - - existing = session.exec( - select(Target).where( - Target.stratum_id == economy_stratum.id, - Target.variable == var_name, - Target.period == year, - Target.source == DataSource.OBR, - ) - ).first() - - if existing: - continue - - session.add( - Target( - stratum_id=economy_stratum.id, - variable=var_name, - period=year, - value=data[var_name], - target_type=TargetType.RATE, - source=DataSource.OBR, - source_url=SOURCE_URL, - is_preliminary=year > 2024, - ) - ) - - # Employment count - if "employment" in data: - existing = session.exec( - select(Target).where( - Target.stratum_id == economy_stratum.id, - Target.variable == "employment", - Target.period == year, - Target.source == DataSource.OBR, - ) - ).first() - - if not existing: - session.add( - Target( - stratum_id=economy_stratum.id, - variable="employment", - period=year, - value=data["employment"], - target_type=TargetType.COUNT, - source=DataSource.OBR, - source_url=SOURCE_URL, - is_preliminary=year > 2024, - ) - ) - - session.commit() - - -def run_etl(db_path=None): - """Run the OBR ETL pipeline.""" - from pathlib import Path - from .schema import DEFAULT_DB_PATH - - path = Path(db_path) if db_path else DEFAULT_DB_PATH - engine = init_db(path) - - with Session(engine) as session: - load_obr_targets(session) - print(f"Loaded OBR projections to {path}") - - -if __name__ == "__main__": - run_etl() diff --git a/db/etl_ons.py b/db/etl_ons.py deleted file mode 100644 index d4619231..00000000 --- a/db/etl_ons.py +++ /dev/null @@ -1,310 +0,0 @@ -""" -ETL for ONS (Office for National Statistics) projections. - -Loads UK population and household projections from ONS. -Data sources: -- National population projections: https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections -- Household projections: https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections/datasets/householdprojectionsforengland -""" - -from __future__ import annotations - -from sqlmodel import Session, select - -from .schema import ( - DataSource, - Jurisdiction, - Stratum, - StratumConstraint, - Target, - TargetType, - init_db, -) - -# ONS 2022-based projections data (2024-2034) -# Source: ONS National Population Projections (2022-based) -# https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections -# Population counts are for the UK as a whole -# Household projections based on ONS household projections data -ONS_DATA = { - # Mid-2024 projections - 2024: { - # Population by broad age groups (counts) - "population_total": 68_265_000, - "population_age_0_15": 12_410_000, # Children - "population_age_16_64": 42_638_000, # Working age - "population_age_65_plus": 13_217_000, # Pension age - # Household projections - "households_total": 28_500_000, - "average_household_size": 2.40, - }, - 2025: { - "population_total": 68_626_000, - "population_age_0_15": 12_448_000, - "population_age_16_64": 42_703_000, - "population_age_65_plus": 13_475_000, - "households_total": 28_750_000, - "average_household_size": 2.39, - }, - 2026: { - "population_total": 68_978_000, - "population_age_0_15": 12_485_000, - "population_age_16_64": 42_759_000, - "population_age_65_plus": 13_734_000, - "households_total": 29_000_000, - "average_household_size": 2.38, - }, - 2027: { - "population_total": 69_321_000, - "population_age_0_15": 12_521_000, - "population_age_16_64": 42_808_000, - "population_age_65_plus": 13_992_000, - "households_total": 29_250_000, - "average_household_size": 2.37, - }, - 2028: { - "population_total": 69_656_000, - "population_age_0_15": 12_555_000, - "population_age_16_64": 42_852_000, - "population_age_65_plus": 14_249_000, - "households_total": 29_500_000, - "average_household_size": 2.36, - }, - 2029: { - "population_total": 69_984_000, - "population_age_0_15": 12_588_000, - "population_age_16_64": 42_891_000, - "population_age_65_plus": 14_505_000, - "households_total": 29_750_000, - "average_household_size": 2.35, - }, - 2030: { - "population_total": 70_306_000, - "population_age_0_15": 12_619_000, - "population_age_16_64": 42_927_000, - "population_age_65_plus": 14_760_000, - "households_total": 30_000_000, - "average_household_size": 2.34, - }, - 2031: { - "population_total": 70_622_000, - "population_age_0_15": 12_649_000, - "population_age_16_64": 42_960_000, - "population_age_65_plus": 15_013_000, - "households_total": 30_250_000, - "average_household_size": 2.34, - }, - 2032: { - "population_total": 70_933_000, - "population_age_0_15": 12_678_000, - "population_age_16_64": 42_991_000, - "population_age_65_plus": 15_264_000, - "households_total": 30_500_000, - "average_household_size": 2.33, - }, - 2033: { - "population_total": 71_240_000, - "population_age_0_15": 12_706_000, - "population_age_16_64": 43_020_000, - "population_age_65_plus": 15_514_000, - "households_total": 30_750_000, - "average_household_size": 2.32, - }, - 2034: { - "population_total": 71_543_000, - "population_age_0_15": 12_733_000, - "population_age_16_64": 43_047_000, - "population_age_65_plus": 15_763_000, - "households_total": 31_000_000, - "average_household_size": 2.31, - }, -} - -SOURCE_URL = "https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections" - - -def get_or_create_stratum( - session: Session, - name: str, - jurisdiction: Jurisdiction, - constraints: list[tuple[str, str, str]], - description: str | None = None, - parent_id: int | None = None, - stratum_group_id: str | None = None, -) -> Stratum: - """Get existing stratum or create new one.""" - definition_hash = Stratum.compute_hash(constraints, jurisdiction) - - existing = session.exec( - select(Stratum).where(Stratum.definition_hash == definition_hash) - ).first() - - if existing: - return existing - - stratum = Stratum( - name=name, - description=description, - jurisdiction=jurisdiction, - definition_hash=definition_hash, - parent_id=parent_id, - stratum_group_id=stratum_group_id, - ) - session.add(stratum) - session.flush() - - for variable, operator, value in constraints: - constraint = StratumConstraint( - stratum_id=stratum.id, - variable=variable, - operator=operator, - value=value, - ) - session.add(constraint) - - return stratum - - -def load_ons_targets(session: Session, years: list[int] | None = None): - """ - Load ONS population and household projections into database. - - Args: - session: Database session - years: Years to load (default: all available 2024-2034) - """ - if years is None: - years = list(ONS_DATA.keys()) - - for year in years: - if year not in ONS_DATA: - continue - - data = ONS_DATA[year] - - # UK population stratum - population_stratum = get_or_create_stratum( - session, - name="UK Population", - jurisdiction=Jurisdiction.UK, - constraints=[("entity_type", "==", "person")], # Person-level data - description="UK total population and age group breakdowns", - stratum_group_id="ons_population", - ) - - # Population count targets - population_vars = [ - ("population_total", TargetType.COUNT), - ("population_age_0_15", TargetType.COUNT), - ("population_age_16_64", TargetType.COUNT), - ("population_age_65_plus", TargetType.COUNT), - ] - - for var_name, var_type in population_vars: - if var_name not in data: - continue - - # Check for existing target - existing = session.exec( - select(Target).where( - Target.stratum_id == population_stratum.id, - Target.variable == var_name, - Target.period == year, - Target.source == DataSource.ONS, - ) - ).first() - - if existing: - continue - - session.add( - Target( - stratum_id=population_stratum.id, - variable=var_name, - period=year, - value=data[var_name], - target_type=var_type, - source=DataSource.ONS, - source_url=SOURCE_URL, - is_preliminary=True, # All projections are preliminary - ) - ) - - # UK households stratum - households_stratum = get_or_create_stratum( - session, - name="UK Households", - jurisdiction=Jurisdiction.UK, - constraints=[("entity_type", "==", "household")], # Household-level data - description="UK household projections", - stratum_group_id="ons_households", - ) - - # Household count targets - if "households_total" in data: - existing = session.exec( - select(Target).where( - Target.stratum_id == households_stratum.id, - Target.variable == "households_total", - Target.period == year, - Target.source == DataSource.ONS, - ) - ).first() - - if not existing: - session.add( - Target( - stratum_id=households_stratum.id, - variable="households_total", - period=year, - value=data["households_total"], - target_type=TargetType.COUNT, - source=DataSource.ONS, - source_url=SOURCE_URL, - is_preliminary=True, - ) - ) - - # Average household size (rate) - if "average_household_size" in data: - existing = session.exec( - select(Target).where( - Target.stratum_id == households_stratum.id, - Target.variable == "average_household_size", - Target.period == year, - Target.source == DataSource.ONS, - ) - ).first() - - if not existing: - session.add( - Target( - stratum_id=households_stratum.id, - variable="average_household_size", - period=year, - value=data["average_household_size"], - target_type=TargetType.RATE, - source=DataSource.ONS, - source_url=SOURCE_URL, - is_preliminary=True, - ) - ) - - session.commit() - - -def run_etl(db_path=None): - """Run the ONS ETL pipeline.""" - from pathlib import Path - from .schema import DEFAULT_DB_PATH - - path = Path(db_path) if db_path else DEFAULT_DB_PATH - engine = init_db(path) - - with Session(engine) as session: - load_ons_targets(session) - print(f"Loaded ONS projections to {path}") - - -if __name__ == "__main__": - run_etl() diff --git a/docs/pe-uk-source-checklist.md b/docs/pe-uk-source-checklist.md index d5bd6b67..1326b653 100644 --- a/docs/pe-uk-source-checklist.md +++ b/docs/pe-uk-source-checklist.md @@ -95,9 +95,36 @@ cannot be obtained. Nothing in uk-data is absent from this table. ## Legacy ETL cleanup -The pre-package `db/etl_obr.py` / `db/etl_ons.py` dicts are superseded by these -packages; cleanup tracked in -[#135](https://github.com/PolicyEngine/chronicle/issues/135). +| ETL series | Chronicle package concept | new package | gap | +|---|---|---|---| +| `db/etl_obr.py` `gdp` (2024-2029) | `obr.nominal_gdp_nsa` (calendar-year nominal GDP, GBP) | `obr-efo-economy-march-2026` | None for 2024-2029. Source table 1.4 publishes calendar-year nominal GDP in GBP billion; Chronicle stores the published level with `value_scale`. | +| `db/etl_obr.py` `total_receipts` (2024-2029) | `obr.public_sector_current_receipts` (fiscal-year public sector current receipts, GBP) | `obr-efo-aggregates-march-2026` | FY2024-25 remains a gap in the staged aggregates workbook: sheet 6.2 starts the public-sector current-receipts row at FY2025-26. FY2025-26 through FY2029-30 are ported. | +| `db/etl_obr.py` `total_managed_expenditure` (2024-2029) | `obr.total_managed_expenditure` (fiscal-year TME, GBP) | `obr-efo-aggregates-march-2026` | FY2024-25 remains a gap in the staged aggregates workbook: sheet 6.1 starts the TME row at FY2025-26. FY2025-26 through FY2029-30 are ported. | +| `db/etl_obr.py` `public_sector_net_borrowing` (2024-2029) | `obr.public_sector_net_borrowing` (fiscal-year net borrowing, GBP) | `obr-efo-aggregates-march-2026` | FY2024-25 remains a gap in the staged aggregates workbook: sheet 6.5 starts the net-borrowing row at FY2025-26. FY2025-26 through FY2029-30 are ported. | +| `db/etl_obr.py` `public_sector_net_debt` (2024-2029) | `obr.public_sector_net_debt_percent_gdp` (fiscal-year PSND, percent of GDP) | `obr-efo-aggregates-march-2026` | The staged aggregates workbook publishes PSND directly as percent of GDP in sheet 6.13, not as a GBP amount. The old ETL's GBP amount remains a gap because converting percent of GDP to GBP would be Chronicle-computed. | +| `db/etl_obr.py` `real_gdp_growth` (2024-2029) | — | — | Gap: the staged economy workbook publishes real GDP levels in sheet 1.1; annual real GDP growth would be derived from those levels and is therefore not a Chronicle fact. | +| `db/etl_obr.py` `unemployment_rate` (2024-2029) | `obr.ilo_unemployment_rate_16_plus` | `obr-efo-economy-march-2026` | None for 2024-2029. Source table 1.6 publishes calendar-year ILO unemployment rate, 16+, percent. | +| `db/etl_obr.py` `cpi_inflation` (2024-2029) | `obr.cpi_inflation` | `obr-efo-economy-march-2026` | None for 2024-2029. Source table 1.7 publishes CPI year-on-year growth. | +| `db/etl_obr.py` `rpi_inflation` (2024-2029) | `obr.rpi_inflation` | `obr-efo-economy-march-2026` | None for 2024-2029. Source table 1.7 publishes RPI year-on-year growth. | +| `db/etl_obr.py` `bank_rate` (2024-2029) | `obr.bank_rate` | `obr-efo-economy-march-2026` | None for 2024-2029. Source table 1.9 publishes the Bank Rate conditioning assumption. | +| `db/etl_obr.py` `employment` (2024-2029) | `obr.employment_16_plus` | `obr-efo-economy-march-2026` | None for 2024-2029. Source table 1.6 publishes calendar-year employment, 16+, in millions; Chronicle stores the published level with `value_scale`. | +| `db/etl_ons.py` `population_total` (2024-2034) | `ons.mid_year_population_estimate` for 2024; `ons.projected_population_principal` for 2024-based projections | existing `ons-mye-2024-uk`; existing `ons-uk-population-projections-2024` | None for 2024-2034 at fact level. The packages publish single-age/sex rows; broad totals are consumer rollups, not separate Chronicle-computed facts. | +| `db/etl_ons.py` `population_age_0_15` (2024-2034) | `ons.mid_year_population_estimate` for 2024; `ons.projected_population_principal` for 2024-based projections | existing `ons-mye-2024-uk`; existing `ons-uk-population-projections-2024` | None for 2024-2034 at fact level. The broad band is a consumer rollup from source-published single-age rows. | +| `db/etl_ons.py` `population_age_16_64` (2024-2034) | `ons.mid_year_population_estimate` for 2024; `ons.projected_population_principal` for 2024-based projections | existing `ons-mye-2024-uk`; existing `ons-uk-population-projections-2024` | None for 2024-2034 at fact level. The broad band is a consumer rollup from source-published single-age rows. | +| `db/etl_ons.py` `population_age_65_plus` (2024-2034) | `ons.mid_year_population_estimate` for 2024; `ons.projected_population_principal` for 2024-based projections | existing `ons-mye-2024-uk`; existing `ons-uk-population-projections-2024` | None for 2024-2034 at fact level. The broad band is a consumer rollup from source-published single-age rows. | +| `db/etl_ons.py` `households_total` (2024-2034) | `ons.households_total` for 2024-2025; `ons.households_by_type` and census TS041 for household-count source surfaces | existing `ons-families-households-2025` (new Table 5 record sets); existing census household packages | 2026-2034 remain gaps for UK household projections: the committed ONS Families & Households workbook publishes estimates through 2025 only. | +| `db/etl_ons.py` `average_household_size` (2024-2034) | `ons.average_household_size` for 2024-2025 | existing `ons-families-households-2025` (new Table 5 record sets) | 2026-2034 remain gaps: the committed ONS Families & Households workbook publishes average household size through 2025 only. | +| `db/etl_hmrc.py` `income_tax` (2021-2022) | Existing adjacent package concepts include `obr.income_tax` forecasts and HMRC SPI income-distribution inputs, but not the exact national HMRC liability totals in this ETL. | — | Gap for the ETL's 2021-2022 hardcoded national amount; not ported in PR A. | +| `db/etl_hmrc.py` `national_insurance` (2021-2022) | Existing adjacent package concepts include OBR NI receipt forecasts, but not the exact HMRC national amount in this ETL. | — | Gap for the ETL's 2021-2022 hardcoded national amount; not ported in PR A. | +| `db/etl_hmrc.py` `capital_gains_tax` (2021-2022) | Existing adjacent package concepts include `hmrc.cgt_*` taxpayer/statistics rows and `obr.capital_gains_tax` forecasts, but not the exact national ETL amount. | — | Gap for the ETL's 2021-2022 hardcoded national amount; not ported in PR A. | +| `db/etl_hmrc.py` `inheritance_tax` (2021-2022) | — | — | Gap: no covering package found in the local source-package inventory; not ported in PR A. | +| `db/etl_hmrc.py` `taxpayers`, `higher_rate_taxpayers`, `additional_rate_taxpayers` (2021-2022) | Existing adjacent SPI packages publish taxpayer/income-band facts for TY2023-24, not the ETL's 2021-2022 national counts. | — | Gap for the ETL's years and exact national band counts; not ported in PR A. | +| `db/etl_hmrc.py` `total_income` (2021-2022) | Existing SPI packages publish income distribution/count/mean/median concepts for TY2023-24, not the ETL's hardcoded national total-income amount. | — | Gap for the ETL's 2021-2022 hardcoded national amount; not ported in PR A. | +| `db/etl_hmrc.py` `benefits.universal_credit.{recipients,expenditure}` (2021-2022) | Existing DWP UC packages cover May 2025 household counts/splits, not the ETL's 2021-2022 national recipient and expenditure totals. | — | Gap for the ETL's hardcoded national benefit series; not ported in PR A. | +| `db/etl_hmrc.py` `benefits.child_benefit.{recipients,expenditure}` (2021-2022) | — | — | Gap: no covering package found in the local source-package inventory; not ported in PR A. | +| `db/etl_hmrc.py` `benefits.state_pension.{recipients,expenditure}` (2021-2022) | Existing adjacent SPI packages include state-pension income by income band, not DWP state-pension recipient/expenditure totals. | — | Gap for the ETL's hardcoded national benefit series; not ported in PR A. | +| `db/etl_hmrc.py` `benefits.housing_benefit.{recipients,expenditure}` (2021-2022) | Existing adjacent `obr.housing_benefit` expenditure forecasts do not cover recipient counts or the ETL's DWP 2021-2022 national expenditure totals. | — | Gap for the ETL's hardcoded national benefit series; not ported in PR A. | +| `db/etl_hmrc.py` `benefits.pension_credit.{recipients,expenditure}` (2021-2022) | Existing adjacent `obr.pension_credit` expenditure forecasts do not cover recipient counts or the ETL's DWP 2021-2022 national expenditure totals. | — | Gap for the ETL's hardcoded national benefit series; not ported in PR A. | ## Link-rot found during the migration diff --git a/packages/obr/efo_aggregates_march_2026/source_package.yaml b/packages/obr/efo_aggregates_march_2026/source_package.yaml new file mode 100644 index 00000000..5c945d40 --- /dev/null +++ b/packages/obr/efo_aggregates_march_2026/source_package.yaml @@ -0,0 +1,912 @@ +schema_version: ledger.source_package.v1 +package_id: obr-efo-aggregates-march-2026 +label: 'OBR EFO March 2026 fiscal supplementary tables: aggregates' +artifact: + source_name: obr + source_table: 'EFO March 2026 fiscal supplementary tables: aggregates' + resource_package: db + resource_directory: data/obr/efo_aggregates_march_2026 + manifest: manifest.yaml + vintage: efo_march_2026 + extracted_at: '2026-08-19' + extraction_method: xlsx whole-workbook used-range cell parse + parser: xlsx_used_range + artifact_year: 2026 +record_sets: +- record_set_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2025.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2025 + sheet_name: '6.2' + period_type: fiscal_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_current_receipts + label: 'Current Receipts ' + ordinal: 0 + row_number: 78 + expected_row_header_column: B + expected_row_header: 'Current Receipts ' + table_record_kind: total + measures: + - measure_id: public_sector_current_receipts + label: Current Receipts , FY2025-26 + ordinal: 0 + column: D + source_column_id: public_sector_current_receipts + concept: obr.public_sector_current_receipts + source_concept: obr.efo_aggregates.public_sector_current_receipts + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.2, Public + Sector Current Receipts row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2025-26 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2026.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2026 + sheet_name: '6.2' + period_type: fiscal_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_current_receipts + label: 'Current Receipts ' + ordinal: 0 + row_number: 78 + expected_row_header_column: B + expected_row_header: 'Current Receipts ' + table_record_kind: total + measures: + - measure_id: public_sector_current_receipts + label: Current Receipts , FY2026-27 + ordinal: 0 + column: E + source_column_id: public_sector_current_receipts + concept: obr.public_sector_current_receipts + source_concept: obr.efo_aggregates.public_sector_current_receipts + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.2, Public + Sector Current Receipts row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2026-27 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2027.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2027 + sheet_name: '6.2' + period_type: fiscal_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_current_receipts + label: 'Current Receipts ' + ordinal: 0 + row_number: 78 + expected_row_header_column: B + expected_row_header: 'Current Receipts ' + table_record_kind: total + measures: + - measure_id: public_sector_current_receipts + label: Current Receipts , FY2027-28 + ordinal: 0 + column: F + source_column_id: public_sector_current_receipts + concept: obr.public_sector_current_receipts + source_concept: obr.efo_aggregates.public_sector_current_receipts + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.2, Public + Sector Current Receipts row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2027-28 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2028.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2028 + sheet_name: '6.2' + period_type: fiscal_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_current_receipts + label: 'Current Receipts ' + ordinal: 0 + row_number: 78 + expected_row_header_column: B + expected_row_header: 'Current Receipts ' + table_record_kind: total + measures: + - measure_id: public_sector_current_receipts + label: Current Receipts , FY2028-29 + ordinal: 0 + column: G + source_column_id: public_sector_current_receipts + concept: obr.public_sector_current_receipts + source_concept: obr.efo_aggregates.public_sector_current_receipts + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.2, Public + Sector Current Receipts row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2028-29 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2029.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_current_receipts.fy2029 + sheet_name: '6.2' + period_type: fiscal_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_current_receipts + label: 'Current Receipts ' + ordinal: 0 + row_number: 78 + expected_row_header_column: B + expected_row_header: 'Current Receipts ' + table_record_kind: total + measures: + - measure_id: public_sector_current_receipts + label: Current Receipts , FY2029-30 + ordinal: 0 + column: H + source_column_id: public_sector_current_receipts + concept: obr.public_sector_current_receipts + source_concept: obr.efo_aggregates.public_sector_current_receipts + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.2, Public + Sector Current Receipts row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2029-30 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2025.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2025 + sheet_name: '6.1' + period_type: fiscal_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: total_managed_expenditure + label: Total Managed Expenditure1 + ordinal: 0 + row_number: 101 + expected_row_header_column: B + expected_row_header: Total Managed Expenditure1 + table_record_kind: total + measures: + - measure_id: total_managed_expenditure + label: Total Managed Expenditure1, FY2025-26 + ordinal: 0 + column: D + source_column_id: total_managed_expenditure + concept: obr.total_managed_expenditure + source_concept: obr.efo_aggregates.total_managed_expenditure + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.1, Total + Managed Expenditure row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2025-26 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2026.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2026 + sheet_name: '6.1' + period_type: fiscal_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: total_managed_expenditure + label: Total Managed Expenditure1 + ordinal: 0 + row_number: 101 + expected_row_header_column: B + expected_row_header: Total Managed Expenditure1 + table_record_kind: total + measures: + - measure_id: total_managed_expenditure + label: Total Managed Expenditure1, FY2026-27 + ordinal: 0 + column: E + source_column_id: total_managed_expenditure + concept: obr.total_managed_expenditure + source_concept: obr.efo_aggregates.total_managed_expenditure + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.1, Total + Managed Expenditure row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2026-27 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2027.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2027 + sheet_name: '6.1' + period_type: fiscal_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: total_managed_expenditure + label: Total Managed Expenditure1 + ordinal: 0 + row_number: 101 + expected_row_header_column: B + expected_row_header: Total Managed Expenditure1 + table_record_kind: total + measures: + - measure_id: total_managed_expenditure + label: Total Managed Expenditure1, FY2027-28 + ordinal: 0 + column: F + source_column_id: total_managed_expenditure + concept: obr.total_managed_expenditure + source_concept: obr.efo_aggregates.total_managed_expenditure + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.1, Total + Managed Expenditure row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2027-28 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2028.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2028 + sheet_name: '6.1' + period_type: fiscal_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: total_managed_expenditure + label: Total Managed Expenditure1 + ordinal: 0 + row_number: 101 + expected_row_header_column: B + expected_row_header: Total Managed Expenditure1 + table_record_kind: total + measures: + - measure_id: total_managed_expenditure + label: Total Managed Expenditure1, FY2028-29 + ordinal: 0 + column: G + source_column_id: total_managed_expenditure + concept: obr.total_managed_expenditure + source_concept: obr.efo_aggregates.total_managed_expenditure + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.1, Total + Managed Expenditure row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2028-29 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2029.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.total_managed_expenditure.fy2029 + sheet_name: '6.1' + period_type: fiscal_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: total_managed_expenditure + label: Total Managed Expenditure1 + ordinal: 0 + row_number: 101 + expected_row_header_column: B + expected_row_header: Total Managed Expenditure1 + table_record_kind: total + measures: + - measure_id: total_managed_expenditure + label: Total Managed Expenditure1, FY2029-30 + ordinal: 0 + column: H + source_column_id: total_managed_expenditure + concept: obr.total_managed_expenditure + source_concept: obr.efo_aggregates.total_managed_expenditure + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.1, Total + Managed Expenditure row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2029-30 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2025.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2025 + sheet_name: '6.5' + period_type: fiscal_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_borrowing + label: Net borrowing + ordinal: 0 + row_number: 15 + expected_row_header_column: B + expected_row_header: Net borrowing + table_record_kind: total + measures: + - measure_id: public_sector_net_borrowing + label: Net borrowing, FY2025-26 + ordinal: 0 + column: C + source_column_id: public_sector_net_borrowing + concept: obr.public_sector_net_borrowing + source_concept: obr.efo_aggregates.public_sector_net_borrowing + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.5, Net + borrowing row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2025-26 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2026.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2026 + sheet_name: '6.5' + period_type: fiscal_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_borrowing + label: Net borrowing + ordinal: 0 + row_number: 15 + expected_row_header_column: B + expected_row_header: Net borrowing + table_record_kind: total + measures: + - measure_id: public_sector_net_borrowing + label: Net borrowing, FY2026-27 + ordinal: 0 + column: D + source_column_id: public_sector_net_borrowing + concept: obr.public_sector_net_borrowing + source_concept: obr.efo_aggregates.public_sector_net_borrowing + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.5, Net + borrowing row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2026-27 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2027.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2027 + sheet_name: '6.5' + period_type: fiscal_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_borrowing + label: Net borrowing + ordinal: 0 + row_number: 15 + expected_row_header_column: B + expected_row_header: Net borrowing + table_record_kind: total + measures: + - measure_id: public_sector_net_borrowing + label: Net borrowing, FY2027-28 + ordinal: 0 + column: E + source_column_id: public_sector_net_borrowing + concept: obr.public_sector_net_borrowing + source_concept: obr.efo_aggregates.public_sector_net_borrowing + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.5, Net + borrowing row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2027-28 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2028.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2028 + sheet_name: '6.5' + period_type: fiscal_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_borrowing + label: Net borrowing + ordinal: 0 + row_number: 15 + expected_row_header_column: B + expected_row_header: Net borrowing + table_record_kind: total + measures: + - measure_id: public_sector_net_borrowing + label: Net borrowing, FY2028-29 + ordinal: 0 + column: F + source_column_id: public_sector_net_borrowing + concept: obr.public_sector_net_borrowing + source_concept: obr.efo_aggregates.public_sector_net_borrowing + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.5, Net + borrowing row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2028-29 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2029.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2029 + sheet_name: '6.5' + period_type: fiscal_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_borrowing + label: Net borrowing + ordinal: 0 + row_number: 15 + expected_row_header_column: B + expected_row_header: Net borrowing + table_record_kind: total + measures: + - measure_id: public_sector_net_borrowing + label: Net borrowing, FY2029-30 + ordinal: 0 + column: G + source_column_id: public_sector_net_borrowing + concept: obr.public_sector_net_borrowing + source_concept: obr.efo_aggregates.public_sector_net_borrowing + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.5, Net + borrowing row, GBP billion. + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + expected_column_header_row: 5 + expected_column_header: 2029-30 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2024 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2024.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2024 + sheet_name: '6.13' + period_type: fiscal_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), per cent of GDP + ordinal: 0 + row_number: 31 + expected_row_header_column: B + expected_row_header: "Public sector net debt\n (PSND)(d+g)" + table_record_kind: total + measures: + - measure_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), FY2024-25 + ordinal: 0 + column: C + source_column_id: public_sector_net_debt_percent_gdp + concept: obr.public_sector_net_debt_percent_gdp + source_concept: obr.efo_aggregates.public_sector_net_debt + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.13, Public + sector net debt (PSND) row, per cent of GDP. + unit: percent_of_gdp + aggregation: sum + expected_cell_type: number + expected_column_header_row: 5 + expected_column_header: 2024-25 + assertion: observation +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2025.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2025 + sheet_name: '6.13' + period_type: fiscal_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), per cent of GDP + ordinal: 0 + row_number: 31 + expected_row_header_column: B + expected_row_header: "Public sector net debt\n (PSND)(d+g)" + table_record_kind: total + measures: + - measure_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), FY2025-26 + ordinal: 0 + column: D + source_column_id: public_sector_net_debt_percent_gdp + concept: obr.public_sector_net_debt_percent_gdp + source_concept: obr.efo_aggregates.public_sector_net_debt + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.13, Public + sector net debt (PSND) row, per cent of GDP. + unit: percent_of_gdp + aggregation: sum + expected_cell_type: number + expected_column_header_row: 5 + expected_column_header: 2025-26 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2026.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2026 + sheet_name: '6.13' + period_type: fiscal_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), per cent of GDP + ordinal: 0 + row_number: 31 + expected_row_header_column: B + expected_row_header: "Public sector net debt\n (PSND)(d+g)" + table_record_kind: total + measures: + - measure_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), FY2026-27 + ordinal: 0 + column: E + source_column_id: public_sector_net_debt_percent_gdp + concept: obr.public_sector_net_debt_percent_gdp + source_concept: obr.efo_aggregates.public_sector_net_debt + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.13, Public + sector net debt (PSND) row, per cent of GDP. + unit: percent_of_gdp + aggregation: sum + expected_cell_type: number + expected_column_header_row: 5 + expected_column_header: 2026-27 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2027.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2027 + sheet_name: '6.13' + period_type: fiscal_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), per cent of GDP + ordinal: 0 + row_number: 31 + expected_row_header_column: B + expected_row_header: "Public sector net debt\n (PSND)(d+g)" + table_record_kind: total + measures: + - measure_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), FY2027-28 + ordinal: 0 + column: F + source_column_id: public_sector_net_debt_percent_gdp + concept: obr.public_sector_net_debt_percent_gdp + source_concept: obr.efo_aggregates.public_sector_net_debt + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.13, Public + sector net debt (PSND) row, per cent of GDP. + unit: percent_of_gdp + aggregation: sum + expected_cell_type: number + expected_column_header_row: 5 + expected_column_header: 2027-28 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2028.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2028 + sheet_name: '6.13' + period_type: fiscal_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), per cent of GDP + ordinal: 0 + row_number: 31 + expected_row_header_column: B + expected_row_header: "Public sector net debt\n (PSND)(d+g)" + table_record_kind: total + measures: + - measure_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), FY2028-29 + ordinal: 0 + column: G + source_column_id: public_sector_net_debt_percent_gdp + concept: obr.public_sector_net_debt_percent_gdp + source_concept: obr.efo_aggregates.public_sector_net_debt + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.13, Public + sector net debt (PSND) row, per cent of GDP. + unit: percent_of_gdp + aggregation: sum + expected_cell_type: number + expected_column_header_row: 5 + expected_column_header: 2028-29 + assertion: source_projection +- record_set_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2029.v1 + source_record_id_prefix: obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2029 + sheet_name: '6.13' + period_type: fiscal_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: public_sector + domain: public_sector_finances + groupby_dimension: obr.efo_line + rows: + - value_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), per cent of GDP + ordinal: 0 + row_number: 31 + expected_row_header_column: B + expected_row_header: "Public sector net debt\n (PSND)(d+g)" + table_record_kind: total + measures: + - measure_id: public_sector_net_debt_percent_gdp + label: Public sector net debt (PSND), FY2029-30 + ordinal: 0 + column: H + source_column_id: public_sector_net_debt_percent_gdp + concept: obr.public_sector_net_debt_percent_gdp + source_concept: obr.efo_aggregates.public_sector_net_debt + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-aggregates/ + concept_evidence_notes: OBR EFO March 2026 fiscal supplementary tables, sheet 6.13, Public + sector net debt (PSND) row, per cent of GDP. + unit: percent_of_gdp + aggregation: sum + expected_cell_type: number + expected_column_header_row: 5 + expected_column_header: 2029-30 + assertion: source_projection diff --git a/packages/obr/efo_economy_march_2026/source_package.yaml b/packages/obr/efo_economy_march_2026/source_package.yaml new file mode 100644 index 00000000..5e74bd6e --- /dev/null +++ b/packages/obr/efo_economy_march_2026/source_package.yaml @@ -0,0 +1,1557 @@ +schema_version: ledger.source_package.v1 +package_id: obr-efo-economy-march-2026 +label: 'OBR EFO March 2026 detailed forecast tables: economy' +artifact: + source_name: obr + source_table: 'EFO March 2026 detailed forecast tables: economy' + resource_package: db + resource_directory: data/obr/efo_economy_march_2026 + manifest: manifest.yaml + vintage: efo_march_2026 + extracted_at: '2026-08-19' + extraction_method: xlsx whole-workbook used-range cell parse + parser: xlsx_used_range + artifact_year: 2026 +record_sets: +- record_set_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2024 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2024.v1 + source_record_id_prefix: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2024 + sheet_name: '1.4' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions + ordinal: 0 + row_number: 113 + expected_row_header_column: B + expected_row_header: 2024 + table_record_kind: total + guard_cells: + - column: B + row: 2 + expected_value: "1.4 Nominal GDP (\xA3 billion, non-seasonally adjusted)" + label: table title + measures: + - measure_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions, 2024 + ordinal: 0 + column: C + source_column_id: nominal_gdp_nsa + concept: obr.nominal_gdp_nsa + source_concept: obr.efo_economy.nominal_gdp_nsa + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: "OBR EFO March 2026 detailed forecast tables, sheet 1.4 ('Nominal\ + \ GDP (\xA3 billion, non-seasonally adjusted)'), calendar-year row; GBP billion." + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + assertion: observation +- record_set_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2025.v1 + source_record_id_prefix: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2025 + sheet_name: '1.4' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions + ordinal: 0 + row_number: 114 + expected_row_header_column: B + expected_row_header: 2025 + table_record_kind: total + guard_cells: + - column: B + row: 2 + expected_value: "1.4 Nominal GDP (\xA3 billion, non-seasonally adjusted)" + label: table title + measures: + - measure_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions, 2025 + ordinal: 0 + column: C + source_column_id: nominal_gdp_nsa + concept: obr.nominal_gdp_nsa + source_concept: obr.efo_economy.nominal_gdp_nsa + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: "OBR EFO March 2026 detailed forecast tables, sheet 1.4 ('Nominal\ + \ GDP (\xA3 billion, non-seasonally adjusted)'), calendar-year row; GBP billion." + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2026.v1 + source_record_id_prefix: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2026 + sheet_name: '1.4' + period_type: calendar_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions + ordinal: 0 + row_number: 115 + expected_row_header_column: B + expected_row_header: 2026 + table_record_kind: total + guard_cells: + - column: B + row: 2 + expected_value: "1.4 Nominal GDP (\xA3 billion, non-seasonally adjusted)" + label: table title + measures: + - measure_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions, 2026 + ordinal: 0 + column: C + source_column_id: nominal_gdp_nsa + concept: obr.nominal_gdp_nsa + source_concept: obr.efo_economy.nominal_gdp_nsa + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: "OBR EFO March 2026 detailed forecast tables, sheet 1.4 ('Nominal\ + \ GDP (\xA3 billion, non-seasonally adjusted)'), calendar-year row; GBP billion." + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2027.v1 + source_record_id_prefix: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2027 + sheet_name: '1.4' + period_type: calendar_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions + ordinal: 0 + row_number: 116 + expected_row_header_column: B + expected_row_header: 2027 + table_record_kind: total + guard_cells: + - column: B + row: 2 + expected_value: "1.4 Nominal GDP (\xA3 billion, non-seasonally adjusted)" + label: table title + measures: + - measure_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions, 2027 + ordinal: 0 + column: C + source_column_id: nominal_gdp_nsa + concept: obr.nominal_gdp_nsa + source_concept: obr.efo_economy.nominal_gdp_nsa + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: "OBR EFO March 2026 detailed forecast tables, sheet 1.4 ('Nominal\ + \ GDP (\xA3 billion, non-seasonally adjusted)'), calendar-year row; GBP billion." + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2028.v1 + source_record_id_prefix: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2028 + sheet_name: '1.4' + period_type: calendar_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions + ordinal: 0 + row_number: 117 + expected_row_header_column: B + expected_row_header: 2028 + table_record_kind: total + guard_cells: + - column: B + row: 2 + expected_value: "1.4 Nominal GDP (\xA3 billion, non-seasonally adjusted)" + label: table title + measures: + - measure_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions, 2028 + ordinal: 0 + column: C + source_column_id: nominal_gdp_nsa + concept: obr.nominal_gdp_nsa + source_concept: obr.efo_economy.nominal_gdp_nsa + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: "OBR EFO March 2026 detailed forecast tables, sheet 1.4 ('Nominal\ + \ GDP (\xA3 billion, non-seasonally adjusted)'), calendar-year row; GBP billion." + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2029.v1 + source_record_id_prefix: obr.efo_2026_03.economy.nominal_gdp_nsa.cy2029 + sheet_name: '1.4' + period_type: calendar_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions + ordinal: 0 + row_number: 118 + expected_row_header_column: B + expected_row_header: 2029 + table_record_kind: total + guard_cells: + - column: B + row: 2 + expected_value: "1.4 Nominal GDP (\xA3 billion, non-seasonally adjusted)" + label: table title + measures: + - measure_id: nominal_gdp_nsa + label: Nominal GDP NSA, billions, 2029 + ordinal: 0 + column: C + source_column_id: nominal_gdp_nsa + concept: obr.nominal_gdp_nsa + source_concept: obr.efo_economy.nominal_gdp_nsa + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: "OBR EFO March 2026 detailed forecast tables, sheet 1.4 ('Nominal\ + \ GDP (\xA3 billion, non-seasonally adjusted)'), calendar-year row; GBP billion." + unit: gbp + aggregation: sum + expected_cell_type: number + value_scale: 1000000000 + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.employment_16_plus.cy2024 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.employment_16_plus.cy2024.v1 + source_record_id_prefix: obr.efo_2026_03.economy.employment_16_plus.cy2024 + sheet_name: '1.6' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: employment_16_plus + label: Employment (16+, millions) + ordinal: 0 + row_number: 113 + expected_row_header_column: B + expected_row_header: 2024 + table_record_kind: total + measures: + - measure_id: employment_16_plus + label: Employment (16+, millions), 2024 + ordinal: 0 + column: C + source_column_id: employment_16_plus + concept: obr.employment_16_plus + source_concept: obr.efo_economy.employment_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'Employment (16+, millions)'. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000000 + expected_column_header_row: 3 + expected_column_header: Employment (16+, millions) + assertion: observation +- record_set_id: obr.efo_2026_03.economy.employment_16_plus.cy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.employment_16_plus.cy2025.v1 + source_record_id_prefix: obr.efo_2026_03.economy.employment_16_plus.cy2025 + sheet_name: '1.6' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: employment_16_plus + label: Employment (16+, millions) + ordinal: 0 + row_number: 114 + expected_row_header_column: B + expected_row_header: 2025 + table_record_kind: total + measures: + - measure_id: employment_16_plus + label: Employment (16+, millions), 2025 + ordinal: 0 + column: C + source_column_id: employment_16_plus + concept: obr.employment_16_plus + source_concept: obr.efo_economy.employment_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'Employment (16+, millions)'. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000000 + expected_column_header_row: 3 + expected_column_header: Employment (16+, millions) + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.employment_16_plus.cy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.employment_16_plus.cy2026.v1 + source_record_id_prefix: obr.efo_2026_03.economy.employment_16_plus.cy2026 + sheet_name: '1.6' + period_type: calendar_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: employment_16_plus + label: Employment (16+, millions) + ordinal: 0 + row_number: 115 + expected_row_header_column: B + expected_row_header: 2026 + table_record_kind: total + measures: + - measure_id: employment_16_plus + label: Employment (16+, millions), 2026 + ordinal: 0 + column: C + source_column_id: employment_16_plus + concept: obr.employment_16_plus + source_concept: obr.efo_economy.employment_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'Employment (16+, millions)'. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000000 + expected_column_header_row: 3 + expected_column_header: Employment (16+, millions) + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.employment_16_plus.cy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.employment_16_plus.cy2027.v1 + source_record_id_prefix: obr.efo_2026_03.economy.employment_16_plus.cy2027 + sheet_name: '1.6' + period_type: calendar_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: employment_16_plus + label: Employment (16+, millions) + ordinal: 0 + row_number: 116 + expected_row_header_column: B + expected_row_header: 2027 + table_record_kind: total + measures: + - measure_id: employment_16_plus + label: Employment (16+, millions), 2027 + ordinal: 0 + column: C + source_column_id: employment_16_plus + concept: obr.employment_16_plus + source_concept: obr.efo_economy.employment_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'Employment (16+, millions)'. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000000 + expected_column_header_row: 3 + expected_column_header: Employment (16+, millions) + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.employment_16_plus.cy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.employment_16_plus.cy2028.v1 + source_record_id_prefix: obr.efo_2026_03.economy.employment_16_plus.cy2028 + sheet_name: '1.6' + period_type: calendar_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: employment_16_plus + label: Employment (16+, millions) + ordinal: 0 + row_number: 117 + expected_row_header_column: B + expected_row_header: 2028 + table_record_kind: total + measures: + - measure_id: employment_16_plus + label: Employment (16+, millions), 2028 + ordinal: 0 + column: C + source_column_id: employment_16_plus + concept: obr.employment_16_plus + source_concept: obr.efo_economy.employment_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'Employment (16+, millions)'. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000000 + expected_column_header_row: 3 + expected_column_header: Employment (16+, millions) + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.employment_16_plus.cy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.employment_16_plus.cy2029.v1 + source_record_id_prefix: obr.efo_2026_03.economy.employment_16_plus.cy2029 + sheet_name: '1.6' + period_type: calendar_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: employment_16_plus + label: Employment (16+, millions) + ordinal: 0 + row_number: 118 + expected_row_header_column: B + expected_row_header: 2029 + table_record_kind: total + measures: + - measure_id: employment_16_plus + label: Employment (16+, millions), 2029 + ordinal: 0 + column: C + source_column_id: employment_16_plus + concept: obr.employment_16_plus + source_concept: obr.efo_economy.employment_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'Employment (16+, millions)'. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000000 + expected_column_header_row: 3 + expected_column_header: Employment (16+, millions) + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2024 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2024.v1 + source_record_id_prefix: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2024 + sheet_name: '1.6' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent) + ordinal: 0 + row_number: 113 + expected_row_header_column: B + expected_row_header: 2024 + table_record_kind: total + measures: + - measure_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent), 2024 + ordinal: 0 + column: G + source_column_id: ilo_unemployment_rate_16_plus + concept: obr.ilo_unemployment_rate_16_plus + source_concept: obr.efo_economy.ilo_unemployment_rate_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'ILO unemployment rate (16+, per cent)'. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: "ILO unemployment rate \n(16+, per cent)" + assertion: observation +- record_set_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2025.v1 + source_record_id_prefix: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2025 + sheet_name: '1.6' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent) + ordinal: 0 + row_number: 114 + expected_row_header_column: B + expected_row_header: 2025 + table_record_kind: total + measures: + - measure_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent), 2025 + ordinal: 0 + column: G + source_column_id: ilo_unemployment_rate_16_plus + concept: obr.ilo_unemployment_rate_16_plus + source_concept: obr.efo_economy.ilo_unemployment_rate_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'ILO unemployment rate (16+, per cent)'. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: "ILO unemployment rate \n(16+, per cent)" + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2026.v1 + source_record_id_prefix: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2026 + sheet_name: '1.6' + period_type: calendar_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent) + ordinal: 0 + row_number: 115 + expected_row_header_column: B + expected_row_header: 2026 + table_record_kind: total + measures: + - measure_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent), 2026 + ordinal: 0 + column: G + source_column_id: ilo_unemployment_rate_16_plus + concept: obr.ilo_unemployment_rate_16_plus + source_concept: obr.efo_economy.ilo_unemployment_rate_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'ILO unemployment rate (16+, per cent)'. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: "ILO unemployment rate \n(16+, per cent)" + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2027.v1 + source_record_id_prefix: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2027 + sheet_name: '1.6' + period_type: calendar_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent) + ordinal: 0 + row_number: 116 + expected_row_header_column: B + expected_row_header: 2027 + table_record_kind: total + measures: + - measure_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent), 2027 + ordinal: 0 + column: G + source_column_id: ilo_unemployment_rate_16_plus + concept: obr.ilo_unemployment_rate_16_plus + source_concept: obr.efo_economy.ilo_unemployment_rate_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'ILO unemployment rate (16+, per cent)'. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: "ILO unemployment rate \n(16+, per cent)" + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2028.v1 + source_record_id_prefix: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2028 + sheet_name: '1.6' + period_type: calendar_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent) + ordinal: 0 + row_number: 117 + expected_row_header_column: B + expected_row_header: 2028 + table_record_kind: total + measures: + - measure_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent), 2028 + ordinal: 0 + column: G + source_column_id: ilo_unemployment_rate_16_plus + concept: obr.ilo_unemployment_rate_16_plus + source_concept: obr.efo_economy.ilo_unemployment_rate_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'ILO unemployment rate (16+, per cent)'. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: "ILO unemployment rate \n(16+, per cent)" + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2029.v1 + source_record_id_prefix: obr.efo_2026_03.economy.ilo_unemployment_rate_16_plus.cy2029 + sheet_name: '1.6' + period_type: calendar_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent) + ordinal: 0 + row_number: 118 + expected_row_header_column: B + expected_row_header: 2029 + table_record_kind: total + measures: + - measure_id: ilo_unemployment_rate_16_plus + label: ILO unemployment rate (16+, per cent), 2029 + ordinal: 0 + column: G + source_column_id: ilo_unemployment_rate_16_plus + concept: obr.ilo_unemployment_rate_16_plus + source_concept: obr.efo_economy.ilo_unemployment_rate_16_plus + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.6, calendar-year + row, column 'ILO unemployment rate (16+, per cent)'. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: "ILO unemployment rate \n(16+, per cent)" + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.rpi_inflation.cy2024 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.rpi_inflation.cy2024.v1 + source_record_id_prefix: obr.efo_2026_03.economy.rpi_inflation.cy2024 + sheet_name: '1.7' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: rpi_inflation + label: RPI year-on-year growth + ordinal: 0 + row_number: 114 + expected_row_header_column: B + expected_row_header: 2024 + table_record_kind: total + measures: + - measure_id: rpi_inflation + label: RPI year-on-year growth, 2024 + ordinal: 0 + column: C + source_column_id: rpi_inflation + concept: obr.rpi_inflation + source_concept: obr.efo_economy.rpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, RPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: RPI + assertion: observation +- record_set_id: obr.efo_2026_03.economy.rpi_inflation.cy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.rpi_inflation.cy2025.v1 + source_record_id_prefix: obr.efo_2026_03.economy.rpi_inflation.cy2025 + sheet_name: '1.7' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: rpi_inflation + label: RPI year-on-year growth + ordinal: 0 + row_number: 115 + expected_row_header_column: B + expected_row_header: 2025 + table_record_kind: total + measures: + - measure_id: rpi_inflation + label: RPI year-on-year growth, 2025 + ordinal: 0 + column: C + source_column_id: rpi_inflation + concept: obr.rpi_inflation + source_concept: obr.efo_economy.rpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, RPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: RPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.rpi_inflation.cy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.rpi_inflation.cy2026.v1 + source_record_id_prefix: obr.efo_2026_03.economy.rpi_inflation.cy2026 + sheet_name: '1.7' + period_type: calendar_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: rpi_inflation + label: RPI year-on-year growth + ordinal: 0 + row_number: 116 + expected_row_header_column: B + expected_row_header: 2026 + table_record_kind: total + measures: + - measure_id: rpi_inflation + label: RPI year-on-year growth, 2026 + ordinal: 0 + column: C + source_column_id: rpi_inflation + concept: obr.rpi_inflation + source_concept: obr.efo_economy.rpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, RPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: RPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.rpi_inflation.cy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.rpi_inflation.cy2027.v1 + source_record_id_prefix: obr.efo_2026_03.economy.rpi_inflation.cy2027 + sheet_name: '1.7' + period_type: calendar_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: rpi_inflation + label: RPI year-on-year growth + ordinal: 0 + row_number: 117 + expected_row_header_column: B + expected_row_header: 2027 + table_record_kind: total + measures: + - measure_id: rpi_inflation + label: RPI year-on-year growth, 2027 + ordinal: 0 + column: C + source_column_id: rpi_inflation + concept: obr.rpi_inflation + source_concept: obr.efo_economy.rpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, RPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: RPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.rpi_inflation.cy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.rpi_inflation.cy2028.v1 + source_record_id_prefix: obr.efo_2026_03.economy.rpi_inflation.cy2028 + sheet_name: '1.7' + period_type: calendar_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: rpi_inflation + label: RPI year-on-year growth + ordinal: 0 + row_number: 118 + expected_row_header_column: B + expected_row_header: 2028 + table_record_kind: total + measures: + - measure_id: rpi_inflation + label: RPI year-on-year growth, 2028 + ordinal: 0 + column: C + source_column_id: rpi_inflation + concept: obr.rpi_inflation + source_concept: obr.efo_economy.rpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, RPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: RPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.rpi_inflation.cy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.rpi_inflation.cy2029.v1 + source_record_id_prefix: obr.efo_2026_03.economy.rpi_inflation.cy2029 + sheet_name: '1.7' + period_type: calendar_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: rpi_inflation + label: RPI year-on-year growth + ordinal: 0 + row_number: 119 + expected_row_header_column: B + expected_row_header: 2029 + table_record_kind: total + measures: + - measure_id: rpi_inflation + label: RPI year-on-year growth, 2029 + ordinal: 0 + column: C + source_column_id: rpi_inflation + concept: obr.rpi_inflation + source_concept: obr.efo_economy.rpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, RPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: RPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.cpi_inflation.cy2024 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.cpi_inflation.cy2024.v1 + source_record_id_prefix: obr.efo_2026_03.economy.cpi_inflation.cy2024 + sheet_name: '1.7' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: cpi_inflation + label: CPI year-on-year growth + ordinal: 0 + row_number: 114 + expected_row_header_column: B + expected_row_header: 2024 + table_record_kind: total + measures: + - measure_id: cpi_inflation + label: CPI year-on-year growth, 2024 + ordinal: 0 + column: E + source_column_id: cpi_inflation + concept: obr.cpi_inflation + source_concept: obr.efo_economy.cpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, CPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: CPI + assertion: observation +- record_set_id: obr.efo_2026_03.economy.cpi_inflation.cy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.cpi_inflation.cy2025.v1 + source_record_id_prefix: obr.efo_2026_03.economy.cpi_inflation.cy2025 + sheet_name: '1.7' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: cpi_inflation + label: CPI year-on-year growth + ordinal: 0 + row_number: 115 + expected_row_header_column: B + expected_row_header: 2025 + table_record_kind: total + measures: + - measure_id: cpi_inflation + label: CPI year-on-year growth, 2025 + ordinal: 0 + column: E + source_column_id: cpi_inflation + concept: obr.cpi_inflation + source_concept: obr.efo_economy.cpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, CPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: CPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.cpi_inflation.cy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.cpi_inflation.cy2026.v1 + source_record_id_prefix: obr.efo_2026_03.economy.cpi_inflation.cy2026 + sheet_name: '1.7' + period_type: calendar_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: cpi_inflation + label: CPI year-on-year growth + ordinal: 0 + row_number: 116 + expected_row_header_column: B + expected_row_header: 2026 + table_record_kind: total + measures: + - measure_id: cpi_inflation + label: CPI year-on-year growth, 2026 + ordinal: 0 + column: E + source_column_id: cpi_inflation + concept: obr.cpi_inflation + source_concept: obr.efo_economy.cpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, CPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: CPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.cpi_inflation.cy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.cpi_inflation.cy2027.v1 + source_record_id_prefix: obr.efo_2026_03.economy.cpi_inflation.cy2027 + sheet_name: '1.7' + period_type: calendar_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: cpi_inflation + label: CPI year-on-year growth + ordinal: 0 + row_number: 117 + expected_row_header_column: B + expected_row_header: 2027 + table_record_kind: total + measures: + - measure_id: cpi_inflation + label: CPI year-on-year growth, 2027 + ordinal: 0 + column: E + source_column_id: cpi_inflation + concept: obr.cpi_inflation + source_concept: obr.efo_economy.cpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, CPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: CPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.cpi_inflation.cy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.cpi_inflation.cy2028.v1 + source_record_id_prefix: obr.efo_2026_03.economy.cpi_inflation.cy2028 + sheet_name: '1.7' + period_type: calendar_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: cpi_inflation + label: CPI year-on-year growth + ordinal: 0 + row_number: 118 + expected_row_header_column: B + expected_row_header: 2028 + table_record_kind: total + measures: + - measure_id: cpi_inflation + label: CPI year-on-year growth, 2028 + ordinal: 0 + column: E + source_column_id: cpi_inflation + concept: obr.cpi_inflation + source_concept: obr.efo_economy.cpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, CPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: CPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.cpi_inflation.cy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.cpi_inflation.cy2029.v1 + source_record_id_prefix: obr.efo_2026_03.economy.cpi_inflation.cy2029 + sheet_name: '1.7' + period_type: calendar_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: cpi_inflation + label: CPI year-on-year growth + ordinal: 0 + row_number: 119 + expected_row_header_column: B + expected_row_header: 2029 + table_record_kind: total + measures: + - measure_id: cpi_inflation + label: CPI year-on-year growth, 2029 + ordinal: 0 + column: E + source_column_id: cpi_inflation + concept: obr.cpi_inflation + source_concept: obr.efo_economy.cpi_inflation + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.7, calendar-year + row, CPI year-on-year growth column. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 4 + expected_column_header: CPI + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.bank_rate.cy2024 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.bank_rate.cy2024.v1 + source_record_id_prefix: obr.efo_2026_03.economy.bank_rate.cy2024 + sheet_name: '1.9' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: bank_rate + label: Bank Rate + ordinal: 0 + row_number: 113 + expected_row_header_column: B + expected_row_header: 2024 + table_record_kind: total + measures: + - measure_id: bank_rate + label: Bank Rate, 2024 + ordinal: 0 + column: C + source_column_id: bank_rate + concept: obr.bank_rate + source_concept: obr.efo_economy.bank_rate + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.9, calendar-year + row, Bank Rate conditioning assumption. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: Bank Rate + assertion: observation +- record_set_id: obr.efo_2026_03.economy.bank_rate.cy2025 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.bank_rate.cy2025.v1 + source_record_id_prefix: obr.efo_2026_03.economy.bank_rate.cy2025 + sheet_name: '1.9' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: bank_rate + label: Bank Rate + ordinal: 0 + row_number: 114 + expected_row_header_column: B + expected_row_header: 2025 + table_record_kind: total + measures: + - measure_id: bank_rate + label: Bank Rate, 2025 + ordinal: 0 + column: C + source_column_id: bank_rate + concept: obr.bank_rate + source_concept: obr.efo_economy.bank_rate + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.9, calendar-year + row, Bank Rate conditioning assumption. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: Bank Rate + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.bank_rate.cy2026 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.bank_rate.cy2026.v1 + source_record_id_prefix: obr.efo_2026_03.economy.bank_rate.cy2026 + sheet_name: '1.9' + period_type: calendar_year + period: 2026 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: bank_rate + label: Bank Rate + ordinal: 0 + row_number: 115 + expected_row_header_column: B + expected_row_header: 2026 + table_record_kind: total + measures: + - measure_id: bank_rate + label: Bank Rate, 2026 + ordinal: 0 + column: C + source_column_id: bank_rate + concept: obr.bank_rate + source_concept: obr.efo_economy.bank_rate + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.9, calendar-year + row, Bank Rate conditioning assumption. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: Bank Rate + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.bank_rate.cy2027 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.bank_rate.cy2027.v1 + source_record_id_prefix: obr.efo_2026_03.economy.bank_rate.cy2027 + sheet_name: '1.9' + period_type: calendar_year + period: 2027 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: bank_rate + label: Bank Rate + ordinal: 0 + row_number: 116 + expected_row_header_column: B + expected_row_header: 2027 + table_record_kind: total + measures: + - measure_id: bank_rate + label: Bank Rate, 2027 + ordinal: 0 + column: C + source_column_id: bank_rate + concept: obr.bank_rate + source_concept: obr.efo_economy.bank_rate + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.9, calendar-year + row, Bank Rate conditioning assumption. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: Bank Rate + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.bank_rate.cy2028 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.bank_rate.cy2028.v1 + source_record_id_prefix: obr.efo_2026_03.economy.bank_rate.cy2028 + sheet_name: '1.9' + period_type: calendar_year + period: 2028 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: bank_rate + label: Bank Rate + ordinal: 0 + row_number: 117 + expected_row_header_column: B + expected_row_header: 2028 + table_record_kind: total + measures: + - measure_id: bank_rate + label: Bank Rate, 2028 + ordinal: 0 + column: C + source_column_id: bank_rate + concept: obr.bank_rate + source_concept: obr.efo_economy.bank_rate + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.9, calendar-year + row, Bank Rate conditioning assumption. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: Bank Rate + assertion: source_projection +- record_set_id: obr.efo_2026_03.economy.bank_rate.cy2029 + provenance_class: model_output + record_set_spec_id: obr.efo_2026_03.economy.bank_rate.cy2029.v1 + source_record_id_prefix: obr.efo_2026_03.economy.bank_rate.cy2029 + sheet_name: '1.9' + period_type: calendar_year + period: 2029 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: government + entity_role: forecaster + domain: economic_outlook + groupby_dimension: obr.efo_line + rows: + - value_id: bank_rate + label: Bank Rate + ordinal: 0 + row_number: 118 + expected_row_header_column: B + expected_row_header: 2029 + table_record_kind: total + measures: + - measure_id: bank_rate + label: Bank Rate, 2029 + ordinal: 0 + column: C + source_column_id: bank_rate + concept: obr.bank_rate + source_concept: obr.efo_economy.bank_rate + concept_relation: source_label + concept_authority: obr + concept_evidence_url: https://obr.uk/download/march-2026-economic-and-fiscal-outlook-detailed-forecast-tables-economy/ + concept_evidence_notes: OBR EFO March 2026 detailed forecast tables, sheet 1.9, calendar-year + row, Bank Rate conditioning assumption. + unit: percent + aggregation: sum + expected_cell_type: number + expected_column_header_row: 3 + expected_column_header: Bank Rate + assertion: source_projection diff --git a/packages/ons/families_households_2025/source_package.yaml b/packages/ons/families_households_2025/source_package.yaml index 4af5f86c..5b2553e2 100644 --- a/packages/ons/families_households_2025/source_package.yaml +++ b/packages/ons/families_households_2025/source_package.yaml @@ -5,10 +5,10 @@ # production fixture are enumerated at the populace consumption gate. schema_version: ledger.source_package.v1 package_id: ons-families-households-2025 -label: 'ONS families and households 2025, Table 7: UK households by household type, 2018-2025' +label: 'ONS families and households 2025, Tables 5 and 7: UK household size and households by household type, 2018-2025' artifact: source_name: ons - source_table: 'Families and households in the UK 2025, Table 7: households by type' + source_table: 'Families and households in the UK 2025, Tables 5 and 7: household size and households by type' resource_package: db resource_directory: data/ons/families_households_2025 manifest: manifest.yaml @@ -1426,3 +1426,683 @@ record_sets: aggregation: sum value_scale: 1000 expected_cell_type: number +- record_set_id: ons.families_households_2025.table5.all_households.cy2018 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2018.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2018 + sheet_name: '5' + period_type: calendar_year + period: 2018 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2018 estimate + ordinal: 0 + column: W + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2018 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2018 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2018.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2018 + sheet_name: '5' + period_type: calendar_year + period: 2018 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2018 estimate + ordinal: 0 + column: W + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2018 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.all_households.cy2019 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2019.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2019 + sheet_name: '5' + period_type: calendar_year + period: 2019 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2019 estimate + ordinal: 0 + column: T + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2019 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2019 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2019.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2019 + sheet_name: '5' + period_type: calendar_year + period: 2019 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2019 estimate + ordinal: 0 + column: T + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2019 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.all_households.cy2020 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2020.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2020 + sheet_name: '5' + period_type: calendar_year + period: 2020 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2020 estimate + ordinal: 0 + column: Q + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2020 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2020 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2020.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2020 + sheet_name: '5' + period_type: calendar_year + period: 2020 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2020 estimate + ordinal: 0 + column: Q + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2020 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.all_households.cy2021 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2021.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2021 + sheet_name: '5' + period_type: calendar_year + period: 2021 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2021 estimate + ordinal: 0 + column: N + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2021 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2021 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2021.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2021 + sheet_name: '5' + period_type: calendar_year + period: 2021 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2021 estimate + ordinal: 0 + column: N + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2021 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.all_households.cy2022 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2022.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2022 + sheet_name: '5' + period_type: calendar_year + period: 2022 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2022 estimate + ordinal: 0 + column: K + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2022 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2022 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2022.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2022 + sheet_name: '5' + period_type: calendar_year + period: 2022 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2022 estimate + ordinal: 0 + column: K + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2022 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.all_households.cy2023 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2023.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2023 + sheet_name: '5' + period_type: calendar_year + period: 2023 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2023 estimate + ordinal: 0 + column: H + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2023 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2023 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2023.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2023 + sheet_name: '5' + period_type: calendar_year + period: 2023 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2023 estimate + ordinal: 0 + column: H + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2023 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.all_households.cy2024 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2024.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2024 + sheet_name: '5' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2024 estimate + ordinal: 0 + column: E + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2024 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2024 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2024.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2024 + sheet_name: '5' + period_type: calendar_year + period: 2024 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2024 estimate + ordinal: 0 + column: E + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2024 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.all_households.cy2025 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.all_households.cy2025.v1 + source_record_id_prefix: ons.families_households_2025.table5.all_households.cy2025 + sheet_name: '5' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: all_households + label: All households + ordinal: 0 + row_number: 21 + expected_row_header_column: A + expected_row_header: All households + table_record_kind: total + measures: + - measure_id: households_total + label: All households, 2025 estimate + ordinal: 0 + column: B + source_column_id: households_total + concept: ons.households_total + source_concept: ons.families_households_table5.all_households + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 all households + row, thousands. + unit: count + aggregation: sum + expected_cell_type: number + value_scale: 1000 + expected_column_header_row: 12 + expected_column_header: 2025 Estimate + survey_instrument: Labour Force Survey +- record_set_id: ons.families_households_2025.table5.average_household_size.cy2025 + provenance_class: survey_aggregate + record_set_spec_id: ons.families_households_2025.table5.average_household_size.cy2025.v1 + source_record_id_prefix: ons.families_households_2025.table5.average_household_size.cy2025 + sheet_name: '5' + period_type: calendar_year + period: 2025 + geography_id: K02000001 + geography_level: country + geography_name: United Kingdom + geography_vintage: current + entity: household + entity_role: resident_household + domain: household_composition + groupby_dimension: ons.household_size_summary + rows: + - value_id: average_household_size + label: Average household size (number of people) + ordinal: 0 + row_number: 22 + expected_row_header_column: A + expected_row_header: Average household size (number of people) + table_record_kind: total + measures: + - measure_id: average_household_size + label: Average household size, 2025 estimate + ordinal: 0 + column: B + source_column_id: average_household_size + concept: ons.average_household_size + source_concept: ons.families_households_table5.average_household_size + concept_relation: source_label + concept_authority: ons + concept_evidence_url: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/familiesandhouseholdsfamiliesandhouseholds + concept_evidence_notes: Families and households in the UK, 2025 edition, Table 5 average + household size row, number of people. + unit: people_per_household + aggregation: sum + expected_cell_type: number + expected_column_header_row: 12 + expected_column_header: 2025 Estimate + survey_instrument: Labour Force Survey diff --git a/tests/test_chronicle_boundaries.py b/tests/test_chronicle_boundaries.py index b5259b46..4ca73f5b 100644 --- a/tests/test_chronicle_boundaries.py +++ b/tests/test_chronicle_boundaries.py @@ -38,3 +38,69 @@ def test_repository_does_not_ship_raw_microdata_namespace(): assert not (repo_root / "micro").exists() assert not (repo_root / "calibration").exists() assert not (repo_root / "storage").exists() + + +def test_uk_legacy_etl_cleanup_checklist_accounts_for_legacy_series(): + repo_root = Path(__file__).resolve().parents[1] + checklist = (repo_root / "docs" / "pe-uk-source-checklist.md").read_text() + + required_entries = [ + "`db/etl_obr.py` `gdp`", + "`db/etl_obr.py` `total_receipts`", + "`db/etl_obr.py` `total_managed_expenditure`", + "`db/etl_obr.py` `public_sector_net_borrowing`", + "`db/etl_obr.py` `public_sector_net_debt`", + "`db/etl_obr.py` `real_gdp_growth`", + "`db/etl_obr.py` `unemployment_rate`", + "`db/etl_obr.py` `cpi_inflation`", + "`db/etl_obr.py` `rpi_inflation`", + "`db/etl_obr.py` `bank_rate`", + "`db/etl_obr.py` `employment`", + "`db/etl_ons.py` `population_total`", + "`db/etl_ons.py` `population_age_0_15`", + "`db/etl_ons.py` `population_age_16_64`", + "`db/etl_ons.py` `population_age_65_plus`", + "`db/etl_ons.py` `households_total`", + "`db/etl_ons.py` `average_household_size`", + "`db/etl_hmrc.py` `income_tax`", + "`db/etl_hmrc.py` `national_insurance`", + "`db/etl_hmrc.py` `capital_gains_tax`", + "`db/etl_hmrc.py` `inheritance_tax`", + "`db/etl_hmrc.py` `taxpayers`, `higher_rate_taxpayers`, `additional_rate_taxpayers`", + "`db/etl_hmrc.py` `total_income`", + "`db/etl_hmrc.py` `benefits.universal_credit.{recipients,expenditure}`", + "`db/etl_hmrc.py` `benefits.child_benefit.{recipients,expenditure}`", + "`db/etl_hmrc.py` `benefits.state_pension.{recipients,expenditure}`", + "`db/etl_hmrc.py` `benefits.housing_benefit.{recipients,expenditure}`", + "`db/etl_hmrc.py` `benefits.pension_credit.{recipients,expenditure}`", + ] + + for entry in required_entries: + assert entry in checklist + + assert "obr-efo-economy-march-2026" in checklist + assert "obr-efo-aggregates-march-2026" in checklist + assert "ons-families-households-2025" in checklist + assert "2026-2034 remain gaps" in checklist + assert "not ported in PR A" in checklist + + +def test_retired_uk_legacy_etl_modules_are_not_shipped(): + repo_root = Path(__file__).resolve().parents[1] + + assert not (repo_root / "db" / "etl_obr.py").exists() + assert not (repo_root / "db" / "etl_ons.py").exists() + assert not (repo_root / "tests" / "test_etl_obr.py").exists() + assert not (repo_root / "tests" / "test_etl_ons.py").exists() + assert (repo_root / "db" / "etl_hmrc.py").exists() + + +def test_load_cli_no_longer_accepts_retired_uk_legacy_etl_sources(): + cli_source = (Path(__file__).resolve().parents[1] / "db" / "cli.py").read_text() + + assert 'if args.source == "obr"' not in cli_source + assert 'if args.source == "ons"' not in cli_source + assert "load_obr_targets" not in cli_source + assert "load_ons_targets" not in cli_source + assert '"obr",' not in cli_source + assert '"ons",' not in cli_source diff --git a/tests/test_chronicle_bundle.py b/tests/test_chronicle_bundle.py index 34626840..a74ae431 100644 --- a/tests/test_chronicle_bundle.py +++ b/tests/test_chronicle_bundle.py @@ -27,16 +27,16 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "aggregate_duplicate_key_count": 0, "entity_count": 11, "error_count": 0, - "fact_count": 155431, + "fact_count": 155504, "geography_count": 12536, "period_count": 151, "semantic_duplicate_key_count": 12, "skipped_source_count": 10, "source_count": 41, - "source_package_count": 128, + "source_package_count": 130, "warning_count": 1, } - assert len(rows) == 155431 + assert len(rows) == 155504 assert {row["provenance_class"] for row in rows} <= { "administrative", "census", @@ -54,7 +54,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): ) assert rows[0]["aggregate_fact_key"].startswith("ledger.aggregate_fact.v2:") assert rows[0]["semantic_fact_key"].startswith("ledger.semantic_fact.v2:") - assert source_packages["source_package_count"] == 128 + assert source_packages["source_package_count"] == 130 assert source_packages["skipped_source_count"] == 10 assert sorted(item["source"] for item in source_packages["skipped_sources"]) == [ "census-acs-s0101-congressional-district-age-2024", @@ -68,7 +68,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "jct-obbba-revenue-estimates-2025", "jct-tax-expenditures-2024", ] - assert coverage["fact_count"] == 155431 + assert coverage["fact_count"] == 155504 assert coverage["counts"]["by_source"] == { "bea": 445, "bfp_economic_outlook": 5, @@ -96,9 +96,9 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "nbb_national_accounts": 1, "nisra": 510, "nrs": 5589, - "obr": 196, + "obr": 253, "onem_rva_unemployment": 1, - "ons": 65630, + "ons": 65646, "onss_contributions": 1, "opgroeien_groeipakket": 11, "scotgov": 2504, @@ -113,7 +113,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "welshgov": 198, } table_counts = coverage["counts"]["by_source_table"] - assert len(table_counts) == 123 + assert len(table_counts) == 125 assert table_counts["usda_snap:SNAP FY2025 Monthly State Participation"] == 636 assert table_counts["irs_soi:Congressional District Data 2022"] == 26880 assert table_counts["irs_soi:IRS SOI County Data 2022"] == 6286 @@ -315,18 +315,18 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "calendar_year:2015": 74, "calendar_year:2016": 72, "calendar_year:2017": 72, - "calendar_year:2018": 84, - "calendar_year:2019": 83, - "calendar_year:2020": 83, - "calendar_year:2021": 3990, - "calendar_year:2022": 1911, - "calendar_year:2023": 6200, - "calendar_year:2024": 33791, - "calendar_year:2025": 4438, - "calendar_year:2026": 235, - "calendar_year:2027": 214, - "calendar_year:2028": 214, - "calendar_year:2029": 214, + "calendar_year:2018": 86, + "calendar_year:2019": 85, + "calendar_year:2020": 85, + "calendar_year:2021": 3992, + "calendar_year:2022": 1913, + "calendar_year:2023": 6202, + "calendar_year:2024": 33799, + "calendar_year:2025": 4446, + "calendar_year:2026": 241, + "calendar_year:2027": 220, + "calendar_year:2028": 220, + "calendar_year:2029": 220, "calendar_year:2031": 2, "fiscal_year:1996": 33, "fiscal_year:1997": 33, @@ -356,12 +356,12 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "fiscal_year:2021": 33, "fiscal_year:2022": 33, "fiscal_year:2023": 385, - "fiscal_year:2024": 610, - "fiscal_year:2025": 1284, - "fiscal_year:2026": 1439, - "fiscal_year:2027": 28, - "fiscal_year:2028": 28, - "fiscal_year:2029": 28, + "fiscal_year:2024": 611, + "fiscal_year:2025": 1288, + "fiscal_year:2026": 1443, + "fiscal_year:2027": 32, + "fiscal_year:2028": 32, + "fiscal_year:2029": 32, "fiscal_year:2030": 28, "month:2023-01": 1, "month:2023-12": 6, @@ -435,7 +435,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): assert ( coverage["counts"]["by_geography"]["congressional_district:5001700US0601"] == 56 ) - assert coverage["counts"]["by_geography"]["country:K02000001"] == 4189 + assert coverage["counts"]["by_geography"]["country:K02000001"] == 4262 assert coverage["counts"]["by_geography"]["country:K03000001"] == 312 assert len(coverage["counts"]["by_geography"]) == 12536 assert coverage["counts"]["by_entity"] == { @@ -443,8 +443,8 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "dwelling": 12708, "family": 107, "firm": 1439, - "government": 237, - "household": 40432, + "government": 294, + "household": 40448, "institutional_sector": 103, "pension_plan": 2, "person": 60272, diff --git a/tests/test_chronicle_source_package.py b/tests/test_chronicle_source_package.py index 7fec3999..d5e9f92d 100644 --- a/tests/test_chronicle_source_package.py +++ b/tests/test_chronicle_source_package.py @@ -3463,6 +3463,124 @@ def test_kff_marketplace_effectuated_enrollment_builds_2024_state_facts(): assert values_by_record[ca].value == 1_795_695 +def test_obr_efo_economy_package_validates_macro_series_counts(): + report = validate_source_package("obr-efo-economy-march-2026", year=2026) + + assert report.valid + assert report.counts == { + "record_set_count": 36, + "row_count": 36, + "measure_count": 36, + "source_record_count": 36, + "source_region_count": 36, + } + + +def test_obr_efo_economy_package_builds_cell_faithful_macro_facts(): + package = load_source_package("obr-efo-economy-march-2026") + cells = package.build_source_cells(2026) + facts = package.build_facts(2026, cells=cells) + values_by_record = {fact.source_record_id: fact for fact in facts} + + assert validate_source_cells(cells).valid + assert validate_facts(facts).valid + assert len(facts) == 36 + + nominal_gdp_2024 = values_by_record[ + "obr.efo_2026_03.economy.nominal_gdp_nsa.cy2024." + "nominal_gdp_nsa.nominal_gdp_nsa" + ] + cpi_2025 = values_by_record[ + "obr.efo_2026_03.economy.cpi_inflation.cy2025." + "cpi_inflation.cpi_inflation" + ] + bank_rate_2029 = values_by_record[ + "obr.efo_2026_03.economy.bank_rate.cy2029.bank_rate.bank_rate" + ] + + assert nominal_gdp_2024.value == 2_890_664_000_000 + assert nominal_gdp_2024.period.type == "calendar_year" + assert nominal_gdp_2024.assertion == "observation" + assert nominal_gdp_2024.measure.concept == "obr.nominal_gdp_nsa" + assert cpi_2025.value == pytest.approx(3.3730368724933735) + assert cpi_2025.assertion == "source_projection" + assert bank_rate_2029.value == pytest.approx(3.741552661678499) + + +def test_obr_efo_aggregates_package_validates_fiscal_series_counts(): + report = validate_source_package("obr-efo-aggregates-march-2026", year=2026) + + assert report.valid + assert report.counts == { + "record_set_count": 21, + "row_count": 21, + "measure_count": 21, + "source_record_count": 21, + "source_region_count": 21, + } + + +def test_obr_efo_aggregates_package_builds_cell_faithful_fiscal_facts(): + package = load_source_package("obr-efo-aggregates-march-2026") + cells = package.build_source_cells(2026) + facts = package.build_facts(2026, cells=cells) + values_by_record = {fact.source_record_id: fact for fact in facts} + + assert validate_source_cells(cells).valid + assert validate_facts(facts).valid + assert len(facts) == 21 + + psnb_2025 = values_by_record[ + "obr.efo_2026_03.aggregates.public_sector_net_borrowing.fy2025." + "public_sector_net_borrowing.public_sector_net_borrowing" + ] + psnd_2024 = values_by_record[ + "obr.efo_2026_03.aggregates.public_sector_net_debt_percent_gdp.fy2024." + "public_sector_net_debt_percent_gdp.public_sector_net_debt_percent_gdp" + ] + + assert psnb_2025.value == pytest.approx(132_735_075_755.52568) + assert psnb_2025.period.type == "fiscal_year" + assert psnb_2025.assertion == "source_projection" + assert psnb_2025.measure.concept == "obr.public_sector_net_borrowing" + assert psnd_2024.value == pytest.approx(93.16136288446387) + assert psnd_2024.measure.unit == "percent_of_gdp" + assert psnd_2024.assertion == "observation" + + +def test_ons_families_households_package_adds_household_totals_and_size(): + report = validate_source_package("ons-families-households-2025", year=2025) + + assert report.valid + assert report.counts == { + "record_set_count": 24, + "row_count": 96, + "measure_count": 24, + "source_record_count": 96, + "source_region_count": 24, + } + + package = load_source_package("ons-families-households-2025") + cells = package.build_source_cells(2025) + facts = package.build_facts(2025, cells=cells) + values_by_record = {fact.source_record_id: fact for fact in facts} + + households_2025 = values_by_record[ + "ons.families_households_2025.table5.all_households.cy2025." + "all_households.households_total" + ] + average_size_2025 = values_by_record[ + "ons.families_households_2025.table5.average_household_size.cy2025." + "average_household_size.average_household_size" + ] + + assert households_2025.value == 29_003_000 + assert households_2025.measure.concept == "ons.households_total" + assert average_size_2025.value == pytest.approx(2.36) + assert average_size_2025.measure.concept == "ons.average_household_size" + assert average_size_2025.measure.unit == "people_per_household" + + def test_render_string_templates_integer_year_with_filing_year(): """Integer years must still template both ``{year}`` and ``{filing_year}``.""" template = "Tax Year {year} (Filing Year {filing_year})" diff --git a/tests/test_etl_obr.py b/tests/test_etl_obr.py deleted file mode 100644 index 1f6e3055..00000000 --- a/tests/test_etl_obr.py +++ /dev/null @@ -1,182 +0,0 @@ -"""Tests for OBR (Office for Budget Responsibility) projections ETL.""" - -import pytest -from sqlmodel import Session, select - -from db.schema import ( - DataSource, - Jurisdiction, - Stratum, - Target, - TargetType, - init_db, -) -from db.etl_obr import load_obr_targets, OBR_DATA - - -class TestObrETL: - """Tests for OBR projections ETL.""" - - @pytest.fixture - def session(self, tmp_path): - """Create a test database session.""" - db_path = tmp_path / "test.db" - engine = init_db(db_path) - with Session(engine) as session: - yield session - - def test_load_creates_uk_budget_stratum(self, session): - """Should create UK budget stratum.""" - load_obr_targets(session, years=[2024]) - - stratum = session.exec( - select(Stratum).where(Stratum.name == "UK Public Finances") - ).first() - - assert stratum is not None - assert stratum.jurisdiction == Jurisdiction.UK - - def test_load_creates_gdp_projection(self, session): - """Should create UK GDP projection targets.""" - load_obr_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "gdp", - Target.period == 2024, - Target.source == DataSource.OBR, - ) - ).first() - - assert target is not None - assert target.value == OBR_DATA[2024]["gdp"] - assert target.target_type == TargetType.AMOUNT - - def test_load_creates_receipts_projection(self, session): - """Should create total receipts projection.""" - load_obr_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "total_receipts", - Target.period == 2024, - ) - ).first() - - assert target is not None - assert target.value == OBR_DATA[2024]["total_receipts"] - - def test_load_creates_expenditure_projection(self, session): - """Should create total managed expenditure projection.""" - load_obr_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "total_managed_expenditure", - Target.period == 2024, - ) - ).first() - - assert target is not None - assert target.value == OBR_DATA[2024]["total_managed_expenditure"] - - def test_load_creates_borrowing_projection(self, session): - """Should create public sector net borrowing projection.""" - load_obr_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "public_sector_net_borrowing", - Target.period == 2024, - ) - ).first() - - assert target is not None - - def test_load_creates_economy_stratum(self, session): - """Should create UK economy stratum for macro indicators.""" - load_obr_targets(session, years=[2024]) - - stratum = session.exec( - select(Stratum).where(Stratum.name == "UK Economy") - ).first() - - assert stratum is not None - assert stratum.jurisdiction == Jurisdiction.UK - - def test_load_creates_unemployment_projection(self, session): - """Should create UK unemployment rate projection.""" - load_obr_targets(session, years=[2025]) - - target = session.exec( - select(Target).where( - Target.variable == "unemployment_rate", - Target.period == 2025, - Target.source == DataSource.OBR, - ) - ).first() - - assert target is not None - assert target.target_type == TargetType.RATE - - def test_load_creates_inflation_projection(self, session): - """Should create CPI inflation projection.""" - load_obr_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "cpi_inflation", - Target.period == 2024, - Target.source == DataSource.OBR, - ) - ).first() - - assert target is not None - assert target.target_type == TargetType.RATE - - def test_load_future_years(self, session): - """Should load projection years through 2029.""" - load_obr_targets(session, years=[2028, 2029]) - - targets_2028 = session.exec( - select(Target).where( - Target.period == 2028, - Target.source == DataSource.OBR, - ) - ).all() - targets_2029 = session.exec( - select(Target).where( - Target.period == 2029, - Target.source == DataSource.OBR, - ) - ).all() - - assert len(targets_2028) > 0 - assert len(targets_2029) > 0 - - def test_load_multiple_years(self, session): - """Should load multiple projection years.""" - load_obr_targets(session, years=[2024, 2025, 2026]) - - targets = session.exec( - select(Target).where(Target.source == DataSource.OBR) - ).all() - periods = {t.period for t in targets} - - assert 2024 in periods - assert 2025 in periods - assert 2026 in periods - - def test_load_idempotent(self, session): - """Loading twice should not duplicate data.""" - load_obr_targets(session, years=[2024]) - count1 = len( - session.exec(select(Target).where(Target.source == DataSource.OBR)).all() - ) - - load_obr_targets(session, years=[2024]) - count2 = len( - session.exec(select(Target).where(Target.source == DataSource.OBR)).all() - ) - - assert count1 == count2 diff --git a/tests/test_etl_ons.py b/tests/test_etl_ons.py deleted file mode 100644 index 32a361d5..00000000 --- a/tests/test_etl_ons.py +++ /dev/null @@ -1,205 +0,0 @@ -"""Tests for ONS (Office for National Statistics) projections ETL.""" - -import pytest -from sqlmodel import Session, select - -from db.schema import ( - DataSource, - Jurisdiction, - Stratum, - Target, - TargetType, - init_db, -) -from db.etl_ons import load_ons_targets, ONS_DATA - - -class TestOnsETL: - """Tests for ONS projections ETL.""" - - @pytest.fixture - def session(self, tmp_path): - """Create a test database session.""" - db_path = tmp_path / "test.db" - engine = init_db(db_path) - with Session(engine) as session: - yield session - - def test_load_creates_uk_population_stratum(self, session): - """Should create UK population stratum.""" - load_ons_targets(session, years=[2024]) - - stratum = session.exec( - select(Stratum).where(Stratum.name == "UK Population") - ).first() - - assert stratum is not None - assert stratum.jurisdiction == Jurisdiction.UK - - def test_load_creates_total_population_projection(self, session): - """Should create UK total population projection targets.""" - load_ons_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "population_total", - Target.period == 2024, - Target.source == DataSource.ONS, - ) - ).first() - - assert target is not None - assert target.value == ONS_DATA[2024]["population_total"] - assert target.target_type == TargetType.COUNT - assert target.is_preliminary is True - - def test_load_creates_age_group_projections(self, session): - """Should create population projections by age groups.""" - load_ons_targets(session, years=[2024]) - - # Check 0-15 age group - target_0_15 = session.exec( - select(Target).where( - Target.variable == "population_age_0_15", - Target.period == 2024, - ) - ).first() - - assert target_0_15 is not None - assert target_0_15.value == ONS_DATA[2024]["population_age_0_15"] - - # Check 16-64 age group - target_16_64 = session.exec( - select(Target).where( - Target.variable == "population_age_16_64", - Target.period == 2024, - ) - ).first() - - assert target_16_64 is not None - assert target_16_64.value == ONS_DATA[2024]["population_age_16_64"] - - # Check 65+ age group - target_65_plus = session.exec( - select(Target).where( - Target.variable == "population_age_65_plus", - Target.period == 2024, - ) - ).first() - - assert target_65_plus is not None - assert target_65_plus.value == ONS_DATA[2024]["population_age_65_plus"] - - def test_load_creates_uk_households_stratum(self, session): - """Should create UK households stratum.""" - load_ons_targets(session, years=[2024]) - - stratum = session.exec( - select(Stratum).where(Stratum.name == "UK Households") - ).first() - - assert stratum is not None - assert stratum.jurisdiction == Jurisdiction.UK - - def test_load_creates_household_projections(self, session): - """Should create household count projection.""" - load_ons_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "households_total", - Target.period == 2024, - Target.source == DataSource.ONS, - ) - ).first() - - assert target is not None - assert target.value == ONS_DATA[2024]["households_total"] - assert target.target_type == TargetType.COUNT - - def test_load_creates_average_household_size(self, session): - """Should create average household size projection.""" - load_ons_targets(session, years=[2024]) - - target = session.exec( - select(Target).where( - Target.variable == "average_household_size", - Target.period == 2024, - Target.source == DataSource.ONS, - ) - ).first() - - assert target is not None - assert target.value == ONS_DATA[2024]["average_household_size"] - assert target.target_type == TargetType.RATE - - def test_load_future_years(self, session): - """Should load projection years through 2034.""" - load_ons_targets(session, years=[2033, 2034]) - - targets_2033 = session.exec( - select(Target).where( - Target.period == 2033, - Target.source == DataSource.ONS, - ) - ).all() - targets_2034 = session.exec( - select(Target).where( - Target.period == 2034, - Target.source == DataSource.ONS, - ) - ).all() - - assert len(targets_2033) > 0 - assert len(targets_2034) > 0 - - def test_load_multiple_years(self, session): - """Should load multiple projection years.""" - load_ons_targets(session, years=[2024, 2025, 2026]) - - targets = session.exec( - select(Target).where(Target.source == DataSource.ONS) - ).all() - periods = {t.period for t in targets} - - assert 2024 in periods - assert 2025 in periods - assert 2026 in periods - - def test_load_idempotent(self, session): - """Loading twice should not duplicate data.""" - load_ons_targets(session, years=[2024]) - count1 = len( - session.exec(select(Target).where(Target.source == DataSource.ONS)).all() - ) - - load_ons_targets(session, years=[2024]) - count2 = len( - session.exec(select(Target).where(Target.source == DataSource.ONS)).all() - ) - - assert count1 == count2 - - def test_all_projections_marked_preliminary(self, session): - """All ONS projections should be marked as preliminary.""" - load_ons_targets(session, years=[2024, 2030]) - - targets = session.exec( - select(Target).where(Target.source == DataSource.ONS) - ).all() - - for target in targets: - assert target.is_preliminary is True - - def test_load_all_years(self, session): - """Should load all available years when years=None.""" - load_ons_targets(session, years=None) - - targets = session.exec( - select(Target).where(Target.source == DataSource.ONS) - ).all() - periods = {t.period for t in targets} - - # Should have data for all years 2024-2034 - expected_years = set(range(2024, 2035)) - assert periods == expected_years