Cross-repo links
By the end of this page you will know how the services in one application actually talk to each other, and what the analysis could not resolve.
Prerequisites
- An application with two or more sources, ingested (Attach sources).
- Admin or Developer role.
Why this exists
Each repository on its own tells you nothing about how it is used. The link report joins them: it matches outbound HTTP calls to the endpoints that serve them, and message publishers to the consumers that receive them.
This only works because all the repositories are in one application. It is the main reason to keep them together.
The six numbers
| Statistic | What it counts |
|---|---|
| API links | Calls from one repository resolved to an endpoint in another |
| Message flows | Publishers matched to consumers |
| Queue bindings | The exchange-to-queue wiring that connects them |
| Unresolved calls | Outbound calls with no known target |
| Messaging gaps | Published messages nobody consumes, or consumers nobody feeds |
| Shared data | Tables or stores more than one repository touches |
The last three are findings, not failures. An unresolved call might be a third-party API, or it might be a service nobody told you about. A published message nobody consumes is either dead code or a missing subscriber.
Reading the table
Caller → Calls → Served by → Match.
Three behaviours are worth knowing, because each one looks like a bug until you know it is not.
Routes are matched by position, not by name
GET /api/products/{productId} matches GET /api/products/{id:guid} in another repository. The parameter names differ; the shape does not. Templates are normalised by position before matching.
An ambiguous call is left unlinked, on purpose
When a call could be served by endpoints in two different repositories and nothing distinguishes them, no edge is drawn and the call is reported as ambiguous.
This is deliberate, and it is the right trade. An agent treats an edge as fact. A wrong cross-repo link sends it confidently to the wrong service, which costs far more than a missing link that shows up as “unresolved” and gets a human’s attention.
Gaps are reported rather than hidden
A call with no target and a message with no consumer are listed, not quietly dropped. That is often the most useful part of the report.
When nothing crosses a boundary
The empty state says it plainly: “Either this application has one repo, or its services genuinely do not call each other. Both are legitimate answers.”
A set of services that share a database but never call each other is a real architecture, and an empty link report is the correct description of it.
Common issues
- “This version was not linked” — The ingest completed before the linking stage, or the application has one source.
- Everything is unresolved — The calling code uses a client the detectors do not recognise, or the serving repository is not attached to this application.
- A link you know exists is missing — Check whether the call is reported as ambiguous. Two candidate endpoints and nothing to choose between them means no edge.
- Message flows are empty but you use a broker — Queue bindings are what join publishers to consumers. If the binding configuration is not in any attached repository, the two halves cannot be matched.