Skip to content

Orchestration Governance

Orchestration governance gates composition, not primitives. A single agent browsing on its own, writing to a canvas it holds editor on, or sending one mesh message is never gated by this layer — each of those already carries its own permission check (a canvas role, a mesh capability), and passing that check is the end of the story for a single action taken alone.

Why composition is the thing that needs a separate gate

A single action's own permission check can only ever reason about that one action. It has no way to see that the action is the second hop in a chain, that a chain has already touched three other agents, or that this run also included a browser action earlier. Those are properties of a sequence of actions, not of any one of them — so no per-action check, however strict, can catch them. Governance exists specifically to reason about the sequence: agent A triggers agent B and B goes on to take a gated action; a chain that reaches a third agent; or a single run that mixes a browser action with an agent trigger. That last case is deliberately included even though the browser capability itself is roadmap (see Entitlements), because the composition risk exists independent of whether the mixed-in action is fully shipped yet.

Why two independent gates instead of one

Forming a chain requires both a cloud entitlement (nexus.orchestration) and a local setting to be enabled — and both default off. Either one being closed is enough to block every chain. Requiring two independent keys, controlled from two different places, means neither a cloud-side entitlement flip nor a local misconfiguration is by itself sufficient to enable autonomous chains — closing either one is a real, immediate stop, not a suggestion the other side can override.

Why the controls are coarse-grained today

Maximum chain depth, maximum distinct agents per chain, an orchestrator allowlist that starts empty, an optional per-hop approval setting, and a stop-all control are the levers available now. An empty allowlist by default means nothing can orchestrate until it's explicitly added — the same default-deny posture the canvas takes on roles. Depth and breadth limits bound the worst case of a runaway chain even when everything else is configured to allow it. The stop-all control exists because none of the other controls are useful in the middle of an incident if there isn't also a way to halt everything already in flight.

Why settings are re-read at enforcement time, not cached

Turning the local setting off takes effect on the very next hop, with no restart required. A cached copy of "is orchestration currently allowed" would mean an operator's decision to stop it mid-incident wouldn't actually take hold until whatever held it cached refreshed — which defeats the purpose of having a fast, local, no-cloud-round-trip control in the first place.

Why denial reasons are distinguishable

A chain can be denied for any of: no entitlement, the local setting disabled, depth exceeded, breadth exceeded, the orchestrator not on the allowlist, or a global stop in effect. Each of those demands a different fix — buying an entitlement is not the same action as raising a limit, and neither is the same as realizing someone hit stop-all five minutes ago. Collapsing all six into one generic "denied" would leave the person debugging it guessing which of six unrelated things to go check.

Roadmap

The per-hop approval prompt and a live chain-activity view are not yet built. Today's controls — depth, breadth, the allowlist, the two entitlement/setting gates, and stop-all — are enforced without a human-in-the-loop confirmation step at each hop, and without a live view of what's currently running. Until those ship, the coarse controls above are the only lever; there is no per-hop pause point to fall back on.

Built with purpose.