Introduction
Flock
Self-evolving agent coordination runtime — the harness is the flock.
Terminal demo — run → episode → multiplexer
Offline / no CDN — static transcript
$ flock plugin list
$ flock run --goal "reach target" --plugin gridworld
episode satisfied
$ flock run --json | head -3
Download flock-demo.cast ·
Run live from repo root: ./docs/demo/flock-demo.sh
Flock is a Rust coordination runtime where agents wake from a decaying pressure field, verify work through typed harness recursion (RAH), and improve topology from episode logs.
What makes Flock different
| Dimension | Typical harness (Claude Code, OpenCode) | Flock |
|---|---|---|
| Coordination | Scripts / chat / manager | Stigmergic pressure field + scheduler |
| Topology | Fixed | Evolved from .flock/episodes/ |
| Recursion | API subagents | RAH verified depth in multiplexer panes |
| Execution | Vendor PTY | In-tree flock-multiplexer + flock dashboard |
Flock is not a meta-harness wrapper or workflow DSL. Default flock run uses deterministic plugins (gridworld, shell) — wire your LLM via MCP, ACP, or remote panes. See What Flock is / is not.
Conventions
| Term | Meaning |
|---|---|
| Binary | flock — single CLI entrypoint |
| Config | Layered flock.toml → see flock.toml reference |
| Workspace state | .flock/ — episodes, archive, local overrides |
| Episode path | .flock/episodes/<goal-id>.json |
| Event names | NDJSON event field from flock-events |
| MCP tools | flock_* prefix — discovery via flock_discover_tools / flock_search_tools |
| Socket API | NDJSON on multiplexer socket — see Socket API |
Episode flywheel
flowchart LR
RUN[flock run] --> LOG[.flock/episodes]
LOG --> EVOLVE[flock evolve]
EVOLVE --> GATE[flock drift-check]
GATE --> RUN
class RUN runtime
class LOG runtime
class EVOLVE evolve
class GATE gate
- Run — scheduler-led goal loop (
flock run) or RLM verify/act (flock run --rlm) - Log — reproducible episode JSON with optional pane topology
- Evolve — topology mutations from episode corpus
- Gate —
flock drift-checkmanifest guardrails
First success in one command after install:
flock run --goal "reach target" --plugin gridworld
Episode JSON lands in .flock/episodes/. Full walkthrough: Quickstart.
Quick paths
| Goal | Page |
|---|---|
| First episode in 2 minutes | Quickstart |
| Multiplexer → dashboard → run | Daily driver |
| Cursor / Claude / Codex in panes | Agent guide |
| NDJSON socket automation | Socket API |
| MCP tool catalog | MCP tools |
| Full CLI surface | CLI reference |
Build this book locally
cargo install mdbook mdbook-mermaid
mdbook-mermaid install book
mdbook build book
mdbook serve book # http://localhost:3000
Or run ./scripts/smoke-docs.sh (included in ./scripts/verify.sh).
Live site: flock-docs.pages.dev — deploy via .github/workflows/docs.yml.
For LLM agents: llms.txt.
Install
Get the flock binary on your machine and confirm the verify trio passes.
Install methods
| Method | Command | Best for |
|---|---|---|
| Install script | curl -fsSL https://raw.githubusercontent.com/Alphabetsoup16/Flock/main/install.sh | bash | Quick try / operators |
| From clone | git clone … && ./install.sh | Development |
| Cargo path | cargo install --path crates/flock-cli | Rust contributors |
| Cargo release build | cargo build --release -p flock-cli | CI / local dev |
Requires stable Rust from rustup.rs; toolchain pinned in rust-toolchain.toml.
After install script or release build, ensure flock is on PATH:
export PATH="$PWD/target/release:$PATH" # from repo root
Verify trio
Run these three commands after install — all should succeed:
flock --version
flock run --goal "reach target" --plugin gridworld
flock doctor
Episode JSON appears under .flock/episodes/. For full CI parity, see Verify and ./scripts/verify.sh.
Optional: mdbook (docs contributors)
cargo install mdbook mdbook-mermaid --locked
mdbook build book
Next steps
| Goal | Page |
|---|---|
| First episode walkthrough | Quickstart |
| Multiplexer daily loop | Daily driver |
| Agent onboarding | Agent guide |
Quickstart
Get from clone to a gridworld episode in under two minutes.
Terminal demo
Offline / no CDN — static transcript
$ flock plugin list
$ flock run --goal "reach target" --plugin gridworld
episode satisfied
$ flock run --rlm --max-steps 4
$ flock multiplexer ensure && flock herd status
Download flock-demo.cast ·
Record live: asciinema rec docs/demo/flock-demo.cast -c “./docs/demo/flock-demo.sh”
Install
See Install for install methods and the verify trio.
From a clone (recommended for development):
git clone https://github.com/Alphabetsoup16/Flock.git flock && cd flock
./install.sh
export PATH="$PWD/target/release:$PATH"
One-liner (release binary):
curl -fsSL https://raw.githubusercontent.com/Alphabetsoup16/Flock/main/install.sh | bash
Or with Cargo directly:
cargo install --path crates/flock-cli
Requires stable Rust from rustup.rs; toolchain pinned in rust-toolchain.toml.
First success
flock run --goal "reach target" --plugin gridworld
Structured JSON appears on stdout; an episode file lands under .flock/episodes/.
Common commands
flock --help
flock run --goal "reach target" --plugin gridworld
flock run --goal "reach target" --plugin gridworld --rlm
flock evolve --episodes 16 --workspace .flock/episodes
flock replay --episode .flock/episodes/<goal-id>.json
flock replay --episode .flock/episodes/<goal-id>.json --continue-run
flock multiplexer ensure
flock dashboard # ratatui control tower (daily driver)
flock herd status
flock drift-check
flock plugin list
flock mcp
MCP server
flock mcp
Wire your MCP client to the stdio JSON-RPC surface. Tool catalog: MCP tools.
Remote multiplexer
flock remote --goal "reach target" --plugin gridworld
flock remote --ssh user@host --goal "reach target" --plugin gridworld
flock remote --stub --goal "reach target"
Default socket: ~/.config/flock/flock.sock (override with FLOCK_SOCKET).
Verify before you PR
./scripts/verify.sh
Daily driver loop
The recommended local workflow for developing and operating Flock.
Loop
flock multiplexer ensure → flock dashboard → flock run → flock evolve → ./scripts/verify.sh
- Multiplexer —
flock multiplexer ensurestarts the in-tree PTY server (~/.config/flock/flock.sock). - Dashboard —
flock dashboardopens the ratatui control tower (agents, pressure, pane tree). Writes~/.config/flock/statusline.jsonfor MCP observability. - Run —
flock run --goal "…" --plugin gridworld(scheduler) or--rlm(verify/act loop with mux pane topology). - Evolve —
flock evolve --episodes 16 --workspace .flock/episodesmutates topology from episode corpus. - Verify —
./scripts/verify.shbefore every PR (fmt, clippy, hack, tests, smoke benches, dashboard + socket e2e).
Headless CI parity
CI runs the same smoke surface without a TTY:
cargo test -p flock-dashboard --test integration
cargo test -p flock-multiplexer --test socket_integration
flock run --goal "reach target" --plugin gridworld --rlm
Remote / SSH
flock remote --goal "reach target" --plugin gridworld
flock herd attach --session my-work
Dashboard
flock dashboard is the ratatui control tower over the in-tree multiplexer — the daily-driver view of agents, pressure, pane topology, and evolution archive.
Launch
flock multiplexer ensure
flock dashboard
Defaults:
- Socket:
~/.config/flock/flock.sock(override with--socket) - Episodes:
.flock/episodes - Archive:
.flock/archive
Keybindings
| Key | Action |
|---|---|
j / k | Select agent up/down |
Enter | Attach to selected pane (Ctrl+Q to detach) |
r | Refresh agents + layout snapshot |
q | Quit |
Headless observability
The dashboard writes ~/.config/flock/statusline.json on each refresh. MCP tool flock_read_statusline (see MCP tools) reads this snapshot for external monitors.
CI smoke
Dashboard client code is tested against a mock Unix socket:
cargo test -p flock-dashboard --test integration
Included in ./scripts/verify.sh.
What Flock is / is not
Flock is
- A coordination runtime — pressure-field scheduler, typed blackboard, episode logs
- A plugin harness boundary —
FlockPlugin::verify_goaldrives the defaultflock runloop - An in-tree multiplexer — HerdR-shaped NDJSON socket API + PTY panes
- A topology evolution loop —
flock evolvemutates wake maps from episodes - Governance-aware —
flock.tomlhooks, tool pipeline, drift-check manifest
Default flock run uses deterministic plugins (gridworld, shell). The scheduler wakes agents from substrate signals — not a manager LLM.
Flock is not
- An OpenCode / Claude Code / claw-code clone — no drop-in coding agent with dozens of providers on the hot path
- An OpenClaw wrapper — Flock does not host or wrap external harness binaries; it is the coordination runtime
- A meta-harness composition layer — unlike Omnigent-style wrappers, Flock does not orchestrate Claude Code + Codex as black boxes
- A workflow DSL — coordination is the pressure field, not hand-drawn graphs
- A chat router — agent-to-agent NL handoffs are intentionally forbidden
Honest scope: claw-code and OpenClaw optimize single-agent coding loops. Flock optimizes multi-agent coordination geometry — scheduler ticks, pheromone deposits, topology evolution, and multiplexer pane farms.
Comparison snapshot
| Need | Flock | claw-code / OpenClaw |
|---|---|---|
| Daily coding agent | Use flock acp or external editor + MCP | Primary product |
| Multi-pane agent farm | In-tree multiplexer + dashboard | External tmux scripts |
| Topology evolution | flock evolve + archive | Not in scope |
| Stigmergy / pressure field | Core scheduler | Not in scope |
| Provider matrix | Optional verify-path LLM only | Hot-path feature |
Honest adoption path
| Need | Use |
|---|---|
| Prove coordination thesis | flock run, swarm-demo, Govcraft bench in verify.sh |
| Editor integration | flock acp (stdio + prompt → engine) |
| External tool bridge | flock mcp or flock run --mcp |
| Remote pane farm | flock remote --plugin <name> with governance |
| Cursor / Claude daily driver | Pair Flock multiplexer with agent hooks |
Flock deliberately does not chase OpenCode/Claude Code/claw-code feature parity — coordination runtime and honest scope are the product.
Related
Verify
The single verification entry point is ./scripts/verify.sh:
cargo fmt --checkcargo clippy --workspace --all-targets -- -D warningscargo hack check --workspace --each-feature --no-dev-depscargo test --workspace- Release build + CLI smoke tests (run, json, rah-demo, acp, swarm-demo)
- Benchmarks: stigmergy ablation, govcraft acceptance, topology ablation
- Documentation smoke:
./scripts/smoke-docs.sh
./scripts/verify.sh
flock drift-check
CI runs the same script on every PR (.github/workflows/ci.yml).
Troubleshooting
Common first-run failures and fixes.
flock: command not found
cargo install --path crates/flock-cli
# or
cargo build -p flock-cli && export PATH="$PWD/target/debug:$PATH"
Multiplexer socket missing
flock multiplexer ensure
# or
flock herd server
Override socket path: export FLOCK_SOCKET=~/.config/flock/flock.sock
drift-check fails locally
./scripts/drift-guard.sh
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
Guardrail edits require manifest updates — see governance policies.
flock run exits immediately with plugin error
flock plugin list
flock plugin info gridworld
Confirm --plugin name matches registry entry. Shell plugin requires bounded argv — no shell injection.
Dashboard shows disconnected
- Start multiplexer:
flock herd server - Attach session:
flock herd attach - Check
~/.config/flock/statusline.json— see statusline
--json output not parseable
flock run --json emits one FlockEvent per line (NDJSON). Do not mix with pretty-printed episode JSON — episode file is written to .flock/episodes/ separately.
Docs build fails
cargo install mdbook mdbook-mermaid --locked
./scripts/install-mermaid-assets.sh
mdbook build book
Related
Coordination model
Flock agents coordinate through the environment, not dialogue. Work flows via typed blackboard slots, decaying pheromone zones, and scheduler wake pressure — never through conversation loops, router LLMs, or handoff chains that re-encode state in natural language.
The substrate is the coordination protocol. Agents read signals, deposit completion, and wake when dependency pressure crosses a threshold.
Substrate primitives
Blackboard (typed slots)
Shared JSON slots keyed by name. Plugins declare expected slots in their manifest; the runtime writes last_observation after each dispatch. Plugins access slots through PluginContext::blackboard_set / blackboard_get.
Pheromone zones
Zone-keyed signal maps with exponential decay (PheromoneField). Each zone holds named signals (completion, activity, coordination, …). Strength accumulates on deposit and decays each scheduler tick.
Perception radius
CoordinationContext::perception_radius bounds how far an agent “sees” field signals. Today this gates boids-style coordination deposits; future plugins can filter reads by radius.
Pressure field and wake
PressureScheduler holds a pending task queue. Each task has:
- zone — where it runs and where completion is deposited
- dependencies —
(zone, signal)pairs that must read above zero - base_pressure — intrinsic urgency (capped by dependency pressure)
Wake pressure = min(base_pressure, min(dep signals)), boosted by multiplexer deposits. Tasks dispatch when pressure ≥ wake_threshold.
Completion and dependency signals
When a plugin returns NextAction::Complete or Halt, the scheduler deposits completion into the task’s zone. Retries and delegates deposit completion on the source zone, then enqueue dependents that wait on that signal.
Allowed vs forbidden patterns
| Pattern | Status |
|---|---|
| Deposit completion → dependent task wakes | Allowed |
| Blackboard slot handoff (typed JSON) | Allowed |
NextAction::Delegate { task } (typed task descriptor) | Allowed |
Multiplexer pane deposits (pheromone_deposits in observation) | Allowed |
| Agent-to-agent chat / message passing | Forbidden |
| Router LLM choosing next agent | Forbidden |
| Re-encoding substrate state as NL for coordination | Forbidden |
Typed handoffs use TaskDescriptor payloads and blackboard slots — not prose.
Coordination flow
flowchart TB
subgraph encode["Encode"]
G[Goal] --> P[Plugin.encode_task]
P --> T[TaskDescriptor]
end
subgraph scheduler["PressureScheduler"]
T --> Q[Pending queue]
Q --> RP[refresh_pressure]
RP --> DEP{deps satisfied?}
DEP -->|no| DEFER[deferred]
DEP -->|yes| DISPATCH[dispatch_ready]
DISPATCH --> HOST[RunHost.spawn]
end
subgraph substrate["Substrate"]
HOST --> OBS[observation]
OBS --> BB[Blackboard.set]
OBS --> DEPOSIT[pheromone deposits]
DEPOSIT --> FIELD[PheromoneField]
OBS --> COORD[boids coordinate]
COORD --> FIELD
end
subgraph verify["Verify"]
OBS --> V[Plugin.verify_goal]
V --> R[AgentReport]
R -->|Complete| COMP[deposit completion]
COMP --> FIELD
R -->|Retry/Delegate| ENQ[enqueue dependent]
ENQ --> Q
end
FIELD --> RP
class G,P,T,Q,RP,DISPATCH,HOST runtime
class OBS,BB,DEPOSIT,FIELD,COORD substrate
class V,R,COMP,ENQ gate
Scheduler-primary run
FlockEngine::run_goal drives the loop:
- Encode initial task from plugin manifest primary zone
- Tick field decay → refresh pressure → dispatch ready batch (parallel, budget-limited)
- Read host output → apply pheromone deposits → coordinate (boids) in plugin zone
- Verify via plugin → deposit completion → enqueue retries/delegates
- Snapshot field, topology, wake stats into episode JSON
Evolve and multiplexer deposits
flock evolve reads episode logs (pheromone_snapshot, wake_stats, environment_fingerprint) to mutate topology — coordination quality becomes fitness pressure on harness shape.
Remote observations may include pane deposits:
{"pheromone_deposits": [{"zone": "herdr", "signal": "activity", "amount": 0.5}]}
These feed herdr_wake_boost, waking stalled tasks when panes report activity.
Reading order
- Memory architecture — hot/warm/cold layers
- Organism model — genome, circulation, immune gate
- Quickstart — first episode
Memory architecture
Flock memory is the coordination substrate plus durable episode artifacts — not a vector store or chat transcript archive.
Layers
| Layer | Where | Role |
|---|---|---|
| Hot | In-process blackboard + pheromone field | Live stigmergy (decay, wake, dispatch) |
| Warm | .flock/ JSON today; .flock/memory.db planned | Episodes, traces, checkpoints, topology archive |
| Cold | Turso Sync (optional, Phase 3) | Team backup and multi-machine share |
Today (Phase 0)
flock run --goal "reach target" --plugin gridworld # → .flock/episodes/<id>.json
flock replay --episode .flock/episodes/<id>.json
flock replay --continue-run --episode .flock/episodes/<id>.json
Working state: flock_read_blackboard, flock_deposit_signal during live episodes (MCP tools).
Phase 2 (SQLite queries)
When [memory] backend = "sqlite":
flock evolvereadsepisode_metricsaggregates instead of scanning full episode JSONsubstrate_heatmap()andplugin_grounded_fitness()use SQL-native corpus aggregates- MCP
flock_query_field_historyqueries checkpoint-time field snapshots
When [memory] mirror_json = false, episodes are stored only in SQLite — the proposer skips JSON directory scans and reads exclusively from the memory store.
What never goes in the database
- Live pheromone ticks (stay in-process)
- Conversation transcripts for coordination
- Vector embeddings (deferred)
See Coordination model for the coordination protocol.
Organism model
Flock treats the harness as a living organism: genomes express coordination parameters, circulation vitals track field health, and an immune gate rejects harmful topology mutations.
Status: Phases 1–4 complete (circulation, DNA lineage, immune gate, per-zone expression).
Architecture
flock-core/organism.rs DNA types + circulation vitals + zone expression
flock-substrate/pheromone per-zone decay (fallback to global lambda)
flock-runtime/circulation vitals + immune_fever tracking
flock-runtime/engine.rs vitals + genome_id + fever + decay wire-through
flock-evolve/genome.rs lineage + crossover + archive reconstruction
flock-evolve/immune.rs corpus threat detection + auto_reject
flock-evolve/mutator.rs crossover + cold-zone decay adjustment
flock-cli/organism_cmd.rs flock vitals | flock genome list|lineage
Organism loop
flowchart LR
RUN[flock run] --> VITALS[circulation vitals]
VITALS --> EP[episode JSON]
EP --> EV[flock evolve]
EV --> IMM[immune_report]
IMM -->|accept| ARCH[genome archive]
IMM -->|reject| QUAR[quarantine]
class RUN,VITALS,EP runtime
class EV,ARCH evolve
class IMM,QUAR gate
FlockGenomeexpresses coordination + decay params at episode endPheromoneFieldcirculation →CirculationVitalsin episodeflock evolvemutates or crossover (Pareto ≥ 2) →immune_report()gates accept- Quarantined genomes excluded from
archive.nearest()seed - Per-zone decay tuned from proposer cold-zone heatmap
CLI
flock run --goal "reach target" --plugin gridworld
flock vitals
flock evolve --episodes 10
flock genome list
flock genome lineage <genome_id>
Phase completion
| Phase | Deliverable | Status |
|---|---|---|
| 1 Circulation | circulation_vitals, flock vitals, fitness dimension | ✅ |
| 2 DNA | genome_id lineage, archive seed reconstruction, flock genome | ✅ |
| 3 Immune | drift + fitness + immune gate, quarantine, fever deposit | ✅ |
| 4 Expression | per-zone decay, crossover, flux-grid test, fever unit test | ✅ |
flux-grid (optional)
- Feature:
flock-substrate/flux-grid(vendored 64×64Stigmergygrid) - Not enabled in default builds — zone-keyed
PheromoneFieldremains default substrate - Enable for experiments:
cargo build -p flock-substrate --features flux-grid
Known deferred
flux-gridin swarm-demo default path- Full
parent_idslineage CLI (crossover setsparent_ids; CLI shows primaryparent_genome_idonly) RAH_MAX_DEPTHinflock-core(cycle avoidance withflock-evolve↔flock-rah)
See also
- Coordination model — substrate and scheduler
- Quickstart — first episode
- Episode flywheel on Introduction
Topology evolution
Frontier bet: evolution that changes coordination geometry, not prompts.
What this proves
- Episode logs from real
flock run/swarm-demoruns ground fitness viaplugin_grounded_fitness(). flock evolve --episodes 10runs accept/reject over generations (drift + immune gates).- Drift gate: incompatible candidates are rejected on the production path;
drift_rejectedanddrift_violationsappear in CLI JSON when the gate fires. - Gen-0 vs gen-N fitness delta and genome lineage are observable in CLI output.
Quick run
cargo build --release -p flock-cli
bash docs/demo/evolve-proof.sh
Or step by step:
flock swarm-demo
flock run --goal "reach target" --plugin gridworld # repeat 3×
flock evolve --episodes 10 --workspace .flock/episodes
flock genome list
flock genome lineage <genome_id>
Sample output shape
{
"generations": 10,
"accepted": 4,
"rejected": 6,
"drift_rejected": 1,
"drift_violations": [
{ "check_id": "topology_edge_refs", "message": "edge agent-1→agent-2 references missing node(s)" }
],
"gen0_fitness": 0.69,
"final_fitness": 0.74,
"fitness_delta": 0.05,
"seed_source": "episodes",
"pareto_front": []
}
CI gate
Fast smoke (no LLM, fixture episodes only):
cargo run -q -p evolve_proof
Fixture corpus: tests/fixtures/evolve-episodes/ (4 gridworld episodes).
Honest limits
- Fitness is plugin-grounded from in-tree gridworld episodes, not Govcraft 48.5% LLM benchmark.
- Mutations target wake threshold, topology nodes, and per-zone decay — not prompt strings.
- Crossover activates when Pareto front has ≥2 non-quarantined entries.
- Drift gate blocks structurally invalid / manifest-failing candidates before fitness accept.
Related
Evolve → run round-trip
Loop: episodes → evolve → archive → seed run → write-back fitness
Overview
Flock closes the loop between topology evolution and production runs:
flock evolve— mutates harness topology from episode corpus; writes.flock/topology_archive.jsonflock run --seed-archive— seeds topology/coordination from nearest archive entry; logsgenome_id+genome_seedevent- Write-back — after a successful run, merges episode fitness into the archive entry (by
genome_id)
Write-back is enabled with --write-back or automatically when --seed-archive is used. Pass --no-write-back to disable the automatic path.
Quick reproduce
EVOLVE_FIX="tests/fixtures/evolve-episodes"
mkdir -p .flock/episodes
cp "$EVOLVE_FIX"/*.json .flock/episodes/
flock evolve --episodes 10 --workspace .flock/episodes
flock run --goal "reach target" --plugin gridworld --seed-archive --json
Expected in episode JSON:
genome_id— seeded from archivefitness— plugin-grounded success scoreevents[]containinggenome_seedand (when write-back applies)archive_write_back
Write-back semantics
- Trigger:
GoalStatus::Satisfiedand bothgenome_id+fitnesspresent - Merge:
TopologyArchive::write_back_fitnessupdates matching entry by id; re-sorts by success score - Archive path:
--archive(default.flock/topology_archive.json)
JSON events
With --json, archive write-back emits a typed archive_write_back FlockEvent line before episode_end.
Related
Governance overview
Flock ships two governance surfaces:
- Manifest drift-check —
flock drift-checkenforces required CI checks, style files, and deprecation notices. See policies. - Runtime hooks —
flock.tomlsession hooks and multiplexer agent lifecycle reporting. See hooks.
Neither surface uses a router LLM. Governance is deterministic policy + operator-configured shell hooks.
Quick commands
flock drift-check # manifest guardrails
flock doctor --json # staged runtime diagnostics
Related
Governance policies
Policies that keep Flock’s codebase and guardrails from drifting apart.
Verification pipeline
.github/workflows/ci.yml
│
├── scripts/drift-guard.sh → flock drift-check (manifest)
└── scripts/verify.sh → fmt, clippy, hack, test, build, smoke
CI must call ./scripts/drift-guard.sh then ./scripts/verify.sh only. Do not add duplicate lint or test steps to the workflow — that creates anti-drift debt.
Single source of truth
| Concern | Canonical location |
|---|---|
| Required checks list | crates/flock-governance/src/manifest.rs |
| Check enforcement | flock drift-check (also invoked by drift-guard.sh) |
| Full verification | scripts/verify.sh |
| Code style | Engineering guide |
| License / advisory policy | deny.toml |
When adding a new required check:
- Add a
ManifestCheckentry tomanifest.rs. - Implement validation in
run_drift_check. - If the check belongs in the full suite, add it to
verify.sh. - Note the change in your PR description (required).
PR requirements
PRs that touch any of the following must include a ## Guardrails section in the description explaining what changed and why:
scripts/verify.shscripts/drift-guard.sh.github/workflows/**crates/flock-governance/src/manifest.rsrust-toolchain.toml,clippy.toml,rustfmt.toml,deny.toml
PRs that change Rust style conventions must update the engineering guide in the same PR.
Drift-check command
cargo run -p flock-cli -- drift-check
# or, after install:
flock drift-check
Exits non-zero when any VERIFICATION_MANIFEST expectation fails. Use locally before pushing when editing guardrail files.
Python deprecation
The python/ tree is deprecated and packages were removed. python/README.md must retain a deprecation notice — drift-check enforces this when the directory exists.
Review expectations
- Guardrail changes: one maintainer approval minimum.
- Manifest changes: confirm
flock drift-checkand./scripts/verify.shboth pass in CI. - No
allow(dead_code)in crate sources without removing the check from manifest (not permitted).
Related
- Agent hooks — multiplexer lifecycle reporting
- CLI reference —
flock drift-check
Agent hooks
Flock supports two hook surfaces: governance lifecycle hooks (configured in flock.toml) and multiplexer agent lifecycle reporting (socket API for editor agents).
Governance lifecycle hooks (flock.toml)
Configure deterministic shell hooks in layered config (flock.toml, ~/.flock/config.toml, .flock/local.toml):
[[hooks.hooks]]
event = "SessionStart"
command = "./scripts/hooks/session-start.sh"
[[hooks.hooks]]
event = "PreToolUse"
command = "./scripts/hooks/pre-tool.sh"
[[hooks.hooks]]
event = "PostToolUse"
command = "./scripts/hooks/post-tool.sh"
[[hooks.hooks]]
event = "SessionEnd"
command = "./scripts/hooks/session-end.sh"
Accepted event / kind values: SessionStart, SessionEnd, PreToolUse, PostToolUse (snake_case aliases also work).
Each command receives a single JSON payload line on stdin:
| Event | Payload fields |
|---|---|
SessionStart | goal_id, plugin |
SessionEnd | goal_id, status |
PreToolUse | tool, argv, agent_id |
PostToolUse | tool, argv, success |
Invocation paths
| Path | When hooks run |
|---|---|
flock run | SessionStart/SessionEnd on episode boundaries; PreToolUse/PostToolUse on MCP tool calls and shell plugin execution via ToolGovernancePipeline |
flock run --rlm | Same session hooks; mux delegate steps use nested sub_harness panes |
| Shell plugin | PreToolUse/PostToolUse with tool: "shell" and argv in payload |
Hook commands must exit 0; non-zero exits fail the surrounding operation.
Multiplexer agent lifecycle (socket API)
Agents (Claude Code, Codex, Cursor) can report lifecycle state to the multiplexer without relying on screen heuristics.
Socket API
{"id":"1","method":"pane.report_agent","params":{
"pane_id": "w1:p1",
"agent": "claude",
"state": "working",
"source": "hook"
}}
States: idle, working, blocked, done, unknown.
When source is hook, screen heuristics are ignored until the pane is reset.
Shell hook example
Install into your agent wrapper (~/.config/flock/hooks/herdr-agent-state.sh):
#!/usr/bin/env bash
# Usage: herdr-agent-state.sh <pane_id> <agent> <state>
PANE_ID="${1:?pane_id}"
AGENT="${2:?agent}"
STATE="${3:?state}"
SOCKET="${FLOCK_SOCKET:-$HOME/.config/flock/flock.sock}"
printf '%s\n' "{\"id\":\"hook\",\"method\":\"pane.report_agent\",\"params\":{\"pane_id\":\"$PANE_ID\",\"agent\":\"$AGENT\",\"state\":\"$STATE\",\"source\":\"hook\"}}" \
| nc -U "$SOCKET"
Claude / Codex / Cursor integration
| Agent | Suggested hook point |
|---|---|
| Claude Code | Wrap claude in a shell function; call hook on tool-approval and turn-complete |
| Codex | Export CODEX_HOOK_CMD pointing to the script above |
| Cursor | Use cursor-agent lifecycle env callbacks if available; else poll is fallback |
CLI wait helper
flock herd wait --pane w1:p1 --status idle --timeout-ms 60000
Equivalent to events.wait with pane_agent_status_changed.
Environment
| Variable | Purpose |
|---|---|
FLOCK_SOCKET | Override default ~/.config/flock/flock.sock |
FLOCK_ENV=1 | Set in spawned pane shells (detect flock-managed sessions) |
Related
Multiplexer overview
Flock ships an in-tree PTY multiplexer with a HerdR-shaped NDJSON socket API. One binary (flock) serves daily-driver pane farms without an external herdr binary.
Architecture
flock herd server → flock-multiplexer (Unix socket)
│
├── pane.spawn / pane.attach (PTY proxy)
├── events.subscribe / events.wait
└── pane.report_agent (hook protocol)
Pane agent status feeds the pressure field: agent_status observations can deposit pheromones that boost scheduler wake on the herdr zone.
Quick start
flock herd server # background socket
flock swarm-demo # scheduler-led multi-pane demo
flock herd attach # interactive session
Attach modes
| Mode | Command | Use |
|---|---|---|
| Poll | flock herd status | Headless CI, scripts |
| Proxy | flock herd attach | Daily-driver TTY |
Related
Plugin architecture
What Is a FlockPlugin?
A plugin is a goal environment adapter: it encodes goals into runnable tasks, verifies observations against goals, and scores outcomes for evolution.
#![allow(unused)]
fn main() {
#[async_trait]
pub trait FlockPlugin: Send + Sync {
fn name(&self) -> &'static str;
fn encode_task(&self, goal: &Goal) -> TaskDescriptor;
async fn verify_goal(&self, goal: &Goal, observation: &serde_json::Value) -> AgentReport;
fn fitness(&self, goal: &Goal, report: &AgentReport) -> FitnessVector;
fn tools(&self) -> Vec<ToolSpec> { vec![] }
}
}
Supporting traits:
GoalVerifier— verify-only surface for RLM loopsCrucibleAdapter— verify + automatic remediation hints (CruciblePluginAdapter)
Coordination hooks (optional, via context at runtime):
PluginContext— blackboard read/write, budget snapshotCoordinationContext— zone list, perception radius,deposit_signal/read_signal
Current plugins
| Plugin | Kind | LLM | Description |
|---|---|---|---|
| gridworld | Simulator | No | Deterministic 5×5 grid; agents navigate to target; boids coordination deposits |
| shell | Executor | No | Bounded subprocess (argv, cwd, timeout); exit code + output verification |
| crucible | Adapter | No | Wraps any FlockPlugin with remediation on failure |
Lifecycle
register → encode → scheduler run → verify → episode snapshot → evolve fitness
- Register —
PluginRegistry::builtin()loads built-ins + manifest TOML - Encode —
encode_task(goal)produces initialTaskDescriptorpayload - Run — scheduler enqueues in plugin primary zone; host executes; observations flow back
- Verify —
verify_goalreturnsAgentReportwithNextAction - Episode — runtime writes
.flock/episodes/<goal-id>.json - Evolve —
flock evolvereads episodes; plugin name inenvironment_fingerprintseeds archive lookup
Plugin manifest (plugin.toml)
name = "gridworld"
description = "Deterministic 5x5 grid navigation simulator"
version = "0.1.0"
[zones]
primary = "grid"
default = ["grid", "goal"]
[blackboard]
slots = ["state", "last_observation"]
Manifests live at crates/flock-plugins/<name>/plugin.toml. Discovery scans that tree at registry init.
Add a plugin in under 10 minutes
flock plugin new myplugin
flock plugin list
flock run --goal "your goal" --plugin myplugin
Installed plugins register automatically via plugins.toml + build.rs — no registry.rs edit.
Extension points
| Extension | Location |
|---|---|
| Plugins | flock-plugin-api, flock-plugins |
| RunHost backends | flock-runtime::RunHost, flock-rah, flock-herdr |
| Evolve hooks | flock-evolve — GepaHook, EpisodeLogProposer |
| Governance | flock-governance — VERIFICATION_MANIFEST |
| Multiplexer | flock-multiplexer — pane deposits → observations |
Related
CLI overview
Flock is a single binary (flock) with subcommands for goal runs, evolution, multiplexer control, MCP, and diagnostics.
Precedence
Configuration resolves in this order (highest wins):
- CLI flags — e.g.
--goal,--plugin,--json - Environment variables — e.g.
FLOCK_MUX_AUTO,FLOCK_SESSION_SPEND_CAP_USD - Layered config files — see
flock.toml
Output modes
| Mode | Flag / entrypoint | Use when |
|---|---|---|
| Human text | default | Interactive terminal |
| NDJSON events | flock run --json | CI, automation, log pipelines |
| MCP stdio | flock mcp | Cursor, Claude Desktop, other MCP clients |
| ACP stdio | flock acp | Editor-class agents (Zed, experimental) |
| Socket NDJSON | flock multiplexer server | Dashboard, remote attach, HerdR parity |
Episode JSON is always written to .flock/episodes/<goal-id>.json on successful runs (separate from --json stdout).
Top-level commands
| Command | Page |
|---|---|
run | run |
evolve | evolve |
remote | remote |
herd | herd |
plugin | plugin |
mcp | mcp |
telemetry | telemetry |
doctor | doctor |
replay | replay |
swarm-demo, rah-demo | demos |
Other commands: multiplexer, acp, skills, drift-check, memory, integration, vitals, genome, dashboard, completions, ipc (deprecated). Run flock <cmd> --help for flags.
Shell completions
Completions are generated from live clap metadata so they stay in sync with the CLI:
flock completions bash # bash completion script
flock completions zsh # zsh completion script
flock completions fish # fish completion script
Install examples:
# bash (user-local)
mkdir -p ~/.local/share/bash-completion/completions
flock completions bash > ~/.local/share/bash-completion/completions/flock
# zsh
flock completions zsh > "${fpath[1]}/_flock"
# fish
mkdir -p ~/.config/fish/completions
flock completions fish > ~/.config/fish/completions/flock.fish
Re-run after upgrading flock when subcommands or flags change.
Help snapshots
CLI help is snapshot-tested in CI. After intentional CLI changes:
UPDATE_SNAPSHOTS=1 cargo test -p flock-cli cli_help_snapshot
See Deployment.
Recipes
First episode (gridworld):
flock run --goal "reach target" --plugin gridworld
Headless CI with typed events:
flock run --goal "reach target" --plugin gridworld --json | grep episode_end
Daily-driver mux path:
flock multiplexer server &
flock dashboard &
flock run --goal "reach target" --plugin gridworld --mux
Evolve then seed a run:
flock evolve --episodes 10 --workspace .flock/episodes
flock run --goal "reach target" --plugin gridworld --seed-archive
flock run
Scheduler-led goal loop with a plugin verifier. Writes episode JSON to .flock/episodes/<goal-id>.json.
Usage
flock run --goal <GOAL> [--plugin gridworld] [--resume [<GOAL_ID>]]
[--rlm] [--max-steps 8]
[--audit <PATH>] [--json] [--mcp] [--model <URL_OR_NAME>]
[--genome <ID>] [--seed-archive] [--archive .flock/topology_archive.json]
[--write-back] [--no-write-back] [--mux] [--no-mux]
When resuming, --goal is optional (defaults to checkpoint description). Plugin comes from the checkpoint.
Key flags
| Flag | Default | Notes |
|---|---|---|
--goal | required unless --resume | Natural-language goal text |
--plugin | gridworld | Verifier plugin (flock plugin list) |
--resume | off | Continue from .flock/checkpoints/ (optional goal UUID; default latest) |
--rlm | off | In-tree RLM verify/act loop |
--max-steps | 8 | Max RLM steps when --rlm |
--json | off | NDJSON flock-events on stdout |
--mcp | off | Process mcp_tools from observation payload |
--mux | off | Scheduler-led run via in-process multiplexer panes |
--seed-archive | off | Seed topology from evolve archive before run |
--write-back | auto with --seed-archive | Merge fitness into archive after success |
--mux runs via MuxHarnessHost; episode JSON includes pane_tree. Set FLOCK_MUX_AUTO=1 to auto-enable when the default multiplexer socket is live (--no-mux overrides).
--json events
| Event | Summary |
|---|---|
episode_start | goal_id, plugin, goal |
scheduler_tick | tick, pending |
task_dispatched | tick, task_id, zone |
verify_result | tick, zone, goal_met |
cost_rollup | per-tick usd, tokens, session total_usd, total_tokens |
deposit | zone signal deposit |
archive_write_back | optional genome merge |
episode_end | goal_id, status, fitness, episode_path |
See statusline for dashboard consumption.
Recipes
Gridworld smoke (verify.sh default):
flock run --goal "reach target" --plugin gridworld
RLM verify/act:
flock run --goal "reach target" --plugin gridworld --rlm --max-steps 4
Resume mid-goal:
flock run --goal "reach target" --plugin gridworld
flock run --resume
Mux topology in episode:
flock run --goal "reach target" --plugin gridworld --mux
Evolve round-trip:
flock evolve --episodes 5 --workspace .flock/episodes
flock run --goal "reach target" --plugin gridworld --seed-archive --write-back
Related
flock evolve
Evolve harness topology from episode logs. Optional Python GEPA hook; drift gate rejects incompatible mutations.
Usage
flock evolve [--episodes 10] [--workspace .flock/episodes] [--hook rust|seed-only] [--summarize]
Key flags
| Flag | Default | Notes |
|---|---|---|
--episodes | 10 | Generations to run |
--workspace | .flock/episodes | Episode JSON corpus directory |
--hook | rust | Proposer hook (seed-only for fixture tests) |
--summarize | off | Write .flock/episode_summary.json without evolving |
--summarize compacts the corpus for the proposer (DRY with substrate heatmap). Drift-incompatible candidates are rejected and logged.
Recipes
Standard evolve from local episodes:
flock run --goal "reach target" --plugin gridworld
flock evolve --episodes 10 --workspace .flock/episodes
Summarize only (no mutation):
flock evolve --summarize --workspace .flock/episodes
Seed archive then run:
flock evolve --episodes 10
flock run --goal "reach target" --plugin gridworld --seed-archive
Related
flock herd
HerdR-shaped UX over the in-tree multiplexer — common attach, status, and tab operations without raw socket JSON.
Usage
flock herd <SUBCOMMAND>
Subcommands include server, status, tabs, attach, wait, and related multiplexer helpers. Run flock herd --help for the current list.
Recipes
Check multiplexer health:
flock herd status
Attach to a running session:
flock herd attach <session-id>
List tabs before attach:
flock herd tabs
Daily-driver stack:
flock multiplexer server &
flock herd status
flock dashboard
Related
flock remote
Attach to the in-tree multiplexer and run a governed goal on remote panes.
Usage
flock remote --goal <GOAL> [--plugin gridworld] [--socket <PATH>]
[--ssh user@host] [--stub] [--audit <PATH>]
Key flags
| Flag | Notes |
|---|---|
--goal | Required goal text |
--plugin | Verifier plugin (default gridworld) |
--socket | Multiplexer NDJSON socket path |
--ssh | Remote host for SSH attach |
--stub | Deterministic stub run (CI smoke) |
--audit | Optional governance audit JSONL |
Governance pipeline (with_governance) applies on the remote hot path.
Recipes
Local stub smoke (verify.sh):
flock remote --stub --goal "reach target" --plugin gridworld
Remote with audit trail:
flock remote --goal "refactor auth module" --plugin shell --audit .flock/audit.jsonl
Related
flock plugin
List, inspect, scaffold, install, and uninstall dynamic plugins.
Usage
flock plugin list
flock plugin info <NAME>
flock plugin new <NAME>
flock plugin install --from <DIR>
flock plugin install --git <URL> [--name <NAME>]
flock plugin uninstall <NAME>
Installed plugins register via plugins.toml and build.rs — no hand-editing registry.rs.
Recipes
List registered plugins:
flock plugin list
Install from local directory:
flock plugin install --from ./my-plugin
cargo build --release -p flock-cli # rebuild to register
Install from git:
flock plugin install --git https://github.com/example/flock-gridworld-extra.git
Uninstall:
flock plugin uninstall sample-plugin
Related
flock mcp
MCP stdio JSON-RPC server exposing stigmergy and harness tools from the shared registry.
Usage
flock mcp
Methods: initialize, tools/list, tools/call. Same registry as flock run --mcp live episodes.
Recipes
List tools (stdio):
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | flock mcp
Discovery flow:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"flock_search_tools","arguments":{"query":"deposit"}}}' \
| flock mcp
Wire Cursor: see Cursor setup.
Related
flock telemetry
Query dashboard telemetry database — sessions, agent transitions, vitals snapshots, and per-tick cost rollups — without a TTY.
Usage
flock telemetry [--limit 20] [--db <PATH>]
flock dashboard --history [--limit 20]
Default DB: ~/.config/flock/telemetry.db.
Key flags
| Flag | Default | Notes |
|---|---|---|
--limit | 20 | Max rows per query |
--db | user config path | Override telemetry database |
Summary JSON includes cost_rollup_count, session_cost_usd, session_tokens, and recent_costs (from governance cost_rollup wire events recorded while the dashboard is open).
Recipes
Headless session list:
flock telemetry --limit 5
Dashboard history JSON:
flock dashboard --history --limit 10
Related
flock doctor
Staged runtime diagnostics: multiplexer socket, governance manifest, plugin registry, evolve archive, latest episode vitals.
Usage
flock doctor [--workspace .] [--json]
Exits non-zero when any stage fails. --json for automation.
Stages
| Stage | Checks |
|---|---|
| Multiplexer | Default socket reachable |
| Governance | Manifest / config load |
| Plugins | Registry matches plugins.toml |
| Archive | Topology archive readable |
| Vitals | Latest episode circulation metrics |
Recipes
Local workspace check:
flock doctor --workspace .
CI-friendly JSON:
flock doctor --json | jq .
Related
flock replay
Replay a saved episode JSON or audit JSONL file. --continue-run resumes from checkpoint when supported.
Usage
flock replay <PATH> [--continue-run]
Recipes
Inspect last episode:
flock replay .flock/episodes/latest.json
Replay audit trail:
flock replay .flock/audit.jsonl
Related
Demo commands
Scheduler and RAH demos for verify.sh and local exploration.
flock swarm-demo
Multi-pane scheduler-led swarm coordination demo.
flock swarm-demo
Expects output with pane_count, mux_host, and sub_harness_depth (verify.sh smoke).
flock rah-demo
Depth-3 RAH pane spawn demo — multiplexer + topology binding.
flock rah-demo
Expects "pane_tree_depth": 3 and "episode_pane_tree": true.
Recipe: demo → evolve flywheel
flock run --goal "reach target" --plugin gridworld --mux > .flock/episodes/mux-run.json
flock evolve --episodes 3 --workspace .flock/episodes
Related
CLI reference
The CLI reference is split into per-subcommand pages with flags tables and recipes.
Start here: CLI overview
Quick links
| Command | Page |
|---|---|
run | run |
evolve | evolve |
herd | herd |
remote | remote |
plugin | plugin |
mcp | mcp |
telemetry | telemetry |
doctor | doctor |
replay | replay |
completions | overview — shell completions |
| Demos | demos |
Help text is snapshot-tested in crates/flock-cli/tests/cli_help_snapshot.rs. Update snapshots with UPDATE_SNAPSHOTS=1 cargo test -p flock-cli cli_help_snapshot.
flock.toml reference
Layered configuration for governance, shell policy, hooks, and MCP permissions. Schema source: crates/flock-governance/src/config.rs.
File locations (merge order)
| Layer | Path | Precedence |
|---|---|---|
| User | ~/.flock/config.toml | lowest |
| Project | flock.toml (walk up from cwd) | middle |
| Local | .flock/local.toml (same repo as project flock.toml) | highest |
Later layers override earlier ones. CLI flags and environment variables override all files.
Example
[governance]
session_spend_cap_usd = 12.5
max_risk_score = 0.85
denied_paths = ["/secret", "~/.ssh"]
[shell]
allowed_commands = ["echo", "cargo", "git"]
denied_commands = ["rm", "curl"]
denied_patterns = ["sudo .*"]
max_output_bytes = 65536
[permissions]
default_mode = "ask"
[permissions.tools]
flock_propose_mutation = "deny"
flock_deposit_signal = "allow"
[[hooks.hooks]]
event = "PreToolUse"
command = "./scripts/hooks/pre-tool.sh"
Sections
[governance]
| Key | Type | Description |
|---|---|---|
session_spend_cap_usd | float | Session spend ceiling |
max_risk_score | float | Risk score threshold |
denied_paths | string[] | Paths blocked for tool/file access |
[shell]
| Key | Type | Description |
|---|---|---|
allowed_commands | string[] | Allowlist for shell plugin |
denied_commands | string[] | Blocked command names |
denied_patterns | string[] | Regex patterns to block |
max_output_bytes | integer | Cap captured stdout/stderr |
[permissions]
| Key | Type | Description |
|---|---|---|
default_mode | allow | ask | deny | Default MCP tool policy |
[permissions.tools] | map | Per-tool overrides |
Permission modes filter tools/list before exposure to MCP clients.
[[hooks.hooks]]
| Key | Type | Description |
|---|---|---|
event | string | Hook event name |
command | string | Shell command to invoke |
See Agent hooks.
Environment overrides
| Variable | Maps to |
|---|---|
FLOCK_SESSION_SPEND_CAP_USD | governance.session_spend_cap_usd |
FLOCK_MAX_RISK_SCORE | governance.max_risk_score |
FLOCK_SHELL_ALLOWED | CSV → shell.allowed_commands |
FLOCK_SHELL_DENIED | CSV → shell.denied_commands |
FLOCK_DENIED_PATHS | CSV → governance.denied_paths |
FLOCK_PERMISSION_MODE | permissions.default_mode |
Full list: Environment variables.
Related
MCP tools
Flock exposes a progressive-disclosure MCP surface: meta-tools for discovery, compact listings in tools/list, and full schemas on demand via flock_describe_tool.
Registry: crates/flock-runtime/src/mcp/registry.rs
Stdio server: flock mcp
Live episodes: flock run --mcp → FlockEngine::call_mcp_tool
Discovery flow
flowchart LR
A[Agent starts] --> B{flock_discover_tools<br/>or flock_search_tools}
B --> C[flock_describe_tool]
C --> D[Invoke operational tool]
D --> E[Governance + trace]
class A runtime
class B runtime
class C substrate
class D substrate
class E gate
- Discover —
flock_discover_toolsreturns domain-indexed tool cards (no full schemas). - Search —
flock_search_toolswithquery(and optionaldomain) narrows by intent. - Describe —
flock_describe_toolwithnamereturns full schema, preconditions, side effects, examples. - Invoke —
tools/callor livemcp_toolsobservation payload.
Meta-tools are always listed with full schemas. Operational tools in tools/list use compact cards (call flock_describe_tool for parameters).
Meta tools
| Tool | Domain | Purpose |
|---|---|---|
flock_discover_tools | meta | Browse domains and tool names |
flock_search_tools | meta | Keyword search over catalog |
flock_describe_tool | meta | Full ToolSpec for one tool |
Operational tools
| Tool | Domain | Summary | Live (--mcp) | Governance |
|---|---|---|---|---|
flock_deposit_signal | substrate | Deposit pheromone into zone | Yes | pre/post hooks |
flock_read_signal | substrate | Read signal strength | Yes | read-only |
flock_read_blackboard | substrate | Read blackboard slot | Yes | read-only |
flock_topology_snapshot | substrate | Harness topology JSON | Yes | read-only |
flock_metrics | substrate | Session counters | Yes | read-only |
flock_multiplexer_status | multiplexer | Dashboard statusline snapshot | Yes | read-only |
flock_propose_mutation | evolve | Verify/accept topology mutation | Yes | high-impact gate |
flock_recall | memory | Recall durable memory by key | Yes | read-only |
flock_remember | memory | Store durable memory entry | Yes | pre/post hooks |
flock_query_field_history | substrate | Query pressure-field history | Yes | read-only |
All operational tools are in LIVE_TOOL_NAMES for flock run --mcp.
Start the server
flock mcp
Wire your MCP client to stdin/stdout JSON-RPC. Cursor config example in Cursor setup.
Example: discovery sequence
{"name": "flock_search_tools", "arguments": {"query": "deposit", "domain": "substrate"}}
{"name": "flock_describe_tool", "arguments": {"name": "flock_deposit_signal"}}
{"name": "flock_deposit_signal", "arguments": {"zone": "grid", "signal": "coordination", "amount": 2.0}}
Example: live episode
Observation payload for flock run --goal "..." --plugin gridworld --mcp:
{
"mcp_tools": [
{
"tool": "flock_deposit_signal",
"args": { "zone": "grid", "signal": "coordination", "amount": 2.0 }
}
]
}
Trace JSONL emits mcp_discovery for meta-tools and mcp_tool for operational calls. Governance pre/post hooks apply on the hot path.
Design principles
| Principle | Implementation |
|---|---|
| Progressive discovery | Meta-tools before full schemas |
| Context efficiency | Compact tools/list for operational tools |
| Live parity | Same registry for flock mcp and flock run --mcp |
| Description quality | Summary + preconditions + side effects per tool |
Adding a tool
- Add
ToolSpecinregistry.rsand register inall_tool_specs(). - Add handler in
handlers.rsand route incall_tool_with_registry. - Add name to
LIVE_TOOL_NAMESif live episodes should expose it. - Update this page and run
cargo test -p flock-runtime.
See also MCP overview and Agent guide.
Socket API
Flock exposes a newline-delimited JSON (NDJSON) API over a Unix domain socket. The in-tree flock-multiplexer server implements HerdR-compatible automation methods; flock-herdr is the NDJSON client.
Source: crates/flock-multiplexer/src/api.rs · HerdR-compatible NDJSON automation (external herdr binary not required)
Connect
| Setting | Default |
|---|---|
| Socket path | $FLOCK_SOCKET → ~/.config/flock/flock.sock → $XDG_RUNTIME_DIR/flock.sock |
| Protocol | One JSON request per line; one JSON response per line |
| Streaming | events.subscribe and pane.attach may stream additional NDJSON events |
Ensure the server is running:
flock multiplexer ensure
# or
flock herd server
Example request:
{"id": 1, "method": "ping", "params": {}}
Example response:
{"id": 1, "result": {"type": "pong", "version": "...", "protocol": "..."}}
Errors use {"id": ..., "error": {"code": "...", "message": "..."}}.
Method catalog
| Method | Purpose |
|---|---|
ping | Health check; returns server and protocol version |
session.snapshot | Full session tree snapshot |
session.attach | Resolve named session → workspace + pane |
workspace.create | Create workspace with label, optional cwd |
workspace.list | List workspaces |
tab.create | Create tab in workspace |
tab.list | List tabs (optional workspace filter) |
tab.focus | Focus tab by id |
pane.split | BSP split (direction, ratio, optional cwd) |
pane.swap | Swap panes |
pane.zoom | Zoom pane (mode: toggle / in / out) |
pane.focus | Focus pane |
pane.list | List panes (optional workspace/tab filter) |
pane.read | Read visible screen text |
pane.send_text | Send text to pane PTY |
pane.send_keys | Send key sequence |
pane.send_input | Send text and/or keys |
pane.resize | Resize PTY rows/cols |
pane.write | Raw write to pane |
pane.attach | Stream pane output (subscription) |
pane.report_agent | Hook: report agent name + state |
pane.clear_agent_authority | Clear agent authority on pane |
agent.get | Agent info for target pane |
agent.send | Send text to agent pane |
agent.list | List agents (optional workspace filter) |
agent.start | Start registered agent in new/split pane |
agent.explain | Diagnose agent state heuristics |
events.subscribe | Stream filtered events |
events.wait | Block until matching event (timeout) |
worktree.create | Git worktree helper |
worktree.list | List worktrees |
worktree.remove | Remove worktree |
server.live_handoff | Graceful server restart (layout preserved) |
server.stop | Acknowledge stop (server may exit) |
Methods marked Stream return an initial result then additional NDJSON event lines on the same connection.
CLI mapping
| Automation need | CLI |
|---|---|
| Rich status dashboard | flock herd status |
| Attach to pane | flock herd attach --pane <id> |
| Wait for agent idle | flock herd wait --pane <id> --status idle |
| Install agent hooks | flock integration install <agent> |
| Remote over SSH | flock remote --ssh user@host |
Agent detection
Screen heuristics detect Claude, Codex, and Cursor agent states (idle / working / blocked). Hooks via pane.report_agent provide authoritative state when integrations are installed.
Live handoff
server.live_handoff writes ~/.config/flock/sessions/handoff.json, spawns a replacement daemon, and releases the socket. PTY processes are not preserved across handoff — layout and visible text restore only.
Testing
cargo test -p flock-multiplexer
cargo test -p flock-herdr
flock multiplexer ensure
flock herd status
See Daily driver loop for the operator workflow.
Environment variables
| Variable | Default | Purpose |
|---|---|---|
FLOCK_SOCKET | ~/.config/flock/flock.sock | Multiplexer Unix socket path |
FLOCK_ENV | unset | Set to 1 in flock-managed pane shells |
RUST_LOG | info | Tracing filter for flock subcommands |
FLOCK_DOCS_URL | https://flock-docs.pages.dev | llms.txt / sitemap base URL in CI scripts |
OLLAMA_URL | unset | Optional local LLM for ignored integration tests |
Session / remote
| Variable | Purpose |
|---|---|
SSH_AUTH_SOCK | Used by flock remote --ssh for agent forwarding |
Hooks
See agent hooks for FLOCK_SOCKET in shell hook scripts.
Related
Agent guide
Onboarding for AI agents operating Flock panes — Claude Code, Codex, Cursor, and Pi. Paste this page (or llms.txt) into your agent context before driving Flock.
What you are operating
Flock is a coordination runtime, not a chat router. Agents coordinate through:
- Blackboard — typed JSON slots
- Pheromone field — decaying zone signals that wake the scheduler
- Multiplexer panes — PTY sessions with NDJSON socket control
Do not coordinate via agent-to-agent natural language. Use substrate tools and pane deposits.
Install (operator machine)
curl -fsSL https://raw.githubusercontent.com/Alphabetsoup16/Flock/main/install.sh | bash
export PATH="$HOME/.cargo/bin:$PATH" # if install.sh used cargo install
Verify:
flock run --goal "reach target" --plugin gridworld
ls .flock/episodes/
Daily-driver loop
flock multiplexer ensure # start socket server
flock dashboard # ratatui control tower (optional)
flock herd status # agent states across panes
flock run --goal "..." --plugin shell --mcp
Episode flywheel: flock run → .flock/episodes/*.json → flock evolve → flock drift-check.
Agent-specific pane setup
| Agent | Start in pane | Hook install |
|---|---|---|
| Claude Code | claude in pane | flock integration install claude |
| Codex | codex in pane | flock integration install codex |
| Cursor | Cursor terminal or cursor CLI | MCP via flock mcp (see below) |
| Pi | pi in pane | Use Pi programmatic/RPC mode in pane |
Spawn via socket API:
{"id": 1, "method": "agent.start", "params": {"name": "claude", "focus": true}}
Or CLI: flock herd attach --pane <id> after flock herd status.
MCP workflow (Cursor and headless agents)
- Operator wires
flock mcpin MCP settings (Cursor setup). - Agent calls
flock_search_tools→flock_describe_tool→ invoke. - For live substrate during episodes, operator runs
flock run --mcp.
Key tools: flock_deposit_signal, flock_read_blackboard, flock_topology_snapshot, flock_multiplexer_status.
Full catalog: MCP tools.
Socket automation (HerdR-shaped)
Connect to ~/.config/flock/flock.sock. One JSON request per line.
{"id": 1, "method": "ping", "params": {}}
{"id": 2, "method": "agent.list", "params": {}}
{"id": 3, "method": "pane.read", "params": {"pane_id": "w1:p1", "lines": 40}}
{"id": 4, "method": "events.wait", "params": {"match_event": {"agent_status": "idle"}, "timeout_ms": 60000}}
Full method table: Socket API.
Diagnosis recipes
| Symptom | Check | Fix |
|---|---|---|
| No socket | flock herd status fails | flock multiplexer ensure |
| Agent stuck “working” | flock herd agent explain --pane <id> | Wait or pane.report_agent hook |
| MCP tools missing | Cursor MCP panel | Restart Cursor; verify flock mcp path |
| Episode not written | flock run exit code | Run with --json; check plugin goal |
| Drift rejected | flock drift-check output | Review flock.toml governance section |
Flags agents should know
| Command | When |
|---|---|
flock run --json | Headless NDJSON contract (episode_start … episode_end) |
flock run --mcp | Live MCP tools on running engine |
flock run --rlm | RLM verify/act loop |
flock remote --ssh user@host | Remote pane farm |
flock evolve --episodes N | Topology mutation from corpus |
Do not invent flags — verify with flock --help or CLI reference.
Skills
Flock scans .flock/skills/ and ~/.cursor/skills/ on flock run. Author skills as SKILL.md with frontmatter; install via Cursor skills UI or copy into project.
Honest limits
- Flock is not OpenCode/Claude Code — no built-in 75-provider coding agent on the hot path.
- Default
flock runuses deterministic plugins; wire your LLM via MCP or panes. - Agent-to-agent chat coordination is forbidden by design.
Cursor setup
Use Flock in Cursor via MCP (flock mcp). ACP is available for experiments but MCP is the primary editor path.
Install
git clone https://github.com/Alphabetsoup16/Flock.git && cd Flock
./install.sh
export PATH="$PWD/target/release:$PATH"
Wire MCP in Cursor
Add a server entry to Cursor MCP config (Settings → MCP, or ~/.cursor/mcp.json):
{
"mcpServers": {
"flock": {
"command": "/path/to/Flock/target/release/flock",
"args": ["mcp"]
}
}
}
Set command to your built target/release/flock path. Restart Cursor.
Discovery flow: flock_search_tools → flock_describe_tool → invoke. Full catalog: MCP tools.
First smoke
flock run --goal "reach target" --plugin gridworld
flock run --goal "reach target" --plugin gridworld --json
flock mcp
MCP vs ACP
| Path | Cursor use |
|---|---|
flock mcp | Primary — tool discovery, substrate read/write |
flock acp | Experimental — in-process prompt bridge only |
Skills and memory
Skills: .flock/skills/ and ~/.cursor/skills/ are both scanned on flock run.
Memory is the substrate (blackboard, field, episodes) — see Memory architecture. Vector RAG is deferred; hybrid SQLite/Turso plan is documented in-repo under docs/MEMORY_ARCHITECTURE.md (not yet migrated to this book).
Agent onboarding
For paste-into-agent context: Agent guide.
ACP (Agent Client Protocol)
Flock ships an ACP v1 stdio agent via flock acp. Editors such as Zed can spawn Flock as an external coordination agent — scheduler-primary runs that produce episodes, not chat transcripts.
MCP remains the primary Cursor integration path. See Cursor setup.
Capabilities
| Method | Status |
|---|---|
initialize | Protocol v1, camelCase agent capabilities |
session/new | Binds sessionId → flock-memory acp_sessions |
session/prompt | Runs FlockEngine + persist_episode_bundle; emits session/update stream |
session/resume | Restores checkpoint metadata (no chat replay) |
session/load | Replays episode metadata via session/update notifications |
session/cancel | Aborts in-flight prompt task |
session/close | Cancels + marks session closed |
permissions/request | Governance pipeline; set FLOCK_ACP_AUTO_DENY=1 in CI |
prompt | Deprecated alias for session/prompt |
Phase 2 ships async streaming notifications, tool bridge (flock_* registry), and permission UX. Phase 3 enables in-process mux episodes (context.mux: true or FLOCK_MUX_AUTO=1).
Diagnostics
flock acp doctor
Prints protocol version, agent capabilities, memory backend, and env flags (FLOCK_MUX_AUTO, FLOCK_ACP_AUTO_DENY).
Zed smoke (5 steps)
- Build Flock:
cargo build --release -p flock-cli - Copy examples/zed-acp.json into your Zed settings agents list (adjust
commandpath). - Open a workspace with a
.flock/directory (or let Flock create one on first prompt). - Start the Flock agent in Zed and send:
reach targetwith context plugingridworld. - Confirm the agent returns
stopReason: completed, ≥3session/updatenotifications, and.flock/episodes/<goal_id>.jsonexists.
Mux episodes
Set "mux": true in prompt context or export FLOCK_MUX_AUTO=1 when a multiplexer socket is healthy. ACP attaches pane_tree to persisted episodes for evolve flywheel compatibility.
Limitations
- No full chat transcript replay on
session/load— episode metadata only (MEMORY_ARCHITECTURE). - External editor MCP servers are bridged for
flock_*tools only in Phase 2; shell/file tools remain editor-side. - crates.io publish for library crates is dry-run only until the API stabilizes.
Related
- Engineering plan:
docs/ACP_IMPLEMENTATION_PLAN.mdin the repository (not published in this book) - CLI reference —
flock acp - Deployment — releases
MCP overview
Flock exposes stigmergy and harness tools via flock mcp (stdio CLI) and live episodes (flock run --mcp).
Start the server
flock mcp
Wire your MCP client to stdin/stdout JSON-RPC (same surface as cargo run -p flock-mcp).
Quick tool list
| Tool | Description |
|---|---|
flock_discover_tools | Browse tool domains |
flock_search_tools | Keyword search |
flock_describe_tool | Full schema for one tool |
flock_deposit_signal | Deposit stigmergic signal |
flock_read_blackboard | Read blackboard slot |
flock_topology_snapshot | Harness topology JSON |
flock_multiplexer_status | Dashboard statusline |
flock_propose_mutation | Topology mutation (governed) |
Full catalog with live-column and governance notes: MCP tools.
Operational tools in LIVE_TOOL_NAMES are available on flock run --mcp (see crates/flock-runtime/src/mcp/registry.rs).
Live episode example
{
"mcp_tools": [
{
"tool": "flock_deposit_signal",
"args": { "zone": "grid", "signal": "coordination", "amount": 2.0 }
}
]
}
Governance pre/post hooks apply on the MCP hot path when --mcp is set.
Editor integration
- Cursor setup — wire MCP in Cursor settings
- Agent guide — onboarding for Claude/Codex/Cursor/Pi
Statusline and observability
Flock exposes two complementary observability surfaces:
statusline.json— dashboard pane/agent snapshot (MCP-readable)flock run --json— typedflock-eventsNDJSON stream
Both are produced by the same runtime; they serve different consumers.
statusline.json
Written by flock dashboard to ~/.config/flock/statusline.json (override with workspace config).
{
"connected": true,
"socket": "/Users/you/.config/flock/flock.sock",
"agents": { "total": 3, "idle": 1, "working": 1, "blocked": 0, "done": 1, "unknown": 0 },
"selected": { "pane_id": "w1:p1", "agent": "claude", "status": "working" },
"vitals": { "circulation_score": 0.82, "deferred_ratio": 0.1, "cold_zone_count": 0, "herdr_pulse": 0.4 },
"live_pressure": { "zone_intensity": {} },
"telemetry": { "agent_transitions": 42 }
}
MCP read path
Use flock mcp tools or flock dashboard --history for headless telemetry queries.
flock-events schema (--json)
flock run --json emits one serde-tagged event per line. Canonical variants:
| Event | When |
|---|---|
episode_start | Before scheduler loop |
scheduler_tick | Each tick |
wake_summary | After dispatch batch |
task_dispatched | Per dispatched task |
verify_result | Plugin verify |
tool_decision | MCP / governance tool path |
permission_denied | Governance deny |
budget_exhausted | Dispatch cap hit |
deposit | Pheromone deposit |
archive_write_back | Post-run archive merge |
episode_end | After episode JSON written |
Multiplexer events.subscribe can bridge the same schema via EmittedEvent::from_flock_event.
Related
Engineering guide
Rust conventions for Flock contributors. Guardrail enforcement lives in governance policies.
Toolchain
- Pin via
rust-toolchain.toml - Format:
cargo fmt --all - Lint:
cargo clippy --workspace --all-targets -- -D warnings
Verification
./scripts/verify.sh
flock drift-check
Crate boundaries
| Crate | Responsibility |
|---|---|
flock-core | Types: Goal, EpisodeLog, topology |
flock-runtime | Scheduler, engine, MCP hot path |
flock-events | Unified observability schema |
flock-cli | Operator surface |
flock-multiplexer | PTY + socket API |
Docs
- Book is canonical public docs (
book/src/) docs/holds specs and staging; do not link GitHub blobs from book pages
Related
Documentation style
Guidelines for Flock book pages.
Voice
- Honest scope — say what Flock is not early
- Operator-first — copy-paste commands that produce visible artifacts
- No placeholder social proof
Formatting
- One H1 per page (mdbook enforces)
- Use
> **Note**/> **Warning**admonitions - Mermaid diagrams: no inline
style fill:#...(breaks dark mode) - Max 3 columns in comparison tables
Links
- Relative book links only — never link to raw GitHub
docs/blobs from book pages - Cross-link concepts ↔ reference ↔ integrations
Brand tokens
See book/theme/css/custom.css for Flock palette (--flock-runtime, --flock-substrate, etc.).
Harness capability docs
- Single source:
docs/harness-manifest.tomldrivesdocs/HARNESS_FEATURES.mdand the landscape table indocs/COMPETITIVE_MATRIX.md. - Update workflow: edit the manifest, then
cargo run -p harness-docs -- generate. - CI:
./scripts/check-harness-doc-parity.sh(viaverify.shsmoke-docs) fails on drift.
Related
Deployment
Audience: maintainers publishing docs and configuring CI.
Documentation site (mdbook → Cloudflare Pages)
Flock docs are built with mdbook from book/ and deployed on every push to main that touches book/, docs/, or .github/workflows/docs.yml.
| Environment | URL |
|---|---|
| Production | https://flock-docs.pages.dev |
| Workers subdomain | https://flock-docs.sgoldbeg.workers.dev (may vary by account) |
Local build
cargo install mdbook mdbook-mermaid --locked # once
mdbook build book
open book/book/index.html
Live preview:
mdbook serve book --open
./scripts/verify.sh runs scripts/smoke-docs.sh, which includes mdbook build book.
CLI help snapshots
When CLI flags or subcommands change intentionally:
UPDATE_SNAPSHOTS=1 cargo test -p flock-cli cli_help_snapshot
verify.sh runs cli_help_snapshot tests (BL-014). MCP tool names must appear in MCP tools — enforced by scripts/check-mcp-doc-parity.sh (BL-015).
CI workflow
Workflow: .github/workflows/docs.yml
- Install Rust toolchain and mdbook
mdbook build book→ output inbook/book/cloudflare/wrangler-actionuploadsbook/book/to Pages projectflock-docs
Model A (canonical): GitHub Actions direct upload — not Cloudflare Git integration. Keep CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in GitHub secrets.
gh workflow run docs.yml # manual deploy
Required GitHub secrets
| Secret | Description |
|---|---|
CLOUDFLARE_API_TOKEN | Account Settings Read + Cloudflare Pages Edit |
CLOUDFLARE_ACCOUNT_ID | 32-char account ID from dashboard sidebar — not a zone ID |
Troubleshooting
| Symptom | Fix |
|---|---|
| Deploy 403 | Token lacks Pages Edit for target account |
| Wrong account ID | Copy from Workers & Pages sidebar, not zone overview |
| Dashboard build token error | Disconnect Git builds; use Model A CI upload only |
Application / CLI releases
The Flock CLI is not yet published to crates.io (API still moving). Install from source:
cargo install --path crates/flock-cli --locked
Semver tags and CI
| Step | Command / workflow |
|---|---|
| Local verify | ./scripts/verify.sh |
| Release prep (dry-run publish) | ./scripts/release-prep.sh [version] |
| Tag push | git tag -a v0.1.0 -m "Release v0.1.0" && git push origin v0.1.0 |
| GitHub Release | .github/workflows/release.yml — verify, artifact upload, changelog body |
MSRV: rust-version = "1.75" in root Cargo.toml. Release workflow pins toolchain 1.75.
Changelog: CHANGELOG.md (Keep a Changelog format).
CI runs ./scripts/verify.sh on every PR and push to main.
Related
Frontier positioning
Thesis: Flock owns stigmergic runtime coordination, verified harness recursion (RAH), and episode-grounded topology evolution — not meta-harness wrapping or workflow DSLs.
What Flock is not competing on
- claw-code / OpenClaw — single-agent coding loops and provider matrices
- Omnigent-style wrappers — composing external harnesses with policy YAML
- LangGraph / workflow DSLs — hand-drawn agent graphs
What Flock owns
| Wedge | Evidence |
|---|---|
| Pressure-field scheduler | flock run, stigmergy benches in verify.sh |
| In-tree multiplexer | HerdR-shaped socket API, no external binary |
| Topology evolution | flock evolve, .flock/topology_archive.json |
| Honest verification | flock drift-check, plugin-grounded fitness |
Adoption framing
Use Flock when coordination geometry must evolve from episode logs — not when you need a drop-in Claude Code replacement.
Related
Stigmergy ablation
Method: In-tree honest proxies — not upstream Govcraft LLM meeting-scheduling (48.5% paper benchmark).
Summary
| Bench | Stigmergy | Random / baseline | Notes |
|---|---|---|---|
Chain dispatch (stigmergy_ablation) | 5/5 zones | 0/5 zones | Dependency wake via pheromone deposits |
| Gridworld success rate (8 runs) | 100% | 100% | Both configs reach target; chain dispatch is the discriminant |
Govcraft proxy (govcraft_acceptance) | 41.7% booking rate | 8.3% booking rate | Discrete slot scheduling with PheromoneField |
| Upstream Govcraft | — | — | Requires API keys / Ollama; not bundled in-tree |
Raw JSON (CI reproduce)
{"stigmergy_chain_completed":5,"random_chain_completed":0,"stigmergy_success_rate":1.0,"random_success_rate":1.0}
{"bench":"govcraft_acceptance","mode":"in_tree_honest_equivalent","stigmergy_bookings":200,"random_bookings":40,"stigmergy_rate":0.4166666666666667,"random_rate":0.08333333333333333}
Honest labeling
- In-tree proxy:
benches/govcraft_acceptanceandbenches/stigmergy_ablationusePheromoneField+ scheduler semantics shaped after Govcraft pressure-field-experiment. - Not reproduced: LLM agent meeting scheduling at 48.5% vs 12.6% conversation baseline from the January 2026 paper.
- CI: Both benches run in
./scripts/verify.shon every PR.
Reproduce
cargo run -q -p stigmergy_ablation
cargo run -q -p govcraft_acceptance
bash docs/demo/run-ablation.sh
./scripts/verify.sh