System

Agent Swarm

A self-hosted, multi-host runtime where tools are the platform and agents are compositions

Rust · 95,000 lines · 23 cratesSandboxed Docker seatsLocal open-weight and frontier models
Every call · one frozen pipeline A tool contributes one step, its core behaviour; the other eleven belong to the platform.
A persona is a declaration
toolspolicyworkspaceprofile
29personas, each a composition
The safe path is the only path
  • 12steps every tool call passes through, in a frozen order
  • 40declarative tools, none without golden and attack fixtures
  • 0commits to the main repository across three coding-agent runs on a local model
  • 60+locked decisions in a 2,000-line master plan

Every new agent an organisation adds tends to arrive with its own tooling, its own permissions and its own messaging, and every one of those is a new place for something to go wrong. I wanted to build the safety machinery once, make it the only path, and make adding an agent a matter of declaring one. Agent Swarm is that runtime. Tools are the platform: every action any agent takes passes through one frozen, tested pipeline. The runtime runs coding, analysis and service agents on local open-source models and on frontier models, spans more than one machine, and its persona library and container launcher start the seats of my governance platform.

The idea

Validation, authorisation, rate limits, quotas, retries, sanitisation, audit and observation happen in the same order for every call, and that order cannot change without sign-off. A tool contributes only its core behaviour. Most tools are YAML declarations. No tool enters the catalog without golden fixtures and attack fixtures, and the build fails otherwise. The full account is Tools are the platform.

I froze the pipeline order. Less flexibility, and exactly one way an action happens.

Agents are compositions. A persona is a tool subset, a policy, a workspace and a container or execution profile, and a new one is a declaration. An agent cannot call what it was not granted and never holds a credential it does not need.

What a persona is made of
toolspolicyworkspaceprofile
a granted subset of the shared cataloglimits and approvalsits own files onlycontainer or session
What it can never do
An ungranted tool
An unneeded credential
A model address or key
Outside the pipeline
every attempt stops at the same boundary

What I built

An agentic loop over a provider-neutral model layer with an endpoint pool and a terms-of-service firewall that decides which traffic may reach which provider. The loop pattern was adapted from an open-source project.

An agent registry with heartbeats, a reaper and drift detection, plus signed agent-to-agent messaging with chain-depth checks, so agents find and call one another and every message is attributable.

A persona launcher that starts sandboxed containers per persona with scoped tokens, workspaces and budgets.

Cross-host federation, and a durability path that turns agent actions into searchable observations in my memory service.

Hash-pinned tool catalogs with drift detection: every host runs the same approved catalog, checked by content hash, with notification-driven updates that fall back to polling under measured saturation thresholds and hysteresis so a host never flaps.

One host's catalog updates over time
notification-drivensaturated: pollingnotifications again
fast path: a database notification per catalog change
fallback: measured saturation switches to polling; hysteresis delays the switch back

A carve gate that keeps product crates free of estate-specific imports, so the runtime is separable from the estate it grew up in.

The launcher alone is about 23,000 lines, and the catalog carries 50 golden fixtures.

Across hosts

One work order can fan out into hundreds of agents on one machine or thousands across hosts I control, from a workstation to a data centre, coordinated over a signed agent-to-agent mesh in which every message is checked locally for sub-millisecond peer authorisation with no central round-trip. Each agent heartbeats its presence to the registry, and in-flight work from an agent that stops heartbeating is reclaimed automatically. Agents never hold a model address or key; the runtime proxies every model call through a per-turn router over local GPU nodes and registered bridges. Secrets never touch disk: a broker releases only what a specific action needs, when it needs it.

Network · egress allow-list, a budget per agent
Container · dropped privileges, read-only root filesystem
Agentno model address, no key on disk; model calls leave through the per-turn router, one secret arrives for one action

The judgment in it

I left one tool kind declared but not runnable instead of releasing it with the pipeline partly bypassed.

I required fixtures for trivial tools, because exceptions are where the holes are.

For the coding agent's acceptance runs I chose a narrow scripted task over an impressive demo, so the security property got tested instead of the model's cleverness. A failing-test run that stopped without pushing counted as a pass. The runs are told in A coding agent that never holds the keys.

Run 1
edittestcommitpushmerge req.
Run 2
edittestcommitpushmerge req.
Run 3
edittestcommitpushmerge req.
merge requests opened by the gatekeeper in runs 1 and 2run 3: tests failed, nothing pushed

I held a phase at conditional pass on two failed gates instead of narrowing the criteria, and had the missing tooling built afterwards.

What it demonstrates

Making the safe path the only path for agent actions; defence-in-depth sandboxing; reliability engineering for distributed configuration; and least-privilege design for autonomous coding agents, proven on a local model.

Stories

Tools are the platform · A coding agent that never holds the keys · Separation of duties for AI work

Technologies

Rust · Tokio · Docker · Redis Streams · PostgreSQL · YAML tool definitions · JSON Schema · RS256-signed envelopes · Open-weight local models on vLLM · Content hashing