Finding things
Code health and dependencies
Trace dependencies, callers, paths, and blast radius; inspect cycles, unused code, complexity, contradictions, drift, scan history, and trends.
“what would break if I change this function?”
Callers and dependents, from the graph.
“show me this project's code health”
Circular dependencies, unused code, and complexity hot spots.
“is anything still using the legacy client?”
Every dependent, or an honest nothing.
You can ask about the change you want to make. The assistant should recognize when a text lookup is not enough and inspect relationships, callers, and blast radius without waiting for you to name the graph operation.
Why a graph and not a search
Text search finds the name. A graph knows the relationship. "What calls this" is a different question from "what mentions this", and only one of them is safe to base a refactor on.
What it reports
Relationships around one change
| Question | What the graph can return |
|---|---|
| What does this depend on? | Direct and, when useful, transitive dependencies |
| What uses this? | Reverse dependencies and every known usage of a module, function, type, variable, or component |
| How does A reach B? | A path between two graph nodes |
| Who calls this function? | A bounded call path |
| What is related? | Nearby nodes and selected relationship types |
| What would this change affect? | Impact and blast radius for a modification, rename, signature change, or deletion |
| Why was this area shaped this way? | Decisions linked to the graph node when they exist |
Project-wide health
| Signal | What it means |
|---|---|
| Circular dependencies | Cycles between modules—the reason a “small” change spreads |
| Unused code | Functions, types, modules, and variables with no known references |
| Complexity | Long or highly branching functions that deserve inspection |
| Contradictions | Saved knowledge that conflicts with other current context |
| Code drift | Areas where code and the recorded project understanding have diverged |
Using it before a refactor
The order that saves time:
- Search for the exact symbol or area so the target is unambiguous.
- Check reverse usages and blast radius. If it is larger than expected, that is the first finding.
- Trace the important call or dependency path rather than opening every related file.
- Check cycles, drift, and linked decisions in the area.
- Treat unused code as candidates, then verify before deleting.
A refactor with a real blast radius
Suppose you want to change verifyToken so it returns a typed failure instead
of a boolean. An exact source search identifies the symbol; the graph answers
the questions that decide whether the change is small:
- Which middleware, background jobs, tests, and command-line paths call it?
- Is there a call path from the public request handler to the verifier through wrappers whose names never mention tokens?
- Which modules depend on the current return type?
- Does the auth package already participate in a cycle that this change could deepen?
- Is there a linked decision explaining why one caller bypasses the normal middleware?
If the graph shows twelve callers rather than the expected two, split the work or write a plan before editing. After the refactor, rerun the same checks and save a new quality snapshot. The useful comparison is not “the build passed”; it is “all known callers moved, no new cycle appeared, and the baseline did not regress.”
An “unused” verifyLegacyToken result still needs inspection. It may be loaded
by reflection, called through an interface, or used only by an external
consumer. The graph supplies a candidate and its known relationships, not a
guarantee that deletion is safe.
Snapshots and trends
Ask the assistant to save a code-health baseline after a meaningful scan or cleanup. Later scans can show whether cycles and complexity are going up or down over a quarter — which turns "the codebase feels worse" into a number.
There are three different time views:
- Freshness says whether the dashboard cache is current enough to trust.
- History lists saved scan runs and their state.
- Trends compare counts over time.
A saved snapshot makes a deliberate baseline. It does not refresh the source index by itself.
Building and refreshing the graph
The graph is derived after source indexing. A new project or a large batch of changes may need graph ingestion before relationship queries are complete. Check freshness before treating an empty result as proof that no dependency exists.
Repository text remains the authority for a newly edited file that has not been indexed yet.
Believing "unused"
Reflection, dynamic dispatch, and code called only from outside the repository can look unused. Treat the list as candidates, not a delete queue — check the blast radius of each before removing it.
If it doesn't work
Empty results on a new project. The graph builds after indexing. Give it a few minutes, then rerun.
It missed a caller. Dynamic dispatch and reflection aren't traceable statically. The graph is a strong signal, not a proof.
Complexity flags code I'm happy with. It measures shape, not quality. A long switch statement is fine; it just measures long.
A dashboard count differs from the code I just changed. Check freshness and the latest scan history, refresh the index and graph, then compare again.
A diagram disagrees with the graph. The diagram is a deliberately saved model; the graph is derived from indexed code. Verify the current source and update the stale record.