Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Flock

Self-evolving agent coordination runtime — the harness is the flock.

Rust MIT CI verified
Install
curl -fsSL https://raw.githubusercontent.com/Alphabetsoup16/Flock/main/install.sh | bash

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

DimensionTypical harness (Claude Code, OpenCode)Flock
CoordinationScripts / chat / managerStigmergic pressure field + scheduler
TopologyFixedEvolved from .flock/episodes/
RecursionAPI subagentsRAH verified depth in multiplexer panes
ExecutionVendor PTYIn-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

TermMeaning
Binaryflock — single CLI entrypoint
ConfigLayered flock.toml → see flock.toml reference
Workspace state.flock/ — episodes, archive, local overrides
Episode path.flock/episodes/<goal-id>.json
Event namesNDJSON event field from flock-events
MCP toolsflock_* prefix — discovery via flock_discover_tools / flock_search_tools
Socket APINDJSON 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
  1. Run — scheduler-led goal loop (flock run) or RLM verify/act (flock run --rlm)
  2. Log — reproducible episode JSON with optional pane topology
  3. Evolve — topology mutations from episode corpus
  4. Gateflock drift-check manifest 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

GoalPage
First episode in 2 minutesQuickstart
Multiplexer → dashboard → runDaily driver
Cursor / Claude / Codex in panesAgent guide
NDJSON socket automationSocket API
MCP tool catalogMCP tools
Full CLI surfaceCLI 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

MethodCommandBest for
Install scriptcurl -fsSL https://raw.githubusercontent.com/Alphabetsoup16/Flock/main/install.sh | bashQuick try / operators
From clonegit clone … && ./install.shDevelopment
Cargo pathcargo install --path crates/flock-cliRust contributors
Cargo release buildcargo build --release -p flock-cliCI / 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

GoalPage
First episode walkthroughQuickstart
Multiplexer daily loopDaily driver
Agent onboardingAgent 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
  1. Multiplexerflock multiplexer ensure starts the in-tree PTY server (~/.config/flock/flock.sock).
  2. Dashboardflock dashboard opens the ratatui control tower (agents, pressure, pane tree). Writes ~/.config/flock/statusline.json for MCP observability.
  3. Runflock run --goal "…" --plugin gridworld (scheduler) or --rlm (verify/act loop with mux pane topology).
  4. Evolveflock evolve --episodes 16 --workspace .flock/episodes mutates topology from episode corpus.
  5. Verify./scripts/verify.sh before 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

See Dashboard and Verify.

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

KeyAction
j / kSelect agent up/down
EnterAttach to selected pane (Ctrl+Q to detach)
rRefresh agents + layout snapshot
qQuit

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 boundaryFlockPlugin::verify_goal drives the default flock run loop
  • An in-tree multiplexer — HerdR-shaped NDJSON socket API + PTY panes
  • A topology evolution loopflock evolve mutates wake maps from episodes
  • Governance-awareflock.toml hooks, 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

NeedFlockclaw-code / OpenClaw
Daily coding agentUse flock acp or external editor + MCPPrimary product
Multi-pane agent farmIn-tree multiplexer + dashboardExternal tmux scripts
Topology evolutionflock evolve + archiveNot in scope
Stigmergy / pressure fieldCore schedulerNot in scope
Provider matrixOptional verify-path LLM onlyHot-path feature

Honest adoption path

NeedUse
Prove coordination thesisflock run, swarm-demo, Govcraft bench in verify.sh
Editor integrationflock acp (stdio + prompt → engine)
External tool bridgeflock mcp or flock run --mcp
Remote pane farmflock remote --plugin <name> with governance
Cursor / Claude daily driverPair 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.

Verify

The single verification entry point is ./scripts/verify.sh:

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo hack check --workspace --each-feature --no-dev-deps
  • cargo 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

  1. Start multiplexer: flock herd server
  2. Attach session: flock herd attach
  3. 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

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

PatternStatus
Deposit completion → dependent task wakesAllowed
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 passingForbidden
Router LLM choosing next agentForbidden
Re-encoding substrate state as NL for coordinationForbidden

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:

  1. Encode initial task from plugin manifest primary zone
  2. Tick field decay → refresh pressure → dispatch ready batch (parallel, budget-limited)
  3. Read host output → apply pheromone deposits → coordinate (boids) in plugin zone
  4. Verify via plugin → deposit completion → enqueue retries/delegates
  5. 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

