Open your service catalog and pick a service at random. Check the owner, the dependencies, the on-call. There is a good chance at least one of those is wrong. Not because anyone was careless, but because the catalog was declared once and production kept moving.
This is the quiet failure at the center of every developer portal, and it is about to get expensive.
Declared, not observed
Almost every service catalog is populated by declaration. An engineer writes an entry, usually a YAML file, describing a service, its owner, and what it depends on. Backstage, Cortex, Compass, and Roadie are all built on this assumption: that humans will keep the catalog accurate.
They will not. Not because they are lazy, but because the work is invisible and never finished. A team reorganizes. A dependency shifts. A new service ships on a Friday. The catalog-info.yaml is correct the day it is written and drifts from there. In practice the gap opens within about two weeks, and it compounds.
You already know this, because you have lived it. The real dependency graph gets discovered during the incident, at 3am, when the catalog turns out to have been describing a system that no longer exists.
The stakes just changed
For years a stale catalog was a productivity tax. An engineer hit a wrong entry, lost twenty minutes, noticed, and corrected course. Annoying, survivable.
That calculus breaks the moment the reader of the catalog is no longer only human. Coding agents, deployment agents, and incident-response agents now read the catalog and act on what it says. The twenty-minute detour a person would have caught becomes an action taken in production, on a dependency that moved months ago.
This is the same shift we keep coming back to: the move from observe to control. Once software is acting on your production estate, the accuracy of the context it reads stops being a convenience and becomes a safety property. The catalog nobody maintains has quietly become the context layer every agent that touches production depends on.
Observe the catalog instead of declaring it
The fix is not more discipline. It is a different architecture.
A service catalog should be observed, not declared. Instead of asking humans to describe production in YAML, derive the catalog from what production is actually doing: read the repositories, the distributed traces, the deploy events, and the incident history, and reconcile the catalog on every change. Ownership comes from deploy history and contributor activity. Dependencies come from the observed call graph. Readiness is scored from real SLOs, alerts, and incidents. Blast radius is calculated from live topology.
If that sounds familiar, it is because it is the same foundation as the Production Context Graph. The service catalog is simply the graph made legible: the view a human or an agent reaches for when the question is "what is this service, who owns it, and what breaks if it fails." It is the context half of the Context and Control Model, made concrete.
Every fact carries where it came from
There is one more requirement, and it matters most now that agents are in the loop. Every fact in the catalog has to carry its provenance. Each dependency is labeled runtime (observed from the live call graph), synthesized (inferred from patterns), or intent (declared in code), each with a confidence score. Where there is no evidence, the catalog says so rather than filling the gap.
That is the difference between a catalog a human tolerates and one an agent can safely act on. A person can sense when an entry looks off. An agent needs the catalog to tell it, explicitly, how much to trust each fact before it acts.
Where to start
If you are running Backstage, Cortex, Compass, or Roadie, the catalog is not your enemy. The declaration model is. You can keep the portal and change how it stays true.
- See the approach applied to your own stack: the self-maintaining service catalog.
- Go deeper on the architecture and the migration path in the Service Catalog guide.
Your catalog is going to be read by something that acts on it. It should reflect what is running, not what someone declared six months ago.



