Skip to content
Skills Library
Programming · Building & coding

cleanup-codebase

/cleanup-codebase

Reduce concepts, duplication, and ceremony in internal code while touching nearby code. Use when working an existing path and you spot dead fields, redundant wrappers, or speculative abstractions; distinct from refactor-break-bw-compat (internal hygiene, not public API removal).

Licence
Apache-2.0
Last repository change
08.07.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
4
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 08.07.2026, without references to retired models or APIs.

Licence

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

What it does and when to use it

Reduce concepts, duplication, and ceremony in internal code while touching nearby code. Use when working an existing path and you spot dead fields, redundant wrappers, or speculative abstractions; distinct from refactor-break-bw-compat (internal hygiene, not public API removal).

Original author description

Reduce concepts, duplication, and ceremony in internal code while touching nearby code. Use when working an existing path and you spot dead fields, redundant wrappers, or speculative abstractions; distinct from refactor-break-bw-compat (internal hygiene, not public API removal).

How it works

  1. Mandates, not suggestions
  2. What "real boundary" means
  3. When to Apply
  4. When NOT to Apply
  5. Decision rubric
  6. Workflow
  7. Constitutional Rules (Non-Negotiable)
  8. Validation Gates
  9. Exit Codes
Original SKILL.md headings · 118 lines, 1,450 words
SKILL.md preview
---
name: cleanup-codebase
description: Reduce concepts, duplication, and ceremony in internal code while touching nearby code. Use when working an existing path and you spot dead fields, redundant wrappers, or speculative abstractions; distinct from refactor-break-bw-compat (internal hygiene, not public API removal).
---

# Cleanup codebase — local simplicity, ruthlessly applied

Code rots in two directions: outward (drift from the original design) and downward (accretion of dead state, redundant indirection, speculative ceremony). This skill addresses the second. The thesis is local: you are already in nearby code for some other reason; while you are there, remove what does not earn its keep.

**Modern insight (2025)**: Kent Beck's *Tidy First?* thesis and Casey Muratori's dataflow-first design heuristic both converge on the same conclusion that this skill's compress-side operations operationalize — small, frequent, atomic cleanups embedded in the active commit stream beat scheduled "cleanup PRs" by a wide margin. Scheduled cleanups bundle unrelated concerns and become unreviewable; embedded cleanups stay reviewable because their scope is the file already in your hands.

See [dead-fields](references/dead-fields.md) for examples of dead struct fields, props, and class members.
See [redundant-wrappers](references/redundant-wrappers.md) for examples of single-line passthrough functions that should be inlined.
See [dead-config](references/dead-config.md) for stale feature flags, environment variables, and dead config branches.

---

## Mandates, not suggestions

These are mandates, not suggestions. Internalize them as rules; do not paraphrase.

### 1. Minimize concepts, duplication, and ceremony.

Every concept the reader has to hold in their head has a cost. Every duplicated piece of logic has two places to drift apart. Every ceremonial wrapper, factory, or builder that does not protect a real boundary is a tax on every future reader. Reducing concepts is not the same as reducing lines — it is reducing the number of distinct things a reader has to track.

### 2. One real owner per contract. No mirroring, no wrappers unless they remove real coupling.

A "contract" is the truth about what some piece of state means or what some operation does. It must have exactly one owner. Mirroring (two structures holding the same field; two services maintaining the same cached state) is a guaranteed-future-bug pattern. Wrappers are coupling-removal tools — if a wrapper just renames or forwards without removing coupling, it is ceremony.

### 3. Local simplicity over speculative abstraction. Add indirection only when it removes real coupling or protects a real boundary.

"Speculative" means "I might need this later." You will not need it later in the form you imagine now, and the indirection you add now will make the actual future change harder. Indirection earns its keep when it removes coupling that *currently* exists, or when it protects a *current* boundary (process, untrusted-input, async/sync seam). Otherwise it is dead-weight ceremony.

### 4. When caller and callee are both local with no real boundary, change both directly.

A "local change" that has to ripple through three wrapper layers is not local — it is coupled. If `caller` and `callee` are both yours, both in the same module, with no API boundary between them, refactoring them in lockstep is correct. Resist the urge to "preserve the interface" of internal functions; an internal function's interface is whoever calls it.

### 5. Remove dead code, fields, config, and stale state while touching nearby code.

Dead code is not free. It misleads readers about what the system does, it survives grep searches and pulls attention, it tricks reviewers into preserving it "just in case." While you are in nearby code for some other reason, remove what is dead. Make the deletion its own atomic commit so reviewers see exactly what disappeared.

---

## What "real boundary" means

Indirection earns its keep at: **public API surfaces**, **process/network seams** (RPC, HTTP, queues), **untrusted-input boundaries**, **async/sync seams**, **runtime seams** (FFI, WASM, JNI), and **test/production seams** where mocks legitimately substitute. A swappable-implementation contract counts only when >1 real impl ships today — not "might exist later."

Not boundaries: internal modules in the same crate/package, helpers in the same file, cross-module calls without a constraint that prevents co-change.

---

## When to Apply

- You are editing `foo.py` for an unrelated feature; while reading the file, you notice a dead field
- A refactor commit just ripped out a code path; the leftover wrapper, dead branch, or stale flag should leave with it
- Reviewing a PR diff that adds an unnecessary wrapper or duplicates state; flag and request inline simplification
- Onboarding to a codebase — surface candidates for the original author to confirm dead

## When NOT to Apply

