ci: pin ruff's rule set so lint stops drifting

Merged
SA
3mo ago
+16-0

lint is currently red on every PR against bux, including ones that touch no Python at all (e.g. #270, a one-line dependency bump). Nothing in our code broke.

Cause. .github/workflows/ci.yml runs pip install --quiet ruff unpinned, and the repo has no ruff config. So lint enforced whatever ruff's default rule selection happened to be on the day CI ran. Ruff has since widened those defaults, and ruff check agent/ now reports 224 errors against unmodified main (345ecbd) — I verified this in a clean worktree of main, same count, so it is not PR-specific.

The 224 break down as rules that were never in the old default set:

CountRule
101BLE001blind-except
44S110try-except-pass (bandit)
33PLW1510subprocess-run-without-check (pylint)
12UP037quoted-annotation
7I001unsorted-imports
27RUF100, ASYNC*, EXE001, FURB*, ISC004, SIM*, UP022, S112, PLW1509assorted

Zero E/F errors — the code is clean under what CI was actually enforcing.

Fix. Add a root ruff.toml selecting the rule set explicitly (E4, E7, E9, F) instead of inheriting a moving default. This is version-independent: a future ruff release can widen its defaults all it likes and our lint stays put.

I deliberately did not fix the 224. Most are BLE001/S110 in agent code where swallowing exceptions is the intended behaviour, and a 224-error sweep does not belong in a CI-repair PR. Opting into any of those rule families is a real decision — worth its own PR where the fixes get reviewed on their merits.

This does not weaken lint. Verified against ruff 0.16.4:

  • ruff check agent/ → All checks passed! (exit 0)
  • A probe file with import os unused and a reference to an undefined name still fails with F401 + F821.
  • Still enabled: E722 bare-except, E711/E712 identity comparisons, E401/E402 import placement, E721 type-comparison, E741 ambiguous names, and all of pyflakes.

Follow-up: ci.yml should pin the ruff version too, so behaviour changes within the selected rules can't surprise us. I had that change written but the push was rejected — the token lacks workflow scope. Left as a follow-up and noted in a comment in ruff.toml.

Once this lands, #270 goes green on rebase.


Summary by cubic

Pins ruff’s lint rule set via a new root ruff.toml to stop CI drift and restore deterministic linting. Before: CI installed unpinned ruff and enforced changing defaults, producing 224 new failures on unchanged code; now: explicit select = ["E4", "E7", "E9", "F"] preserves the previously enforced checks.

Notes

  • Adds ruff.toml only; no source changes. ruff check agent/ passes on ruff 0.16.4.
  • Still catches real breakage (e.g., F401 unused imports, F821 undefined names, E722 bare-except); does not enable BLE001/S110/PLW1510/etc.
  • Rebase open PRs to pick up the config and unblock CI.
  • Follow-up: pin the ruff version in .github/workflows/ci.yml once a token with workflow scope is available.