Mapping services once is straightforward. You write the integrations, the graph populates, and it looks complete. The hard part starts three months later when six teams have shipped changes, two services have been deprecated, and four new ones have formed dependencies nobody recorded. Keeping the graph accurate over time is a different problem from building it.
Why graphs go stale
The obvious answer is that documentation does not keep up with code. That is true but it is not the whole story. Even teams with good documentation discipline end up with stale dependency maps, because the map is maintained separately from the system it describes.
Every time a service adds a new upstream dependency, someone has to remember to update the graph. Most of the time they do not, not because they are careless but because they are focused on shipping the change. The graph drifts gradually and quietly until an incident surfaces a dependency nobody knew existed.
Continuous discovery
The approach we landed on treats the dependency graph as an output of the running system rather than a document maintained alongside it. STRAND discovers dependencies from live traffic, service mesh data, and infrastructure configuration continuously. The graph updates as the system changes, not when someone remembers to update it.
This sounds obvious in retrospect. The harder part was making discovery reliable enough that engineers would actually trust the graph. A map with gaps is worse than no map at all if it gives teams false confidence about what they know.
We spent a significant amount of time on edge cases. Services that only communicate under specific conditions. Async dependencies through message queues that do not show up in synchronous traffic analysis. Infrastructure-level dependencies that exist outside the service mesh entirely. Each one required a different discovery mechanism.
Trust is the hard part
The graph is only useful if engineers trust it enough to act on it. That trust gets built slowly and lost quickly. One incident where the graph showed a clean blast radius and the actual impact was wider than expected will set adoption back significantly.
We track graph accuracy continuously and surface confidence indicators alongside dependency data. When discovery has not seen traffic on a dependency recently, that gets flagged. When a service has changed in ways that might have introduced new dependencies since the last discovery cycle, that gets flagged too.
The goal is not a perfect graph. It is a graph that is honest about what it knows and what it is less certain about, so engineers can make informed decisions rather than trusting something that looks complete but is not.