|
| 1 | +--- |
| 2 | +name: ruff-recursive-fix |
| 3 | +description: Run Ruff checks with optional scope and rule overrides, apply safe and unsafe autofixes iteratively, review each change, and resolve remaining findings with targeted edits or user decisions. |
| 4 | +--- |
| 5 | + |
| 6 | +# Ruff Recursive Fix |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +Use this skill to enforce code quality with Ruff in a controlled, iterative workflow. |
| 11 | +It supports: |
| 12 | + |
| 13 | +- Optional scope limitation to a specific folder. |
| 14 | +- Default project settings from `pyproject.toml`. |
| 15 | +- Flexible Ruff invocation (`uv`, direct `ruff`, `python -m ruff`, or equivalent). |
| 16 | +- Optional per-run rule overrides (`--select`, `--ignore`, `--extend-select`, `--extend-ignore`). |
| 17 | +- Automatic safe then unsafe autofixes. |
| 18 | +- Diff review after each fix pass. |
| 19 | +- Recursive repetition until findings are resolved or require a decision. |
| 20 | +- Judicious use of inline `# noqa` only when suppression is justified. |
| 21 | + |
| 22 | +## Inputs |
| 23 | + |
| 24 | +Collect these inputs before running: |
| 25 | + |
| 26 | +- `target_path` (optional): folder or file to check. Empty means whole repository. |
| 27 | +- `ruff_runner` (optional): explicit Ruff command prefix (for example `uv run`, `ruff`, `python -m ruff`, `pipx run ruff`). |
| 28 | +- `rules_select` (optional): comma-separated rule codes to enforce. |
| 29 | +- `rules_ignore` (optional): comma-separated rule codes to ignore. |
| 30 | +- `extend_select` (optional): extra rules to add without replacing configured defaults. |
| 31 | +- `extend_ignore` (optional): extra ignored rules without replacing configured defaults. |
| 32 | +- `allow_unsafe_fixes` (default: true): whether to run Ruff unsafe fixes. |
| 33 | +- `ask_on_ambiguity` (default: true): always ask the user when multiple valid choices exist. |
| 34 | + |
| 35 | +## Command Construction |
| 36 | + |
| 37 | +Build Ruff commands from inputs. |
| 38 | + |
| 39 | +### 0. Resolve Ruff Runner |
| 40 | + |
| 41 | +Determine a reusable `ruff_cmd` prefix before building commands. |
| 42 | + |
| 43 | +Resolution order: |
| 44 | + |
| 45 | +1. If `ruff_runner` is provided, use it as-is. |
| 46 | +2. Else if `uv` is available and Ruff is managed through `uv`, use `uv run ruff`. |
| 47 | +3. Else if `ruff` is available on `PATH`, use `ruff`. |
| 48 | +4. Else if Python is available and Ruff is installed in that environment, use `python -m ruff`. |
| 49 | +5. Else use any project-specific equivalent that invokes installed Ruff (for example `pipx run ruff`), or stop and ask the user. |
| 50 | + |
| 51 | +Use the same resolved `ruff_cmd` for all `check` and `format` commands in the workflow. |
| 52 | + |
| 53 | +Base command: |
| 54 | + |
| 55 | +```bash |
| 56 | +<ruff_cmd> check |
| 57 | +``` |
| 58 | + |
| 59 | +Formatter command: |
| 60 | + |
| 61 | +```bash |
| 62 | +<ruff_cmd> format |
| 63 | +``` |
| 64 | + |
| 65 | +With optional target: |
| 66 | + |
| 67 | +```bash |
| 68 | +<ruff_cmd> format <target_path> |
| 69 | +``` |
| 70 | + |
| 71 | +Add optional target: |
| 72 | + |
| 73 | +```bash |
| 74 | +<ruff_cmd> check <target_path> |
| 75 | +``` |
| 76 | + |
| 77 | +Add optional overrides as needed: |
| 78 | + |
| 79 | +```bash |
| 80 | +--select <codes> |
| 81 | +--ignore <codes> |
| 82 | +--extend-select <codes> |
| 83 | +--extend-ignore <codes> |
| 84 | +``` |
| 85 | + |
| 86 | +Examples: |
| 87 | + |
| 88 | +```bash |
| 89 | +# Full project with defaults from pyproject.toml |
| 90 | +ruff check |
| 91 | + |
| 92 | +# One folder with defaults |
| 93 | +python -m ruff check src/models |
| 94 | + |
| 95 | +# Override to skip docs and TODO-like rules for this run |
| 96 | +uv run ruff check src --extend-ignore D,TD |
| 97 | + |
| 98 | +# Check only selected rules in a folder |
| 99 | +ruff check src/data --select F,E9,I |
| 100 | +``` |
| 101 | + |
| 102 | +## Workflow |
| 103 | + |
| 104 | +### 1. Baseline Analysis |
| 105 | + |
| 106 | +1. Run `<ruff_cmd> check` with the selected scope and options. |
| 107 | +2. Classify findings by type: |
| 108 | + - Autofixable safe. |
| 109 | + - Autofixable unsafe. |
| 110 | + - Not autofixable. |
| 111 | +3. If no findings remain, stop. |
| 112 | + |
| 113 | +### 2. Safe Autofix Pass |
| 114 | + |
| 115 | +1. Run Ruff with `--fix` using the same scope/options. |
| 116 | +2. Review resulting diff carefully for semantic correctness and style consistency. |
| 117 | +3. Run `<ruff_cmd> format` on the same scope. |
| 118 | +4. Re-run `<ruff_cmd> check` to refresh remaining findings. |
| 119 | + |
| 120 | +### 3. Unsafe Autofix Pass |
| 121 | + |
| 122 | +Run only if findings remain and `allow_unsafe_fixes=true`. |
| 123 | + |
| 124 | +1. Run Ruff with `--fix --unsafe-fixes` using the same scope/options. |
| 125 | +2. Review resulting diff carefully, prioritizing behavior-sensitive edits. |
| 126 | +3. Run `<ruff_cmd> format` on the same scope. |
| 127 | +4. Re-run `<ruff_cmd> check`. |
| 128 | + |
| 129 | +### 4. Manual Remediation Pass |
| 130 | + |
| 131 | +For remaining findings: |
| 132 | + |
| 133 | +1. Fix directly in code when there is a clear, safe correction. |
| 134 | +2. Keep edits minimal and local. |
| 135 | +3. Run `<ruff_cmd> format` on the same scope. |
| 136 | +4. Re-run `<ruff_cmd> check`. |
| 137 | + |
| 138 | +### 5. Ambiguity Policy |
| 139 | + |
| 140 | +If there are multiple valid solutions at any step, always ask the user before proceeding. |
| 141 | +Do not choose silently between equivalent options. |
| 142 | + |
| 143 | +### 6. Suppression Decision (`# noqa`) |
| 144 | + |
| 145 | +Use suppression only when all conditions are true: |
| 146 | + |
| 147 | +- The rule conflicts with required behavior, public API, framework conventions, or readability goals. |
| 148 | +- Refactoring would be disproportionate to the value of the rule. |
| 149 | +- The suppression is narrow and specific (single line, explicit code when possible). |
| 150 | + |
| 151 | +Guidelines: |
| 152 | + |
| 153 | +- Prefer `# noqa: <RULE>` over broad `# noqa`. |
| 154 | +- Add a brief reason comment for non-obvious suppressions. |
| 155 | +- If two or more valid outcomes exist, always ask the user which option to prefer. |
| 156 | + |
| 157 | +### 7. Recursive Loop and Stop Criteria |
| 158 | + |
| 159 | +Repeat steps 2 to 6 until one of these outcomes: |
| 160 | + |
| 161 | +- `<ruff_cmd> check` returns clean. |
| 162 | +- Remaining findings require architectural/product decisions. |
| 163 | +- Remaining findings are intentionally suppressed with documented rationale. |
| 164 | +- Repeated loop makes no progress. |
| 165 | + |
| 166 | +Each loop iteration must include `<ruff_cmd> format` before the next `<ruff_cmd> check`. |
| 167 | + |
| 168 | +When no progress is detected: |
| 169 | + |
| 170 | +1. Summarize blocked rules and affected files. |
| 171 | +2. Present valid options and trade-offs. |
| 172 | +3. Ask the user to choose. |
| 173 | + |
| 174 | +## Quality Gates |
| 175 | + |
| 176 | +Before declaring completion: |
| 177 | + |
| 178 | +- Ruff returns no unexpected findings for the chosen scope/options. |
| 179 | +- All autofix diffs are reviewed for correctness. |
| 180 | +- No suppression is added without explicit justification. |
| 181 | +- Any unsafe fix with possible behavioral impact is highlighted to the user. |
| 182 | +- Ruff formatting is executed in every iteration. |
| 183 | + |
| 184 | +## Output Contract |
| 185 | + |
| 186 | +At the end of execution, report: |
| 187 | + |
| 188 | +- Scope and Ruff options used. |
| 189 | +- Number of iterations performed. |
| 190 | +- Summary of fixed findings. |
| 191 | +- List of manual fixes. |
| 192 | +- List of suppressions with rationale. |
| 193 | +- Remaining findings, if any, and required user decisions. |
| 194 | + |
| 195 | +## Suggested Prompt Starters |
| 196 | + |
| 197 | +- "Run ruff-recursive-fix on the whole repo with default config." |
| 198 | +- "Run ruff-recursive-fix only on src/models, ignore DOC rules." |
| 199 | +- "Run ruff-recursive-fix on tests with select F,E9,I and no unsafe fixes." |
| 200 | +- "Run ruff-recursive-fix on src/data and ask me before adding any noqa." |
0 commit comments