Appearance
Runtime topology view
Director's tree is derived state. Every node you see is computed by DirectorRuntimeAdapter from a small set of read ops issued by DirectorApp. This page documents how that composition works, so an operator can read the tree honestly.
Bus is authority
Director is the canonical example of P1.43 — bus actors are the substrate's authority; HTTP only at unavoidable boundaries. Every input below is a bus invocation against a system.* actor. Director does not call GET /api/runtimes, GET /api/apps, or any inventory HTTP endpoint. The HTTP surface Director uses is the closed list (browser bootstrap, NATS-WS upgrade, static asset serving); inventory truth lives on the bus.
If you find a Director adapter calling an HTTP endpoint for inventory data, that is a bug, not a feature.
Inputs
DirectorRuntimeAdapter.loadCatalogWithRuntimes makes two parallel calls:
| Op | What it returns |
|---|---|
system.registry registry.list | Logical mount claims with their providers (logicalMount, providers[] with localMount, providerRuntimeId, runtimeWireRoot, componentType, metadata). |
system.runtimes runtimes.registered | Live runtime records with runtimeId, type, app, sessionMount, actorCount, lastHeartbeat, inventory[] of mounted actors. |
buildCatalogFromBindings then merges the two: each registry binding becomes a CatalogEntry whose mount is the canonical claim, localMount is what the runtime actually serves, runtimeRoot is the wire root, and runtimeId connects to the runtime record. If a runtime advertised an inventory[] for that mount, its type, description, and hasChildren are preferred over the binding's own metadata.
The "three names" rule
For every visible node Director keeps three pieces of identity, intentionally not collapsed:
- Binding name (canonical mount):
system.registry,chat.conversation,system.agents.memory. This is the operator-stable address. - Runtime identity:
runtime://chat-dev-01— which process serves it. - Wire prefix (target root): the bus root advertised by the runtime (
runtime.sessionMountorbinding.runtimeWireRoot).
DirectorTopology (src/services/DirectorTopology.ts) renders that into the user-facing strings:
ts
{
browserRoot, authorityRoot, runtimeRoot, platformRoot,
browserLabel, // "signed in as <authorityRoot>"
runtimeLabel // "runtime: <runtimeRoot>" or "no live runtime attached"
}The top bar of director-app shows browserLabel and runtimeLabel so an operator can immediately distinguish "I am signed in as X but the page is talking to a different runtime root Y" from "the page is hitting its own browser realm".
Tree construction
DirectorRuntimeAdapter.buildTree(root, catalog) (line ~758) builds an IDirectorTreeNode[] rooted on the authority root by:
- Sorting catalog entries lexicographically by mount.
- Splitting each canonical mount on
.and creating intermediate nodes for every prefix (system.observabilityis a parent node even if it isn't itself a binding). - Setting
componentClasson the leaf to the catalog entry'stype. - Copying through
purpose,promptable,regime,runtimeRoot,runtimeId,runtimeType,hasChildren.
buildVisibleRootTree and _graftRuntimeInventoryIntoVisibleRoots then overlay the runtime-inventory branch — for runtimes that report inventoryMode: 'embedded' or 'pull', child mounts that aren't already in the registry catalog get attached under a synthetic node so the operator can still see what the runtime actually has mounted.
What "no live runtime attached" means
DirectorTopology chooses runtimeLabel based on runtimeRoot. Cases:
- No runtime root.
runtimeRootempty →"no live runtime attached for <authorityRoot>". The browser bootstrap could not point Director at any runtime. Usually means: the gateway responded butsystem.runtimesis empty, or the page navigated before runtimes were ready, or the authority root has no runtimes registered to it. - Leaf-targeted.
targetKind === 'leaf'→"attached runtime for <authorityRoot>". The bootstrap targeted a downstream leaf rather than the platform root. - Normal.
"runtime: <runtimeRoot>", optionally followed by"via: <platformRoot>"if a platform forwarder is in front.
What this view cannot show
- Runtimes that exist but did not register with
system.runtimes. Anything fully out-of-band (manualnodeprocesses, Smithers experiments) won't appear. - Provider/account topology. Director sees the wire root, not who owns the authority root. For account/Space context, see matrix-edge / matrix-web Devices pages.
- Runtime resource usage. No CPU/memory in the tree.
system.observability.metrics(target) would feed that, but the metrics rendering is not in the current Director UI.
See also
Source:
projects/matrix-3/packages/director/src/services/DirectorTopology.ts(lines 1-76),DirectorRuntimeAdapter.ts(lines 209-525, 758-862), andtypes.ts(IDirectorTreeNode,IDirectorRuntimeEntry).