Impact analysis
The most expensive class of AI-assisted code change is the one where the assistant looks confident, makes a small edit, and quietly breaks something three modules away. The change compiles. The local tests pass. Production breaks two hours later because some downstream caller wasn't covered.
cix's impact analysis exists to make those downstream effects visible before the change happens.
What it does
You give it a target — a function, a route, a database table, a configuration value — and ask: "what depends on this?"
You get back a structured report:
- Direct callers. Every place that imports or invokes the target.
- Transitive callers. What depends on those callers, up to a depth you choose.
- Affected request surfaces. HTTP routes and GraphQL fields whose handlers transitively touch the target.
- Affected tests. Test files that exercise the target or any caller of it.
- Affected data models. Tables and columns connected to the target through the code path.
- A risk tier. High, medium, or low — with reasons.
This is the report a careful engineer would produce by hand if they had a free afternoon. The system produces it in a single query.
Why this matters
Refactors stop being scary. "Rename this widely-used function" goes from a multi-hour manual exercise of grep, read, edit, repeat — into a structured task with a clear inventory of touch points. The assistant (or you) can work through the list deliberately instead of discovering casualties one CI failure at a time.
Reviews get faster. A reviewer looking at a change can see, alongside the diff, the impact report that informed the change. "Does this rename break anything?" turns into "the impact report shows seventeen call sites; I'll spot-check three."
Risky changes get flagged before merge. A change that touches a function with high transitive fan-in returns a high-risk tier with the reasons attached. The assistant can use that signal to decide whether to proceed alone or to surface the change for human review first.
What it analyzes
Impact analysis works against most kinds of project anchor:
- Symbols — "what depends on
format_invoice?" - Files — "what does this file's contents affect, transitively?"
- HTTP routes — "if I change the response shape of
GET /orders/:id, what client code might break?" - GraphQL fields — "if I deprecate this field, who selects it?"
- Database tables — "if I drop this table, what queries reference it?"
- Packages or modules — "what imports anything from this package?"
The query takes a depth parameter so you can choose between "direct callers only" (cheap, immediate) and "everything within three hops" (slower, exhaustive).
What it cannot do
Impact analysis is a static analysis. It works from the code on disk and the index built from it. That means:
- Dynamic dispatch is best-effort. A handler registered through a runtime lookup table is harder to attribute to a route than one declared statically. The system reports what it can statically determine and flags lower-confidence matches as such.
- Reflection and metaprogramming are partial. A method called through
getattr(self, name)wherenamecomes from a config file will not show up in the caller list. This is true of every static analysis tool, not a quirk of cix. - External callers are invisible. If your function is part of a public API and someone is consuming it from outside the repo, cix doesn't know about them. You still need a separate strategy for tracking downstream consumers.
- Two same-named symbols in different packages can confuse the resolver. When you have
Objectdefined in bothlib/http/serveandfs/types, the system may pick one and analyze callers of that one. The output flags this when it happens, but you should check the resolved target before trusting the report.
These are real limits. They are documented honestly because they affect when you should and shouldn't rely on the report.
When to reach for it
- Before a rename or signature change. Always. The cost of running it is small; the cost of skipping it can be large.
- When auditing a function for dead-code candidacy. If the impact report shows zero callers and zero tests, that's strong evidence the function is unused.
- When choosing what to change. Two functions could be the right place to make a fix; the impact report tells you which has a smaller blast radius.
- When estimating effort. A change with seventeen call sites takes longer than a change with two. The report puts a number on something otherwise hard to estimate.
In practice
In the pre-release cleanup case study, the assistant used impact analysis to find that an entire controller was querying a table dropped one migration earlier — every endpoint in that controller was returning 500 errors, but the team hadn't noticed because the controller was rarely called. Without impact analysis, this would have surfaced when a customer hit the endpoint. With impact analysis, it surfaced during a routine pre-release sweep.
That's the value: making downstream effects visible at edit time instead of incident time.
Related
- Schema awareness — pairs with impact analysis when the change touches a table.
- Workflow: refactoring — the end-to-end refactor flow that uses this feature.
- Limitations — exactly where impact analysis is and isn't trustworthy.