Skip to content

fix(ci): declare the ruff rule set in config, unpin ruff and black - #71

Draft
bamr87 wants to merge 2 commits into
mainfrom
fix/fleet-doctor-aieo-ruff-ruleset
Draft

fix(ci): declare the ruff rule set in config, unpin ruff and black#71
bamr87 wants to merge 2 commits into
mainfrom
fix/fleet-doctor-aieo-ruff-ruleset

Conversation

@bamr87

@bamr87 bamr87 commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Problem

Repo: bamr87/aieo · Workflow: .github/workflows/ci.yml · Signals: failing, high-cost-low-value

14d Actions data: 15 runs · 28.2m consumed · 24.9m wasted · 11.8% effective · 14.3% success · 7.5 runs/wk, 0% scheduled. Nearly every run ended non-success, and the lint job was the one failing on all of them — including every open Dependabot PR, which is where most of the wasted minutes came from.

Evidence, from the lint job of run 31148732558 (job 92773729410):

  • Installed toolchain: black-25.11.0, ruff-0.16.1, mypy-2.3.0.
  • Run ruff check backend/Found 754 errors.
  • The reported codes are I001, UP006, UP007, UP035, RUF012, BLE001, B008, EM101 … none of which are in ruff's historical default selection.
  • The repo tree contains no ruff configuration at all — no pyproject.toml, ruff.toml, .ruff.toml, setup.cfg, or tox.ini anywhere (checked against git/trees/main?recursive=1).

Root cause

ruff check backend/ was running with no declared rule set, so it inherited whatever ruff's built-in defaults happened to be on the day CI ran. ruff 0.16 broadened those defaults well past the historical E4/E7/E9/F. The result, with zero source changes:

ruff ruff check backend/
0.15.4 All checks passed!
0.16.1 Found 754 errors.

The lint step's install line was pip install black==25.11.0 ruff mypy — ruff floated, so the 0.16.1 release reached CI the day it shipped and turned main and every open PR red.

#70 (merged 2026-08-07 06:09 UTC) stopped the bleeding by pinning ruff==0.15.4, and explicitly named this as the follow-up: "worth doing deliberately, with a committed ruff.toml so the rule set is explicit and can not drift again silently." That pin also conflicts with the fleet ALWAYS-LATEST dependency policy (docs/DEPENDENCIES.md, adopted in bamr87/bamr87@6ea7be9: no exact pins, no version ceilings, no committed lockfiles), and it leaves the underlying defect in place — the rule set is still undeclared, so the next unpin re-breaks the job.

Fix

Pin the behaviour, not the version:

  1. New ruff.toml at the repo root with [lint] select = ["E4", "E7", "E9", "F"] — ruff's pre-0.16 default, i.e. exactly the rule set this tree is already known to be clean against. A root config is an ancestor of backend/, so it applies to the paths ruff check backend/ lints.
  2. .github/workflows/ci.yml: drop the ruff==0.15.4 pin so ruff floats again per policy. black stays pinned — see below.

Now a future ruff release cannot change which rules run — only a reviewed edit to ruff.toml can. Widening the rule set becomes a deliberate cleanup rather than an upgrade side effect.

No application code is touched, and nothing is suppressed: the 754 findings are still real, they are just no longer silently conscripted into the gate. They remain available as an opt-in cleanup (565 are auto-fixable per #70) by extending select.

Expected impact

  • Removes the standing lint failure from main and from all four open Dependabot PRs, so those runs stop burning minutes on a red gate: ~25 of the 28.2 minutes/14d currently wasted, and CI stops re-failing on every future ruff release.
  • Restores ALWAYS-LATEST for ruff in this repo (_data/fleet.yml dependencies:).

Verified by this PR's own CI, which exercises latest ruff against the new config.

Not in this PR

black is still pinned, deliberately

The first push of this branch unpinned black too. CI rejected it: latest black wants to reformat 11 files (app/api/v1/{audit,citations,optimize,workspace,content}.py, app/services/{prompt_loader,workspace_service}.py, app/analyzers/{readability_scorer,text_utils}.py, app/services/site_snapshot/exporters.py, alembic/versions/002_workflow_metadata.py), so the lint job stayed red — on formatting, not on the regression this PR is about. The pin is restored.

That is a real remaining policy gap, but it is a different kind of problem: black is a formatter with no rule set to declare, so the ruff.toml trick has no equivalent. Bringing it under ALWAYS-LATEST means absorbing one formatting-only commit, which deserves its own PR and its own .git-blame-ignore-revs entry rather than riding along here. Note that black's stable style only changes in its January release, so the pin is low-risk in the meantime — unlike ruff's defaults, which moved without warning.

Dependabot

.github/dependabot.yml still enrols pip, npm, and docker with open-pull-requests-limit: 10. Under ALWAYS-LATEST there is nothing for those ecosystems to bump, and each PR costs a 3-job CI run — the hub reduced its own config to the Actions-majors exception. Worth a separate change; it is a different file with different blast radius.

Links

claude added 2 commits August 7, 2026 06:58
`ruff check backend/` ran with no ruff configuration anywhere in the repo,
so its rule set was whatever ruff's built-in defaults happened to be on the
day CI ran. ruff 0.16 broadened those defaults past the historical
E4/E7/E9/F, and the lint job went from clean to "Found 754 errors." with no
source change, turning `main` and every open PR red.

#70 stopped the bleeding by pinning `ruff==0.15.4`, and named this as the
follow-up. Pinning the tool version also conflicts with the fleet
ALWAYS-LATEST dependency policy (no exact pins, no lockfiles), and leaves
the rule set undeclared, so the next unpin re-breaks the job.

Pin the behaviour instead of the version: commit a `ruff.toml` whose
`select` reproduces ruff's pre-0.16 default (the rule set this tree is
known to be clean against), and drop the `ruff==` and `black==` pins so
both tools float per policy. Widening the rule set is now a reviewable
change to one file rather than an upgrade side effect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Unpinning black alongside ruff widened the change past the failure being
fixed: latest black reformats 11 backend files, so the lint job stayed red
on formatting rather than on the ruff regression this PR is about.

black is a formatter with no rule set to declare, so bringing it under
ALWAYS-LATEST means absorbing one formatting-only commit — a deliberate
change that deserves its own PR and its own .git-blame-ignore-revs entry.

Co-Authored-By: Claude Opus 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.

2 participants