- **Standalone "cleanup sweep" PRs** — these mix unrelated changes, become unreviewable, and conflict with the `<git>` charter's "one concern per commit" rule. Solution: `git move --fixup` to embed the cleanup as an atomic commit alongside the active change.
- **Files you are not otherwise touching** — opportunistic edits become unreviewable noise; the cleanup must ride alongside work that justifies you being in that file.
- **Speculative removals you cannot prove are safe** — if you cannot grep-confirm that nothing reads a field, do not delete it; investigate first.
- **Public API surfaces** — that is `refactor-break-bw-compat`'s territory and needs a migration plan.

---

## Decision rubric

| Pattern | Action | Notes |
|---------|--------|-------|
| Wrapper that adds nothing but a rename | Inline, then delete the wrapper | Renames are not abstractions |
| Field set in constructor, never read after | Delete the field and its assignment | Grep all consumers first |
| Config flag where both branches are dead (always-on or always-off) | Delete the flag, keep the winning path | Often legacy migration debt |
| Adapter between two structurally equivalent local types | Collapse to one type | Different names ≠ different concepts |
| Helper used in 3+ places that genuinely names a shared concept | Keep | Real reuse, real naming |
| Helper used in 1 place that wraps a 2-line body | Inline | The wrapper is overhead |
| State mirrored across two services / two structs | Pick one owner; the other reads from it | Mirroring is the bug |
| Comment that contradicts the code | Update or delete the comment | Stale comments mislead |
| `TODO` from > 6 months ago | Open issue or delete | Indefinite TODOs are noise |

---

## Workflow

1. **Identify candidate** — while in the file for another reason, spot dead/redundant code.
2. **Confirm dead** — `git --no-pager grep -n` (or `ast-grep`) to verify no consumers; check tests, docs, configs, error messages.
3. **Check coupling effects** — does removal break the build? Force a refactor of the only consumer? That is a separate decision; record it.
4. **Verify against `~/.claude/claude/system-prompt-baseline.md` `<git>` charter** — cleanup is its own atomic commit. If it is mixed in with behavior change, split via `git move --fixup` / `git split`.
5. **Apply the deletion** — `git rip` the file or precise `Edit` for partial removal; never comment-out.
6. **Verify** — build, tests, type-check still pass. If a test was the only consumer of the dead code, that test was probably testing the dead code; see `tests-purge-unneeded`.
7. **Search for ghosts** — string references in docs, error messages, config keys, env vars, log lines that mention the removed concept.

---

## Constitutional Rules (Non-Negotiable)

1. **Never bundle cleanup with behavior change in one commit** — split via `git move --fixup` so each commit has exactly one concern. Cleanup commits ride alongside behavior commits in the same PR; that is fine and encouraged.
2. **Never add an abstraction during cleanup** — cleanup removes; if a new abstraction is genuinely warranted, that is a *separate* commit with its own justification.
3. **Never extend cleanup beyond files already touched by the active change** — opportunistic sweeps across the codebase are out of scope; they belong in scheduled refactor work that has its own plan.

## Validation Gates

| Gate | Pass Criteria | Blocking |
|------|---------------|----------|
| Atomic commit | Cleanup is its own commit, separate from behavior change | Yes |
| Dead confirmation | `grep`/`ast-grep` confirms no consumers in code, tests, docs, configs | Yes |
| No new abstractions | Diff is net-deletion (or inline-and-delete) only | Yes |
| Build + tests pass | Repo-native verification on every touched language | Yes |
| Ghost search | No leftover references in docs, error messages, env vars | Yes |

## Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Clean — atomic deletion landed, all consumers updated, build green |
| 11 | Consumer found that was not in the original grep — investigate and either preserve or migrate |
| 12 | Build / test regression — rollback required |
| 13 | Mixed-concern commit — must split via `git move --fixup` before merging |
| 14 | New abstraction introduced — separate the commit, justify the abstraction independently |
| 15 | Ghost references found — cleanup incomplete |
Files in this package (4)
  • SKILL.md 9 KB
  • references/dead-config.md 4 KB
  • references/dead-fields.md 3 KB
  • references/redundant-wrappers.md 4 KB

Versions

The database has no other skills named cleanup-codebase.

Database snapshot: 13.11.2026 · package version 81100b9ce895 (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100refactor
    Audits the codebase for code quality issues and refactors without changing external behavior. This skill should be used when the user asks to "refactor the codebase", "clean up code quality", "eliminate duplication", "improve abstractions", "enforce consistency", "remove dead…
  • 100code-simplification
    Use when a named module, file set, or dependency slice needs less code and structure without losing required behavior. Covers dead code, unused settings, and redundant wrappers. Use simplify to choose the right level of work, architecture-simplification to reorganize modules,…
  • 100refactor
    Improve existing code without changing behavior: scan smells, simplify, dedupe, reuse utilities, and verify after edits. Use for refactor, cleanup, simplify, reduce duplication, extract method, dead code, or code smells. No PR.
  • 82lessloc
    Find, review or remove code a codebase does not need (duplicates, copies under other names, dead code, needless abstractions, files, folders, comments, dependencies) without changing behavior. Use for "audit", "find bloat", "consolidate", "slim this", "reduce LOC", "what can I…
  • 90improve
    Makes existing code easier to understand without changing behavior. Use to simplify structure, remove duplication or dead code, improve names, or remove unnecessary abstractions.
  • 86principle-subtract-before-you-add
    Apply when sequencing an addition, refactor, or rewrite. Remove dead weight, redundant validators, and stub references first, then build on the simpler base.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.