Repository navigation
Conversation
ConstituencyImpactRecord and LocalAuthorityImpactRecord no longer have x or y fields. Both records forbid extra fields, so a record carrying either, even as null, is refused, and the gateway reports a job whose result has one as failed. Apps deployed for older policyengine.py versions still send both, so this must not merge until no such app is routed. Nothing uses pydantic's exclude_if any more, so the contract's pydantic floor returns to 2.0, and the five locks that record it return to their state on main. Regenerate the gateway's golden OpenAPI, which drops both properties and the description's paragraph about them. Written red-green: the contract tests failed first with "DID NOT RAISE" for records and job results carrying x or y, and because the records still declared both fields; the gateway returned 200 instead of 500 for a result with x and y; and the generated client's record models still took x and y. 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 #923
Same-Repository Draft PR Check
PolicyEngine/policyengine-sim-api, not a personal fork.Summary
Stacked on #919, which stops sending
xandyand makes them optional in the contract. This PR removes them from the contract's area records altogether:ConstituencyImpactRecordandLocalAuthorityImpactRecordhave noxory. A record that carries either, even asnull, is refused (extra="forbid").exclude_ifany more, so the contract's pydantic floor returns to 2.0, and the five lock files that record it matchmainagain.xory.Which routed .py versions still send x and y
What the repository shows:
build_next_routing_state(insrc/modal/utils/update_version_registry.py) adds the deployed app's routes and bundle manifest and never removes another version's; the restore commands put back earlier snapshots. Nothing in the repository retires a route. The gateway'sresolve_routeserves pinnedversionandpolicyengine_versionrequests from that routing state, or from the legacy version dicts.Deploy versioned Modal executorstep in.github/workflows/simulation-deploy.reusable.ymldeployspolicyengine-simulation-py<version>for the .py version pinned in the executor'spyproject.toml. Apps for earlier versions keep the code they were built with.xandy, and from bae99c5 (28 September 2026) the executor refused an area without them. Since the executor moved toprojects/policyengine-simulation-executor(3 July 2026), its .py pins onmainhave been 4.18.9, 4.20.3, 4.21.1 (reverted the same day), 4.22.0, 5.0.4, 5.2.0, 6.1.2, 6.2.1, 6.2.3, 6.2.7, 6.3.4, 6.4.1, 6.5.0, 6.6.0, 6.7.0, 6.7.5 and 6.10.0; earlier pins were not traced.policyengine-simulation-py6-10-0. If the pin moves first (an automated update to 6.11.1 exists as a branch), the 6.10.0 app keeps sendingxandytoo.Unverified: the routing state lives in Modal Dicts (
simulation-api-routing-stateand the legacysimulation-api-*-versionsdicts) in each Modal environment, not in the repository, so I can't tell which of those versions are actually routed in beta or prod, or whether any of their apps were stopped by hand. I also haven't checked that apps built before 24 July produced UK area records at all. Those builds passed .py's area rows through, and those rows carryxandy.So meeting the merge condition needs a step this repository doesn't have: retire the routes to every app built before #919 deployed (or decide that pinned requests to those versions may fail). Jobs those apps computed before the change, and that are still pollable, would also fail validation once this deploys.
Testing
Written red-green: the tests were written first and seen failing for the expected reason, then the code was written and both were committed together.
test_records_with_x_or_y_are_refused(both, either one, or both null, on each record) andtest_a_job_status_refuses_area_records_with_x_and_y(breakdown and national results) failed withDID NOT RAISE;test_records_validate_and_dump_without_x_or_yfailed because the records still declared both fields.test__given_records_with_x_and_y_from_an_older_app__then_the_job_failsgot 200 instead of 500.test_generated_client_area_records_have_no_x_or_yfailed because the record models still tookxandy.Commands run (focused, locally):
uv run --frozen pyteston the contract'stest_macro_output_uk_geography.py,test_local_area_breakdown.pyandtest_gateway_models.py; the gateway'stest_endpoints.pyandtest_openapi_golden.py; the entry'stest_openapi.py; and the executor'stest_simulation_output_geographic.py,test_simulation_output_builder.py,test_uk_local_authority_metadata.pyandtest_stage12_runtime.py.python -m policyengine_simulation_gateway.generate_openapi;./scripts/generate-clients.sh, thenuv run --frozen pytest tests/ -m "not requires_gcp and not beta_only"inpolicyengine-apis-integ: everything passed excepttest_ping, which needs a gateway running on localhost.make check,python scripts/run_quality_guards.pywithGITHUB_BASE_REF=main,python -m scripts.rules render(no changes) and.github/scripts/check-uv-locks.sh.CI completeandPR descriptionjobs until Stop sending x and y on UK area results #919 merges.🤖 Generated with Claude Code