Skip to content

Commit 8eba23a

Browse files
anth-volkclaude
andcommitted
Merge origin/main into feat/stage-12a-entrypoint-permissions
Brings in #765 (ruff check in CI with the first group of rule families), #809 (policyengine 6.4.1) and #791 (redacted Stage 12 failure cause). Conflicts: - auth.py: kept this branch's Callable and Literal imports and sorted the stdlib import block the way main's newly enabled I rule expects. - docs/generated/rules.md: regenerated with python -m scripts.rules render from the auto-merged registry, which holds main's enforced sim.quality.ruff-lint and this branch's sim.deploy.permission-enforcement-wired (34 of 48 rules blocking). ruff check . passes under main's ruff.toml with ruff 0.15.22, so this branch's own code needed no further changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 parents 6e29801 + 9cd0ca3 commit 8eba23a

169 files changed

Lines changed: 1686 additions & 713 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/pr.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ jobs:
9999
- name: Run ruff format check
100100
run: uv run ruff format --check projects/*/src libs/*/src
101101

102+
- name: Run ruff check
103+
run: uv run ruff check .
104+
102105
quality-guards:
103106
name: Quality guards
104107
# Full CI runs only on the lowest unmerged pull request in a stack.

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ To add or change a rule, read `docs/engineering/skills/rules-registry.md`.
139139
- `sim.quality.every-project-tested`: Every project and library with unit tests runs them in the PR test matrix. (doc-only, not checked: follow it yourself)
140140
- `sim.quality.ruff-format-src`: Source code under projects/*/src and libs/*/src is formatted with ruff format. (blocking: ruff format)
141141
- `sim.quality.ruff-format-tests`: Test code is formatted with ruff format too; CI currently checks only src directories. (doc-only, not checked: follow it yourself)
142-
- `sim.quality.ruff-lint`: Python code passes ruff check with the rules selected in ruff.toml (ruff's defaults, made explicit); CI does not run ruff check yet. (advisory: ruff check (E4, E7, E9, F), not blocking)
142+
- `sim.quality.ruff-lint`: All Python code passes ruff check with every rule family selected in ruff.toml, with no ratchet; families are added one themed group at a time until the selection is ALL. (blocking: ruff check (E4, E7, E9, F, FLY, FURB, I, PIE, PYI, RET, RSE, UP, W))
143143
- `sim.quality.tests-pass`: Each project's unit tests pass in its own locked environment. (blocking: CI job `test`)
144144

145145
### CI workflows and scripts

‎changelog_entry.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Made CLAUDE.md and the Copilot instructions thin pointers to AGENTS.md, required workflow logic longer than one line to live in tested and shellchecked scripts, and registered the tracking-issue rule
55
- Added a rules registry (rules/registry.toml) with a standard-library tool that validates it, checks every rule is enforced where it claims, and renders docs/generated/rules.md and the Rules block in AGENTS.md
66
changed:
7+
- Ran ruff check in CI with the first group of rule families (imports, pyupgrade and other safe auto-fixes) and fixed every finding
78
- Moved the multi-line `run` blocks of the simulation deployment workflows into single-line steps and tested scripts without changing their behaviour or outputs, leaving only the release-sentinel and routing-rollback blocks in the one-line `run` rule's baseline
89
- Moved multi-line `run` blocks in the PR, image smoke and client publishing workflows into single-line steps and tested scripts, tested the dependency-update scripts, fixed the shellcheck finding in modal-precompute.sh, and enforced the CI-script testing and shellcheck rules with empty baselines
910
- Added CODEOWNERS for the rule machinery, pinned CI's ruff to 0.15.22 with an explicit rule selection, and documented that agents never bypass branch rules
@@ -21,3 +22,4 @@
2122
- Bound UK constituency and local-authority weight matrices to the certified data release of the selected dataset instead of the unversioned bucket copy, and stopped runs before they start when the matrix lacks the run year or household dimension
2223
- Released each Stage 12 database session after its operation instead of holding pooled sessions through calculations, retried opening each Stage 12 coordinator and worker database connection that the pooler refused without ever retrying a statement or commit, and reported Stage 12 failures to telemetry before recording them in the database so a failed write cannot hide the original error
2324
- Accepted a null SPM provenance in Stage 12 aggregate artifacts, so UK and other reports without SPM calculations are saved, while every supplied provenance record is still validated
25+
- Recorded a redacted, bounded Stage 12 failure cause naming the exception, failing stage, simulation role and message instead of only the exception class, and kept a failed worker's recorded cause on its simulation and report

‎docs/generated/rules.md‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ Every rule that governs `policyengine-sim-api` is listed here with how it is enf
88

99
| Tier | enforced | ratcheted | advisory | doc-only | Total |
1010
| --- | ---: | ---: | ---: | ---: | ---: |
11-
| mechanical | 32 | 1 | 1 | 14 | 48 |
11+
| mechanical | 33 | 1 | 0 | 14 | 48 |
1212
| metric | 0 | 0 | 0 | 0 | 0 |
1313
| judgment | 0 | 0 | 0 | 0 | 0 |
1414

15-
**Blocking:** 33 of 48 rules.
15+
**Blocking:** 34 of 48 rules.
1616

1717
## Gaps
1818

@@ -35,7 +35,7 @@ Every rule that governs `policyengine-sim-api` is listed here with how it is enf
3535

3636
### Advisory (checked but not blocking)
3737

38-
- `sim.quality.ruff-lint`: Python code passes ruff check with the rules selected in ruff.toml (ruff's defaults, made explicit); CI does not run ruff check yet.
38+
- None.
3939

4040
### Unproven (no proof that the checker rejects a bad example)
4141

@@ -249,7 +249,7 @@ flowchart LR
249249
| `sim.quality.every-project-tested` | Every project and library with unit tests runs them in the PR test matrix. | mechanical | doc-only | no | nothing | — | — |
250250
| `sim.quality.ruff-format-src` | Source code under projects/*/src and libs/*/src is formatted with ruff format. | mechanical | enforced | yes | ruff format | `pr.yml:lint` | — |
251251
| `sim.quality.ruff-format-tests` | Test code is formatted with ruff format too; CI currently checks only src directories. | mechanical | doc-only | no | nothing | — | — |
252-
| `sim.quality.ruff-lint` | Python code passes ruff check with the rules selected in ruff.toml (ruff's defaults, made explicit); CI does not run ruff check yet. | mechanical | advisory | no | ruff check (E4, E7, E9, F) | — | — |
252+
| `sim.quality.ruff-lint` | All Python code passes ruff check with every rule family selected in ruff.toml, with no ratchet; families are added one themed group at a time until the selection is ALL. | mechanical | enforced | yes | ruff check (E4, E7, E9, F, FLY, FURB, I, PIE, PYI, RET, RSE, UP, W) | `pr.yml:lint` | — |
253253
| `sim.quality.tests-pass` | Each project's unit tests pass in its own locked environment. | mechanical | enforced | yes | CI job `test` | `pr.yml:test` | — |
254254

255255
```mermaid
@@ -260,18 +260,17 @@ flowchart LR
260260
e_ruff_format["ruff format"]
261261
j_CI_pr_yml_lint["CI pr.yml:lint"]
262262
r_sim_quality_ruff_format_tests("sim.quality.ruff-format-tests (doc-only)")
263-
r_sim_quality_ruff_lint("sim.quality.ruff-lint (advisory)")
264-
e_ruff_check__E4__E7__E9__F_["ruff check (E4, E7, E9, F)"]
265-
local_only>"not run in CI"]
263+
r_sim_quality_ruff_lint("sim.quality.ruff-lint (enforced)")
264+
e_ruff_check__E4__E7__E9__F__FLY__FURB__I__PIE__PYI__RET__RSE__UP__W_["ruff check (E4, E7, E9, F, FLY, FURB, I, PIE, PYI, RET, RSE, UP, W)"]
266265
r_sim_quality_tests_pass("sim.quality.tests-pass (enforced)")
267266
e_CI_job_test["CI job test"]
268267
j_CI_pr_yml_test["CI pr.yml:test"]
269268
r_sim_quality_every_project_tested -.-> gap_unenforced
270269
r_sim_quality_ruff_format_src --> e_ruff_format
271270
e_ruff_format --> j_CI_pr_yml_lint
272271
r_sim_quality_ruff_format_tests -.-> gap_unenforced
273-
r_sim_quality_ruff_lint --> e_ruff_check__E4__E7__E9__F_
274-
e_ruff_check__E4__E7__E9__F_ -.-> local_only
272+
r_sim_quality_ruff_lint --> e_ruff_check__E4__E7__E9__F__FLY__FURB__I__PIE__PYI__RET__RSE__UP__W_
273+
e_ruff_check__E4__E7__E9__F__FLY__FURB__I__PIE__PYI__RET__RSE__UP__W_ --> j_CI_pr_yml_lint
275274
r_sim_quality_tests_pass --> e_CI_job_test
276275
e_CI_job_test --> j_CI_pr_yml_test
277276
```

‎libs/policyengine-fastapi/fixtures/ping/shared.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
"""Shared fixtures for ping endpoint tests."""
22

3+
import pytest
34
from fastapi import FastAPI
45
from fastapi.testclient import TestClient
5-
import pytest
6-
76
from policyengine_fastapi import ping
87
from policyengine_fastapi.health import HealthRegistry
98

‎libs/policyengine-fastapi/src/policyengine_fastapi/__init__.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@
44

55
from .observability import (
66
ObservabilityConfig as ObservabilityConfig,
7+
)
8+
from .observability import (
79
SimulationStage as SimulationStage,
10+
)
11+
from .observability import (
812
TracerCaptureMode as TracerCaptureMode,
13+
)
14+
from .observability import (
915
build_observability as build_observability,
16+
)
17+
from .observability import (
1018
get_observability as get_observability,
1119
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
from .jwt_decoder import JWTDecoder
2+
3+
__all__ = ["JWTDecoder"]

‎libs/policyengine-fastapi/src/policyengine_fastapi/auth/jwt_decoder.py‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from typing import Any
1+
import logging
2+
3+
import jwt
24
from fastapi import Depends, HTTPException, status
35
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
4-
import jwt
5-
import logging
66

77
# Based on the auth0 article: https://auth0.com/blog/build-and-secure-fastapi-server-with-auth0/
88

@@ -35,8 +35,7 @@ def __call__(
3535
if self.auto_error:
3636
LOG.info("Invalid auth token: Throwing 4XX error")
3737
raise err
38-
else:
39-
LOG.info("Ignoring invalid auth token")
38+
LOG.info("Ignoring invalid auth token")
4039
return None
4140

4241
def _validate(self, token: HTTPAuthorizationCredentials | None):

‎libs/policyengine-fastapi/src/policyengine_fastapi/database.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from pathlib import Path
2-
from typing import Any, Callable, Generator
1+
from collections.abc import Callable, Generator
2+
from typing import Any
3+
34
from sqlalchemy import Engine, StaticPool, create_engine
45
from sqlmodel import Session
56

‎libs/policyengine-fastapi/src/policyengine_fastapi/exit.py‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
"""
55

66
import logging
7+
from collections.abc import Callable
78
from contextlib import asynccontextmanager
8-
from functools import wraps
9-
from typing import Any, Callable, TypeVar, cast
10-
11-
from fastapi import FastAPI
9+
from typing import Any, TypeVar
1210

1311
log = logging.getLogger(__name__)
1412

0 commit comments

Comments
 (0)