build(ruff): pin lint.select to CI's rule set + stale-noqa audit (#246)#267
Conversation
CI lints with trunk's ruff (pinned 0.15.17), whose plugin injects no `--select`, so it runs ruff's own default rule set resolved from our config. With no [tool.ruff.lint] table, a local `ruff` of a different version could enforce a different default — local green != CI green. Pin `select = ["E4", "E7", "E9", "F"]`, which reproduces that default byte-for-byte (verified via `ruff check --show-settings`: identical enabled-rule set), so local == CI regardless of ruff version. No ratcheting beyond what CI already enforces. Stale-noqa audit: using RUF100 (unused-noqa) as an oracle over the pinned set, 59 directives in src/ plus the ANN001/E301 directives in tests/ referenced non-enabled codes (BLE001, S603/S607, PLC0415, ANN001, B027, E301) — inert suppressions from past reviews. Removed the stale ruff codes while preserving every `# nosec` bandit suppression and the design rationale on each seam-translation site. Kept the F401 re-exports and E402/F811 directives (enabled codes), all verified load-bearing (RUF100 flagged none). RUF100 now clean across src/ + tests/. Refs #246
|
Warning Review limit reached
Next review available in: 14 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
WalkthroughRuff lint selection is now explicit and aligned with CI. Inline lint suppressions were removed or clarified across runtime modules and tests, while exception handling, subprocess calls, lazy imports, and test behavior remain unchanged. ChangesLint configuration and adapter cleanup
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@CodeRabbit review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pyproject.toml`:
- Around line 64-69: Update the Ruff configuration comment near select to avoid
claiming exact CI parity across arbitrary Ruff versions. Either pin the Ruff
executable through the repository’s existing tooling, or revise the comment to
state only that the selected rule families match CI; preserve select = ["E4",
"E7", "E9", "F"] unless the executable pin requires a related configuration
change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fe832653-da08-4b5b-8c92-05578e15f57b
📒 Files selected for processing (27)
pyproject.tomlsrc/bmad_loop/adapters/base.pysrc/bmad_loop/adapters/generic.pysrc/bmad_loop/adapters/multiplexer.pysrc/bmad_loop/adapters/opencode_http.pysrc/bmad_loop/data/plugins/tea/tea_plugin.pysrc/bmad_loop/data/plugins/unity/unity_plugin.pysrc/bmad_loop/data/plugins/unity/unity_teardown.pysrc/bmad_loop/diagnostics.pysrc/bmad_loop/engine.pysrc/bmad_loop/install.pysrc/bmad_loop/plugins/bus.pysrc/bmad_loop/plugins/registry.pysrc/bmad_loop/probe.pysrc/bmad_loop/process_host.pysrc/bmad_loop/recovery_flow.pysrc/bmad_loop/resolve.pysrc/bmad_loop/runs.pysrc/bmad_loop/runsetup.pysrc/bmad_loop/stories_engine.pysrc/bmad_loop/sweep.pysrc/bmad_loop/tui/app.pysrc/bmad_loop/tui/widgets.pysrc/bmad_loop/verify.pytests/test_hook_bus.pytests/test_plugin_tea.pytests/test_plugin_workflows.py
Address CodeRabbit review on #267: `select` pins rule families, not ruff's implementation version, so the old comment's "any version enforces exactly what CI enforces" overclaimed. Reword to scope exact parity to the repo's pinned ruff — `trunk check` (trunk 0.15.17, what CI runs and the documented local lint) and the uv.lock-resolved 0.15.17 — and note a bare newer ruff gets rule-family parity only (new rules can land under these prefixes). Also raise the dev-dependency floor `ruff>=0.4` -> `ruff>=0.15.17` so the uv-path pin is explicit rather than relying on lock resolution; the resolved version is unchanged (uv.lock stays 0.15.17, specifier-only diff). Selected rule set is unchanged (verified via `ruff check --show-settings`). Refs #246
Part of #246 (lint-alignment half; the env-var registry PR — F-9b — remains a separate follow-up, so this intentionally does NOT auto-close the issue).
What & why
pyproject.tomlhad no[tool.ruff.lint]table, so localruffran whatever default its version ships while CI's trunk runs a pinnedruff@0.15.17. Trunk's ruff plugin (v1.10.2) injects no--select— it runsruff checkand lets ruff resolve config from ourpyproject.toml. With no lint table that resolves to ruff's default set, so a local ruff of a different version can diverge: local green ≠ CI green.Changes
1. Pin the rule set (mirror CI, no ratcheting)
This reproduces ruff's default byte-for-byte — verified with
ruff check --show-settings(0.15.17): the enabled-rule set is identical (59 rules) with and without the explicitselect. Nothing stricter than what CI already enforces.2. Stale-noqa audit (issue title)
Used ruff's own
RUF100(unused-noqa) as an oracle over the pinned set. It flagged 59 directives insrc/plus theANN001/E301directives intests/as referencing non-enabled codes (BLE001,S603/S607,PLC0415,ANN001,B027,E301) — inert suppressions accreted from past reviews.# nosecbandit suppression (bandit is a separate, enabled trunk linter — count unchanged, 31 → 31) and the design rationale on eachexcept Exceptionseam-translation site.F401re-export pins and theE402/F811directives (all enabled codes) — RUF100 flagged none, confirming each is load-bearing. Theverify.py/install.py/runsetup.py/cli.py:40-54re-exports were not touched (the F401-autofix trap was avoided:--no-fixthroughout).RUF100is intentionally not added toselect(that would ratchet stricter than CI); it was used only as an audit oracle.Result:
ruff check --extend-select RUF100is clean acrosssrc/+tests/; every surviving# noqareferences an enabled code.Verification
trunk check --all— 238 files, no issues (ruff / black / isort / bandit all green).test_module_skills_syncfailures are pre-existing on cleanmain(.agents/.claudemodule.yamldrift), unrelated to this change.No CHANGELOG entry (internal tooling config).
Summary by CodeRabbit
Chores
Tests