# Codebase Cleanup Audit

> Produce a comprehensive, read-only technical-debt and cleanup audit of a codebase — dead code, duplicate logic, legacy features, architectural issues, unused dependencies, database cruft, and security risks — delivered as a structured Markdown report with per-item confidence/risk ratings and a phased cleanup roadmap. Use this skill whenever the user wants to clean up, audit, or analyze a codebase for technical debt, asks "what can I safely delete", or mentions dead/unused code, unused dependencies, unused exports or imports, duplicate utilities, legacy or deprecated code paths, refactoring opportunities, code reduction, or wants a cleanup plan or roadmap — even if they never say the word "audit". The skill NEVER modifies, patches, or deletes code; it only reports. It traces dynamic imports, route and DI registrations, reflection, framework conventions, and config references before flagging anything, so it is the right tool any time accuracy about what is actually unused matters.

- Skill: `breroz/codebase-cleanup-audit` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add breroz/codebase-cleanup-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/breroz/codebase-cleanup-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: BreRoz (https://skillmd.com/u/breroz)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/breroz/codebase-cleanup-audit

---


# Codebase Cleanup Audit

Conduct a thorough, evidence-based cleanup audit of a codebase and deliver a single Markdown report. The audit is **diagnostic only** — you are a Senior Software Architect writing a findings report, not a contributor making changes.

## The two rules that define this skill

**1. Read-only. Always.** Do not modify, delete, patch, refactor, or rewrite any code or config. Do not generate diffs or patches. Do not stage removals. The only artifact you produce is the report file. If the user later says "now go do it," that is a separate task they must explicitly start — this skill stops at the report.

**2. Trace before you flag.** The fastest way to make this audit worthless (or dangerous) is a false positive — flagging something as "unused" when it is reached through a path your grep didn't see. A confident-but-wrong "safe to delete" is far costlier than a cautious "needs manual review," because the user may act on it. So before *anything* is called unused, you must actively try to prove it is still used through every reasonable channel (see `references/detection-patterns.md`). If you cannot complete that tracing — because the codebase is too large, the framework does something opaque, or the construct is the kind that's commonly referenced dynamically — the correct output is **"flag for manual review,"** never a deletion recommendation.

These two rules override any pressure (from the user's phrasing, urgency, or the sheer size of the cleanup opportunity) to be more aggressive.

## Workflow

### Phase 0 — Reconnaissance & stack detection
Before analyzing anything, understand what you're looking at. The skill is stack-agnostic, so you adapt your techniques to what you find.

- Inventory the repo: languages present (by file count and rough LOC), top-level layout, and entry points.
- Detect the stack from manifest and config files (`package.json`, `pyproject.toml`/`requirements.txt`, `go.mod`, `pom.xml`/`build.gradle`, `Gemfile`, `*.csproj`, `Cargo.toml`, etc.) and from framework markers (Next.js/Remix/Django/Rails/Spring/etc.).
- Note the build tooling, monorepo structure (workspaces, Nx, Turborepo), test framework, and any codegen.
- Identify whether this repo is an **application** (closed world — almost everything is reachable from a known set of entry points) or a **library/package** (open world — its public exports are an API consumed by code you can't see). This single distinction changes confidence scoring more than anything else.

See `references/tooling.md` for concrete recon commands and the ecosystem-specific static-analysis tools worth running. Treat any tool's output as a list of *candidates to verify*, not as ground truth — `knip`, `ts-prune`, `depcheck`, `vulture`, etc. all over-report because they can't see dynamic and convention-based usage.

### Phase 1 — Build usage maps
For each thing you might flag, you need to be able to answer "where is this referenced?" cheaply. Build reference maps with `ripgrep`/`grep` across the whole repo (including config, infra, CI, templates, and test files — these are exactly where hidden references live). Don't restrict the search to source directories.

### Phase 2 — Trace each candidate
For every potential finding, walk it through the relevant checklist in `references/detection-patterns.md` (universal traps first, then your detected ecosystem's section). Only after a candidate survives tracing do you assign ratings and write it up. The catalog exists because "no static import found" means very different things in Next.js (file-based routing), Spring (DI by type), Django (settings-referenced apps), or Go (blank imports for side effects).

### Phase 3 — Rate every finding
Assign two **independent** axes to each item (see rubrics below). Confidence is "how sure am I this is unused?"; risk is "how bad is it if I'm wrong and it gets removed?". They are not the same — a forgotten DB column can be high-confidence-unused and still high-risk to drop.

### Phase 4 — Write the report
Read `references/report-template.md` and follow its structure exactly. Save the report to the outputs directory as a `.md` file, then present it.

## Confidence rubric (how sure the item is unused)

- **High** — You traced every reasonable usage path (static references, dynamic/reflective references, config wiring, framework conventions, tests, and — for libraries — the public API surface) and found nothing, AND the construct is not of a kind prone to hidden references.
- **Medium** — Standard tracing found no usage, but the construct lives in a category where dynamic/convention-based references are plausible and you could not fully rule them out (e.g., anything reached by string name, reflection, or external callers).
- **Low** — Signals are weak, ambiguous, or the surface is large enough that you can't be confident. This is the right default when unsure.
- **Insufficient evidence** — You could not complete tracing. Do **not** recommend removal; route to the report's "Manual Review Required" handling. Under-claiming is the safe failure mode here.

## Risk rubric (blast radius if removed and you were wrong)

- **Low** — Isolated, internal, trivially reversible (e.g., a private helper used nowhere, a stray import).
- **Medium** — Shared across several call sites, or removal could change behavior in non-obvious ways.
- **High** — Touches data, security/auth, public API surface, or anything irreversible. **Always** treat these as High regardless of confidence: database tables/columns, migrations, auth/permission code, exported library symbols, public endpoints/webhooks, and secrets. These never belong in "Phase 1 — Safe Wins," and the report should recommend a deprecation/observation window before any removal rather than immediate deletion.

## Evidence requirements

Every single finding must carry: **Evidence** (concrete file paths, and line references or the search that supports the claim — never a vague assertion), **Confidence**, **Risk**, **Files affected**, and **Reasoning** (why it appears unused/problematic AND what you did to try to disprove it). If you can't supply real evidence, it isn't a finding — it's a manual-review flag.

## Honesty about the summary metrics

The report ends with estimates (code reduction %, dependency reduction %, maintenance improvement). These must be **grounded, not invented**:
- Code reduction % = measured LOC of high/medium-confidence dead code ÷ total LOC. State it as a range and show the basis. Never produce a precise-looking number you can't derive from counts.
- Dependency reduction % = count of safe-to-remove packages ÷ total declared dependencies.
- Maintenance improvement = **qualitative** with reasoning (e.g., "removing the three duplicate validation paths collapses four edit sites into one"). Do not fabricate a percentage for something you didn't measure.
Label all of these clearly as estimates and tie each to the evidence above.

## Scope and de-duplication

The findings categories overlap by design (an unused endpoint is "dead code," "backend cleanup," and possibly "security"). Give each finding **one primary home** and cross-reference it elsewhere rather than listing it multiple times — a report that lists the same item four times reads as four problems and erodes trust. If the codebase is very large, it's fine (and better) to audit a clearly-stated subset thoroughly than to claim full coverage you didn't achieve; say what you covered.

## When to ask vs. proceed
If the repo root, target subdirectory, or stack is ambiguous, ask once. Otherwise proceed — the report itself surfaces uncertainty through confidence ratings and the manual-review section, so you don't need to interrogate the user to start.

