with one click
lint-battalion
// Mass linter error remediation via auto-fix sprint + parallel subagent battalions. Handles 500+ trivial errors mechanically, escalates semantic errors to specialists, and enforces contamination checks.
// Mass linter error remediation via auto-fix sprint + parallel subagent battalions. Handles 500+ trivial errors mechanically, escalates semantic errors to specialists, and enforces contamination checks.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | lint-battalion |
| category | software-development |
| description | Mass linter error remediation via auto-fix sprint + parallel subagent battalions. Handles 500+ trivial errors mechanically, escalates semantic errors to specialists, and enforces contamination checks. |
| version | 1 |
| priority | high |
| tags | ["linting","bulk-fix","parallel-agents","code-quality","mass-remediation"] |
500+ linter errors is not 500 separate decisions. It is a batch processing problem.
This skill turns mass lint remediation into a pipeline:
Research on multi-agent code search (AgentGroupChat-V2, RepoAudit) shows parallel agents on partitioned tasks scale sub-linearly. Linting is ideal for this: errors are independent, fixes are local, and verification is objective.
debug-subagent)This skill requires a companion Python script that is bundled with the skill.
When installing with --with-scripts, the script is copied alongside SKILL.md automatically.
npx jerry-skills install --agent pi --skill lint-battalion --with-scripts
Pi Agent (flat layout):
python ~/.pi/agent/skills/lint-battalion/lint_battalion.py --help
Hermes (grouped layout):
python ~/.hermes/skills/software-development/lint-battalion/lint_battalion.py --help
For manual copy or development symlinks, see the skill-development-with-supporting-files skill.
Run the linter's built-in auto-fix first. Goal: reduce error count with zero token spend.
# ESLint
npx eslint . --fix
# Biome
npx biome check --write
# Prettier (formatting only)
npx prettier --write .
# TypeScript (type-only, but often reveals lint-adjacent issues)
npx tsc --noEmit
Gate: If errors drop below 50, switch to single-agent mode. No battalion needed.
Log: Record how many errors auto-fix eliminated and how many remain.
Run the linter again and capture structured output.
Recommended (zero agent tokens):
# ESLint JSON output -> auto-categorized batches
npx eslint . --format json | python ~/.pi/agent/skills/lint-battalion/lint_battalion.py --markdown --json -o batches.json
# Biome
npx biome check --json | python ~/.pi/agent/skills/lint-battalion/lint_battalion.py --markdown --json -o batches.json
# Ruff
ruff check --output-format json | python ~/.pi/agent/skills/lint-battalion/lint_battalion.py --markdown --json -o batches.json
Alternative (agent tools):
# Summarize by rule with jq
npx eslint . --format json | jq -r '.[] | .ruleId' | sort | uniq -c | sort -rn
Categorize each remaining error:
| Category | Description | Example | Fix Strategy |
|---|---|---|---|
auto | Should have been caught by --fix | N/A | Run --fix again, check config |
mechanical | Purely syntactic, no logic change | Missing import, unused var, wrong quote style | Subagent batch |
semantic | Requires understanding code intent | Type mismatch, unreachable code, async/sync conflict | Specialist subagent |
architectural | Violates pattern, needs refactor | Cyclic dependency, God class, wrong layer | Escalate to human |
Tooling: If the linter does not support JSON output, grep/sed the text output into a structured list per file and rule.
Group errors into battalion-sized batches.
Batching rules:
Batch types:
| Type | Assignment | Max Parallel |
|---|---|---|
| Mechanical | General lint fix subagent | 5 |
| Semantic | Specialist subagent (type-aware) | 2 |
| Architectural | Human review or refactor-safely | 1 |
Pre-flight: Before spawning subagents, run a quick scan for:
Spawn subagents with scoped, identical prompts.
Subagent prompt template:
You are a Lint Fix Subagent. Your ONLY job is fix the specific linter errors in your assigned files.
## Your Batch
Files: [file1.ts, file2.ts]
Errors:
- [rule-id] [message] @ [file]:[line]:[col]
## Rules
- Fix ONLY the listed errors. Do not "improve" adjacent code.
- Prefer the smallest possible change (one line > five lines).
- If a fix requires >3 lines or touches >2 files, STOP and report "NEEDS_REFACTOR".
- After fixing, run the linter on your files and report: PASS / FAIL.
- Do not add new dependencies.
- Do not change logic unless the lint rule explicitly requires it.
- Do not suppress rules with eslint-disable without justification.
## Output Format
1. Changes made (file + line + before -> after)
2. Linter result (PASS / FAIL)
3. Any errors you could not fix and why
Execution:
delegate_task with tasks array)After all subagents report:
npx eslint .Contamination causes:
Prevention:
Errors surviving 3 cycles fall into these buckets:
| Bucket | Action | Skill |
|---|---|---|
| False positive | Suppress with inline disable + justification | None |
| Type mismatch requiring logic change | Route to debug-subagent | debug-subagent |
| Missing types spanning many files | Batch as architectural, fix in dedicated refactor | refactor-safely |
| Linter config issue | Update .eslintrc / biome.json / tsconfig.json | None |
Escalation rule: If >10% of original errors are survivors, re-examine categorization. You likely misclassified architectural errors as semantic or mechanical.
Maintain a running log:
## Lint Battalion Log
### Phase 0 — Auto-Fix
- Initial errors: 547
- Auto-fix resolved: 423
- Remaining: 124
### Phase 1 — Categorize
- Mechanical: 98
- Semantic: 21
- Architectural: 5
### Phase 2 — Batches
- Mechanical: 5 batches of ~20 errors each
- Semantic: 2 batches of ~10 errors each
- Architectural: 1 batch (deferred)
### Phase 3 — Execution
- Batch M1-M5: PASS (all 5)
- Batch S1: PASS
- Batch S2: FAIL (2 errors remain, retry cycle 1)
### Phase 4 — Verification
- Total errors after battalion: 7
- New errors introduced: 0 (clean)
### Phase 5 — Triage
- 3 false positives → inline disable
- 4 semantic → `debug-subagent`
| Error Count | Max Subagents | Max Cycles | Typical Time |
|---|---|---|---|
| 50-100 | 3 | 2 | 3-5 min |
| 100-300 | 5 | 2 | 5-10 min |
| 300-500 | 5 | 3 | 8-15 min |
| 500+ | 5 | 3 | 10-20 min |
Token budget heuristic: Mechanical fixes cost ~100 tokens/error. Semantic fixes cost ~500 tokens/error. Plan accordingly.
--fix could handle. Token waste.| Skill | Integration Point |
|---|---|
checklist-manifesto | Phase gates and contamination checks |
debug-subagent | Semantic errors requiring logic understanding |
refactor-safely | Architectural errors needing structural change |
codebase-divide-conquer-search | Finding related files when errors span unknown modules |
iterative-patch-repair | If a subagent's first fix is close but wrong |
pre-deployment-gate | Final lint check before commit |
Situation: 612 ESLint errors after migrating a project to stricter TypeScript rules.
Phase 0: eslint --fix resolves 498 errors. 114 remain.
Phase 1: Categorize:
mechanical: missing return types, unused importssemantic: any types that need real typesarchitectural: cyclic imports between services/ and models/Phase 2: Batches:
components/, hooks/, utils/services/ and api/Phase 3: Spawn 5 mechanical + 2 semantic subagents.
any types in auth.ts require understanding external API shape.Phase 4: Re-run linter. 102 errors remain → 12 new errors? No. Clean. 2 errors from S2 batch.
Phase 5:
types/ to break cycles"Result: 612 → 0 in 12 minutes. 1 structural decision deferred to human.