Skip to content

Add dead-code gate (vulture) - #21

Merged
jonnyspicer merged 2 commits into
mainfrom
chore/dead-code-gate
Aug 11, 2026
Merged

jonnyspicer merged 2 commits into
mainfrom
chore/dead-code-gate

Conversation

@jonnyspicer

Copy link
Copy Markdown
Contributor

Adds a vulture dead-code gate: tools/check-dead-code.sh, a whitelist, and a CI step.

Why a wrapper rather than calling vulture directly

The obvious setup excludes tests/, which makes anything used only by
tests look dead — the single largest source of false positives. This scans
tests so their usage counts, then drops findings whose location is a test
file, which is the behaviour you actually want.

Combined with excluding build artefacts (a stale source copy that doubles every
finding) and ignoring framework-dispatched decorators, that took the estate-wide
count from 217 to 102 without a single judgement call.

The whitelist has two sections, deliberately

Contracts — names genuinely referenced by something vulture cannot see:
stdlib http.server handler methods, ssl.SSLContext attributes, generated
wire models. These are permanent.

UNREVIEWED — 27 entries in this repo that appear genuinely dead and
need a decision: delete, or finish wiring up whatever was left unfinished.

This section is a backlog, not an exemption. Nothing here has been deleted,
because "this config field is never read" usually means someone left work
half-done, and that is a call for whoever wrote it. Listing them keeps the gate
green today, so it starts catching new dead code from this PR onward
rather than waiting on a cleanup that may take weeks.

Verified

Gate passes on this branch, and fails (exit 1) when a dead function is added —
tested, since a gate that cannot fail is worthless.

🤖 Generated with Claude Code

Adds tools/check-dead-code.sh, a vulture wrapper shared across the org, plus
a whitelist and a CI step.

The wrapper exists because the obvious vulture setup — excluding tests — makes
anything used only by tests look dead, which is the largest single source of
false positives. This scans tests so their usage counts, then drops findings
whose location is a test file. Across the estate that took the raw finding
count from 217 to 102 without a single judgement call; build artefacts and
framework decorators account for the rest.

The whitelist separates two things that are usually conflated: names vulture
cannot see being used (framework contracts, wire formats), and names that
appear genuinely dead but need a decision. The second section is a backlog,
listed so the gate is green today and starts catching NEW dead code
immediately.
Three entries were labelled by filename pattern rather than by what they
are: bistatic_models.py matched a models.py rule, and the two *_nested_value
helpers matched a config-field rule. The names and locations were right; only
the explanatory comments were wrong.
@jonnyspicer
jonnyspicer merged commit 9811b31 into main Aug 11, 2026
2 checks passed
@jonnyspicer
jonnyspicer deleted the chore/dead-code-gate branch August 11, 2026 01:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant