Characterization tests document what a function does today so a refactor can be checked against captured outputs (Honeybadger). They are the right safety net, and Michael Feathers frames the legacy workflow around finding change points and test points before touching behavior (BSSw). But a characterization test only pins behavior at the boundary you chose. Pick the wrong boundary and you have pinned a private helper while the contract your users depend on sits three frames up.
The call-site map fills that gap. It answers a question a test cannot: who can observe this function, and through which doors? The freeCodeCamp walkthrough makes the same point in its prerequisites: before writing characterization tests you should know where the behavior starts, what state it changes, which external systems it touches, and which outputs may be consumed elsewhere (freeCodeCamp). That is a call-site map in plain English.
For an agent the stakes are higher than for a human. Practitioners report that LLM tools handle greenfield work far better than existing codebases with custom conventions, and that agents consistently ignore most of the surrounding code, producing copy-paste changes that miss reusable logic elsewhere (Hacker News discussion). A map the agent must consult is the cheapest correction: it puts the neighborhood in front of the model in compressed form instead of making it rediscover the neighborhood.
Here is a decision rule the first search result will not give you:
If a shared function has more than one caller in a different layer from its own definition, map call sites before you characterize. If it has exactly one caller in the same file, skip the map and write the characterization test directly.
The map is overhead. It pays off in proportion to the number of callers and the number of entry points that can reach them.



