Define a team
Guide (informative) · For: operators · Prereqs: Quickstart
The Quickstart gives you one agent. To run a specific team (your own
channels, your own agents, and exactly who may read and post where), describe it once in a
cotal.yaml and launch it with a single command.
What a manifest is
Section titled “What a manifest is”A manifest (cotal.yaml, kind: Mesh) is the declarative form of what you’d otherwise do by
hand: start a broker, seed channels, spawn agents, and mint each agent creds scoped to the channels
it may use. It is a convenience over the CLI and adds no wire concepts. Today it is single-space
(one space: per file).
It is channel-centric: you list the channels, and under each one name the agents that may read and post. Cotal inverts that into one least-privilege credential per agent, so the file reads the way you think about a team (“who’s in #review?”), while each agent only gets the access you granted.
Quickstart
Section titled “Quickstart”A complete, runnable manifest (two agents, two channels, no separate files):
apiVersion: cotal/v1kind: Meshspace: main # the default space, runnable fresh or right after `cotal up`agent: claude # the harness that runs each agent
agents: # inline personas (no external files needed) planner: instructions: Break the work into steps and post the plan. builder: instructions: Implement the smallest change that works.
channels: general: subscribe: [planner, builder] # auto-listen at boot allowPublish: [planner, builder] # may post: default-deny, so list everyone who posts review: subscribe: [planner] # only planner auto-listens allowSubscribe: [planner, builder] # builder MAY read #review, but isn't auto-subscribed allowPublish: [planner, builder]Save it as cotal.yaml and launch:
cotal topology view -f cotal.yaml # validate + render the access graph (no broker needed)cotal up -f cotal.yaml # broker + channels + agents, all freshcotal ps --space main # see the agents the manager bootedcotal web --space main # ...or watch it in the browsercotal down # stop the whole meshThe manifest introduces no access model of its own; the three verbs are the same ones
Cotal uses everywhere: subscribe (auto-listen at boot, and implicitly may read),
allowSubscribe (read; defaults to subscribe, must be a superset of it), and
allowPublish (post; default-deny: an empty or omitted list means nobody posts).
Above, builder may read #review but doesn’t auto-listen to it. Every top-level key,
the three agents: forms, channel cards, and the resolution rules are in the
manifest reference.
The command lifecycle
Section titled “The command lifecycle”| Command | What it does |
|---|---|
cotal topology view -f <file> |
Validate the file and render its access graph. Read-only: needs no broker, mutates nothing. Run it before you launch. |
cotal up -f <file> |
Bring up a fresh mesh: broker + seeded channels + booted agents. |
cotal spawn -f <file> |
Deploy a manifest additively onto a mesh that is already running. |
cotal down [-f <file>] |
Tear down (see “Tearing down” below). |
up -f and spawn -f accept --dry-run (preview the plan, change nothing). up -f also takes
--server / --host / --space / --runtime / --open to override the file for one run.
If a Cotal mesh is already running at the manifest’s broker address (e.g. the default
127.0.0.1:4222fromcotal up),up -frefuses; it never re-seeds a live broker. The check is on the address, not thespace:name. Runcotal downfirst, point the manifest at another address (broker: { servers: nats://127.0.0.1:14999 }, or--server), or usecotal spawn -fto deploy onto the running mesh.
Tearing down. A fresh mesh from up -f is torn down with plain cotal down: it owns the
whole space. An additive deploy from spawn -f is torn down with cotal down -f <file> (or
cotal down -f <file> --run <id>), which removes only that run’s agents and channels.
Ownership and teardown
Section titled “Ownership and teardown”The rule: up -f owns the whole space; spawn -f owns only what it created. Cotal only ever
tears down what it owns; foreign actors on a shared mesh are never touched.
- A fresh mesh from
up -f→cotal downstops all of it. - An additive deploy from
spawn -frecords a creation-only ledger (.cotal/manifests/<runId>.json) of exactly the channels and agents it added;cotal down -fremoves only those. The run id is printed byspawn -fand is the filename under.cotal/manifests/; pass it todown -f --run <id>when the file has changed since the deploy (an edited file no longer matches its ledger) or to finish a teardown that was retained.
down -f is deliberately conservative; it treats the ledger as untrusted and validates before
deleting: an owned agent is stopped only when the live agent’s recorded name and id match; an
owned channel is removed only when no other members remain; and if the broker is unreachable or
anything is uncertain, nothing remote is removed and the ledger is retained for a later
down -f --run <id>. It is local-only: run it from the checkout that created the run.
(.cotal/ holds creds, the ledger, and runtime artifacts: add it to your .gitignore; commit
your cotal.yaml and persona files, not what’s under it.)
Deploying onto a shared mesh (spawn -f)
Section titled “Deploying onto a shared mesh (spawn -f)”spawn -f is additive and never adopts or mutates anything it didn’t create. It classifies each
declared item against the live mesh:
| Item | Classification | Behaviour |
|---|---|---|
| Channel, brand-new | created + owned | Seeded and recorded in the ledger. |
| Channel, already present | exists-unmanaged |
Left untouched: card not mutated; the desired card is shown against the live one. |
| Agent, not yet created | will-create | Booted and recorded. |
| Agent, already created, unchanged | already-owned | No-op. |
| Agent, already created, policy changed | stale |
Exits non-zero unless --allow-stale <names> (then it restarts). |
Security. If an unmanaged actor already has read access to a channel you declare,
spawn -fprints a warning: an isolation conflict on a shared mesh. It is an explicit lower bound (presence plus the broker membership feed), not a guarantee that no other access exists.
Operating a manifest mesh
Section titled “Operating a manifest mesh”Every mesh-touching command resolves the broker from the mesh registry, so --space <name> is
enough; send, channels, console, web, the manifest verbs, and the manager control commands
(cotal ps / stop / attach, plus cotal spawn --detach) all reach a manifest mesh on any port
with no --server:
cotal ps --space research-team # finds research-team's broker via the registry--server remains an explicit override for an off-registry broker.
See manifest.md for the complete field reference and the resolution rules,
channels and permissions for the access model, and
agent files for the persona format the agents: entries point at.