Should Kanban be our Board, fed by Hermes? Yes — and it decides the per-agent-store question
Should Kanban be our Board, fed by Hermes? Yes — and it decides the per-agent-store question
Young, 2026-10-11: "Each agent own task db, that will be messy and unable to track tasks on their db. Kanban tracks everything on the plan. Goals and tasks. Should we add kanban as our Board and feed by Hermes?"
Yes. And it answers the previous question, the per-agent store question, in the same move: if the board is the upstream, then a worker does not need its own database at all — it needs an adapter.
1. What I measured before saying yes
The gap is real and it is bigger than a preference. The V3 worker does not know the board exists — measured:
grep -rn 'HERMES_KANBAN|kanban.db|kanban_db' --include='*.py' .solos
(no results — the V3 worker does NOT know the board exists)
So today, putting a task on the board does nothing to the executor. Two task systems, no bridge — the exact V2 defect ("two state machines with no bridge"), live in V3, and Young has just proposed the fix.
What the board has that we need — kanban.db carries 39 columns per task, including
everything the executor reads from a task row:
| The executor needs | Kanban has |
|---|---|
| a task id | id |
| what to do | title + body |
| who runs it | assignee |
| state | status (triage/todo/ready/running/blocked/review/done/archived) |
| priority | priority |
| retry/limits | max_retries, max_runtime_seconds |
| model pinning | model_override, provider_override |
| goal loop | goal_mode, goal_max_turns |
| claim exclusivity | claim_lock, claim_expires — atomic, built |
And the claim is the part we would have to build if we kept our own store: V2's eight concurrent writers on one JSON file produced 849 corruption events. Kanban's atomic claim already exists.
And the entry exists — operation/runtime/worker.py is the process a service runs
("drives RuntimeLoop — claim, run, sweep, heartbeat"), and serve.py is the A2A
entry. The only missing piece is the adapter between them.
2. The architecture this produces
Young / Sol / Min / Mira
│ hermes kanban create --assignee ace ...
▼
┌────────────────────────────┐
│ kanban.db (the ONE board) │ ← lifecycle truth: triage→todo→ready→running→done
│ 39 cols, atomic claims │
└────────────┬───────────────┘
│ dispatcher claims atomically (built, inside the gateway)
▼
┌────────────────────────────┐
│ V3 worker (operation/) │ ← the lane: should NOT need its own task db
│ RuntimeLoop + TaskStore │ it reads the board; "tasks.db" becomes work
│ │ NOTES, not a second registry
└────────────────────────────┘
Note the direction: the board feeds the workers, not the other way around. "Feed by
Hermes" is exactly that — the board is upstream, the executor is downstream, and a
result written back into kanban_complete means board → worker → board.
So the answer to the previous question changes: with the board as upstream, the
per-agent tasks.db files should not exist as task registries. A worker's store
becomes its attempt notebook, not a row-of-truth — the board is the row of truth.
3. 🔴 What I would do — and what it costs
The adapter is the one missing piece, and it is a read-only upstream:
| Step | What | Why it is safe |
|---|---|---|
| 1 | kanban_adapter.py: read the board (--json), map status→local_state through cortex.tasks — never a copy, always a mapping | uses the contract D2 named, so no second vocabulary |
| 2 | worker.py --db default becomes the ONE shared store, and <agent>-tasks.db becomes a notes file (attempts, results) not a registry | the ten-database defect Young flagged, resolved by the change of role |
| 3 | a task's kanban id is stored on the task row (external_task_id), so one card = one task | makes the join mechanical and the drift probe possible |
| 4 | never write status back to the board from the executor — result via kanban_comment; lifecycle truth stays on the board | Tam's rule, in our tree: a worker never owns lifecycle truth |
What this does NOT touch: the task contract (cortex/tasks/, D2), the five Heart
worker units, the A2A listener, the already-proven executor. It is one new file and
one default change.
4. What I am NOT deciding today
- Whether the dispatcher spawns the worker, or the worker polls. Tam's lane doc
says a plugin lane can supply
spawn_fn— the Heart could be claimed by the board (a card assigned toace), or it could poll for its own cards. Different failure shapes: the board-claimed model needs a fence (workers can only mutate their own card); the polling model needs a lock. Sol's lane and his call; I have not tested either live. dispatch_in_gatewayis not read on this host. The dispatcher demonstrably runs (it spawned workers), but I have never read the key's value. If it isfalse, the board→worker path above has a hole nobody can see until a card sits forever onready— which is Tam'sskipped_nonspawnableshape.- The per-agent store's "single-writer" contract (
store.pydocuments it) has not been tested with two writers on one file. The shared store needs that test before the default flips.
5. The one-sentence answer
Yes — Kanban is the board, Hermes feeds it, and with the board as upstream the
per-agent tasks.db files stop being task registries and become attempt notes. One
new file (the adapter), one default change, one probe — the V2 "no bridge" defect
cannot exist in a system with only one board.

