Skip to main content
Technical Overview

How the dead code agent works

Learn about call graphs, dead paths, confidence scoring, and the pull request pipeline.

Call graph construction

YAGNI creates a complete interprocedural call graph from your source using several static analysis techniques:

  • Import resolution: follows all import and require statements to map module dependencies
  • Function call extraction: identifies every direct call site, including method chains
  • Type-flow analysis: follows constructor patterns, class instantiation, and interface implementations
  • Dynamic dispatch estimation: flags calls through interfaces and reflection as uncertain

The graph connects every function and module to the callers able to reach it from any entry point, including HTTP handlers, CLI commands, cron jobs, event listeners, and queue consumers.

Dead path detection

A path qualifies as dead only when both criteria are met:

  1. No reachable caller exists in the static call graph starting from any known entry point
  2. No runtime trace data shows the path being exercised (when runtime traces are available)

Paths failing only the static criterion but passing the runtime criterion go to review, not automatic removal, handling dynamic dispatch that static analysis cannot fully resolve.

Confidence scoring

Each detected dead path gets a confidence score from 0 to 100. Scores above 85 create automated pull requests, while scores from 60-85 appear in the dashboard as manual review candidates.

Score range Signal Action
85 to 100 No callers, no runtime hits, no dynamic dispatch Automated PR opened
60 to 84 No callers, runtime inconclusive or absent Surfaced in dashboard for manual review
40 to 59 No callers, some dynamic dispatch detected Flagged with caution label, awaits team decision
Below 40 Ambiguous caller chain or reflection-heavy path Logged only, no action taken

PR pipeline

When a dead path exceeds the automated threshold, YAGNI:

  1. Removes the dead modules from a working copy of your branch
  2. Runs your configured test command in an isolated container
  3. If tests pass: opens a pull request against your target branch with a summary of what was removed and why
  4. If tests fail: logs the failure and defers the removal until the next analysis cycle

.yagniignore

Add a .yagniignore file at the repository root to omit paths from analysis. It follows .gitignore-style syntax:

.yagniignore
# Vendor code
vendor/
node_modules/

# Deprecated but stable APIs
src/api/v1/legacy/

# Migration helpers
scripts/migrations/

# Test fixtures
__fixtures__/

Entries in .yagniignore stay out of the call graph entirely. They will not appear in dead path reports or qualify for automated removal.