Skip to content

Select every Ruff rule, configured as the simulation API and the Public API configure it - #55

Merged
anth-volk merged 22 commits into
mainfrom
claude/rules-ruff-all
Nov 2, 2026
Merged

anth-volk merged 22 commits into
mainfrom
claude/rules-ruff-all

Conversation

@anth-volk

@anth-volk anth-volk commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #61

Part of #53, which tracks the end state and closes with the last of the fix pull requests stacked on this one.

What this does

Ruff selects every rule (ALL), configured as the simulation API and the Public API configure it. 16.1 · 8 in the plan; stacked on #52 (16.1 · 7, making the PR description check required, is a manual step and has no pull request). Anthony decided the design on round 1: mirror both services instead of ratcheting the ignore list.

  • select = ["ALL"], with the services' four global ignores. COM812 and ISC001 conflict with ruff format. D203 and D213 conflict with D211 and D212, which the configuration keeps; they apply once the D family leaves the temporary list. E501 is no longer ignored, as in both services.

  • CPY (copyright notices) stays off, with its reason in pyproject.toml. Ruff 0.16, which uv.lock pins here, checks CPY001, while the Ruff 0.15 both services run keeps it in preview, so neither enforces it.

  • Two more preview rules stay enforced here. ISC004 (all 108 of the ISC findings) and PLR0917 (5 of the 75 PLR findings) are also stable in Ruff 0.16 but only preview rules in the services' Ruff 0.15, so this repository enforces them and the services do not. They stay enforced; the stacked pull requests fix their findings.

  • Per-file ignores as in both services, each registered as a ruff per-file-ignore rule. These are the registry guide's file-level exceptions. The existing guard checks that each pattern exists with those codes, that it covers only files that may take an exception, and that every pattern has a rule:

    Rule Pattern Codes
    emitter.quality.tests-ruff-exemptions **/tests/** ANN ARG001 ARG002 ARG005 D1 DTZ001 DTZ011 INP001 N802 PLC0415 PLR2004 S101 S105 S106 S108 S603 S607 S608 SLF001 T201 TID253
    emitter.quality.unittest-ruff-exemptions scripts/rules/tests/** PT
    emitter.quality.command-line-scripts-ruff-exemptions scripts/** DTZ011 S603 S607 T201
    emitter.quality.tools-ruff-exemptions tools/** N999 S603 T201
    emitter.quality.installed-checks-ruff-exemptions tools/{check-installed,installed-smoke,installed-interface-smoke}.py PLC0415 S101

    The test codes are the Public API's 20 plus the simulation API's S108. The comment and the rule statement now explain each of them, including INP001 and TID253. There are no Python files under .github, so there is no .github/** entry. The root conftest.py is not under tests, and the rules tool allows no exception at the root, so the fix pull requests change its code instead.

  • namespace-packages lists scripts, tools and the two Alembic directories, which have no __init__.py on purpose (INP001), as both services list theirs.

  • flake8-tidy-imports and flake8-type-checking, as in both services (round 2):

    • banned-module-level-imports lists the modules imported only inside the function that needs them: the telemetry and Hugging Face service modules, which their entry points import only when create_module runs, and the Hub client's HfApi and CommitOperationAdd, which huggingface/service/hub.py imports only in the functions that build them. TID253 refuses these at module level outside tests, and PLC0415 accepts their in-function imports, which removes 4 findings.
    • runtime-evaluated-base-classes lists sqlalchemy.orm.DeclarativeBase, so TC never moves an import that a model's Mapped[...] annotation needs at runtime.
    • The new rule emitter.quality.runtime-evaluated-models-resolve registers tests/test_runtime_evaluated_annotations.py, adapted from the services' tests of the same name. It checks that every model in microcosm_emitter resolves, as Ruff resolves bases, to a listed base; that the resolution handles each kind of base; and that every mapper configures. The file is added to guard_test_globs.
  • The families not fixed yet are ignored until the pull requests stacked on this one fix them. On round 2's head, 79b468a, 1,593 findings remained in 26 families; with this head's import settings, 1,589. They are listed in ignore under a "Not fixed yet" comment, grouped as the stacked pull requests fix them. Each pull request removes its group, and the last leaves only the permanent ignores:

    1. exception messages and raising (469): EM 240, TRY 227, RSE 2 — Fix Ruff's exception-raising findings (EM, RSE, TRY) #58;
    2. docstrings (458): D 458;
    3. typing-only imports, annotations and in-function imports (180): TC 80, ANN 79, PLC 21;
    4. broad excepts, security findings, prints and private access (131): BLE 61, S 42, T20 22, SLF 6;
    5. smaller rules (262): ISC 108, PT 72, RET 16, ARG 14, PTH 10, E 9, SIM 9, RUF 6, FBT 6, C4 4, PERF 3, PLW 3, A 2;
    6. complexity (89): PLR 75, C90 14.
  • emitter.quality.ruff-lint describes ALL, the permanent ignores, the registered per-file ignores and, until the stacked pull requests land, the families not fixed yet.

  • The README's development section says how Ruff is configured.

Removed in round 1: the ruff-ignores guard and its comparison with the base branch, with its tests and fixtures; the ratcheted emitter.quality.ruff-families-not-yet-fixed rule, with its baseline and the downgrade naming #54; and the test that each listed family still had findings. The rules tool, the registry guide and every workflow are as on the base branch. #54 is closed as not planned.

Test-first record

Commit Result
3578e12 The Ruff configuration and its rules Configuration and registration only, so no red step. ruff check . and ruff format --check . (Ruff 0.16.10 from uv.lock) pass; all five guards pass, also with GITHUB_BASE_REF=main.
79b468a The rules tool as on the base branch The guards and ruff check . pass.
7235422 Test the model bases (round 2) Red: of the three new tests, test_every_model_base_is_listed_for_ruff fails, listing all 10 models (both declarative bases resolve to the unlisted sqlalchemy.orm.DeclarativeBase); the other two pass.
bef4f36 The two settings, the rule and the wording Green: the three tests pass. ruff check . and ruff format --check . pass. The guards pass against main and against #52's branch. A probe file confirms that TID253 refuses the banned imports at module level and that PLC0415 accepts them inside a function.

Before round 1's design was replaced, its commits were tested as recorded in their messages (37a3005, 0b85710, 30aea27, e5ff693, 87f903d, d259a7b, 106f3f5); their code is gone from this head. Only the three new tests were run, by node ID; no command ran a test directory or suite.

CI

No workflow, trigger or script changes. The new tests run in ci.yml's existing tests job (pytest -m "not collector"), which needs no new environment variable or secret. With no [rule.downgrade] left in the registry, the "Check the rules registry" step's issue lookup has nothing to look up, as on the base branch.

Release

The fragment is changelog.d/ruff-select-all.changed.md, a patch bump: merging releases the next patch version of both distributions. There are no source changes, so the wheels are unchanged.

🤖 Generated with Claude Code

anth-volk and others added 8 commits October 30, 2026 19:54
Brings review round 1 of #48.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings review round 1 of #50 and main after #43's merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings review round 1 of #52.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With every Ruff rule selected, [tool.ruff.lint] ignore switches rules
off. Test a ruff-ignores guard that fails on an ignored rule which neither
its rule's baseline (the families not fixed yet) nor one of its
exceptions (rules that stay off, with their reasons) lists, on a baseline
entry Ruff no longer ignores, so the baseline shrinks, on a stale or
unnamed exception, and on a rule listed in both. The proof fixtures
ignore an unlisted S, and only listed rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scripts/rules/ruff_ignores.py fails when [tool.ruff.lint] ignore or
extend-ignore holds a selector that neither its rule's baseline nor one of
its exceptions lists, when a baseline entry or an exception names a
selector Ruff does not ignore, when an exception names none, and when a
selector is listed both ways. It reads the configuration only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
[tool.ruff.lint] selects ALL, ignoring only the rules that stay off:
COM812 and ISC001, which conflict with ruff format, D203 and D213, which
conflict with D211 and D212, and E501, as before. emitter.quality.ruff-lint
now describes ALL. ruff check . fails on this tree: 7,991 findings in 28
families, which the next commit lists as not fixed yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
[tool.ruff.lint] ignore now also lists the 28 rule families with findings,
and ruff check . passes. emitter.quality.ruff-families-not-yet-fixed, a
ratcheted rule enforced by the new ruff-ignores guard, lists them in its
baseline (rules/baselines/ruff-families-not-yet-fixed.txt, 28 entries),
which the guard's base comparison lets only shrink, and the five rules
that stay off as its exceptions, with their reasons. As a new rule that
starts ratcheted, it has a [rule.downgrade] naming #54, which tracks
fixing the families. The registry guide's Baselines section says how
the ignore list is ratcheted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@anth-volk
anth-volk added this pull request to stack #46 October 30, 2026 16:10
@anth-volk anth-volk changed the title claude/rules ruff all Select every Ruff rule, ratcheting the rule families not fixed yet Oct 30, 2026
anth-volk and others added 4 commits October 30, 2026 20:25
Brings review round 2 of #48: the uv release written once, in pyproject.toml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 1 of #55:

- Compared with the base branch, the baseline may lose families but gain
  none, and the rule may gain no exception: swapping a fixed family for
  another, or moving one into a new exception, kept the count from
  growing and passed.
- Ruff's top-level ignore and extend-ignore count as ignoring;
  extend-per-file-ignores is refused; an excluded path, and another Ruff
  configuration (ruff.toml, .ruff.toml, or a nested pyproject.toml with
  [tool.ruff]), needs an exception naming it.
- A ratcheted rule that tolerates entries keeps its [rule.downgrade],
  not only when it is added.
- Two tests are renamed or made exact, as the review asked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- compare_with_base, which the guard runs against the base branch,
  refuses a baseline family or a rule exception the base branch's
  ruff-ignores rule does not have, so a family can leave the list but
  not join it, also when the count does not grow.
- The ruff-ignores guard also reads [tool.ruff] ignore and extend-ignore,
  refuses extend-per-file-ignores, and requires an exception for each
  excluded path and for each other Ruff configuration: ruff.toml,
  .ruff.toml, or a pyproject.toml with [tool.ruff] below the root.
- Validation requires a [rule.downgrade] on every ratcheted rule that
  tolerates entries, not only on a new one.
- Baseline files are read with one parser, baseline.baseline_lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tests/test_ruff_families.py runs Ruff with every rule selected except the
rules that stay off for good, and fails when a family the baseline lists
has no finding left, so the pull request that fixes a family's last
finding also takes it off the list. It runs in ci.yml's tests job, where
Ruff is installed, as emitter.quality.ruff-families-still-have-findings;
the rules tool stays standard-library only.

No red step on this tree: every listed family has findings. With FURB,
which has none, added to the baseline, the test failed naming FURB; the
baseline was then restored.

The pyproject.toml comment says D211 and D212 apply once D is fixed, and
the registry guide describes the base comparison and the family check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk and others added 4 commits October 30, 2026 21:08
Brings main after #45, Dependabot in place of the custom relock, and the
PR description check's Dependabot exception. docs/generated/rules.md and
AGENTS.md are rendered from the merged registry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings main after #48's merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Ruff selects ALL and ignores COM812, ISC001, D203 and D213 everywhere,
  as both services do, and CPY, which Ruff 0.16 checks but their Ruff 0.15
  keeps in preview.
- Per-file ignores for tests, the rules tool's unittest tests, scripts/,
  tools/ and the installed-artifact checks, each registered as a ruff
  per-file-ignore rule, as both services register theirs.
- The rule families with findings not fixed yet stay in the ignore list
  until the pull requests stacked on this one fix them, one group each.
- Remove the ratchet on the ignore list: the ruff-ignores guard and its
  base-branch comparison, its tests and fixtures, the
  ruff-families-not-yet-fixed rule and baseline, and the test that each
  listed family still has findings. The guide's "Ruff is never
  ratcheted" wording returns.
- Keep validation's requirement that a ratcheted rule with entries has a
  [rule.downgrade]; its test moves to test_guard.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without the ratcheted Ruff rule, the stricter downgrade check and the
shared baseline parser have nothing in this pull request that needs them,
so baseline.py, validate.py, their test and the registry guide return to
the base branch's version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@anth-volk anth-volk changed the title Select every Ruff rule, ratcheting the rule families not fixed yet Select every Ruff rule, configured as the simulation API and the Public API configure it Oct 30, 2026
anth-volk and others added 2 commits October 30, 2026 21:52
Adapted from the simulation API's and the Public API's
runtime-evaluated-models-resolve tests: every model under
microcosm_emitter has a base that resolves, as Ruff resolves it, to a
name in [tool.ruff.lint.flake8-type-checking]
runtime-evaluated-base-classes, the resolution model handles each kind
of base, and every mapper configures. The first test fails until the
setting lists sqlalchemy.orm.DeclarativeBase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- [tool.ruff.lint.flake8-type-checking] runtime-evaluated-base-classes
  lists sqlalchemy.orm.DeclarativeBase, so Ruff keeps the imports the
  models' Mapped annotations need at runtime. The new rule
  emitter.quality.runtime-evaluated-models-resolve registers the tests
  that check every model resolves to it, as the services register theirs.
- [tool.ruff.lint.flake8-tidy-imports] banned-module-level-imports lists
  the modules imported only inside the function that needs them: the
  telemetry and Hugging Face service modules, and the Hub client's HfApi
  and CommitOperationAdd. TID253 refuses them at module level outside
  tests, and PLC0415 accepts their in-function imports.
- The tests exemption's statement and comment explain INP001 and TID253,
  and the registry comment that discovery cannot see ruff format
  --check is back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk added a commit that referenced this pull request Oct 30, 2026
- The host entry point: module settings that are not an object end
  startup with exit code 1 and the fixed "startup_failure" text on
  stderr, and no module is loaded.
- The Orrery delivery: an upload answer whose uploads value is not a
  list keeps the job pending with the
  publication_invalid_evidence_or_response code, after one request.
- The telemetry block request: a blocking_gate_ids value that is not a
  list queues no event and leaves the lifecycle unchanged.

The tests pass on #55's code, where these checks raised ValueError, and
on this branch. The startup test's variable is named startup_reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk and others added 2 commits November 2, 2026 17:41
#60 becomes the bottom of the stack. The only conflict was in
docs/generated/rules.md, which python -m scripts.rules render
regenerated from the merged registry; AGENTS.md was rendered the same
way. setup-uv keeps enable-cache: false in pr.yaml and push.yaml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@anth-volk
anth-volk removed this pull request from stack #46 November 2, 2026 14:03
@anth-volk
anth-volk changed the base branch from main to claude/uv-cache-without-uv November 2, 2026 14:04
@anth-volk
anth-volk added this pull request to stack #72 November 2, 2026 14:04
Base automatically changed from claude/uv-cache-without-uv to main November 2, 2026 14:25
@anth-volk
anth-volk marked this pull request as ready for review November 2, 2026 15:06
@anth-volk
anth-volk merged commit 2b88444 into main Nov 2, 2026
12 checks passed
@anth-volk
anth-volk deleted the claude/rules-ruff-all branch November 2, 2026 15:06
anth-volk added a commit that referenced this pull request Nov 2, 2026
#58 to #69 were rebased onto main after #55 merged, so this merge
conflicted in the 18 files this branch had changed on top of #69. Each
keeps this branch's side, plus the version commit's bump in
pyproject.toml; python -m scripts.rules render regenerated the rules
view. The tree differs from e0cfd8e exactly by main's version commit
d732aab (2b88444..d732aab).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configure Ruff like the Public API and the simulation API, with a temporary list of families not fixed yet

1 participant