Task: Delete provably unreachable code
SkillDev toolsAutonomous maintenance routine that deletes provably unreachable code
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Task: Delete provably unreachable code skill
What this skill tells your AI
The instructions your AI receives, as published by bex-co/beancount-io in .agents/skills/routine-dead-code-removal/SKILL.md and read by ahel’s review.
Usage: /routine-dead-code-removal [package-or-path]
Run the target package's dead-code detector, prove each hit is truly
unreachable, delete it (with the tests and fixtures that only existed for it),
make the package's checks pass, and ship each removal via /ship.
Contract
Read .agents/skills/routine-shared/contract.md first — it defines
preconditions, scope resolution, verify gates, the ship protocol, the budget,
and universal STOPs. This file adds only what is specific to dead code. Floor
even without it: never ship red; one finding per ship; anything in a
DO_NOT_DO.md is a hard STOP.
Workflow
1. Scope
Resolve scope per the contract. With no argument, prefer running
scripts/lint-deadcode.sh from the repo root once as a survey, then pick the
one package with the most promising hits.
2. Discover
cd into the package, then run its detector:
- JS/TS packages (
mobile,dashboard,backend-cluster/backend-v2,backend-cluster/ledger,backend-cluster/agent-box) →yarn lint:deadcode(Knip; config in the package'sknip.jsonc) cli/→make deadcode(Vulture; high-confidence only)
Also legitimate finds while reading nearby code: commented-out blocks,
if (false)-style branches, early-return shadowed code. A detector hit is a
candidate, not proof.
3. Prove it
For every candidate, sweep for references the detector can't see before touching anything:
- Grep the whole package for the symbol/file name as a string — dynamic imports, registries, config-referenced entries, test fixtures.
- Expo Router is file-based: files under
mobile/app/are routes reachable by navigation and deep links even with zero imports — never a dead-code finding. - Codegen inputs (GraphQL documents,
codegen.ts,apollo.config.json) and build/tooling entry points (babel.config.js, scripts referenced frompackage.json) count as reachable.
A confirmed false positive is its own legitimate finding: add a scoped
ignore to the package's knip.jsonc (with a short reason) instead of deleting,
so the detector stays trustworthy.
4. Fix
- Prefer the safe fixers where they apply:
yarn lint:deadcode:fix/make deadcode-fix— then review the resulting diff before keeping it (rootCLAUDE.mdrule). Discard anything the proof step didn't cover. - Delete manually what the fixers can't reach (commented-out blocks, unreachable branches).
- Delete tests and fixtures whose only purpose was exercising the removed code — they travel with it.
5. Verify
Run the owning package's full gate from the contract's table, plus a clean re-run of the detector to confirm nothing was orphaned by the deletion.
6. Ship
Compose /ship for this one removal. Loop back to step 2 while candidates and
budget remain.
What NOT to do
- Never delete a branch that is dead only because a feature flag holds one
value — that is
routine-shipped-feature-inliner's job. - Never delete one of two live duplicate implementations — that is
routine-dup-unifier's job (it repoints callers first). - Never touch the CLI's vendored
favacode, codegen output, or lockfiles. - Never trust a Knip/Vulture hit without the reference sweep — file-based routes and dynamic lookups are exactly where detectors lie.
Arguments
$ARGUMENTS
Signals
- GitHub stars
- 267
- Forks
- 30
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
routine-dead-code-removal- Source
- github.com/bex-co/beancount-io