Flock memory is the coordination substrate plus durable episode artifacts — not a vector store or chat transcript archive.

Layers

LayerWhereRole
HotIn-process blackboard + pheromone fieldLive stigmergy (decay, wake, dispatch)
Warm.flock/ JSON today; .flock/memory.db plannedEpisodes, traces, checkpoints, topology archive
ColdTurso 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 evolve reads episode_metrics aggregates instead of scanning full episode JSON
  • substrate_heatmap() and plugin_grounded_fitness() use SQL-native corpus aggregates
  • MCP flock_query_field_history queries 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
  1. FlockGenome expresses coordination + decay params at episode end
  2. PheromoneField circulation → CirculationVitals in episode
  3. flock evolve mutates or crossover (Pareto ≥ 2) → immune_report() gates accept
  4. Quarantined genomes excluded from archive.nearest() seed
  5. 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

PhaseDeliverableStatus
1 Circulationcirculation_vitals, flock vitals, fitness dimension
2 DNAgenome_id lineage, archive seed reconstruction, flock genome
3 Immunedrift + fitness + immune gate, quarantine, fever deposit
4 Expressionper-zone decay, crossover, flux-grid test, fever unit test

flux-grid (optional)

  • Feature: flock-substrate/flux-grid (vendored 64×64 Stigmergy grid)
  • Not enabled in default builds — zone-keyed PheromoneField remains default substrate
  • Enable for experiments: cargo build -p flock-substrate --features flux-grid

Known deferred

  • flux-grid in swarm-demo default path
  • Full parent_ids lineage CLI (crossover sets parent_ids; CLI shows primary parent_genome_id only)
  • RAH_MAX_DEPTH in flock-core (cycle avoidance with flock-evolveflock-rah)

See also

Topology evolution

Frontier bet: evolution that changes coordination geometry, not prompts.

What this proves

  1. Episode logs from real flock run / swarm-demo runs ground fitness via plugin_grounded_fitness().
  2. flock evolve --episodes 10 runs accept/reject over generations (drift + immune gates).
  3. Drift gate: incompatible candidates are rejected on the production path; drift_rejected and drift_violations appear in CLI JSON when the gate fires.
  4. 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.

Evolve → run round-trip

Loop: episodes → evolve → archive → seed run → write-back fitness

Overview

Flock closes the loop between topology evolution and production runs:

  1. flock evolve — mutates harness topology from episode corpus; writes .flock/topology_archive.json
  2. flock run --seed-archive — seeds topology/coordination from nearest archive entry; logs genome_id + genome_seed event
  3. 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 archive
  • fitness — plugin-grounded success score
  • events[] containing genome_seed and (when write-back applies) archive_write_back

Write-back semantics

  • Trigger: GoalStatus::Satisfied and both genome_id + fitness present
  • Merge: TopologyArchive::write_back_fitness updates 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.

Governance overview

Flock ships two governance surfaces:

  1. Manifest drift-checkflock drift-check enforces required CI checks, style files, and deprecation notices. See policies.
  2. Runtime hooksflock.toml session 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

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

ConcernCanonical location
Required checks listcrates/flock-governance/src/manifest.rs
Check enforcementflock drift-check (also invoked by drift-guard.sh)
Full verificationscripts/verify.sh
Code styleEngineering guide
License / advisory policydeny.toml

