fix(lint): pin the ruff rule set, and clear what it selects - #56
Merged
Conversation
CI was red with 201 findings that no code change caused. This repo carries no ruff configuration at all, so its rule set is whatever the installed ruff happens to default to -- and CI installs it unpinned (`ruff>=0.5`). ruff 0.16 widened its defaults, CI picked up 0.16.1, and a green repo went red on rules the project never opted into. Measured rather than assumed: ruff 0.16.1 with `--select E4,E7,E9,F` (its own documented default set) reports ZERO findings here, exactly as 0.15.13 does with no config. Every one of the 201 came from the default set expanding underneath us. Custodian hit the same class of failure from the other side in its adapters, where a global 0.16.1 shadowed a pinned 0.15.13 and produced 1222 phantom findings against a gate no venv could fix. So the fix is to state the intent once, in `[tool.ruff.lint].select`, where a future release cannot revise it. The selection is the defaults this repo has always passed, plus nine rules adopted deliberately -- each mechanical, auto-fixable, and cleared in this same commit rather than left as a promise: I001, UP017, UP035, UP037, UP045, RUF022, RUF023, FURB188, PLR0402. 112 fixes applied by `ruff check --fix` across 37 files, the bulk of it `datetime.timezone.utc` -> `datetime.UTC` and import ordering. The one class that can change behaviour is FURB188; all four sites were the guarded form (`if s.startswith(p): s = s[len(p):]`), which `removeprefix` reproduces exactly. Suite is unchanged at 16 failed / 488 passed, and the 16 are identical by name before and after -- diffed, not counted. The rules NOT selected are listed in the config with a reason each, rather than being silently absent. BLE001, S110/S112, PLC0415 and E402 are mostly deliberate patterns already annotated at their sites; B008 is a straight false positive for Typer, whose whole CLI surface is built from `typer.Option(...)` defaults. DTZ*, PLW1510, TRY004 and RUF059 are real signals worth adopting later, but each needs judgement per site and adopting one means clearing every hit in that pass. CI's floor moves 0.5 -> 0.15 so every selected code is known to the installed ruff. It is a floor, not a pin: the config is what stops the drift now. No log entry: `.console/log.md` is at exactly 400/400, so any entry trips RC1 and fails the audit. That the convention to log every change and the gate capping the log are now mutually exclusive here is itself the argument in Custodian ADR 0001, which recommends rationale live in the commit message. It does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
CI was red with 201 findings that no code change caused.
This repo carries no ruff configuration at all, so its rule set is whatever the installed ruff happens to default to — and CI installs it unpinned (
ruff>=0.5). ruff 0.16 widened its defaults, CI picked up 0.16.1, and a green repo went red on rules the project never opted into.Measured, not assumed
--select E4,E7,E9,F(documented default set)Every one of the 201 came from the default set expanding underneath us. Custodian hit the same class of failure from the other side in its adapters, where a global 0.16.1 shadowed a pinned 0.15.13 and produced 1222 phantom findings against a gate no venv could fix.
The fix
State the intent once, in
[tool.ruff.lint].select, where a future release cannot revise it. The selection is the defaults this repo has always passed, plus nine rules adopted deliberately — each mechanical, auto-fixable, and cleared in this same commit rather than left as a promise:112 fixes applied by
ruff check --fixacross 37 files — mostlydatetime.timezone.utc→datetime.UTCand import ordering.The one risky class, checked
FURB188(slice →removeprefix) is the only autofix here that can change behaviour — the two differ when the prefix is absent. All four sites were the guarded form:which
removeprefixreproduces exactly.Rules deliberately NOT selected
Listed in the config with a reason each, rather than silently absent:
typer.Option(...)defaultsVerification
0.5→0.15so every selected code is known. It's a floor, not a pin — the config is what stops the drift now.No log entry
.console/log.mdis at exactly 400/400, so any entry trips RC1 and fails the audit. That the convention to log every change and the gate capping the log are now mutually exclusive here is itself the argument in Custodian ADR 0001, which recommends rationale live in the commit message. It does.🤖 Generated with Claude Code