| name | flint-plan |
| description | Plan fixes for confirmed violations. Use after flint-review to create independent fix tasks for parallel execution. |
| allowed-tools | Read, Glob, Grep |
| context | fork |
| agent | Plan |
| model | sonnet |
Flint Plan - Strategic Fix Planning
Plan how to fix confirmed violations from flint-review. Output independent fix tasks that can be executed in parallel by lightweight workers.
When to Use
- After
flint-review has triaged the checklist
- Before spawning parallel
flint-fix workers
- When you need strategic planning for complex fixes
Input: Reviewed Checklist
# Flint Review: src/
- [x] Use 'is None' not '== None'
- [x] utils.py:33 `if x == None:` [!]
- [x] utils.py:35 `if x != None:` [!]
- [x] api.py:72 `while result == None:` [!] — found by review
- [x] Don't use mutable default arguments
- [x] config.py:23 `def load(opts={})` [!]
- [ ] ~~Avoid bare except~~ — false positive, intentional error boundary
Output: Fix Tasks
Output a list of independent fix tasks, one per file, that Haiku workers can execute in parallel.
# Flint Fix Tasks
## Task 1: utils.py
**Violations:**
- Line 33: `if x == None:` → `if x is None:`
- Line 35: `if x != None:` → `if x is not None:`
**Instructions:**
Replace `== None` with `is None` and `!= None` with `is not None`. Simple find-replace, no semantic changes.
---
## Task 2: api.py
**Violations:**
- Line 72: `while result == None:` → `while result is None:`
**Instructions:**
Same pattern as Task 1. Single line change.
---
## Task 3: config.py
**Violations:**
- Line 23: `def load(opts={})` → mutable default argument
**Instructions:**
1. Change signature to `def load(opts=None):`
2. Add at function start: `if opts is None: opts = {}`
This is a multi-line fix that changes the function body.
---
Total: 3 tasks across 3 files (can run in parallel)
Planning Strategy
1. Group by File
Group all violations for the same file into one task. This:
- Minimizes file I/O
- Avoids merge conflicts
- Allows atomic fixes per file
2. Order Within File
List violations in reverse line order so fixes don't shift line numbers:
Line 100 first → Line 50 → Line 10 last
3. Classify Fix Complexity
Simple (single-line):
- Pattern replacement:
== None → is None
- Import changes:
import os.path → from pathlib import Path
Medium (multi-line):
- Mutable defaults: signature + body change
- Adding error handling: wrap in try/except
Complex (requires context):
- Refactoring patterns
- Changing function signatures with callers
- Security fixes that need careful review
4. Include Context
For each task, include:
- Exact line numbers and current code
- The specific fix to apply
- Any caveats or edge cases
- Whether it's safe for auto-fix
5. Flag Risky Fixes
Mark tasks that need human review:
## Task 4: auth.py [NEEDS REVIEW]
**Violations:**
- Line 42: `eval(user_input)` — security vulnerability
**Instructions:**
This requires security review. Suggested fix depends on use case:
- If parsing JSON: use `json.loads()`
- If parsing Python literals: use `ast.literal_eval()`
- If executing code: remove or sandbox
Task Format
Each task should be self-contained with:
## Task N: filename.py [optional flags]
**Violations:**
- Line X: `current code` → `fixed code` (if simple)
- Line Y: `current code` — description of issue
**Instructions:**
Clear, actionable instructions a Haiku worker can follow.
Include the fix approach, not just "fix this".
**Fix Hint:** (from rule, if available)
The hint from the rule definition to guide the fix.
What NOT to Plan
- False positives (already filtered by review)
- Items marked for manual review
- Violations in generated/vendored code
- Fixes that would break tests (flag for human review)
Next Steps
After planning, the orchestrator spawns parallel flint-fix workers:
Task: flint-fix on utils.py (Task 1 instructions)
Task: flint-fix on api.py (Task 2 instructions)
Task: flint-fix on config.py (Task 3 instructions)
All run concurrently since they operate on different files.