Cotal
DocsAPI Reference
Build integrationsEmbedding reference

Delegated seat contracts

Delegated seats outside the manager's filesystem

The portable lifecycle bootstrap design and SPEC §13.17 define how a managed agent that enrollManagedAgent already enrolled starts in a child that cannot see the manager's filesystem. The ordinary spawn path writes the token and sentinel under the manager's workspace root and hands the runtime a launch whose bearer command and material file are paths on that filesystem, so such a child needs this path instead.

Runtime handoff

The delegation boundary is one optional runtime method. A runtime that implements Runtime.spawnDelegated(launch, handoff) receives two values and no paths: a DelegatedSeatLaunch (connector name, persona text, managerInstanceId, model and the other launch choices) and a ManagedLifecycleHandoff (space, owner, actor, the host-chosen lifecycleUid, broker and IdP pins, the pinned exchange base, the sentinel, the channel lists, and the raw actor token). The manager enrolls once, as it does today, and builds the handoff from what it holds. It never sends the token to the host, never copies a file from its workspace or secret store, and never builds a local launch for that seat. No signer, issuer or callout record, loopback capability, provisioner or manager credential, control token, or manager path crosses. A spawn choice that only the manager's host can honour is refused before enrollment: --resume, a manifest agent's continuity: exact, --cwd, and any shared MCP server, whether from --share-tools or the config default (--share-tools none passes).

A delegated manager also refuses a caller-supplied persona config override in resolve-agent, spawn and direct Manager.startAgent calls. The shared persona resolver refuses before checking or reading that path, with failed-precondition on the wire and one fixed execution-mode message. Pass a named catalog persona instead. This does not change locally executing managers. A resolved manifest can still use its own validated, host-materialized persona resource. The wire schemas accept no internal resolved field that could bypass the config refusal.

Child bootstrap

The runtime creates one provider resource under managedRuntimeKey(target), writes the handoff into it as one 0600 file and the persona beside it, and runs the stock bootstrap there: cotal spawn --config <persona-file> --space <space> --name <actor> --expect-owner <owner> --expect-lifecycle-uid <uid> with COTAL_MANAGED_HANDOFF_FILE naming the file and COTAL_MANAGER_INSTANCE naming the launching manager. delegatedSeatCommand builds that argv and env. cotal spawn reads the file into memory, deletes it and drops the variable before it parses flags, prints help or loads extensions, so every outcome, a refusal of its own flags included, leaves no file. It refuses before any broker connection or exchange request when COTAL_MANAGER_INSTANCE is absent (COTAL_MANAGED_HANDOFF_FILE requires COTAL_MANAGER_INSTANCE; DelegatedSeatLaunch.managerInstanceId is required and a newer CLI child under an older manager or runtime refuses every delegated launch, so managers and the CLI must be upgraded together) or malformed, or when the space, owner, actor, or lifecycle UID differ from the expected values, and then runs the enrollment-redeem consumer: it registers the mesh in its own home, writes the token to its own 0600 file, and exchanges it through agent-bearer --exchange-url unchanged. It never enrolls, redeems, or mints a token or UID.

Provider closure guarantees

Readiness is still mesh presence. A create whose answer is lost leaves the handle running, so the launch settles uncertain and stays held; the manager never retries it. A provider read that finds no resource under the key is not an exit, because the create may still land. Every close by managedRuntimeKey is fenced: it completes only once the create was answered or the provider refuses any later create under the key. A provider that names its own resources may run the create as a durable operation keyed by managedRuntimeKey and close through the identifier its authenticated create response returned, kept where the host can read it without the manager. Only that response binds an identifier to the key; one derived from the key or found by name or listing is never closed or adopted, and while the response is unknown the launch stays held. Every stop, the reap of a child whose parent exited and Manager.stop({ withAgents: true }) included, runs prepareAgentRetirement for the UID-exact target, then stop() on the handle spawnDelegated returned, then the terminal barrier. preparePreservation refuses a cut that holds a delegated seat, and a Manager.stop() after a refused cut retires the seat through the same steps. After the manager is gone the host runs the same steps, makes the same fenced close by managedRuntimeKey, and finishes at MANAGED_RETIRE_PATH. Supply spawnDelegated only from a runtime whose host can make that fenced close without the manager. The enrollment redeem (COTAL_ENROLLMENT_FILE) stays for lifecycles whose token the host generated itself; a host cannot mint one for a manager-enrolled lifecycle because it holds only the digest.

Delegated recovery contracts

Core exports RemoteDelegatedRecoveryRequest, RemoteDelegatedRecoveryResult, RemoteDelegatedRecoveryLaunchRequest, their closed parsers, and parseDelegatedRecoveryDescriptor. Runtime.rebindDelegated describes an optional same-child rebind. These are contracts for SPEC §13.18, not an enabled recovery path. The current Manager does not call the new method or reconstruct delegated rows. Its public adoptRuntimeHandle returns a native handle without inserting a managed row.

A supporting host retains the descriptor in the original user-intent consuming CAS, binds each claim to the original instance and current registration, and supplies complete fenced scans. The manager needs its original persistent secret store and a runtime that can verify the same child execution after process loss. It must retain held aliases before reconciling accepted goals. Missing storage or unverified child identity keeps recovery held; neither permits another launch. The request parsers validate data, not fresh host authority or durable transactions. Existing hosts continue to refuse the opt-in launch extension rather than silently ignore it.

Refused launch choices

Host-dependent launch choices are refused before enrollment. See the detailed contract.

Retirement order

Delegated stop and retirement follow the provider closure guarantees. See the detailed contract.

On this page