Move Stage 12 output planning behind country-owned typed contracts
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Anfängerfreundlichkeit
- 35/100
Rechercherichtung
Start by reading stage12_runtime/output_planning.py, SimulationOutputBuilder.serialize(), and the Stage 12 wire-contract definitions; the issue requires documenting current US and UK outputs and their dataset sources before implementation. Then investigate the country-owned policyengine configuration and tests to map calculated, conditional, and preserved columns. Done means a coordinated, versioned planning interface and service conversion satisfy the listed contract, validation, integration, and migration criteria.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Context
Stage 12 must determine the complete output schema before it dispatches the independent baseline and reform simulations. The current implementation in stage12_runtime/output_planning.py does this by constructing data-free Simulation objects with model_construct(), invoking country configuration functions, asking the country model to resolve entity variables, and combining those calculated variables with dataset columns known to the simulation service.
This fixed the immediate failure mode where RequestedSimulationOutput(variables=("*",)) did not materialize every column later consumed by SimulationOutputBuilder. It also gave both child simulations one typed, deterministic plan whose hash can be verified before aggregation.
Issue #707 and PR #708 add timing around this work. They intentionally do not change the planning behavior. This issue tracks the broader cleanup that should follow after #708 is integrated.
Problem
The current implementation has several fragile integration boundaries:
- The simulation service creates partially initialized
Simulationinstances withSimulation.model_construct(..., dataset=None, ...). This bypasses normal model validation and assumes that every output configurator only reads policy, model, andextra_variables. - Output requirements are maintained in two places. The planner predicts which variables the existing report serializer will consume, but the serializer does not expose a typed declaration of those dependencies. A serializer change can therefore make the plan incomplete.
- The simulation service contains country- and dataset-specific knowledge, including UK source columns such as
constituency_code_oaandla_code_oa. - The current
ReportOutputRequirementslooks selective, but Stage 12 requires the complete aggregate profile. Only cliff-impact and labor-supply options currently change the plan. - Frame validation proves that entities and columns exist, but it does not express stronger contracts such as expected data types, nullability, units, or whether a column is calculated or copied from a specific dataset version.
- The planner depends directly on mutable
Simulation.extra_variablesand the internal behavior ofresolve_entity_variables()instead of a dedicated, supported planning interface. - PR #708 passes observability stages into the planner. The instrumentation is useful, but the domain planner should not need to depend on service-specific observability types.
Desired architecture
Make the policyengine package the source of truth for country-owned report-output planning, and keep the simulation service responsible for distributed execution.
policyengine package
Add a public, strongly typed planning interface that accepts explicit report requirements, baseline and reform policy configuration, country, and dataset metadata. It should return a deterministic declaration of:
- calculated variables required for each entity;
- variables added conditionally for labor-supply responses or cliff impacts;
- source-dataset columns that must be preserved;
- any schema metadata needed to validate those outputs.
The interface must not require the caller to construct an invalid or data-free Simulation. It may use a dedicated validated planning context internally.
The report serializer and output planner must share one dependency declaration. Adding a new calculation to a report must either automatically add its required variables to the plan or fail a focused contract test in the package that owns the report calculation.
Dataset-provided columns must come from typed dataset metadata or another country-owned declaration. policyengine-sim-api must not contain a hard-coded list of UK dataset columns.
The package-level types must avoid an inverse dependency on policyengine-simulation-contract. If wire-contract types remain in the simulation repository, add an explicit conversion layer between the package planning result and Stage12OutputPlan.
policyengine-sim-api
Reduce stage12_runtime/output_planning.py to orchestration:
- Validate the Stage 12 report request.
- Convert it into the public
policyengineplanning request. - Invoke the package planning interface once.
- Convert the result into the versioned Stage 12 wire contract.
- Send the identical immutable plan to the baseline and reform workers.
- Retain deterministic sorting, hashing, bundle-provenance checks, row-identity checks, and output-frame validation.
Move timing concerns to the coordinator or inject a neutral planning-observer protocol. The package-facing planner must not import the simulation service's Stage enumeration.
Required investigation
Before implementation, document:
- every output currently consumed by
SimulationOutputBuilder.serialize()for US and UK reports; - which variables are calculated, which are source-dataset columns, and which are conditional;
- the supported dataset/version source for each preserved column;
- whether the complete Stage 12 report profile should remain the only supported profile or whether requirements should become genuinely selective;
- which validation attributes are stable enough to include in the public contract beyond entity and column names;
- the compatibility and release sequence required between
policyenginebundles andpolicyengine-sim-api.
Acceptance criteria
- Stage 12 no longer calls
Simulation.model_construct()to discover output requirements. -
policyengineexposes a documented, strongly typed report-output planning interface for both US and UK. - The report serializer and planner use one source of truth for required calculated variables.
- Dataset-provided columns are declared by country/dataset-owned code or metadata, not hard-coded in
policyengine-sim-api. - The same deterministic plan is still sent to both Stage 12 child simulations.
- Plans remain versioned, canonically ordered, and hashable.
- Child workers still validate their materialized frames before publishing artifacts.
- The coordinator still rejects artifacts with mismatched plans, bundle provenance, roles, output schemas, or row identity.
- The planning interface fails explicitly for unsupported countries, datasets, report profiles, and unavailable source columns.
- Unit tests cover US and UK planning, budget outputs, geographic outputs, cliff impacts, active and inactive labor-supply responses, unsupported datasets, and missing declared columns.
- Contract tests prove that every column consumed by the report serializer is present in the declared output plan.
- Integration tests run baseline and reform children independently and successfully aggregate their validated artifacts.
- Observability continues to distinguish country-model loading, output configuration, variable resolution, and child-input preparation without coupling package domain types to service observability types.
- Migration and release documentation states the minimum compatible
policyenginebundle and the required cross-repository merge/deployment order.
Non-goals
- Removing the typed Stage 12 plan or its hash.
- Combining the independently executed baseline and reform simulations.
- Moving distributed execution or artifact persistence into the
policyenginepackage. - Preserving the current internal planning implementation for backward compatibility; Stage 12 and its certified bundle can move together to the new versioned interface.
Relationship to current work
- #707 / #708 should land independently because their measurements are needed to establish the current preparation cost and confirm the effect of this cleanup.
- This work should be divided into coordinated
policyengineandpolicyengine-sim-apichanges, with the package interface released before the simulation service begins consuming it.
- Vorherrschende Sprache
- Python
- Sterne
- 1
- Forks
- 1
- Ø Merge
- 1 T. 7 Std.
- Gemergte PRs (30 T.)
- 23
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus PolicyEngine/policyengine-sim-api
-
Integration tests fail due to missing UV virtual environment setupEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
PolicyEngine/policyengine-sim-api#314 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Update policyengine to 6.2.2Evtl. vergeben @policyengine hat das heute übernommen. Offen
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 20/100
PolicyEngine/policyengine-sim-api#730 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
PolicyEngine/policyengine-sim-api#728 ·
Maintainer antworten meist innerhalb von 1 Tag
-
UK: constituency and local-authority runs use enhanced-FRS weight matrices, and every UK run requires `la_code_oa`; both break on a Microcosm UK defaultEvtl. vergeben @juaristi22 hat das vor 2 Tagen übernommen. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 42/100
PolicyEngine/policyengine-sim-api#725 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 68/100
PolicyEngine/policyengine-sim-api#724 ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in PolicyEngine/policyengine-sim-api
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
rpm-software-management/mock#1824 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
jpata/particleflow#520 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug good first issue hacktoberfest
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 78/100
gridhead/gi-loadouts#699 ·
Maintainer antworten meist innerhalb von 13 Tagen
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 86/100
FinanceFlash/unvibecode#206 ·
Maintainer antworten meist innerhalb von 1 Tag