Files
buzz/crates/buzz-swarm
Eva fed802fa7d fix(swarm): route declared env sources and default private workdirs
A {env: VAR} source reached every harness, not only the agents that
declare it: sibling processes inherited a per-agent credential from the
parent environment. Remove every declared source (agent env, auth_tag,
and raw defaults, including disabled agents) from the inherited
environment; declarers still receive the value under the declared name.

Agents defaulted to the config directory as workdir, which is where
generated keys/ live, so each shell-capable agent started beside its
siblings' private keys. Default to workspaces/<name> beside the config,
created 0700 on start and reported by validate. The default now lives
only in the plan.

README: state exactly what shutdown cleans up. Swarm kills the harness's
own process group; buzz-acp moves agents into their own groups and stops
them on SIGTERM, so a forced shutdown or harness crash relies on host
containment.

Also build Secret directly and format executable().

Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
2026-09-23 14:09:29 -04:00
..

buzz-swarm

Run Buzz agents from a laptop, Kubernetes pod, EC2 instance, or another Linux/macOS host. Swarm resolves each agent's key, signs its NIP-OA owner attestation using the existing SDK, then starts one buzz-acp process per agent/relay pair. Every connection for an agent uses the same key and auth tag. There is no fixed relay-count limit.

The existing harness handles relay connections, conversations, agent sessions, and tools. Swarm adds only configuration, identity setup, and process supervision. It runs where you launch it; your deployment platform provisions the host, logs, and persistent storage.

Start

Install buzz-swarm and the existing agent runtime:

cargo install --path crates/buzz-swarm --locked
cargo install --path crates/sprig --locked
# Create Sprig's standard personality links in the directory on PATH:
cd "${CARGO_HOME:-$HOME/.cargo}/bin"
ln -s sprig buzz-acp
ln -s sprig buzz-agent
ln -s sprig buzz-dev-mcp

Separately installed buzz-acp, buzz-agent, and buzz-dev-mcp binaries also work. Create buzz-swarm.yaml:

owner:
  nsec: { env: BUZZ_OWNER_NSEC }
defaults:
  relays: [wss://team.example.com, wss://project.example.com]
agents:
  - name: helper
  - name: reviewer
    nsec: { file: keys/reviewer.nsec } # optional existing identity

Supply the owner's private key through the referenced environment variable or file. The runtime also needs its usual model/provider configuration and credentials, inherited from the environment or provided under env in YAML.

buzz-swarm --config /etc/buzz/swarm.yaml validate
buzz-swarm --config /etc/buzz/swarm.yaml
buzz-swarm --config /etc/buzz/swarm.yaml --only helper

Missing agent keys are generated once and saved as keys/<name>.nsec beside the config, with mode 0600. Subsequent runs reuse them. Mount that directory on persistent storage in ephemeral containers, or supply keys from your secret manager. validate checks swarm wiring, identities, and the harness executable; it writes no keys or directories and starts nothing. Generated preview identities are temporary. The runtime validates its own model and ACP settings when started.

The owner must have access to every target relay, and each relay must support NIP-OA. Profiles, channel membership, conversation history, and memory remain local to each community. Set a profile and invite agents to the relevant channels on each relay. The harness defaults to responding only to its owner.

Configuration

See buzz-swarm.example.yaml. Agent fields replace defaults; env merges by variable name. Unknown fields are rejected.

Fields Purpose
owner.nsec, owner.conditions Owner key and optional NIP-OA conditions
name, nsec, auth_tag, enabled Per-agent identity and selection
relays Non-empty relay list, shared or per agent
workdir Existing working directory; default workspaces/<name> beside the config, created 0700 on start
harness Executable path or name on PATH, default buzz-acp
restart, max_restarts on-failure (default), always, or never; default budget 10
env Existing ACP/agent options and credentials

Keys and environment values accept literals, {env: VARIABLE}, or {file: PATH}. Prefer references for secrets; file contents are trimmed. Swarm file paths resolve relative to its directory, with ~ expansion. Paths embedded inside runtime environment values retain the runtime's own semantics, usually relative to workdir.

Configure the runtime directly using its existing environment contract:

defaults:
  relays: [wss://team.example.com]
  env:
    BUZZ_AGENT_PROVIDER: anthropic
    BUZZ_AGENT_MODEL: your-model-id
    ANTHROPIC_API_KEY: {env: ANTHROPIC_API_KEY}
    BUZZ_ACP_SYSTEM_PROMPT: You are a helpful engineering teammate.
    BUZZ_ACP_RESPOND_TO: owner-only

Swarm defaults BUZZ_ACP_AGENT_COMMAND to buzz-agent and BUZZ_ACP_MCP_COMMAND to buzz-dev-mcp. Override these under env for another ACP runtime; an empty MCP command disables it. See buzz-acp --help and buzz-agent for runtime options. Ambient BUZZ_ACP_* settings are cleared; use YAML env to configure them explicitly. Model/provider environment variables are inherited unless the file names them as a source. Swarm owns relay and identity variables; YAML env cannot override them. Every {env: VARIABLE} source in the file, including in defaults and disabled agents, is removed from the inherited environment; only agents that declare it receive its value, under the declared name. Processes sharing an OS user still share that user's filesystem access.

An existing agent key and pre-signed auth_tag can be supplied without owner, so a remote execution host need not hold the owner's key. Swarm verifies each tag against its agent key, owner, and time conditions. All agents in a swarm must have the same owner. Duplicate identity/relay pairs are rejected. Separate deployments must also avoid running the same pair twice.

Lifecycle and verification

Swarm stays in the foreground. Harness stdout/stderr go directly to the caller; use the runtime or deployment platform for logging. Failures retry with 1–60 second backoff; the restart budget resets after 60 seconds of uptime. Clean exits stay ended under the default policy. Final failures produce exit code 1.

Ctrl-C or SIGTERM stops harness process groups with 15 seconds of grace (start --grace SECONDS). A second signal forces shutdown. Remaining members of the harness's own group are killed before its leader is reaped, including on natural exit. Swarm does not track processes a harness moves into other groups. The default buzz-acp does this for each agent and stops those groups itself on SIGTERM; after a forced shutdown or a harness crash they can outlive Swarm. Run Swarm under container or service containment when that matters. Workdirs are ordinary directories, not sandboxes.

cargo test -p buzz-swarm
cargo clippy -p buzz-swarm --all-targets -- -D warnings

Tests launch real fixture processes to check identity/tag reuse, key persistence, config-relative invocation, failure before launch, and process cleanup. They do not contact hosted relays or model providers.