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