It is tempting to think that once you have parsed a codebase into a graph of calls and references, you have understood it. You have not. You have built a very accurate map of the streets and learned nothing about which roads people actually drive.
Every edge is not equal
A call from a hot path to the function that gates a payment is not the same kind of edge as a call into a logging helper, even though the graph draws them identically. Understanding is knowing which edges carry weight — which changes ripple, which boundaries are load-bearing, which two files always break together for reasons the imports never reveal.
- Structure tells you what connects to what. It does not tell you what matters.
- Two systems with identical graphs can have completely different risk surfaces.
- The edges that hurt you are often the ones the static structure cannot see.
An index answers where. Understanding answers so what. The second question is the whole job.
So the graph is a starting point, not a finish line. We layer history, ownership, and change-coupling on top of it, because a relationship that the source never declares is still a relationship. Understanding is the graph plus the judgment about which parts of it you should be afraid of.