When adding a new required check:

  1. Add a ManifestCheck entry to manifest.rs.
  2. Implement validation in run_drift_check.
  3. If the check belongs in the full suite, add it to verify.sh.
  4. 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.sh
  • scripts/drift-guard.sh
  • .github/workflows/**
  • crates/flock-governance/src/manifest.rs
  • rust-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-check and ./scripts/verify.sh both pass in CI.
  • No allow(dead_code) in crate sources without removing the check from manifest (not permitted).

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:

EventPayload fields
SessionStartgoal_id, plugin
SessionEndgoal_id, status
PreToolUsetool, argv, agent_id
PostToolUsetool, argv, success

Invocation paths

PathWhen hooks run
flock runSessionStart/SessionEnd on episode boundaries; PreToolUse/PostToolUse on MCP tool calls and shell plugin execution via ToolGovernancePipeline
flock run --rlmSame session hooks; mux delegate steps use nested sub_harness panes
Shell pluginPreToolUse/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

AgentSuggested hook point
Claude CodeWrap claude in a shell function; call hook on tool-approval and turn-complete
CodexExport CODEX_HOOK_CMD pointing to the script above
CursorUse 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

VariablePurpose
FLOCK_SOCKETOverride default ~/.config/flock/flock.sock
FLOCK_ENV=1Set in spawned pane shells (detect flock-managed sessions)

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

ModeCommandUse
Pollflock herd statusHeadless CI, scripts
Proxyflock herd attachDaily-driver TTY

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 loops
  • CrucibleAdapter — verify + automatic remediation hints (CruciblePluginAdapter)

Coordination hooks (optional, via context at runtime):

  • PluginContext — blackboard read/write, budget snapshot
  • CoordinationContext — zone list, perception radius, deposit_signal / read_signal

Current plugins

PluginKindLLMDescription
gridworldSimulatorNoDeterministic 5×5 grid; agents navigate to target; boids coordination deposits
shellExecutorNoBounded subprocess (argv, cwd, timeout); exit code + output verification
crucibleAdapterNoWraps any FlockPlugin with remediation on failure

Lifecycle

register → encode → scheduler run → verify → episode snapshot → evolve fitness
  1. RegisterPluginRegistry::builtin() loads built-ins + manifest TOML
  2. Encodeencode_task(goal) produces initial TaskDescriptor payload
  3. Run — scheduler enqueues in plugin primary zone; host executes; observations flow back
  4. Verifyverify_goal returns AgentReport with NextAction
  5. Episode — runtime writes .flock/episodes/<goal-id>.json
  6. Evolveflock evolve reads episodes; plugin name in environment_fingerprint seeds 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

ExtensionLocation
Pluginsflock-plugin-api, flock-plugins
RunHost backendsflock-runtime::RunHost, flock-rah, flock-herdr
Evolve hooksflock-evolveGepaHook, EpisodeLogProposer
Governanceflock-governanceVERIFICATION_MANIFEST
Multiplexerflock-multiplexer — pane deposits → observations

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):

  1. CLI flags — e.g. --goal, --plugin, --json
  2. Environment variables — e.g. FLOCK_MUX_AUTO, FLOCK_SESSION_SPEND_CAP_USD
  3. Layered config files — see flock.toml

Output modes

ModeFlag / entrypointUse when
Human textdefaultInteractive terminal
NDJSON eventsflock run --jsonCI, automation, log pipelines
MCP stdioflock mcpCursor, Claude Desktop, other MCP clients
ACP stdioflock acpEditor-class agents (Zed, experimental)
Socket NDJSONflock multiplexer serverDashboard, 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

CommandPage
runrun
evolveevolve
remoteremote
herdherd
pluginplugin
mcpmcp
telemetrytelemetry
doctordoctor
replayreplay
swarm-demo, rah-demodemos

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

FlagDefaultNotes
--goalrequired unless --resumeNatural-language goal text
--plugingridworldVerifier plugin (flock plugin list)
--resumeoffContinue from .flock/checkpoints/ (optional goal UUID; default latest)
--rlmoffIn-tree RLM verify/act loop
--max-steps8Max RLM steps when --rlm
--jsonoffNDJSON flock-events on stdout
--mcpoffProcess mcp_tools from observation payload
--muxoffScheduler-led run via in-process multiplexer panes
--seed-archiveoffSeed topology from evolve archive before run
--write-backauto with --seed-archiveMerge 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

EventSummary
episode_startgoal_id, plugin, goal
scheduler_ticktick, pending
task_dispatchedtick, task_id, zone
verify_resulttick, zone, goal_met
cost_rollupper-tick usd, tokens, session total_usd, total_tokens
depositzone signal deposit
archive_write_backoptional genome merge
episode_endgoal_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

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

FlagDefaultNotes
--episodes10Generations to run
--workspace.flock/episodesEpisode JSON corpus directory
--hookrustProposer hook (seed-only for fixture tests)
--summarizeoffWrite .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

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

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

FlagNotes
--goalRequired goal text
--pluginVerifier plugin (default gridworld)
--socketMultiplexer NDJSON socket path
--sshRemote host for SSH attach
--stubDeterministic stub run (CI smoke)
--auditOptional 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

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

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.

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

FlagDefaultNotes
--limit20Max rows per query
--dbuser config pathOverride 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

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

StageChecks
MultiplexerDefault socket reachable
GovernanceManifest / config load
PluginsRegistry matches plugins.toml
ArchiveTopology archive readable
VitalsLatest episode circulation metrics

Recipes

Local workspace check:

flock doctor --workspace .

CI-friendly JSON:

flock doctor --json | jq .

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

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

CLI reference

The CLI reference is split into per-subcommand pages with flags tables and recipes.

Start here: CLI overview

CommandPage
runrun
evolveevolve
herdherd
remoteremote
pluginplugin
mcpmcp
telemetrytelemetry
doctordoctor
replayreplay
completionsoverview — shell completions
Demosdemos

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)

LayerPathPrecedence
User~/.flock/config.tomllowest
Projectflock.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]

KeyTypeDescription
session_spend_cap_usdfloatSession spend ceiling
max_risk_scorefloatRisk score threshold
denied_pathsstring[]Paths blocked for tool/file access

[shell]

KeyTypeDescription
allowed_commandsstring[]Allowlist for shell plugin
denied_commandsstring[]Blocked command names
denied_patternsstring[]Regex patterns to block
max_output_bytesintegerCap captured stdout/stderr

[permissions]

KeyTypeDescription
default_modeallow | ask | denyDefault MCP tool policy
[permissions.tools]mapPer-tool overrides

Permission modes filter tools/list before exposure to MCP clients.

[[hooks.hooks]]

KeyTypeDescription
eventstringHook event name
commandstringShell command to invoke

See Agent hooks.

Environment overrides

VariableMaps to
FLOCK_SESSION_SPEND_CAP_USDgovernance.session_spend_cap_usd
FLOCK_MAX_RISK_SCOREgovernance.max_risk_score
FLOCK_SHELL_ALLOWEDCSV → shell.allowed_commands
FLOCK_SHELL_DENIEDCSV → shell.denied_commands
FLOCK_DENIED_PATHSCSV → governance.denied_paths
FLOCK_PERMISSION_MODEpermissions.default_mode

Full list: Environment variables.

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 --mcpFlockEngine::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
  1. Discoverflock_discover_tools returns domain-indexed tool cards (no full schemas).
  2. Searchflock_search_tools with query (and optional domain) narrows by intent.
  3. Describeflock_describe_tool with name returns full schema, preconditions, side effects, examples.
  4. Invoketools/call or live mcp_tools observation 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

ToolDomainPurpose
flock_discover_toolsmetaBrowse domains and tool names
flock_search_toolsmetaKeyword search over catalog
flock_describe_toolmetaFull ToolSpec for one tool

Operational tools

ToolDomainSummaryLive (--mcp)Governance
flock_deposit_signalsubstrateDeposit pheromone into zoneYespre/post hooks
flock_read_signalsubstrateRead signal strengthYesread-only
flock_read_blackboardsubstrateRead blackboard slotYesread-only
flock_topology_snapshotsubstrateHarness topology JSONYesread-only
flock_metricssubstrateSession countersYesread-only
flock_multiplexer_statusmultiplexerDashboard statusline snapshotYesread-only
flock_propose_mutationevolveVerify/accept topology mutationYeshigh-impact gate
flock_recallmemoryRecall durable memory by keyYesread-only
flock_remembermemoryStore durable memory entryYespre/post hooks
flock_query_field_historysubstrateQuery pressure-field historyYesread-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

PrincipleImplementation
Progressive discoveryMeta-tools before full schemas
Context efficiencyCompact tools/list for operational tools
Live paritySame registry for flock mcp and flock run --mcp
Description qualitySummary + preconditions + side effects per tool

Adding a tool

  1. Add ToolSpec in registry.rs and register in all_tool_specs().
  2. Add handler in handlers.rs and route in call_tool_with_registry.
  3. Add name to LIVE_TOOL_NAMES if live episodes should expose it.
  4. 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

SettingDefault
Socket path$FLOCK_SOCKET~/.config/flock/flock.sock$XDG_RUNTIME_DIR/flock.sock
ProtocolOne JSON request per line; one JSON response per line
Streamingevents.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

MethodPurpose
pingHealth check; returns server and protocol version
session.snapshotFull session tree snapshot
session.attachResolve named session → workspace + pane
workspace.createCreate workspace with label, optional cwd
workspace.listList workspaces
tab.createCreate tab in workspace
tab.listList tabs (optional workspace filter)
tab.focusFocus tab by id
pane.splitBSP split (direction, ratio, optional cwd)
pane.swapSwap panes
pane.zoomZoom pane (mode: toggle / in / out)
pane.focusFocus pane
pane.listList panes (optional workspace/tab filter)
pane.readRead visible screen text
pane.send_textSend text to pane PTY
pane.send_keysSend key sequence
pane.send_inputSend text and/or keys
pane.resizeResize PTY rows/cols
pane.writeRaw write to pane
pane.attachStream pane output (subscription)
pane.report_agentHook: report agent name + state
pane.clear_agent_authorityClear agent authority on pane
agent.getAgent info for target pane
agent.sendSend text to agent pane
agent.listList agents (optional workspace filter)
agent.startStart registered agent in new/split pane
agent.explainDiagnose agent state heuristics
events.subscribeStream filtered events
events.waitBlock until matching event (timeout)
worktree.createGit worktree helper
worktree.listList worktrees
worktree.removeRemove worktree
server.live_handoffGraceful server restart (layout preserved)
server.stopAcknowledge stop (server may exit)

Methods marked Stream return an initial result then additional NDJSON event lines on the same connection.

CLI mapping

Automation needCLI
Rich status dashboardflock herd status
Attach to paneflock herd attach --pane <id>
Wait for agent idleflock herd wait --pane <id> --status idle
Install agent hooksflock integration install <agent>
Remote over SSHflock 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

VariableDefaultPurpose
FLOCK_SOCKET~/.config/flock/flock.sockMultiplexer Unix socket path
FLOCK_ENVunsetSet to 1 in flock-managed pane shells
RUST_LOGinfoTracing filter for flock subcommands
FLOCK_DOCS_URLhttps://flock-docs.pages.devllms.txt / sitemap base URL in CI scripts
OLLAMA_URLunsetOptional local LLM for ignored integration tests

Session / remote

VariablePurpose
SSH_AUTH_SOCKUsed by flock remote --ssh for agent forwarding

Hooks

See agent hooks for FLOCK_SOCKET in shell hook scripts.

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/*.jsonflock evolveflock drift-check.

Agent-specific pane setup

AgentStart in paneHook install
Claude Codeclaude in paneflock integration install claude
Codexcodex in paneflock integration install codex
CursorCursor terminal or cursor CLIMCP via flock mcp (see below)
Pipi in paneUse 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)

  1. Operator wires flock mcp in MCP settings (Cursor setup).
  2. Agent calls flock_search_toolsflock_describe_tool → invoke.
  3. 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

SymptomCheckFix
No socketflock herd status failsflock multiplexer ensure
Agent stuck “working”flock herd agent explain --pane <id>Wait or pane.report_agent hook
MCP tools missingCursor MCP panelRestart Cursor; verify flock mcp path
Episode not writtenflock run exit codeRun with --json; check plugin goal
Drift rejectedflock drift-check outputReview flock.toml governance section

Flags agents should know

CommandWhen
flock run --jsonHeadless NDJSON contract (episode_start … episode_end)
flock run --mcpLive MCP tools on running engine
flock run --rlmRLM verify/act loop
flock remote --ssh user@hostRemote pane farm
flock evolve --episodes NTopology 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 run uses deterministic plugins; wire your LLM via MCP or panes.
  • Agent-to-agent chat coordination is forbidden by design.

See What Flock is / is not.

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_toolsflock_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

PathCursor use
flock mcpPrimary — tool discovery, substrate read/write
flock acpExperimental — 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

MethodStatus
initializeProtocol v1, camelCase agent capabilities
session/newBinds sessionIdflock-memory acp_sessions
session/promptRuns FlockEngine + persist_episode_bundle; emits session/update stream
session/resumeRestores checkpoint metadata (no chat replay)
session/loadReplays episode metadata via session/update notifications
session/cancelAborts in-flight prompt task
session/closeCancels + marks session closed
permissions/requestGovernance pipeline; set FLOCK_ACP_AUTO_DENY=1 in CI
promptDeprecated 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)

  1. Build Flock: cargo build --release -p flock-cli
  2. Copy examples/zed-acp.json into your Zed settings agents list (adjust command path).
  3. Open a workspace with a .flock/ directory (or let Flock create one on first prompt).
  4. Start the Flock agent in Zed and send: reach target with context plugin gridworld.
  5. Confirm the agent returns stopReason: completed, ≥3 session/update notifications, and .flock/episodes/<goal_id>.json exists.

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.

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

ToolDescription
flock_discover_toolsBrowse tool domains
flock_search_toolsKeyword search
flock_describe_toolFull schema for one tool
flock_deposit_signalDeposit stigmergic signal
flock_read_blackboardRead blackboard slot
flock_topology_snapshotHarness topology JSON
flock_multiplexer_statusDashboard statusline
flock_propose_mutationTopology 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

Statusline and observability

Flock exposes two complementary observability surfaces:

  1. statusline.json — dashboard pane/agent snapshot (MCP-readable)
  2. flock run --json — typed flock-events NDJSON 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:

EventWhen
episode_startBefore scheduler loop
scheduler_tickEach tick
wake_summaryAfter dispatch batch
task_dispatchedPer dispatched task
verify_resultPlugin verify
tool_decisionMCP / governance tool path
permission_deniedGovernance deny
budget_exhaustedDispatch cap hit
depositPheromone deposit
archive_write_backPost-run archive merge
episode_endAfter episode JSON written

Multiplexer events.subscribe can bridge the same schema via EmittedEvent::from_flock_event.

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

CrateResponsibility
flock-coreTypes: Goal, EpisodeLog, topology
flock-runtimeScheduler, engine, MCP hot path
flock-eventsUnified observability schema
flock-cliOperator surface
flock-multiplexerPTY + socket API

Docs

  • Book is canonical public docs (book/src/)
  • docs/ holds specs and staging; do not link GitHub blobs from book pages

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
  • 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.toml drives docs/HARNESS_FEATURES.md and the landscape table in docs/COMPETITIVE_MATRIX.md.
  • Update workflow: edit the manifest, then cargo run -p harness-docs -- generate.
  • CI: ./scripts/check-harness-doc-parity.sh (via verify.sh smoke-docs) fails on drift.

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.

EnvironmentURL
Productionhttps://flock-docs.pages.dev
Workers subdomainhttps://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

  1. Install Rust toolchain and mdbook
  2. mdbook build book → output in book/book/
  3. cloudflare/wrangler-action uploads book/book/ to Pages project flock-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

SecretDescription
CLOUDFLARE_API_TOKENAccount Settings Read + Cloudflare Pages Edit
CLOUDFLARE_ACCOUNT_ID32-char account ID from dashboard sidebar — not a zone ID

Troubleshooting

SymptomFix
Deploy 403Token lacks Pages Edit for target account
Wrong account IDCopy from Workers & Pages sidebar, not zone overview
Dashboard build token errorDisconnect 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

StepCommand / workflow
Local verify./scripts/verify.sh
Release prep (dry-run publish)./scripts/release-prep.sh [version]
Tag pushgit 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.

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

WedgeEvidence
Pressure-field schedulerflock run, stigmergy benches in verify.sh
In-tree multiplexerHerdR-shaped socket API, no external binary
Topology evolutionflock evolve, .flock/topology_archive.json
Honest verificationflock 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.

Stigmergy ablation

Method: In-tree honest proxies — not upstream Govcraft LLM meeting-scheduling (48.5% paper benchmark).

Summary

BenchStigmergyRandom / baselineNotes
Chain dispatch (stigmergy_ablation)5/5 zones0/5 zonesDependency 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 rate8.3% booking rateDiscrete slot scheduling with PheromoneField
Upstream GovcraftRequires 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_acceptance and benches/stigmergy_ablation use PheromoneField + 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.sh on every PR.

Reproduce

cargo run -q -p stigmergy_ablation
cargo run -q -p govcraft_acceptance
bash docs/demo/run-ablation.sh
./scripts/verify.sh