# Swarm Dispatch: Workers, Claims, Heartbeats, and Auto-Block
## Introduction: the gap between dispatch and completion
The previous articles in this series established the Council of Three — three specialist parent agents with explicit spawn protocols and reporting lines — and the shared kanban board as the single source of truth for coordination state. Both articles treated the board as a static surface: tasks exist in rows, profiles read from them, state transitions are recorded. But the board is not a bulletin board. It is a live dispatch system, and the gap between “a task is ready” and “a task is done” is filled with a protocol that must survive process death, context window eviction, and the fundamental unreliability of autonomous workers.
This article examines that protocol. Not the architecture of the board — S5.2 covered that — but the operational mechanics of how tasks move from ready to done, what happens when workers fail, and why the system blocks instead of guessing when it runs out of information.
## The dispatch algorithm
When the kanban dispatcher runs its tick, it performs a three-step matching operation. First, it queries for tasks in `ready` status. Second, it matches each ready task’s `assignee` field against the set of known profile names. Third, for each matched pair, it spawns a worker process — a fresh Hermes session with the profile’s skills, memory, and model configuration loaded into its system prompt.
The critical constraint is that the dispatcher is single-threaded per profile. If a profile already has a task in `running` status (claimed, heartbeat active), the dispatcher will not spawn a second worker for that same profile. This is not a limitation; it is a design choice. A profile represents a specific capability — a specific set of skills, a specific memory slice, a specific doctrinal focus. Running two instances of the same profile simultaneously would create race conditions on shared memory and duplicate skill loading. The board serializes per-profile work so that each worker gets a clean, uncontested execution context.
For true parallelism, the system relies on profile diversity. The Council of Three provides three parent profiles. The fleet includes 42+ profiles across child agents, specialist workers, and ephemeral microsharks. When five tasks are ready and assigned to five different profiles, the dispatcher fans out — five worker processes, five parallel execution contexts, all coordinating through the same SQLite board. The swarm is not a single entity running faster; it is multiple entities running simultaneously, each constrained to its own domain.
## The claim protocol
A worker process begins by calling `kanban_show()` to read its assigned task. This is not optional — it is the first defensive check. Between dispatch and startup, the task may have been blocked, reassigned, or archived by another profile or by the human operator. The worker must verify that it is still authorized to run before doing any work.
Once verified, the worker claims the task by writing a lock to the row. The lock contains three fields: the hostname where the worker is running, the process ID, and an expiration timestamp. The expiration is typically 15 minutes, extendable by heartbeat. Until the lock expires or the worker explicitly releases it, no other profile can claim that task.
This claim protocol is deliberately simple. It does not use distributed locks, consensus algorithms, or two-phase commit. It uses a single SQLite row with a timestamp check. The simplicity is the point: the board runs on a single machine (the MacBook Pro that hosts the Council), and SQLite’s write serialization is sufficient. If the system ever needs to distribute across multiple hosts, the claim protocol would need to evolve — but for a 42-profile fleet on one machine, a single-writer database with timestamp-based locks is exactly the right level of complexity.
## Heartbeats: the liveness signal
After claiming a task, the worker must periodically call `kanban_heartbeat()` to extend its lock. The heartbeat does two things: it pushes the expiration timestamp forward, and it records a human-readable note about current progress. A good heartbeat names what the worker is doing — “epoch 12/50, loss 0.31” or “scanned 1.2M/2.4M rows” — so the human operator can see progress without opening the task.
The heartbeat interval is configurable but defaults to a few minutes. For tasks expected to complete in under two minutes, heartbeats are skipped entirely. For long-running operations — training runs, large crawls, batch processing — the worker must heartbeat at least once per hour or risk reclamation. The dispatcher checks the last heartbeat timestamp on every tick; if it exceeds the stale threshold, the task is reclaimed and reassigned.
This is the mechanism that prevents zombie processes. A worker that crashes without completing its task will stop heartbeating. The dispatcher detects the stale lock, resets the task to `ready`, and spawns a new worker on the next tick. No human intervention required. The crashed worker’s partial work is preserved in the comment thread — the new worker reads the thread, sees what was attempted, and picks up where the previous one left off (or takes a different approach if the previous one was on a dead end).
## Auto-block: the discipline of not guessing
The most important protocol in the dispatch system is not the claim or the heartbeat — it is auto-block. When a worker encounters a situation it cannot resolve autonomously — missing credentials, an ambiguous requirement, a decision that requires human judgment — it must stop and block rather than guess.
The block protocol is a two-part signal. First, the worker calls `kanban_comment()` to write the full context into the task’s thread: what it was doing, what it found, what decision it needs. Second, it calls `kanban_block()` with a one-sentence reason that names the specific decision. The task moves from `running` to `blocked` on the board, and the human operator sees it on the dashboard.
This is a doctrinal rule, not a suggestion. The Faengz doctrine — the unification layer that governs the Council — specifies that all coordination must be auditable and all state must be durable. A worker that guesses and gets it wrong produces a durable wrong result. A worker that blocks and waits produces a durable record of what it needed and why. The blocked state is recoverable; the wrong state is expensive.
The auto-block discipline also applies to retries. When a worker is respawned after a crash, its first action is to read the comment thread from prior attempts. If the previous attempt blocked, the unblock comment should contain the human’s answer. The worker incorporates that answer and proceeds. If the previous attempt crashed without blocking, the worker diagnoses the crash — was it OOM, a bad model, a broken skill? — and either takes a different approach or blocks with a diagnostic note.
## Recovery: reclaim, reassign, retry
When a worker is stuck — crashing repeatedly, hallucinating, or blocked for too long without resolution — the human operator has three recovery options:
1. **Reclaim.** Abort the running worker immediately and reset the task to `ready`. The existing claim TTL handles this automatically if the worker dies, but reclaim is the manual fast path — useful when the worker is alive but unproductive.
2. **Reassign.** Switch the task to a different profile. This is the right response when the task was assigned to the wrong capability in the first place — a creative task assigned to a DevOps profile, or a research task assigned to an implementer.
3. **Retry.** Let the dispatcher pick up the task again with the same profile. This is appropriate when the crash was transient — an API timeout, a network blip, a model rate limit — and the same worker on the same path is likely to succeed on the next attempt.
Each recovery action is recorded as an event on the task’s audit trail. The board knows who reclaimed, who re-assigned, and how many retries occurred. This is not bureaucracy; it is the proof that the system is self-correcting. A fleet that cannot recover from worker failure is a fleet that fails on first contact with reality.
## The takeaway
The dispatch protocol is the operational nervous system of the Council. The board provides the coordination surface, but the dispatch algorithm, the claim protocol, the heartbeat mechanism, and the auto-block discipline are what make coordination *work*. They transform a static ledger of task state into a live system that survives process death, routes work to the right capability, and stops rather than guesses when it runs out of information.
For builders of multi-agent systems, the lesson is that the hard part is not the architecture — it is the protocol. Any framework can put tasks in a queue and workers in a process group. The question is what happens when a worker dies mid-execution, when a task needs information only a human can provide, when two workers claim the same task, or when a model hallucinates its completion summary. The answer is a protocol: explicit claims, periodic heartbeats, disciplined blocking, and a recovery path that preserves the audit trail. The Council chose this protocol, and it is the reason 42+ profiles can swarm without stepping on each other.




