> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vexa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Swarm (idea)

> Design proposal: agents spawning agents under human approval, coordinating over a shared workspace, with a heartbeat that makes silence the alarm.

<Note>
  **Status: idea.** Nothing on this page is implemented. It is a design proposal for how vexa's
  existing primitives compose into a multi-agent swarm — recorded now so implementation PRs have an
  invariant checklist to build against.
</Note>

**The whole idea in a paragraph:** the agent workspace lives in object storage; redis only carries.
Agents write through per file, checkpoint at turn boundaries, and refresh by manifest etag;
conditional puts reject stale writes. A swarm is defined by the concierge but identified by its
bundle prefix: the shared ledger is membership truth — join by writing your entry, leave by removing
it; a child mounted on the bundle is a member. Fast messages ride existing unit streams; slow
coordination goes through the ledger. Agents request agents via the dispatcher: standing grants
auto-approve, everything else becomes a Telegram card, and approval mints the child's token scope —
silence means denied. Every unit carries its parent chain. The concierge is the single human channel
and swarm manager (map, reaper, finalizer) but never a gatekeeper: it can misreport, not grant. A
fixed-schedule heartbeat reports ground truth — runtime state joined with ledger checkpoints, wedged
agents shown stale. No beat means the system is dead; the runtime watches the concierge itself.

***

A swarm is many agent units working the same problem. Everything below composes primitives that
already exist — the [runtime kernel](/architecture/execution) (spawn + supervise), the redis
`unit:<id>:in` / `unit:<id>:out` streams ([streaming](/architecture/streaming)), the durable
object-storage workspace, and the [governance](/architecture/governance) rule that untrusted
proposals pass through a human gate. The swarm layer is **protocol, not new infrastructure**.

## Swarm = shared ledger

A swarm is **defined by the concierge** (the human-comms agent, below) — it decides that a set of
agents constitutes a swarm working one problem — but **identified by shared state**: the swarm id is
the workspace bundle's object-storage prefix, joining is writing your entry to the coordination
ledger (etag puts make concurrent joins safe), leaving is removing it, and a spawned child mounted
on the same bundle is in the swarm by construction. Definition lives in the manager, truth lives in
the workspace — the concierge can never claim a swarm shape the ledger contradicts. There is no
separate membership service or discovery protocol; the concierge owns the swarm map (live bundles,
members, heartbeat schedule per swarm) and the three lifecycle rules:

* **Reaper** — while assembling the heartbeat, the concierge joins ledger entries against runtime
  state; an entry with no live unit and no recent checkpoint is moved to a tombstone section (kept,
  not deleted, so a resuming agent finds its claim context).
* **Finalizer** — last member out: the concierge promotes durable decisions into the knowledge
  base, archives the ledger, and stops that swarm's heartbeat.
* **Cross-swarm access** — touching *another* swarm's bundle is a grant-shaped event through the
  dispatcher (scoped token for that prefix), not a casual read; otherwise the boundary is only a
  convention.

## Shared workspace (durable plane)

The agent workspace lives in **object storage**, not redis — redis is the carrier, object storage
the store, same split as everywhere else in the [architecture](/architecture/architecture-as-code).

| Rule                          | What it means                                                                                                                |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Write-through                 | every local file write is async-put to the bundle; the local FS is just the working copy                                     |
| Checkpoint at turn boundaries | end of an agent turn = consistent snapshot; agents refresh (manifest etag → conditional GETs) at turn start                  |
| Conditional puts              | writes carry the etag they read; stale overwrites are rejected — this is the concurrency safety between siblings             |
| Coordination ledger           | a HANDOVER-style file *inside* the bundle carries claims, holds, decisions, and open questions; agents read it before acting |

The ledger doubles as each agent's status line — the heartbeat report (below) is assembled from it,
so there is no separate status API.

## Swarm messaging (live plane)

Fast agent↔agent messages ride the **existing** unit streams — a message envelope on
`unit:<id>:in`/`:out`, no new broker or protocol. Slow coordination (claims, decisions) goes through
the workspace ledger and is seen at turn boundaries. Two planes, two latencies, both already deployed.

## Agents requesting agents

Spawning is the runtime's mechanism (P11); *who may spawn what* is policy, owned by a **dispatcher**:

1. **Request** — parent emits `spawn.request.v1` on its `:out` stream: child spec, task, workspace
   scope, budget/TTL, parent id. Parents never call the runtime directly.
2. **Policy** — the dispatcher auto-approves inside a parent's standing grant (e.g. N read-only
   children within budget) and escalates everything else to the human.
3. **Human gate** — an approval card in Telegram: task summary, requester chain, cost, what the
   child can touch. Approve/deny via inline buttons carrying a signed request id.
4. **Grant** — on approve, the dispatcher spawns via the runtime and mints the child a
   [dispatch token](/architecture/execution) whose scope is *the approved scope*. Approval is
   **capability minting, not a yes/no** — the human decision is enforced by the same fail-closed
   token machinery, not by the child's good behavior.
5. **Lineage** — every unit carries its parent chain: kill-tree revocation, budget inheritance,
   and an audit trail ("this agent exists because X approved request Y at 14:32"), recorded in the
   workspace ledger.

Timeouts **fail closed**: no answer in N minutes ⇒ denied, parent re-plans. Standing approvals are
**grant objects in the workspace** — visible, revocable, not dispatcher special cases.

## Concierge & heartbeat

One designated unit — the **concierge** — is the single human channel (the same Telegram bot that
carries approval cards) and the **swarm manager**: it defines swarms, holds the swarm map, and runs
the lifecycle rules above. Humans reply in-thread; the concierge routes `human.message.v1` onto the
target unit's `:in` stream and confirms delivery. It remains manager, not gatekeeper — spawn
approvals still flow through the dispatcher's token minting, so a compromised concierge can
misreport but cannot grant capabilities.

The heartbeat is a **dead-man's switch**: it fires on a fixed schedule, and the human contract is
simply *no message at the expected time ⇒ the system is down*. Silence is the alarm — a dead system
cannot send a failure notification, so none is designed.

* The report is assembled from **ground truth**, not self-reports: runtime supervision state
  (alive/restarts) joined with each agent's last workspace-ledger checkpoint. An alive-but-wedged
  agent shows as **stale** — the common failure, which liveness checks alone miss.
* Pending approvals re-surface in every beat until resolved.
* The **runtime owns the timer** and sends a bare "concierge down" if the concierge misses its
  slot, so the concierge is not a single point of silence.

```
🫀 swarm · 14:00 · all nominal
Units: 4 alive, 0 stale, 1 finished since last beat
• indexer — 3,120/8,400 files (13:58)
• doc-writer — drafting architecture page (13:55)
Approvals pending: 1 (spawn: doc-reviewer, waiting 12m)
Budget: 340k/1M tokens today
```

## Message schemas

| Schema             | Carrier         | Purpose                                                       |
| ------------------ | --------------- | ------------------------------------------------------------- |
| `spawn.request.v1` | `unit:<id>:out` | parent asks for a child (spec, scope, budget, lineage)        |
| `spawn.grant.v1`   | `unit:<id>:in`  | dispatcher's answer: granted (token scope) / denied / timeout |
| `human.message.v1` | `unit:<id>:in`  | human → agent, routed by the concierge, logged to the ledger  |

Unknown message types are ignored, same forward-compatibility rule as `acts.v1`.
