Upgrade engine to 0.47 and observability to 1.3 as exact pins; drop unused pydantic-ai#175
Merged
Merged
Conversation
Since 0.45 the engine requires an explicit data source: data-less Simulation(year=...) raises ValueError. Pass dataset="frs" at the parameter-lookup call sites (construction is lazy and get_baseline_params() shells out to the binary, so no survey data loads), and inject the same default in the sandbox wrapper so model-written run_python code keeps its documented contract. Backend suite against 0.47.0: 229 passed, 10 skipped. Fixes #174 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Beta preview has been cleaned up because this PR was closed. |
Nothing in the backend imports pydantic_ai — its only reference was a vestigial pytest.importorskip guarding a test whose imports don't need it, and docs/engineering/skills/uk-chat-runtime.md already states Pydantic AI is not the active orchestration layer. It also blocked the policyengine-observability upgrade: pydantic-ai pulls logfire, whose opentelemetry-sdk<1.43.0 cap conflicts with observability 1.3.1's >=1.43.0 floor, sending pip into deep backtracking. Dropping it also removes a large transitive tree (logfire, temporalio, xai-sdk, cohere, mistralai) from the production image. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…umentation Since 1.1, structured logs route through a severity-aware destination manager: handled-error operation logs emit at WARNING instead of INFO. Update the one log-capture test that asserts an operation_failed record to capture the WARNING level. 1.3.1 forward-pins the OTel stack (instrumentation >=0.64b0), fixing the _IncludedRouter AttributeError that 500'd CORS preflights on FastAPI >=0.137 (#167), so remove the instrument_fastapi=False workaround from #169. The preflight regression test now exercises the instrumented app; the instrumentation config test flips to assert it is enabled. Backend suite against compiled 0.47.0 + observability 1.3.1 in a fresh resolve: 229 passed, 10 skipped. Fixes #173 Fixes #170 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…pins Range pins let a new in-range release reach production on the next image build with no PR and no tests — the silent-drift failure class from #167/#168. Exact pins make every version change arrive as a tested PR through the dependency-update workflow. The updater keeps its two-tier policy, now keyed on the pinned minor instead of a range cap: same-minor releases are patch updates (auto-merge on green); releases crossing a minor are left for review. Discovery still proposes the newest same-minor patch even when a newer cross-minor release exists. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
08a6343 to
2488746
Compare
Add engine/constants.py with FRS_DATASET and use it for the parameter lookup data source, aggregate simulation defaults, the dataset schema enum/default, the dataset label map, and the sandbox row-level guards. engine/ is imported by tools/ and never the reverse, so the constant is reachable everywhere without cycles. modal_app.py keeps its literal: _preload_engine runs at Modal image build before backend/ is added to the image, so it cannot import backend modules. Test literals stay as-is — they assert the concrete wire contract rather than restating the constant. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 #174
Fixes #173
Fixes #170
What
Migrates both capped dependencies to their current upstream versions, switches them to exact
==pins, and removes the one dependency that blocked the resolve.policyengine-uk-compiled
>=0.44.0,<0.45→==0.47.0The one breaking change in between: since 0.45,
Simulationrequires an explicit data source — data-lessSimulation(year=...)raisesValueError.backend/tools/dispatch.py×2,modal_app.py_preload_engine): passdataset="frs". Construction is lazy andget_baseline_params()shells out to the binary, so no survey data loads on these paths. Can be simplified when Expose dataset-free baseline parameter export policyengine-uk-v2#112 (dataset-free parameter export) ships.backend/engine/sandbox.py):SafeSimulationinjectsdataset="frs"when model-written code passes no data source — therun_pythontool description and tool-contract eval cases document data-less construction, and the FRS guard bookkeeping already treated missing dataset as"frs".test_rejects_frs_row_level_microdatadoubles as the regression test.realtermsmodule, DWP cost-of-living payments (2022/23–2023/24), mortgage interest in AHC, region-level LHA rates, local-authority EFRS, dataset version pinning. Baseline results shift for affected years/measures; no output-contract changes.policyengine-observability
>=1.0.0,<1.1→==1.3.1operation_failedrecord now captures the WARNING level._IncludedRouterAttributeError that 500'd every CORS preflight on FastAPI ≥0.137 (Production outage: every CORS preflight (OPTIONS) returns 500 — OTel FastAPI instrumentation vs FastAPI >=0.137 #167). Theinstrument_fastapi=Falseworkaround from Disable OTel FastAPI auto-instrumentation to stop OPTIONS preflight 500s #169 is removed; the CORS preflight regression test now exercises the instrumented app, and the instrumentation config test flips to assert it is enabled (closes Re-enable FastAPI OTel instrumentation once the observability pin ships and our constraint widens #170).severityandsegment_treefields; core fields now take precedence over caller attributes (no UK chatannotate()keys collide). This unblocks Route observability logs to Google Cloud Logging #142 (Google Cloud Logging destinations).Exact pins + updater format change
Range pins let a new in-range release reach production on the next image build with no PR and no tests — the silent-drift failure class behind #167/#168. With
==pins, every version change arrives as a tested PR via the dependency-update workflow.dependency_bump.pyis updated in lockstep (same PR, somainnever has a format the updater can't parse):Unit tests updated for the new format (20 cases); a live
DRY_RUN=1sweep against PyPI reports both pins current. This is a step toward #168 (full dependency locking) for the two first-party packages; transitive deps still float.Removed:
pydantic-ai[anthropic]Nothing in the backend imports it (its only reference was a vestigial
importorskipin a test whose imports don't need it), anddocs/engineering/skills/uk-chat-runtime.mdalready states Pydantic AI is not the active orchestration layer. It also hard-blocked this upgrade: pydantic-ai pullslogfire, whoseopentelemetry-sdk<1.43.0cap conflicts with observability 1.3.1's>=1.43.0floor, sending pip into deep backtracking (locally ending in a failedtemporaliosource build). Dropping it removes a large transitive tree (logfire, temporalio, xai-sdk, cohere, mistralai) from the production image. TheanthropicSDK is a direct requirement and is unaffected.Verification
Fresh Python 3.13 venv resolved from this branch's
backend/requirements.txt(compiled 0.47.0, observability 1.3.1, otel-instrumentation-fastapi 0.64b0 — no resolver backtracking): 227 passed, 10 skipped, including compiled-integration tests, sandbox FRS-guard tests, the CORS preflight tests against the instrumented app, and the updated dependency-bump script tests. As a bonus validation of the original bug: an intermediate env with instrumentation enabled but the old 0.63b1 instrumentor reproduced the preflight 500s exactly.Notes
chore: bump ...PRs in the old range format in the meantime, close them in favour of this one.🤖 Generated with Claude Code