skills/code-quality/dead-code-eliminator/SKILL.md
Finds and safely removes code that is never executed — unreachable branches, uncalled functions, unused classes, dead feature flags. Use when cleaning up after a feature removal, when the user suspects the codebase has accumulated cruft, or when reducing build/bundle size.
npx skillsauth add santosomar/general-secure-coding-agent-skills dead-code-eliminatorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Dead code is code that cannot execute under any input. It's not "rarely used" — it's never reachable. The distinction matters: deleting rarely-used code is a product decision; deleting dead code is housekeeping.
| Class | How to prove dead | Confidence |
| -------------------------------- | --------------------------------------------------------------- | ---------- |
| Code after return/throw/exit | Syntactic — compiler/linter catches this | Certain |
| Private function, zero callers | Grep the module. Private = no external callers possible. | Certain |
| Branch with constant-false condition | if False:, if (1 == 2). Constant folding. | Certain |
| Public function, zero callers in repo | Grep. But: reflection, plugins, DI, external callers? | Uncertain — see below |
| Feature flag hard-wired off | if config.NEW_CHECKOUT: and the flag is False everywhere, permanently | High (check all envs first) |
| else branch of exhaustive match | All enum values covered above; else can't fire | High (until someone adds an enum value) |
| Zero coverage in tests | Covered-by-nobody. But tests don't cover everything users hit. | Low — absence of test ≠ absence of use |
Static analysis says doThing() has zero callers. Before deleting, check:
getattr(obj, name)(), Class.forName(...), Spring @Component scanning. The call is in a string.__all__, check the public API docs.__getstate__, toJSON(), ORM hooks — called by the framework, not by you.If you can't rule all of these out, it's probably dead but you can't prove dead. Deprecate before delete.
1. Identify → 2. Verify → 3. Deprecate (if public/uncertain) → 4. Delete → 5. Test
| Step | Action |
| ---- | -------------------------------------------------------------------- |
| 1 | Find candidates (static analysis + coverage + grep) |
| 2 | For each: check the uncertainty table above |
| 3 | Uncertain → add a deprecation warning/log, deploy, wait one cycle. Silence = dead. |
| 4 | Delete the code AND its tests AND its imports |
| 5 | Full test suite. Then → behavior-preservation-checker on the containing module. |
Candidate: utils/legacy_format.py — 3 functions, 0% test coverage, no callers found by grep.
Verify:
rg 'legacy_format' --type py → one hit: import utils.legacy_format in utils/__init__.py. Nobody uses the import. Re-exported but unused.setup.py / pyproject.toml [project.scripts] — not there.parse_v1, parse_v2, detect_version — not hook-shaped.Verdict: Dead. But the __init__.py re-export means someone thought it was public. Check git log: last non-formatting commit to legacy_format.py was 3 years ago, message says "migrate to v3 format." The v3 migration finished; v1/v2 parsers are orphaned.
Delete:
__init__.py re-export. Test. Green.utils/legacy_format.py. Test. Green.rg 'legacy_format' one more time — clean.Commit message: Remove dead v1/v2 format parsers — v3 migration completed 2023, no remaining callers.
A flag that's been at one value in every environment for 3+ months is a dead conditional:
if settings.USE_NEW_CHECKOUT:
new_path()
else:
old_path() # ← dead if flag has been True everywhere since Q3
Delete the flag check, inline the winning branch, delete the losing branch. Then delete the flag from config. This is the #1 source of dead code in feature-flag-heavy codebases.
else branch just because the if is always true today. If the condition reads external config, "always true" is a current fact, not an invariant.## Dead (certain — delete now)
- <file>:<symbol> — <proof: private+no-callers | after-return | const-false>
Also delete: <tests, imports>
## Probably dead (deprecate first)
- <file>:<symbol> — <why uncertain: might-be-reflected | public-api>
Deprecation: <log line / warning to add>
Revisit after: <one release cycle>
## Not dead (looked dead, isn't)
- <file>:<symbol> — <actual caller you found>
development
Extracts human-readable pseudocode from a verified formal artifact (Dafny, Lean, TLA+) while preserving the verified properties as annotations, so the proof-carrying logic can be reimplemented in a production language. Use when porting verified code to an unverified target, when documenting what a formal spec actually does, or when handing a verified algorithm to an implementer.
development
Translates natural-language or pseudocode descriptions of concurrent and distributed systems into TLA+ specifications ready for the TLC model checker. Identifies state variables, actions, type invariants, safety properties, and liveness properties from the description. Use when formalizing a protocol, when the user describes a distributed algorithm to verify, when designing a consensus or locking scheme, or when starting formal verification of a concurrent system.
testing
Reduces a TLA+ model so TLC can actually check it — shrinks constants, adds state constraints, abstracts data, or applies symmetry — when the state space is too large to enumerate. Use when TLC runs out of memory, when checking takes hours, or when a spec works at N=2 and you need confidence at larger scale.
development
TLA+-specific instance of model-guided repair — reads a TLC error trace, identifies the enabling condition that should have been false, strengthens the corresponding action, and maps the fix to source code. Use when TLC reports an invariant violation or deadlock and you have the code-to-TLA+ mapping from extraction.