Repository navigation
Conversation
anth-volk
added this pull request to stack #3888
October 13, 2026 12:35
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #3905 +/- ##
===========================================
+ Coverage 43.80% 85.48% +41.68%
===========================================
Files 183 198 +15
Lines 11219 12412 +1193
Branches 1993 2266 +273
===========================================
+ Hits 4915 10611 +5696
+ Misses 5812 1100 -4712
- Partials 492 701 +209 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
anth-volk
force-pushed
the
ruff-annotations
branch
from
October 13, 2026 16:56
ca36072 to
2b3e55d
Compare
anth-volk
removed this pull request from stack #3888
October 13, 2026 19:26
anth-volk
added this pull request to stack #3917
October 13, 2026 19:26
anth-volk
force-pushed
the
ruff-annotations
branch
7 times, most recently
from
October 14, 2026 21:13
cd4765b to
4c0a7c6
Compare
anth-volk
force-pushed
the
ruff-annotations
branch
5 times, most recently
from
October 15, 2026 00:06
1403bc2 to
28faa7d
Compare
Type the cache backend protocol with what callers rely on (string envelopes in, opaque write acknowledgements out) and add a CachePipeline protocol for the queued writes. Decoded envelope payloads are object, because every consumer validates them. A SPMCapabilitySource protocol covers both the HTTP entrypoint client and the release registry adapter that validate_worker_spm accepts. ReformImpactCache.update keeps Any for the keyword changes it forwards unchanged to dataclasses.replace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reform-impact service parameters take the cache's scalar types, with the options hash optional on the write paths that receive it from EconomicImpactSetupOptions. Policy JSON read from the v1 table is a JSONValue. SPMSelection.serialize_selection stays without a return annotation (noqa ANN201) because Pydantic would build the model's serialization JSON schema from it and change the published OpenAPI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Before-validators take and return object. The parameter-tree SQL helpers take mapped columns and return typed column expressions. Three helpers keep Any with a reason: the JSON validators and canonical encoders dispatch on exact type() checks mypy cannot narrow, and read_rows passes core SQLAlchemy selects that Session.exec's overloads do not declare. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
View decorators are generic over the wrapped view's result, so a view returning dict | Response keeps that type plus the error Response. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scripts/rules stays standard-library only. Enforcer.get keeps Any for the raw TOML value that callers read by its shape. scripts/rules changes need mirroring in policyengine-sim-api. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Select ANN everywhere except tests, which need no annotations. The annotation commits before this one fix every finding outside .github/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bump_version.py, find-api-model-versions.py and scripts/check_updates.py (with a ChangelogEntry TypedDict). Annotations only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
api.quality.ruff-lint now includes ANN, and the **/tests/** per-file ignore list (S101, D1, ANN, PLR2004) is registered as api.quality.tests-ruff-exemptions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
ruff-annotations
branch
from
October 15, 2026 15:21
28faa7d to
ccfa83b
Compare
Ruff treats a class as runtime-evaluated when a base resolves, through the import in the class's own module, to a listed name, or when a base defined in the same module is itself runtime-evaluated. It matches the import path, not where the base is defined, so a listed base imported through a re-export is not recognised. The guard compared definition paths, so it would have passed such a subclass while ruff asked for its annotation imports to be moved. The guard now parses each model's module, resolves its bases through the module's imports (including relative imports, attribute access and subscripted generics), follows same-module bases, and fails with the path to add. test_base_resolution_matches_ruff pins the resolution: listed imports, module attributes, same-module chains, generics and relative imports count; re-exports and unlisted third-party bases do not. An experiment against ruff 0.15.12 confirmed each case. No model in the package is affected today. The rule statement and the typing-only-imports skill describe the matching precisely. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 6.4.1 bundle moves policyengine-uk from 2.126.12 to 2.130.1; US stays at 2.2.1. The installed-catalog compatibility test pins exact entity counts so package changes get an explicit review: - variables 7,294 -> 7,330: UK adds 37 and removes one; - parameters 104,158 -> 104,171, parameter values 1,194,256 -> 1,194,357 and parameter nodes 29,300 -> 29,306: UK adds parameters for ESA exempt work and remunerative work, JSA remunerative work, the tax credits Pension Credit passport and the Universal Credit company-owner rules. policyengine-uk 2.129.0 removed the input uc_has_limited_capability_for_work in favour of uc_limited_capability_for_work. A partner still sending it would now fail, so it joins DEPRECATED_VARIABLES: it is dropped with a warning naming the replacement, as for medical_out_of_pocket_expenses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully 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 #3904
Summary
Phase 1 step 1.8, group 3: annotations. Stacked on #3902.
Annotations:
selectgainsANN, and every function outside tests is now annotated: 252 findings inpolicyengine_apiand the scripts, plus 16 in.github/.Any(ANN401): replaced by a real type wherever one exists (56 of 63). Types used includeobjectfor opaque pass-through values, the existingJSONValuealias,CachedReformImpact, StarletteScope,ArrayLike, and two new Protocols (CachePipeline,SPMCapabilitySource).Remaining suppressions: each keeps an inline
# noqa: ANN401with a reason:type()JSON validators mypy can't narrow;Session.execoverloads that reject core selects;dataclasses.replace(**changes);Enforcer.get;One
noqa: ANN201is on a Pydantic wrap serializer, because annotating it would change the published OpenAPI schema.Test-file exemptions:
**/tests/**ignoresS101,D1,ANNandPLR2004, as agreed for step 1.8. This is registered asapi.quality.tests-ruff-exemptions.Annotations checked against the code: I ran mypy over the whole package (beyond the configured v2 scope) and compared it with the base branch. Annotations that didn't match the code were corrected in the commit "Correct annotations that whole-package mypy shows were wrong". Whole-package mypy errors fell from 259 to 182.
Eight new whole-package errors remain:
policyengine_corehas nopy.typed, andConnector.connectand numpy arithmetic returnAny.view_argsis optional, but the route indexes it.get_execution_resultacceptsNone, but its success path needs an execution.Fixing either needs a code change, which is out of scope for an annotation PR.
Runtime-annotation guard: the guard Enable ruff typing-only import rules (TC) #3902 added now resolves each model's bases the way ruff does: through the import in the model's own module, following bases defined in the same module. Ruff matches that import path, not where a base is defined, so a listed base imported through a re-export doesn't count. The old guard compared definition paths and would have missed that case. A new test pins the resolution, and an experiment against ruff 0.15.12 confirmed each case. No model in the package is affected today. The rule statement and
docs/engineering/skills/typing-only-imports.mdnow describe the matching precisely.PolicyEngine bundle 6.4.1 (replaces Update PolicyEngine bundle to 6.4.1 #3939): the Simulation API now runs 6.4.1 (chore(deps): update policyengine to 6.4.1 policyengine-sim-api#809). On 6.3.4, the Public API's "Ensure PolicyEngine bundle is supported by simulation API" check fails with "The us route resolves to a different worker application", which also blocks
master's staging deploy. The bundle moves policyengine-uk from 2.126.12 to 2.130.1; US stays at 2.2.1.test_v2_catalog_installed.py. UK adds 37 variables and removes one, and adds parameters for ESA and JSA remunerative work, the tax credits Pension Credit passport and the Universal Credit company-owner rules.uc_has_limited_capability_for_workin favour ofuc_limited_capability_for_work. It joinsDEPRECATED_VARIABLES, so a partner still sending it gets a warning naming the replacement instead of a failed calculation.Testing
pytest tests/unit tests/contract: 2,358 passed. to_refactor plus dedupe: 53 passed.ruff check/formatare clean repo-wide.scripts/rulesis byte-identical with sim.🤖 Generated with Claude Code