Repository navigation
Conversation
anth-volk
added this pull request to stack #3888
October 13, 2026 17:53
2 tasks done
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-security-logging
branch
from
October 14, 2026 13:52
f973af3 to
6c8d2b6
Compare
anth-volk
force-pushed
the
ruff-security-logging
branch
2 times, most recently
from
October 14, 2026 16:59
747e269 to
899ad06
Compare
anth-volk
force-pushed
the
ruff-security-logging
branch
3 times, most recently
from
October 14, 2026 20:04
c67b555 to
1d13dbe
Compare
anth-volk
force-pushed
the
ruff-security-logging
branch
7 times, most recently
from
October 15, 2026 15:21
509c02c to
dfd8c98
Compare
anth-volk
force-pushed
the
ruff-security-logging
branch
from
October 15, 2026 15:45
dfd8c98 to
1f2e57c
Compare
anth-volk
force-pushed
the
ruff-security-logging
branch
from
October 15, 2026 17:21
1f2e57c to
795091f
Compare
anth-volk
force-pushed
the
ruff-security-logging
branch
2 times, most recently
from
October 16, 2026 06:45
7a6c495 to
7008825
Compare
Delete the commented-out TestPolicySearch class in the to-refactor policy tests, along with the note that introduced it, the commented-out profiler import in the Flask app and the commented-out service imports in the services package. The GPT-4 experiment's example reform is reworded as prose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each of these six scripts has a python3 shebang and a __main__ entry point, so it is meant to be run directly. Git now records them as executable; running them through python is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The user-profile update note keeps its link to issue #2054, which was closed as not planned, and now says so. The simulation serializer note explains that its JSON-in-a-string projection serves only the v1 contract. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The three logging.exception calls in the household routes used the root logger. They now use a module logger, so the records are named after policyengine_api.routes.household_routes; the message text and traceback are unchanged. The module keeps its existing structured logger for log_struct. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The catalog extractor builds a date's midnight with tzinfo=UTC directly instead of attaching UTC afterwards; the result is the same aware value. Every other naive value stays naive, with an inline reason: reform impact start_time and report run timestamps are naive columns (and the runtime cache's datetime.min fallback must compare with them), economy start_time has always held local time, the default year and household period follow the host's local calendar, and the rules registry checks review and expiry dates against the local date. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The eight asserts in the v2 household, policy and user-household services and the two in the rules ci-scripts guard now raise TypeError when the narrowed value has the wrong type. None runs inside a Pydantic validator and nothing catches AssertionError: the v2 routes return their generic 500 and the mirror paths report an "unexpected" failure for either type, and the rules callers check for a missing [ci_scripts] table first. The checks also hold under python -O, which strips asserts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
validate_country no longer prints "Validating country" on every request (#3909). The simulation and report routes no longer print on create and get, where the URL already carries the country and id; their update messages, whose id comes from the request body, become debug records on a module logger with the same text. The remaining prints are output by design and carry a reason: the CLI entry points' JSON evidence and results, the startup timings and the unauthenticated simulation client warning on stderr. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Printing is these scripts' job. The four scripts with more than three prints (the version bump, the migration baseline capture, the local boot smoke test and the rules CLI) route their output through one _report helper. Three of those helpers' prints carry the suppression; the version bump's helper passes its file argument through, which T201 does not flag, and its stderr messages still go to stderr. Every other print carries an inline reason, as does the catalog publication qualification test, whose printed evidence is its report. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Behaviour-identical fixes: the runtime cache version's sha1 is marked usedforsecurity=False (the digest is unchanged), and the GPT-4 experiment parses its embedding strings with ast.literal_eval. Test modules reuse one constant per fake credential or claim token instead of repeating the literal, and the Cloud Run deploy-script tests run bash through one helper. Every other finding keeps its code with an inline reason: try/except/pass on the deliberate telemetry and logging catch-alls (S110, alongside their BLE001 reason), environment-variable and Secret Manager names and test sentinels (S105, S106), fixed repository commands (S603, S607), fixed https and loopback URLs (S310), the experiment's untimed requests (S113), the load test's seeded random mix (S311) and fixed table names in a test query (S608). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Select flake8-datetimez (DTZ), eradicate (ERA), flake8-executable (EXE), flake8-fixme (FIX), flake8-logging-format (G), flake8-logging (LOG), flake8-bandit (S), flake8-print (T20) and flake8-todos (TD). Tests follow all nine: their exemptions stay limited to S101, D1, ANN and PLR2004. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
api.quality.ruff-lint now lists DTZ, ERA, EXE, FIX, G, LOG, S, T20 and TD. The rendered rules page also picks up the rules tool's new hash. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…S101) The user-household and user-policy patch methods asserted that a supplied legacy id is not None before checking it in v1. They now raise TypeError instead, as the other v2 services do. The update models already reject an explicit null legacy id, so neither check can fail for a validated request; if one did, nothing catches either type and the route returns its generic 500. The checks also hold under python -O. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- S105: the Auth0 Management secret environment-variable names and the invalid-token WWW-Authenticate challenge keep their literals with a reason, as do the Auth0 test's Secret Manager path and the route-auth test's leak sentinel. - S106: the Cloud Run deploy-script tests name the Auth0 Management secret resource once, as TEST_AUTH0_SECRET_RESOURCE, instead of repeating the literal three times. - S110: the user routes' failure logging keeps its try/except/pass with the BLE001 reason. - T201: the association qualification command's two prints are its JSON evidence and keep a reason. - EXE001: scripts/qualify_v2_user_association_migration.py has a python3 shebang and a __main__ entry point like its two siblings, so git now records it as executable. These were the other 10 ruff group 6 findings in the code #3891 added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r file Per-file-ignores are now only for tests, CI/CD scripts and command-line scripts, so the "migrations/*/versions/*.py" = ["ALL"] entry moves to [tool.ruff.lint] exclude. The revisions must stay exactly as Alembic generates them (api.migration.alembic-autogenerated-only), so ruff still doesn't lint them when it walks the repository, and ruff format still checks them as before. api.quality.alembic-revisions-unused-imports now describes the exclusion, with no ruff enforcer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e scripts A ruff per-file-ignores entry switches rules off for whole files. That is now acceptable where it's the norm: tests, CI/CD scripts under .github, and command-line scripts (under a scripts directory, or modules run through if __name__ == "__main__"). Everywhere else a kept finding still needs an inline suppression with its reason. The rules guard already requires a per-file-ignore rule for every entry. It now also expands each entry's pattern the way ruff does (globset syntax, where * and ? also match "/", and a pattern also matches a file by its name alone) and fails when the pattern covers any other file, is negated, or matches nothing. scripts/rules/file_exceptions.py holds the definitions, and the registry doc describes the policy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Group 6's rules flag patterns that are the norm in tests, CI/CD scripts and command-line programs: fake credentials, subprocess calls to repository scripts, prints, naive datetimes, fixed URLs. Those files now take file-level exceptions, each registered as a per-file-ignore rule, and the 122 inline suppressions they cover are removed: - tests (**/tests/**, extending api.quality.tests-ruff-exemptions): S105 30, S603 14, DTZ001 13, S607 11, S106 2, S608 2, DTZ011 1, T201 1; - CI/CD scripts (.github/**): T201 6, S310 2; - command-line scripts (scripts/**): T201 17, S603 4, S607 2, DTZ011 2, S310 2, S110 2 (BLE001 stays on those two lines), S311 1; - modules that also run as programs (catalog initialization, the three migration qualifications and worker_spm_release): T201 10. Each entry lists exactly the codes these files suppressed, not whole families, so other security rules still apply to them. Suppressions in application code are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
ruff-security-logging
branch
from
October 16, 2026 07:05
7008825 to
88bf897
Compare
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 #3914
Also fixes #3909: the country validator's
print("Validating country")is removed.Summary
Phase 1 step 1.8, group 6: security, logging and debugging leftovers. Stacked on #3913.
selectgainsS,T20,LOG,G,DTZ,ERA,TD,FIXandEXE. Every finding at the base (262, plus 12 in Stage 12A: Sign-in identity and v1-anchored user associations #3891's code after the restack) is fixed, kept with an inline reason, or, in tests, CI/CD scripts and command-line scripts, covered by a file-level exception. One commit per family.per-file-ignoresentry is now allowed only for:testsorauthenticated_testsdirectory);.github);scriptsdirectory, or a module with a top-levelif __name__ == "__main__":).*and?also match/, and a pattern also matches a file by its name. It fails when the pattern covers any other file, is negated, or matches nothing.scripts/rules/file_exceptions.pyholds the definitions,docs/engineering/skills/rules-registry.md#file-level-exceptionsdocuments them, and six rules-tool tests prove them.per-file-ignorerule:**/tests/**, extendingapi.quality.tests-ruff-exemptions):S105,S106,S603,S607,S608,DTZ001,DTZ011,T201;.github/**):S310,T201;scripts/**):T201,S603,S607,S310,S311,S110,DTZ011;worker_spm_release):T201..github. The 36 suppressions in application code are unchanged."migrations/*/versions/*.py" = ["ALL"]entry moves to[tool.ruff.lint] exclude.ruff check .still skips them, andruff formatstill checks them.api.quality.alembic-revisions-unused-importsnow describes the exclusion.logger.debugcalls on a module logger, because their ids come from the request body.TypeError. None runs inside a Pydantic validator, and nothing catchesAssertionError. Every check was already guaranteed by an earlier one, so none is expected to fire; the v2 routes and the mirror paths treat either type the same way. No production command runs Python with-O, so these asserts were live.capture_migration_baseline.py,smoke_test_local_boot.pyand the rules tool's CLI route output through one_reporthelper. Application code keeps theapi.pystartup timings and the gateway-auth warning on stderr, each with an inline reason.hashlib.sha1(..., usedforsecurity=False)(same digest), and the GPT-4 experiment parses embeddings withast.literal_evalinstead ofeval..github: fixed https and loopback URLs, and a seeded load-test mix.WWW-Authenticatechallenge;requestscalls, where a timeout would change behaviour.S110: eachtry/except/passalready carried a reasonedBLE001suppression from group 5, which now listsS110too.tests/to_refactor/python/test_policy.py). The two TODOs become plain notes; the user-profile one keeps its link to Utilize a technology like Marshmallow to validate inbound requests #2054 and says it was closed. Seven Python scripts with a shebang and a__main__entry point are now executable.api.quality.ruff-lintnow lists the nine families.per-file-ignorerules describe the file-level exceptions.Testing
ruff checkandruff format --check(0.15.12) are clean;scripts/rules/, every changed Python file at every tip differs from the previously pushed tip only in# noqacomments: each version is compared with itsnoqacomments stripped. The other changes are:pyproject.toml;tests/unit(2,685 passed) and the to_refactor, contract and dedupe set (97 passed) were run on this branch before the last change, which touched only the rules tool. They were not re-run after it./v2/openapi.jsonpreview and the legacy spec are byte-identical to the base..githubscripts changed only in comments, output helpers or file mode, and the environment variables they read are unchanged.CI complete, which fails and says why (step 0.7, Make CI enforcement trustworthy before the rules registry #3887). Its full run starts once the PRs below it merge.🤖 Generated with Claude Code