Published agents
Publishing turns a working definition into a locked, versioned, sealed
agent — the shape you share and reproduce. A published agent lives in the
AgentRegistry, keyed by (tenant, name, version), and it is the deterministic
counterpart of the mutable working catalog. This page is mode 2 in depth: the
registry’s immutability and visibility contract, what publishing seals, how a
start consumes it, exposure policy, versioning, and the shipped examples. For the
two-modes overview, start at Agent configuration.
The registry contract
Section titled “The registry contract”A published record is addressed by an operator-meaningful name and a version
(major.minor.patch, ordered numerically). Two properties define it:
- Immutable per version. A
(name, version)that already exists is never overwritten — a re-publish is a typedVersionExistserror, not a silent replace. A session pinned tov1keeps runningv1afterv2publishes. - A new version is a new publish. There is no in-place edit; changing a
published shape means publishing a fresh version. A start pins an exact
(name, version)— there is no “give me latest” for agents, so the shape a caller gets is always the one they named.
The published-agent registry is one of a family of three sibling registries that share this exact publish/resolve contract — alongside the published-skill registry (immutable skill versions) and the strategy-configuration registry (addressable coordination configs). Each is keyed by an identity plus a version, each is immutable per version, and each carries the same cross-tenant visibility posture below. Publishing an agent draws on the other two.
Cross-tenant visibility
Section titled “Cross-tenant visibility”Every published record carries an AllowedTenants scope chosen at publish time.
Own-tenant reads (list, get) stay own-tenant. The one path that can cross tenants
is a single audited resolve, and it is deliberately built to leak nothing:
- One audited boundary. A resolve tries the caller’s own tenant first; only on a miss does it consult foreign records, and only those whose scope permits the caller. The crossing is logged server-side as an audit signal the caller’s result never carries.
- No existence oracle. A record the caller may not see returns the same not-found as a record that does not exist. A probe cannot distinguish “absent” from “present but forbidden,” so it cannot learn whether another tenant’s agent exists — the same opacity the identity & authorization plane enforces for tenant isolation.
Publish-time sealing
Section titled “Publish-time sealing”Publishing is a sealing act, and it runs before anything is stored: the
registry resolves the manifest’s whole asset closure to pinned, published
versions and embeds the resolved content — not just the pins — into a
PublishedAssetBundle on the record. Embedding the content is what makes a
published start self-contained, even a permitted cross-tenant one.
Two things are sealed:
- The skill closure — the manifest’s default skills unioned with every role’s skills, deduplicated, each pinned to its latest published version via the published-skill registry, with the skill body sealed into the bundle.
- The strategy-configuration lock — when the manifest binds one, its coordination skeleton and parameters are resolved and sealed too (see Coordination loops).
Resolution is fail-closed. If any referenced skill isn’t published, or the strategy reference doesn’t resolve, the publish aborts with a typed error and persists nothing — there is no half-sealed record.
An agent that references no skills and binds no strategy still seals an empty bundle — a published record always carries one, so a start never has to fall back to live resolution.
The sealed bundle at start
Section titled “The sealed bundle at start”Starting from a published agent composes the session exclusively from the sealed bundle. Skills come from the bundle’s frozen bodies; the coordination loop comes from the bundle’s sealed strategy — there is no live catalog or registry round-trip, so no edit you make after publishing can reach a published start.
Because the shape is sealed, a published start cannot re-open it. The only inputs a caller may supply are invocation-time ones — the goal, a budget, stall posture, an operator prompt, the VMAO caps, a test-run flag. Supplying a shape-internal field a published agent already locks (a model, tools, a strategy, role config, a context binding) is refused with a typed error before any event is emitted. The registry rejects the mismatched cases the same way: naming both a published agent and a working manifest at once, a malformed reference, or a legacy record whose bundle predates sealing (its fix is to re-publish). This is the deliberate inverse of a live launch, where the request folds over the manifest — here the request may only invoke a shape it cannot alter.
Exposure policy
Section titled “Exposure policy”Visibility (AllowedTenants) says who may resolve a record. Exposure is a
separate, coarser switch — Internal by default, or Served — that says whether
a record is offered for serving at all. It is registry-serving metadata, not part
of the manifest and not part of the sealed bundle, and it is the one attribute
you can flip after publish without cutting a new version.
Exposure is the surface a future agent-to-agent federation would project an agent
card from — the served, visibility-permitted records. That projection is roadmap
direction, not shipped today; exposure exists now as the honest, fail-closed
switch it will build on (an unrecognized stored value resolves to Internal,
never to served).
The shipped shapes
Section titled “The shipped shapes”The substrate seeds two published Deep Research agents at boot, sealed through the real publish path so they carry genuine bundles — the concrete example of one base agent published as multiple locked shapes:
| Published agent | Locks | Coordination loop |
|---|---|---|
io.descoped/deep-research | the VMAO strategy configuration | VMAO — plan, execute, verify, replan |
io.descoped/deep-research-mad | the debate strategy configuration | Debate — N agents argue over R rounds |
Both bind the same research worker, validator, and synthesizer skills; they differ only in the coordination loop they seal — the same domain under two loops, which is exactly what separating the agent from its strategy buys. Both ship scoped to the dev tenant only. The shipped strategy configurations and their parameters have their canonical home on Coordination loops; the published agents lock them.
The console surfaces
Section titled “The console surfaces”The operator console fronts the whole mode-2 lifecycle:
- Publish pre-flight — from an agent’s detail view, a publish panel shows the skill closure that will be sealed with each skill’s published status, a visibility-scope picker, and the name and version to publish. The pre-flight is advisory — it shows what your own tenant can see; the server-side resolve makes the final, fail-closed decision.
- Published agents — the list of published pins, grouped by name with their retained versions, each showing its visibility scope (blanked to “not disclosed” on a cross-tenant read, never revealing another tenant’s scope) and its exposure toggle.
- Launch from published — a start form that offers only the invocation-open inputs, with no tool, model, or role pickers — a direct reflection of the locked-shape contract.
See the operator console for the walkthrough, and Deep Research for the shipped agents as worked examples.
Where this shows up
Section titled “Where this shows up”- Operate: the operator console runs the publish pre-flight, lists pins, and launches from a published agent.
- Build: Deep Research is the shipped published shape.
- Reference:
apomesh-substrate-catalogowns the registry family;apomesh-orchestratorowns the publish and start workflows.