Quick start
From nothing to a running agent fleet. The open-source path needs one command and about ten minutes; the enterprise path adds a cortex and one more.
Prerequisites #
| Thing | Needed for | If missing |
|---|---|---|
curl | The installer itself | Hard requirement |
| Node.js ≥ 18 | The npm install path; required for enterprise | Installer falls back to the standalone binary |
git | Identity detection and the meta-fleet scaffold | Both are skipped, nothing fails |
| Docker | Running a RelataDB cortex locally | Enterprise runs on the file backend instead |
| An agent CLI | Actually running the fleet | Claude Code, opencode or goose — at least one |
fleetsmith itself runs on Windows and ships a Windows binary. The
installer is POSIX shell, so run it under WSL2 or Git Bash. RelataDB is macOS and
Linux only — use Docker Desktop or WSL2 for the enterprise cortex.
Install #
curl -fsSL https://infinia-harness.adid.dev/install.sh | sh
curl -fsSL https://infinia-harness.adid.dev/install.sh | sh -s -- --edition ee
Then load what it wrote:
. ~/.fleetsmith/env.sh
fleetsmith version
The installer does five things, in this order:
- Detects your OS, architecture, Node version and whether Docker is running.
- Installs
fleetsmith— via npm if Node ≥ 18 is present, otherwise as a single self-contained binary. - Works out your identity on the grid from
git config user.email. - For enterprise: installs
fleetsmith-eeand optionally starts a RelataDB cortex in Docker. - Writes
~/.fleetsmith/env.shat mode 600 — it can hold a cortex token.
It is plain POSIX shell served from this site — read install.sh.
--dry-run prints every action it would take and performs none of them.
How it asks #
Every decision can be answered three ways, in this order of precedence:
| # | Way | Example |
|---|---|---|
| 1 | Environment variable | FLEETSMITH_EDITION=ee sh install.sh |
| 2 | Command-line flag | sh install.sh --edition ee |
| 3 | A question with a safe default | Edition (oss or ee) [oss]: |
When there is no terminal to ask on — a pipeline, CI, a Dockerfile — every question
silently takes its default and the run is fully non-interactive. The defaults are chosen
so the no-input path always produces a working open-source install and never writes
outside your home directory. --yes forces that behaviour even when a
terminal is available.
Environment reference #
What to install
Open source, or open source plus the enterprise Intelligence Grid.
A specific version, e.g. 0.7.0. Applies to both packages.
auto picks npm when Node ≥ 18 and npm are present, otherwise the
standalone binary. Enterprise forces npm: it is a normal package that
core loads by module resolution, which a single-file binary cannot do.
Where the standalone binary lands. Ignored on the npm path.
The cortex
auto resolves to existing if RELATA_URL is
already set, docker if Docker is running, otherwise none.
Always none for the open-source edition.
binary installs the signed v2.0.0 release tarball instead of a container.
relatadb/RelataDB is a private repository, so that path needs the GitHub
CLI authenticated as an account with access — the installer checks for it and points
you at Docker rather than attempting a download that cannot succeed.
An existing cortex to point at. Set together with RELATA_TOKEN — a lone
one of the pair is refused rather than half-applied, because it is almost always a
half-exported environment variable.
Your own token, not a shared one, in production. On the Docker path the installer generates one for you and writes it into the env file.
Pinned on purpose. latest moving under a running grid is not a feature.
Host port for the container. The container always listens on 9090 internally.
If a container of this name already exists, the installer reuses it and recovers its bearer token rather than clobbering your data.
Host directory mounted at /data. Survives container recreation.
free is one tenant and a 10 GB cap — right for evaluation and small
teams. server is the recommended default for one org doing real work and
needs a paid, node-hash-bound license.
Wiring
How your work is labelled for teammates. Local-only in the open-source edition.
Copy the bundled meta-fleet into a project's .claude/, so you can say
"build a harness for this project" in Claude Code. Never overwrites an
existing .claude/.
Where to scaffold.
Rewritten on every install. Written at mode 600.
Append a line sourcing the env file to your shell rc. Off by default: it edits a file you own.
Accept every default and ask nothing. Same as --yes.
Never open the terminal, even if one is available.
Print every action, take none. Same as --dry-run.
Your first fleet #
Pick a pattern
From the shape of your work, not from taste. If unsure, pipeline.
fleetsmith patterns
Scaffold a spec
The domain string matters — it drives every generated agent's prompt.
fleetsmith init review-fleet \
--pattern generate-verify \
--domain "reviewing pull requests in a Rust payments service"
Edit and validate
Open fleet.yaml and make the roles real. The validator checks design
smells — parallel writers, skill descriptions that would silently truncate, phases
that split one context in two — not just the schema.
fleetsmith validate fleet.yaml
Compile
All three targets, or just the one you use.
fleetsmith build fleet.yaml --target all
# or: --target claude-code | opencode | goose
Gate it
qa checks the compiled output, not the spec's intentions — handoff
graph against real files, capability leaks, loop bounds, drift.
fleetsmith qa fleet.yaml
Running it #
Restart your agent CLI in the project directory so it picks up the generated files.
Your agents are in .claude/agents/, skills in
.claude/skills/, and the orchestration brief in CLAUDE.md.
Address an agent by name, or describe the work and let the orchestrator delegate.
claude
> review the diff on this branch using the fleet
Project hooks — including the SubagentStop handover gate — do not run
until you accept Claude Code's "trust this folder" prompt. Until then the gate is
silently skipped and the fleet degrades to advisory instructions.
Agents are in .opencode/agents/, with commands and skills alongside and
the handoff graph compiled into opencode.json as
permission.task maps. An agent with no edge to another cannot see it in
the task tool at all.
opencode
> @change-analyst review the diff on this branch
opencode defaults it to 1, which silently prevents a subagent from
delegating. The generated opencode.json raises it — that trap is closed
for you.
Recipes are in .goose/recipes/, and AGENTS.md is read
first-class. Run the orchestrator recipe:
goose run --recipe .goose/recipes/orchestrator.yaml
goose runs different sub-recipes sequentially unless the prompt asks for parallelism, which quietly cost a fleet's declared parallel phases all their concurrency. The generated orchestrator prompt asks.
Enterprise setup #
Nothing below is required to use Infinia Harness. A checkout with no
RELATA_URL and no grid: block behaves exactly like the
open-source edition. This is additive: pre-commit cross-developer awareness that would
otherwise wait for a pull request.
Stand up a cortex
The installer will do it, or do it by hand:
docker run -d \
--name relata \
--restart unless-stopped \
-p 9090:9090 \
-v ~/.relata:/data \
-e RELATA_PROFILE=free \
-e RELATA_BEARER_TOKEN="$(openssl rand -hex 24)" \
openworkbench/relata-db:v2.0.0
Check it is up:
curl -fsS http://127.0.0.1:9090/health
Point a checkout at it
Two ways. The environment pair wins if both are set.
export RELATA_URL=http://127.0.0.1:9090
export RELATA_TOKEN=<your own token>
Or commit the URL — never the token — in fleet.yaml:
fleet:
name: my-fleet
grid:
url: http://your-cortex:9090
token_env: RELATA_TOKEN # the NAME of the env var, not the token
Not warned about — refused. fleet.yaml is meant to be committed, and a
token that lands there once is a permanent credential leak in git history, not a
linting problem to fix on the next commit.
First sync #
fleetsmith grid init fleet.yaml # once per checkout, per developer
fleetsmith grid sync fleet.yaml
Expect a handful on the very first sync in a fresh repo, and none of them mean
anything is broken. Grid ontology types self-register on their own first push, so a
type nobody has pushed yet reports "not registered in the schema" and simply has
nothing to pull. A repo with no fetched origin/main cannot run the
file-declaration enrichment step; push and pull both still work.
Once two developers have synced, each sees the other's in-flight work as read-only files:
cat _fleet/local/grid/peers/alice/LEDGER.md
cat _fleet/local/grid/GRID.md
Then keep it running:
fleetsmith grid sync --watch # SSE doorbell + 5-minute fallback
fleetsmith grid overlaps # cross-developer file and task collisions
fleetsmith grid overlaps --git-only # the same question, no cortex, no network
The console #
A stateless admin UI over the cortex — no second database, no sessions, no user table. Every request carries the caller's own bearer token, so the engine's ACL and audit trail always see the real principal.
RELATA_URL=http://127.0.0.1:9090 \
CONSOLE_ADMINS=alice,bob \
PORT=4173 \
node "$(npm root -g)/fleetsmith-ee/console/server/index.js"
curl http://127.0.0.1:4173/api/health
Troubleshooting #
| Symptom | Cause and fix |
|---|---|
fleetsmith: command not found after installing |
The bin directory is not on this shell's PATH. Run . ~/.fleetsmith/env.sh, or re-run the installer with --shell-rc-style wiring by answering yes to the shell rc question. |
| Agents ignore the handover gate | The workspace is not trusted yet. Accept Claude Code's trust dialog — project hooks do not run until you do. |
| A compiled agent is never delegated to | It has no inbound edge, or its description does not discriminate. Run fleetsmith qa for the graph check and fleetsmith eval for trigger discrimination. |
RELATA_TOKEN is set but RELATA_URL is not |
Exactly what it says — set both or neither. A half-exported pair is refused rather than silently ignored. |
| Enterprise commands are unknown | fleetsmith-ee is not installed, or was installed into a different npm prefix than fleetsmith. Core discovers it by module resolution, so both must share a prefix. |
| Cortex exits shortly after starting | A paid license is expired or its node hash no longer matches — the engine exits rather than continuing unlicensed. Your fleet degrades to the file backend and keeps working. |
docker pull denied |
Use the Docker Hub image openworkbench/relata-db. The ghcr.io/relatadb/relata registry is access-gated. |
Uninstalling #
curl -fsSL https://infinia-harness.adid.dev/install.sh | sh -s -- --uninstall
Removes both npm packages, the standalone binary, the cortex container and the env file.
Your cortex data in ~/.relata is deliberately left alone — deleting a
team's accumulated knowledge is not something an uninstaller should decide.