code-slimming
Remove redundancy from freshly written code: dead code, one-call wrappers, single-implementation interfaces, over-defensive error handling, comments that restate the code, speculative config, and feat
SKILL.md.claude/skills/code-slimming/SKILL.md
GitHubCode Slimming
Subtraction only. Delete and inline in place. Never move code between files, never rename files, never restructure directories — a reviewable diff matters more than a tidy one.
Out of scope, by design: bug hunting, design-pattern advice, adding comments, cross-file refactoring, architectural "you should have fixed the root cause" judgments.
References (this skill's directory, read on demand):
references/redlines.md— what must never be deleted. Read before proposing any deletion.references/checks-mechanical.md— M-tier checks (决定可删无需理解业务).references/checks-judgment.md— J-tier checks, grouped by pass, with batching order.references/scope-creep.md— signals S1–S12 for "AI added what nobody asked for".references/audit-checks.md— the--auditchecklist. Only for--audit; never mix with the M/J checks.references/lang-java.md·lang-go.md·lang-typescript.md·lang-python.md— per-language checks and framework-boilerplate redlines. Read only the ones the diff touches.
All user-facing questions and reports are written in Chinese. Rules stay English.
Arguments
| Arg | Effect |
|---|---|
| (none) | List findings → user confirms → edit → verify → report |
--review |
List findings only. Touch nothing. |
--auto |
Apply M-tier without asking; still confirm J-tier and scope creep. |
--audit [<rev>] |
Review a cleanup that already happened. Skips Steps 2–7 entirely; runs references/audit-checks.md instead. |
| path(s) | Use these files instead of the git diff. |
--audit is not --review. --review dry-runs the M/J checks against code; --audit checks
a finished cleanup — what it deleted that it should not have, what it missed, whether it stayed
inside the subtraction-only contract. Re-running the M/J checks in audit mode produces the same
verdicts as the original pass and adds nothing; use the audit checklist and only that.
Step 1 — Gates
Run in order; stop at the first hard block.
- Rebase/merge in progress (
git statusshows conflicts) → refuse, say why. - Generated files — path or header matches
DO NOT EDIT,@generated,Code generated by,.pb.go,*_pb2.py,openapi/,**/generated/**→ drop them from scope, name them in the report. - Unrelated uncommitted work — the diff spans files with no plausible relation to one task (different modules, mixed intents). Report the split and ask 继续 / 只处理指定文件 / 先去 commit.
- Project CLAUDE.md — read it. Any check that contradicts a documented project rule is disabled, not overridden. State how many were disabled and which, at the top of the report.
Step 2 — Scope
Default: git status --porcelain + git diff HEAD → modified + untracked source files.
Not in a git repo → ask the user for paths. Explicit paths given → use those, skip the diff.
>20 files → stop, report the count, ask 继续 / 分批(10 个一批)/ 缩小范围.
Step 3 — Scan
Six passes, strictly in order. The order is causal: deleting dead code first makes its comments, abstractions, and tests vanish with it, so later passes shrink dramatically.
- Dead code → 2. Duplicate implementation (reuse) → 3. Redundant abstraction →
- Defensive paranoia → 5. Comments → 6. Naming / filler
Never mix categories inside one pass. Every candidate passes the redline filter before it reaches the list.
Reuse search radius (pass 2): the diff's own directories plus any utils / util / common /
shared / helper / lib module in the repo. Not the whole tree.
Reference counting (dead-code checks) is the exception: take the symbols from the diff and
grep the whole repo for them. Approximate counting here means deleting live code.
Step 4 — The list (always before editing)
Present four sections in Chinese. Under --auto, apply 将删 immediately and still present the rest.
- [将删] M-tier. Each:
file:line· what · one-line reason. - [待定] J-tier. Each:
file:line· what · the judgment call the user has to make. Collect answers with AskUserQuestion, recommended option first, in small batches. - [越界] Scope creep. List only. Never delete, not even with
--auto. Each entry cites its signal numbers (e.g.S1 + S4 + S7) so the user can re-check the reasoning. - [跳过] Everything skipped, fully expanded, one line each:
file:line· check · why (redline name, or "误报: …"). This is the user's only feedback channel for calibrating the redlines — never collapse or summarize it.
Then a final section [附注] 非冗余问题(超出本 skill 职责): swallowed exceptions, catch that
only logs and returns success, as any / force-unwrap, rules asserted by a comment the code
doesn't implement. Type, location, count, and one line: 建议跑 code-review-deep. Those code
blocks are excluded from simplification — editing them would mask the problem.
Step 5 — Edit
Delete and inline in place. One pass at a time; verify between passes (Step 6). If a pass breaks verification, revert that whole pass and move on — do not bisect inside it.
Never: move code across files, rename files, restructure directories, rename symbols with callers outside the current file, rewrite for style, or "fix the behavior while you're in there". A change that alters observable behavior gets reverted even if the new behavior looks better.
Step 6 — Verify
Prefer the project's own commands (package.json scripts, Makefile, pyproject.toml, pom.xml).
Fall back to what is globally available here:
| Static first | Then tests | |
|---|---|---|
| Python | ruff check, mypy |
pytest (or uv run pytest) |
| Go | go vet ./..., go build ./... |
go test ./... |
| TS | npx tsc --noEmit |
npm test |
| Java | mvn -q compile |
mvn test |
If nothing runnable exists, say 未验证 and name what was missing. Never imply verification that did not happen.
Step 7 — Report
Terminal only — no report files. Give the diff summary (files touched, lines removed), the skipped list, the 附注 section, and any pass that was reverted with the reason.