AI Adoption GuideSoftwareRetire
Dependency Usage Analyzer
Static analysis plus LLM maps all callers of a deprecated feature or API to quantify retirement blast radius, using tools like Sourcegraph.
Software processDiscoverDesignBuildTestReleaseAdoptSupportRetire
By Don, DoneThat’s AI coach · updated
What this use case covers
A Dependency Usage Analyzer combines static analysis (call graphs, symbol search, import and reference indexes) with an LLM that reads those results and produces a structured map of every caller of a deprecated feature or API. The goal is not to delete code. It is to answer, with evidence, who still depends on the thing you want to retire, how they call it, and how large the change set will be.
Staff engineers typically reach for this when a public or internal API is marked deprecated, a feature flag is scheduled for removal, or a library surface must shrink before a major version bump. Tools such as Sourcegraph (or equivalent code search and SCIP/LSIF-backed graphs) supply the raw references. The model organizes them into a blast-radius report: direct callers, transitive consumers when the graph supports it, call-site patterns, and gaps where resolution failed.
When to run it
Run this analysis when retirement is decided in principle but the cut is not planned yet. Good triggers include:
- A deprecation notice that needs a concrete migration deadline
- A breaking change in a shared package where “who uses this?” is unclear across repos
- Cleanup after a feature flag or dual-write path has been “almost unused” for months
- Pre-work before generating migration guides or assigning ownership of cut tickets
Do not treat the analyzer as a substitute for product or platform decisions. It quantifies impact; it does not decide whether the API should die.
Empty or near-empty output is expected when the target symbol cannot be resolved, the call graph index is missing or stale, or search returns no confident matches. In those cases the honest result is “unknown callers,” not a fabricated list. Engineering should fix indexing, widen the search scope, or fall back to manual review before planning the cut.
How the mapping works
The pipeline is analysis-first, language-second.
- Resolve the target. Pin the deprecated symbol, endpoint, package export, proto field, or feature flag name. Ambiguous names produce noisy maps; prefer fully qualified identifiers and repo-scoped search.
- Collect references. Use code search and call-graph tooling (for example Sourcegraph search, SCIP indexes, or language-server references) to list files, packages, and symbols that touch the target.
- Classify call sites. The LLM groups matches into categories such as production callers, tests, generated code, docs and examples, and dynamic or reflective usage that static tools only partially see.
- Estimate blast radius. Summarize repo count, service ownership hints from path or CODEOWNERS, and rough change difficulty (simple rename vs. behavioral rewrite).
- Flag uncertainty. Mark unresolved aliases, stringly-typed invocations, plugin registries, and cross-language FFI so humans know what the graph missed.
The model should cite paths and symbols from the tool output rather than inventing callers. If the underlying search is incomplete, the report should say so explicitly.
What humans still own
Human-in-the-loop is mandatory at the planning boundary. The model maps callers; engineering still plans the cut.
Staff engineers (or owning teams) should:
- Validate high-impact callers and false positives (especially tests, fixtures, and generated stubs)
- Decide sequence: freeze new usage, ship adapters, migrate critical paths, then remove
- Set ownership and deadlines per service or package
- Choose compatibility strategy (shim, facade, versioned endpoint) when a hard cut is unsafe
- Approve the final deletion or API removal PR after migrations land
The analyzer does not schedule the retirement, rewrite production traffic, or assert that zero callers remain in runtime. Residual risk from dynamic dispatch, mobile clients, or out-of-index repos stays with the owners of the cut.
Inputs, outputs, and failure modes
Useful inputs
- Exact deprecated symbol, API path, or feature identifier
- Repo or monorepo scope, and whether cross-repo search is available
- Fresh static index or search backend (Sourcegraph or equivalent)
- Optional context: deprecation policy, target removal date, known shims
Useful outputs
- Caller inventory (path, symbol, ownership hint, category)
- Pattern summary (how the API is used, not only where)
- Blast-radius estimate suitable for planning tickets
- Explicit uncertainty and “no matches / index missing” sections
Failure modes to treat as empty or blocked
- Symbol not found in the index
- Call graph unavailable for the language or build
- Search limited to a single repo when the API is published elsewhere
- Matches that are only string literals with no resolvable binding
In those cases prefer an empty caller list plus a clear reason over a plausible but unsupported map. Downstream cleanup or migration-guide work should wait until resolution quality is good enough for planning.
How it fits retirement work
This use case sits early in the retire stage for software quality outcomes. It feeds related work rather than replacing it:
- Dead Code Detector helps find unused surfaces after traffic or references dry up; the usage analyzer focuses on known deprecated surfaces and their remaining dependents.
- Migration Guide Generator turns a validated caller map and API diff into guidance for consumers; run mapping first so the guide targets real call patterns.
- Codebase Cleanup Agent executes mechanical removal and follow-up hygiene once migrations are done and humans approve the cut.
A practical sequence for a staff engineer: lock the deprecation target, run the Dependency Usage Analyzer against a current index, review and correct the blast-radius report, plan the migration with owning teams, then use guides and cleanup tooling only after the map is trusted. The retirement succeeds when callers are accounted for and the cut is deliberate, not when the model simply lists files.
Is this worth automating for you?
Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.
DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.
Measure the baseline first