| name | cleanup-slop |
| description | Strip AI slop, narration comments, restated-code comments, in-motion notes, and stub markers. Preserves comments that explain WHY (workarounds, invariants, surprising behavior). Comment-only changes — never touches code logic. Use when the user asks to remove AI slop, clean up comments, strip narration, or remove unhelpful comments. Example queries — "remove the AI slop", "strip the narration comments", "clean up unhelpful comments", "delete the comments that just restate the code". |
| argument-hint | [scope (optional path or glob)] |
| user-invocable | true |
Surgically remove unhelpful comments without touching code. The good comments — workarounds, invariants, citations, non-obvious WHYs — stay. The bad ones — restating code, narrating in-motion edits, AI-generated platitudes — go.
Core rule: a useful comment tells a future reader something they couldn't get by reading the code itself. Everything else is noise.
Preflight
- Language detect — comment syntax differs but the patterns are universal.
- Git state: refuse on dirty tree.
- Report dir: ensure exists.
- No code changes: this skill ONLY edits comments. If a "comment fix" requires changing code, surface to user instead.
Detect
Use grep + heuristics. There's no perfect tool — this is mostly pattern matching.
Patterns to find (HIGH-confidence slop)
A. Restated-code comments — comment says what the code already says.
grep -rn --include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" \
-B0 -A1 -E "^\s*(//|#) (Returns|Sets|Gets|Creates|Updates|Deletes|Removes|Adds|Imports|Exports|Initializes|Initialize|Render|Renders) " . > /tmp/restated.txt
B. In-motion narration — comments describing the edit, not the code.
grep -rn --include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" --include="*.go" --include="*.rs" \
-E "(// |# )(removed|replaced|new approach|updated to|previously|was using|no longer|TODO\(?from claude|TODO\(?ai\)|generated by claude)" \
--exclude-dir=node_modules . > /tmp/narration.txt
C. Stub markers without TODO
grep -rn --include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" \
-E "^\s*(//|#) (implementation here|your code here|fill in|replace this|placeholder)" . > /tmp/stubs.txt
D. AI platitudes — generic preamble that adds nothing.
grep -rn -E "(// |# )(This (function|class|method) (is|will|does|provides|handles|manages|allows))" \
--include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" \
--exclude-dir=node_modules . > /tmp/platitudes.txt
E. Empty docstrings / pass with no real TODO
grep -rn --include="*.py" -B1 -A2 'pass\s*#\s*TODO\s*$' . > /tmp/empty-todo.txt
grep -rn --include="*.py" '"""\s*"""' . > /tmp/empty-docstring.txt
Patterns to PRESERVE
Even if they look formulaic, keep:
- Comments referencing issue/PR/ticket numbers (
// see #1234, // fixes JIRA-456)
- Comments documenting workarounds with reason (
// workaround for Safari bug, see ...)
- Comments stating invariants (
// caller must hold lock, // must run after middleware X)
- Comments warning about non-obvious behavior (
// this MUST stay sync — async breaks ordering)
- Comments citing specs/RFCs/external docs
- License headers, copyright notices
- Type-system pragmas (
// @ts-expect-error, # type: ignore, // eslint-disable-next-line)
- JSDoc/TSDoc on public APIs (even if formulaic — it generates docs)
Assess
Write .claude/cleanup-reports/cleanup-slop-{YYYY-MM-DD}.md:
# Comment Slop Assessment — YYYY-MM-DD
## Summary
- Comments scanned: N
- HIGH (delete): X
- Restated code: x1
- In-motion narration: x2
- Stub markers: x3
- AI platitudes: x4
- Empty docstrings: x5
- MEDIUM (review): Y — stale TODOs >6mo, generic JSDoc on internal funcs
- PRESERVED: Z — comments with citations, invariants, warnings
## Findings
### HIGH — `lib/format.ts:12`
```ts
// Returns the formatted string
function format(s: string): string { ... }
Action: delete the comment line.
HIGH — services/user.ts:88
async function getUser(id: string) { ... }
Action: delete (in-motion narration; the diff/git log records this).
HIGH — apps/api/middleware/auth.ts:5
Action: delete (AI platitude; the function name auth.ts and signature say it).
MEDIUM — lib/parse.ts:34
Stale 8 months. Either resolve or add detail. Flag for human triage.
PRESERVED — apps/api/middleware/auth.ts:42
Citation + invariant + war story. Exemplary comment, keep.
Critical Assessment
[2-3 paragraphs on the comment culture: heavy AI slop suggests recent AI-assisted code generation that wasn't reviewed. Lots of "removed X" suggests insufficient git-log discipline. Few useful WHY comments suggests engineers aren't capturing tribal knowledge.]
## Apply
**Auto-delete HIGH only. NEVER touch code logic.**
### Confidence rubric
**HIGH (delete the comment line):**
- Pattern A-E above, AND
- The comment is immediately above or beside code (not a section header)
- Removing it doesn't leave a dangling reference (no other comment refers to it)
**MEDIUM (report only):**
- Stale TODO/FIXME with no detail (>6 months by git blame)
- Generic JSDoc/docstring on internal functions (could be deleted but might satisfy a lint rule — let human decide)
- Comments that summarize a complex algorithm — usually useful, but if the algorithm is named (e.g., `quickselect`), summary may be redundant
**PRESERVE always:**
- Citations (issues, PRs, RFCs, specs)
- Invariants and load-bearing constraints
- Workaround explanations with reason
- License/copyright
- Type pragmas / lint disables
- JSDoc on public exports
### Execution
1. Use Edit to delete each HIGH comment line. Preserve indentation of surrounding code.
2. If a comment block is multi-line and ALL lines are slop, delete the whole block.
3. If a comment block has a slop preamble + a useful warning, delete only the slop preamble.
4. Single commit: `chore(cleanup): cleanup-slop — removed N unhelpful comments`.
## Verify
Comment changes can't break logic, but they can break:
- Doc generators (TypeDoc, Sphinx) if a JSDoc/docstring on a public API was removed
- Markdown extraction tools
```bash
# Lint catches some malformed-comment issues
bunx biome check . 2>&1 || npx eslint . 2>&1
ruff check . 2>&1
# If docs build script exists, run it
bun run docs 2>/dev/null || npm run docs 2>/dev/null || true
If anything fails: revert that specific file and downgrade.
Output
- "Removed N unhelpful comments. M flagged for human review (stale TODOs, generic JSDoc)."
- Report path.
- Verify status.
NEVER
- Touch any code logic — comments only. If a "fix" needs code changes, escalate.
- Delete comments referencing issue/PR/ticket numbers, RFCs, or specs.
- Delete invariant warnings ("must run before X", "caller holds lock").
- Delete
// @ts-..., // eslint-..., # type: ignore, # noqa pragmas.
- Delete JSDoc/TSDoc on exported public APIs (they feed doc generation).
- Delete license headers or copyright notices.
- Delete comments inside strings or templates that look like comments but aren't.
- "Improve" comments by rewriting them — this skill removes, doesn't author.
- Delete comments in test files that explain test intent (those are often the only documentation of edge-case behavior).