Repository navigation
/reports takes data_source: "local_area_dataset" for UK-wide and nation reports, and no request takes dataset_name - #1070
Draft
anth-volk wants to merge 22 commits into
Conversation
…ing) POST /reports accepts breakdown "local_areas" for a UK-wide or nation report, with or without include_cliffs, and records it in the report's options. A null, another value, another country, or a constituency or local-authority region is refused with 422 at the breakdown field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EconomyReportRequest gains an optional breakdown, left out unless given. Null and any other value are refused with one reason, and the contract's local_area_breakdown_error refuses another country or a region other than uk and the four nations, all with 422 at the breakdown field. Neither include_cliffs nor segmented is passed to it: the national run calculates the cliffs, so the pair is accepted. The report's stored options record the breakdown only when it was asked for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iling) A catalog version's local-area dataset is the one default dataset its constituency and local-authority regions all use, even the national file. A version with no area regions, only one area type, or a dataset for each type has none, and another version's regions are never read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
read_local_area_dataset returns the one default dataset every constituency and local-authority region of the version uses, or None when the version has no such regions, only one type, or a dataset for each. It is never chosen from the request's dataset_name. It may be the national file: Stage 12 leaves the areas out of a UK-wide or nation run whenever the release routes both types to one dataset, so the areas are calculated apart even then. The read-only regions model gains region_type, modelled as the Public API's v2_region_type enum, which the pinned schema comparison checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stacks C1 · 24 on C1 · 23's branch at c924097, for the manifest's UK local_area_reports declaration that the service reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (failing) A report asking for local areas is refused with 400 local_areas_unsupported, before any read, when the default worker's UK entry declares no local-area report runs or another input version. When the declaration names no dataset, the release routes the areas to none of their own and no area part is made. When it names one, the store reads that catalog dataset with the report's inputs, never the request's dataset_name, and refuses it (400 local_area_dataset_mismatch) unless the catalog gives both area types that dataset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The service reads the default worker's UK local_area_reports declaration from the v2 manifest (EconomyWorker.local_area_reports). A report asking for local areas is refused with 400 local_areas_unsupported, before any read, when the worker declares none or another input version. A declaration naming no dataset means the release gives the areas none of their own, so no area part is made. One naming a dataset makes the store read that catalog dataset with the report's inputs, never the request's dataset_name, and refuse it with 400 local_area_dataset_mismatch unless the catalog version gives both area types that dataset. The rule comes from one source, the publisher's own reading of the release (uk_area_regions_routed), so the service, Stage 12's national aggregation and the UK worker decide alike on every release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The user's 2026-11-13 design makes breakdown a request option: it finds or creates the report on the local-area dataset beside the national one, and is never stored in the report's options, so it never changes which report a request names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
breakdown is a request option: EconomyReportRequest.options() no longer records it, so a report's stored options, and whatever names the report by them, are the same with or without it. Its validation and 422 refusals are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ith data_source (failing) data_source: "local_area_dataset" replaces breakdown: the report itself runs on the dataset the default worker's UK entry declares for local-area report runs, read from the catalog in place of the region's default, with its own options. Another value, country or region is refused with 422 at data_source, and so is a release that routes the areas to no dataset of its own (no_local_area_dataset); a worker that declares no local-area runs, and a catalog whose area regions use another dataset, are still refused with 400. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…urce data_source: "local_area_dataset" replaces breakdown on economy reports. The report runs on the dataset the default worker's UK entry declares for local-area report runs: the store reads the catalog version's local-area dataset in place of the region's default, so the report's simulations, population and calculation are on it, and its options are its own, cliffs included. Null, another value, another country and a region other than uk and the four nations are refused with 422 at data_source. A release that routes the areas to no dataset of their own has no local-area dataset, and is refused with 422 no_local_area_dataset (its national reports calculate both area levels). A worker declaring no local-area runs (400 local_areas_unsupported) and a catalog whose area regions use another dataset (400 local_area_dataset_mismatch) stay the service's state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…set (failing) No request chooses a dataset: a report or simulation runs on its region's dataset, or a UK-wide or nation report on the local-area dataset with data_source. POST /reports (economy reports and budget windows) and POST /simulations refuse dataset_name, given or null, with 422, and the OpenAPI document lists it in none of the three requests. The Public API stops sending it first (PolicyEngine/policyengine-api#4307). A re-run still reads its stored report's dataset by name, so a missing stored dataset keeps its unknown_dataset refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EconomyReportRequest, EconomySimulationRequest and BudgetWindowReportRequest lose dataset_name, so their strict models refuse it, given or null, with 422: a report or simulation runs on the dataset the catalog gives its region, or a UK-wide or nation report on the local-area dataset with data_source. A bundle lacking the catalog dataset is always the service's state (dataset_not_in_bundle). The persistence library's EconomyRequest keeps dataset_name, which re-runs set from the stored report. The Public API stops sending the field first (PolicyEngine/policyengine-api#4307), and this deploys only after that. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…area dataset (failing) The check's POST /reports sends data_source: "local_area_dataset", so its current-law Wales 2026 run also calculates Wales's constituencies and local authorities. The coordinator fails a run of such a report unless both area levels have rows or withheld codes, so the check's requirement that the run succeeds covers them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its POST /reports sends data_source: "local_area_dataset", so the run also calculates Wales's constituencies and local authorities, and the coordinator's condition that both area levels have rows or withheld codes makes the run's success cover them (decision 9). DEPLOYMENT.md and the deploy workflow's job comment say so. Changelog fragments for data_source and for removing dataset_name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
C1 · 23 merged main (#1059's re-runs) and pinned the Public API commit that adds withheld_area_codes. Conflicts: the store's report read keeps main's reuse search and reads the local-area dataset; the refusal-code comments name both a re-run's stored rows and a create's region dataset; the package exports both sets of names. The merged store was over the 800-line limit, so the catalog-row reads move unchanged to economy_catalog_rows (read_catalog_rows), re-exported from economy_run_store, and the side-refusal test patches the name where the store now looks it up, taking keyword arguments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 1 found no bugs; these cover its test gaps. Passing as guards: the routes answer 400 local_areas_unsupported and local_area_dataset_mismatch, and 422 no_local_area_dataset at data_source, with their codes; the OpenAPI document lists the three codes; budget windows, household reports and report re-runs refuse data_source as an unknown field; and a report stored on the local-area dataset is re-run on it. Failing: the catalog read refuses a request that names a dataset and the local-area dataset at once, which today reads the local-area one silently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The catalog read refuses, before any read, a request naming a dataset together with the local-area dataset (a re-run names its stored dataset, a create the local-area one), so neither silently wins. The /reports 400 and 422 descriptions, the entry README and the persistence library's README now say a create names no dataset, list the local-area codes, and describe read_local_area_dataset, economy_catalog_rows and LocalAreaDatasetMismatchError. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 2 found no bugs. The /reports 400 description and the entry README now tell the two local-area codes apart from missing rows; read_report_inputs and the persistence README say a request naming two datasets raises ValueError; the re-run test uses a worker declaring no local-area runs, since a re-run never reads the declaration; and the catalog read test builds its request with replace and a UK dataset name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 3 found no bugs; its one finding: the /reports 400 description now says local_areas_unsupported covers a declaration of another input version too, and local_area_dataset_mismatch a catalog version whose area regions don't share the declared dataset (or lack a type). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1069
Same-Repository Draft PR Check
PolicyEngine/policyengine-sim-api, not a personal fork.Changelog
changelog.d/<name>.<type>.md, whose type is breaking, added, changed, fixed or removed:c1-29a-data-source.added.mdandc1-29a-no-dataset-name.removed.md.Stacking, and what must merge and deploy first
v2plan/c1-23-local-area-report-profile): the v2 coordinator and UK workers that calculate a report on the local-area dataset, the manifest's UKlocal_area_reportsdeclaration this PR reads, and the coordinator's check that each area level has a published area or a withheld code. This PR is retargeted tomainwhen Calculate UK-wide and nation reports on the local-area dataset, with their areas and withheld codes #1068 merges, and merges after it.mastersends"dataset_name": nullon every report, budget-window and simulation request, and these request models refuse unknown fields, so deploying this PR before #4307 would make every one of those creates fail with 422.dataset_name: (1) #4307 stops the Public API sending it and makes/v2/reportsand/v2/simulationsrefuse it; it deploys to production. (2) This PR removes it from sim outright. No release accepts and ignores the field in between.data_sourcethroughPOST /v2/reportsin a later change.Summary
data_source: "local_area_dataset"onEconomyReportRequest(economy reports only), left out unless given and never stored as an option: the dataset it chooses is stored with the report's simulations. Null or another value, another country, or a region other thanukand the fourcountry/*nations: 422 atdata_source, with nocode.local_area_reports), checked before any database read. No declaration, or another input version: 400local_areas_unsupported. A declaration with no dataset, meaning the release routes the areas to no dataset of its own: 422no_local_area_datasetat["body", "data_source"], since that release's national reports calculate both area levels. Otherwise the store reads the catalog version's local-area dataset (the one default dataset every constituency and local-authority region uses) in place of the region's default, and answers 400local_area_dataset_mismatchunless it is the declared one. Both 400s are the service's state, which the Public API answers with 503.data_source.dataset_nameonEconomyReportRequest,EconomySimulationRequestorBudgetWindowReportRequest: given or null, it is refused with 422extra_forbidden. The persistence library'sEconomyRequest.dataset_namestays for re-runs, and the catalog read refuses a request naming both a dataset and the local-area dataset. A bundle lacking the catalog dataset is alwaysdataset_not_in_bundle..github/scripts/simulation-staging-economy-check.shsendsdata_source: "local_area_dataset"on its current-law Wales 2026 report. Calculate UK-wide and nation reports on the local-area dataset, with their areas and withheld codes #1068's coordinator fails such a run unless each area level has a published area or a withheld code, and writes those rows in the transaction that marks the run succeeded, so the check's requirement that the run succeeds covers them.DEPLOYMENT.mdand thestaging_economy_checkjob's comment say so.economy_run_storepassed 800 lines once merged with Calculate UK-wide and nation reports on the local-area dataset, with their areas and withheld codes #1068's merge ofmain, so its catalog-row reads moved unchanged toeconomy_catalog_rows(read_catalog_rows), with the moved names re-exported./reports400 and 422 descriptions, the persistence library's README.Deployment code and environment variables
The script, a workflow comment and
DEPLOYMENT.mdchange; no variable or secret is added. The script readsSIMULATION_TEST_AUTH_ISSUER,SIMULATION_TEST_AUTH_AUDIENCE,SIMULATION_TEST_AUTH_CLIENT_IDandSIMULATION_TEST_AUTH_CLIENT_SECRET, mapped in the job step'senv:from the GitHub Actions environment secretsSIMULATION_ENTRYPOINT_AUTH_ISSUER,SIMULATION_ENTRYPOINT_AUTH_AUDIENCE,SIMULATION_ENTRYPOINT_TEST_AUTH_CLIENT_IDandSIMULATION_ENTRYPOINT_TEST_AUTH_CLIENT_SECRET. All four exist inbeta;simulation-deploy.ymlandstage12-deploy.ymlcall the reusable workflow withsecrets: inheritandrelease_environment: beta, and the job runs inenvironment: ${{ inputs.release_environment }}.ECONOMY_CHECK_DEADLINE_SECONDSandECONOMY_CHECK_POLL_SECONDSstay unset (1800 and 15).Not verified (deployed state only): that staging's default v2 worker declares the local-area dataset when the check runs, which is true once #1068's release has published the manifest; that staging's catalog gives both UK area types that dataset; and that a Wales run on the dense dataset (each new UK worker downloads it, about 90 s) finishes within the check's 30 minutes.
Testing
Test-first throughout: each failing test was committed first ("(failing)" in the subject), seen failing for the expected reason, then passing. Only the tests added or modified were run, each by node ID. The PostgreSQL tests ran against a disposable PostgreSQL 17 database with the Public API's v2 chain at the pinned
public-api-commitand its grants applied. The apis-integ client tests ran on a client regenerated from this branch's OpenAPI document. Sim's checks (Ruff, rules rendering, quality guards including file length, lock checks, Pyright for the entry and the persistence library) pass on each commit.test_local_area_submissions.py:test_the_uk_worker_fixture_calculates_on_its_default_dataset,test_the_local_area_dataset_the_worker_cannot_run_is_refused_before_any_read(2 cases),test_a_report_without_a_data_source_needs_no_declaration,test_a_release_that_routes_no_areas_has_no_local_area_dataset,test_the_report_is_calculated_on_the_local_area_dataset_the_worker_routes_to,test_a_catalog_whose_area_regions_use_another_dataset_is_refused,test_a_report_on_the_local_area_dataset_is_rerun_on_it.test_economy_routes.py:test_a_data_source_a_report_cannot_have_is_refused(5),test_a_uk_wide_or_nation_report_may_ask_for_the_local_area_dataset(5),test_a_request_naming_a_dataset_is_refused(6),test_a_local_area_refusal_answers_with_its_code(3),test_only_an_economy_report_takes_a_data_source(2);test_economy_rerun_routes.py::test_a_report_rerun_takes_no_data_source.test_openapi.py:test_economy_requests_name_no_version_and_no_record_id,test_a_report_request_is_an_economy_report_a_budget_window_or_a_household,test_the_local_area_refusals_are_in_the_error_codes.test_economy_submissions.py:test_a_region_dataset_the_bundle_lacks_is_the_services_state,test_the_catalog_dataset_in_the_bundle_is_the_one_calculated,test_a_stored_dataset_the_catalog_lacks_is_named_in_the_refusal,test_a_refusals_detail_is_built_from_the_request_not_the_error;test_staging_economy_check.py::test_the_check_creates_a_small_report_and_waits_for_its_run_to_succeed.test_economy_run_store.py::test_a_report_on_the_local_area_dataset_is_read_on_it,::test_a_declared_dataset_the_catalog_does_not_give_both_area_types_is_refused(3),::test_every_side_refusal_is_raised_with_its_side,::test_a_request_naming_a_dataset_and_the_local_area_dataset_is_refused;test_economy_run_records.py::test_the_local_area_dataset_is_the_one_both_area_types_use,::test_a_catalog_version_without_one_dataset_for_both_area_types_has_none(3),::test_the_local_area_dataset_may_be_the_national_default.test_economy_generated_client.py::test_a_report_request_keeps_omitted_spm_settings_omitted,::test_a_created_report_is_read_with_its_runs,::test_a_created_simulation_is_read_with_its_run;test_budget_window_generated_client.py::test_a_budget_window_request_is_sent_as_given,::test_a_created_budget_window_is_read_with_its_years.Review rounds
Three read-only adversarial review rounds, each over the change against its base at the time; none found a bug.
data_sourcerefused on budget windows, household reports and re-runs, a re-run of a report on the local-area dataset), and the catalog read now refuses a request naming two datasets (its test failed first).No inline suppression is added.
🤖 Generated with Claude Code