CutplaneJoin the private beta

Concept

Change impact analysis

Change impact analysis determines which parts of a system may behave differently because of a change, including the parts whose own source was never edited.


The problem it solves

A diff shows you the code that changed. It does not show you the code that now behaves differently, and those are not the same set.

If a function's return type changes, every caller is affected. None of them appears in the diff, because none of their files were edited. That gap — between what changed and what is affected — is what change impact analysis closes.

How it is computed

Start from the changed symbols: the functions, classes, constants and exports that the diff actually touched. Then walk outward through the call and import graph.

  • Hop 1 — everything that directly imports or calls a changed symbol.
  • Hop 2 — everything that reaches those.
  • Hop n — and so on, until the walk is stopped.

The walk has to be bounded, because in a connected codebase enough hops reach everything, and "the whole repository is affected" is technically true and practically useless. Depth limits and relevance ranking are what make the output a list a person can read.

Why the results should be grouped by component

"37 imports found" is a true statement that helps nobody. It is the wrong altitude: a reviewer cannot act on a count of import statements.

Useful impact analysis groups the reach at the architectural level first — "Checkout, Sessions and subscription renewal may behave differently" — and only then drills into which files and which lines. That ordering matters because the first sentence tells you what to test, and the file list only tells you where to look once you have decided the component matters.

Direct versus downstream

Two kinds of reach are worth separating, because they carry different risk:

  • Direct — this code imports or calls the changed thing. If the signature or behaviour changed, it is affected now.
  • Downstream — this code reaches the changed thing through one or more intermediaries. Whether it is affected depends on whether each intermediary passes the change through.

Direct callers are near-certain. Downstream reach is a possibility that decays with distance, and a tool that presents both with equal confidence is overstating the second.

The honest limits

Static impact analysis is exact about what it can see and blind to the rest:

  • Dynamic dispatch is invisible. getattr, reflection, DI containers, Django's app registry, duck typing — none of it is visible statically, so edges that only exist at runtime are missing.
  • It measures reachability, not behaviour. That a component can reach a changed function does not mean it will behave differently. It means it is worth checking.
  • It cannot rank by business risk. The walk knows the graph, not which of your components takes payments.

The correct posture is that impact analysis produces a candidate set for your attention, not a verdict.


All concepts