What Is Hermes Kanban?
Hermes Kanban is a durable multi-agent task board backed by a local SQLite database (~/.hermes/kanban.db). It lets multiple named AI profiles collaborate on work — each as a full OS process with its own identity, memory, and tools. Unlike delegate_task (which is a synchronous function call), Kanban is a persistent work queue where every handoff survives restarts, supports human-in-the-loop, and leaves a permanent audit trail.
Key difference: delegate_task = RPC call (fork → join). Kanban = Message queue + state machine with resumability, human intervention, and cross-profile collaboration.
Quick Start
# 1. Initialize the board
hermes kanban init
# 2. Start the gateway (hosts the embedded dispatcher)
hermes gateway start
# 3. Create a task
hermes kanban create "research AI funding landscape" --assignee researcher
# 4. Watch activity live
hermes kanban watch
# 5. See the board
hermes kanban list
hermes kanban stats
Complete CLI Command Cheatsheet
Task Lifecycle
| Command | What It Does |
|---|---|
hermes kanban init | Create kanban.db + print setup hint |
hermes kanban create "title" --assignee PROFILE | Create a new task |
hermes kanban list [--mine] [--status S] [--json] | List tasks with filters |
hermes kanban show <id> [--json] | Full task details |
hermes kanban assign <id> PROFILE | Assign/reassign (or ‘none’ to unassign) |
hermes kanban claim <id> [--ttl SECONDS] | Manually claim a task |
Bulk Operations (accept multiple IDs)
hermes kanban complete <id>... [--result "..."] [--summary "..."] [--metadata '{...}']
hermes kanban block <id> "reason" [--ids <id>...]
hermes kanban unblock <id>...
hermes kanban archive <id>...
Dependency Management
hermes kanban link <parent_id> <child_id>
hermes kanban unlink <parent_id> <child_id>
Monitoring & Debugging
hermes kanban watch [--assignee P] [--kinds completed,blocked,...]
hermes kanban tail <id> # live event stream for one task
hermes kanban stats [--json] # per-status + per-assignee counts
hermes kanban runs <id> [--json] # attempt history
hermes kanban log <id> [--tail BYTES] # worker log
hermes kanban context <id> # what a worker sees on spawn
hermes kanban assignees [--json] # profiles + task counts
Dispatcher Control
hermes kanban dispatch [--max N] [--dry-run] [--json] # one-shot pass, skip the 60s wait
hermes kanban daemon --force # DEPRECATED — use gateway instead
Triage & Specification
hermes kanban specify <id> # flesh out a rough idea into a full spec
hermes kanban specify --all --tenant X # sweep every triage task
hermes kanban decompose <id> # auto-fan-out into child tasks
Gateway Notifications
hermes kanban notify-subscribe <id> --platform discord --chat-id ...
hermes kanban notify-list [<id>]
hermes kanban notify-unsubscribe <id> --platform discord --chat-id ...
Multi-Board Management
hermes kanban boards list
hermes kanban boards create <slug> --name "..." --icon 🎮 --switch
hermes kanban boards switch <slug>
hermes kanban boards show
hermes kanban boards rename <slug> "New Name"
hermes kanban boards rm <slug> [--delete]
Maintenance
hermes kanban gc [--event-retention-days N] [--log-retention-days N]
hermes kanban comment <id> "text" [--author NAME]
hermes kanban heartbeat <id> [--note "..."]
Worker Tool Cheatsheet (for agents)
Workers use tool calls, not CLI commands. The dispatcher sets HERMES_KANBAN_TASK in the worker’s environment, enabling a dedicated kanban_* toolset.
| Tool | Purpose | Key Params |
|---|---|---|
kanban_show() | Read task — title, body, prior attempts, comments, parent handoffs | (none — uses env task id) |
kanban_complete(...) | Finish with structured handoff | summary, metadata |
kanban_block(reason) | Escalate for human decision | reason |
kanban_heartbeat(note) | Signal liveness during long ops | note (optional) |
kanban_comment(task_id, body) | Append durable note to thread | task_id, body |
kanban_create(title, assignee) | Fan out (orchestrators only) | title, assignee, parents, skills |
kanban_link(parent_id, child_id) | Add dependency edge | parent_id, child_id |
kanban_show(task_id) | Read any task (orchestrators) | task_id |
Typical worker turn:
kanban_show() # orient — reads env task
# ... do work in $HERMES_KANBAN_WORKSPACE ...
kanban_heartbeat(note="4/8 files done")
# ... more work ...
kanban_complete(
summary="Shipped rate limiter — token bucket, 14 tests pass",
metadata={"changed_files": ["limiter.py", "tests/test_limiter.py"], "tests_run": 14}
)
Collaboration Patterns & Solutions
1. Research Pipeline (Fan-out + Synthesis)
Problem: You need research from multiple angles merged into one report.
Solution: Orchestrator creates 2+ parallel researcher tasks, then a writer task with parent dependencies.
kanban_create(title="research ICP funding, NA", assignee="researcher-a")
kanban_create(title="research ICP funding, EU", assignee="researcher-b")
kanban_create(title="synthesize into brief", assignee="writer",
parents=["t_r1", "t_r2"]) # auto-promotes when both complete
2. Human-in-the-Loop
Problem: Worker needs a decision it can’t make alone.
Solution: Worker calls kanban_block(reason="..."). Human sees it on dashboard or gets gateway notification. Human comments context, then unblocks via /kanban unblock <id>. Dispatcher re-spawns the worker on next tick.
kanban_comment(task_id, body="Full context: user IPs from CF headers, some behind NATs...")
kanban_block(reason="Rate limit key: IP (simple, NAT-unsafe) or user_id (requires auth)?")
3. Scheduled Ops (Cron + Kanban)
Problem: Recurring work that should build a journal over time.
Solution: Use hermes cron to create a task periodically, or use the idempotency key pattern to avoid duplicates.
hermes kanban create "nightly ops review" \
--assignee ops \
--idempotency-key "nightly-ops-$(date -u +%Y-%m-%d)"
4. Fleet Farming (One Profile, Many Subjects)
Problem: One specialist managing N independent workstreams (e.g., 50 social accounts).
Solution: Same profile assigned to multiple tasks with different workspaces or tenants.
hermes kanban create "post for account A" --assignee social --workspace dir:~/accounts/A/
hermes kanban create "post for account B" --assignee social --workspace dir:~/accounts/B/
5. Retry with Context
Problem: A task failed; the next attempt should know what went wrong.
Solution: kanban_show() returns prior runs with outcomes and errors. The retry worker reads these automatically — no need to repeat failed paths.
# Worker reads prior runs from kanban_show():
# Run 1: blocked — "need decision on rate-limit key"
# Run 2: completed — "implemented token bucket..."
hermes kanban runs t_abcd # human view of attempt history
6. Circuit Breaker (Auto-Block on Repeated Failure)
Problem: A task keeps failing and you don’t want it thrashing.
Solution: Dispatcher tracks consecutive failures. After kanban.failure_limit (default 2), the task auto-blocks with the last error as reason. Use per-task override:
hermes kanban create "risky task" --assignee researcher --max-retries 5
7. Multi-Tenant Isolation
Problem: One fleet serving multiple businesses with data isolation.
Solution: Tag tasks with --tenant. Workspace paths and memory prefixes are scoped per tenant.
hermes kanban create "monthly report" --assignee researcher \
--tenant business-a --workspace dir:~/tenants/business-a/data/
8. Board-Based Project Separation
Problem: Unrelated streams of work mixing on one board.
Solution: Create separate boards — each gets its own SQLite DB, workspaces, and logs. Workers spawned for a task can only see their board.
hermes kanban boards create atm10-server --name "Minecraft Ops" --icon 🎮 --switch
hermes kanban --board atm10-server list
hermes kanban --board default list
Task Creation Options
hermes kanban create "title" \
--assignee PROFILE # required for dispatch
--body "..." # full spec, links, acceptance criteria
--parent <id> # dependency (repeatable)
--tenant NAME # multi-tenant scoping
--workspace scratch|dir:<path>|worktree|worktree:<path>
--branch NAME # for worktree workspaces
--priority N # dispatcher tiebreaker
--triage # park in triage column
--idempotency-key KEY # dedup for retried automation
--max-runtime 30m|2h|1d|<s> # per-task runtime cap
--max-retries N # circuit breaker override
--skill NAME # pin specialist skills (repeatable)
--json # machine-readable output
Event Reference
Every transition appends to task_events. Filter with hermes kanban watch --kinds:
| Category | Kinds |
|---|---|
| Lifecycle | created, promoted, claimed, completed, blocked, unblocked, archived |
| Edits | assigned, edited, reprioritized, status |
| Worker telemetry | spawned, heartbeat, reclaimed, crashed, timed_out, stale, spawn_failed, protocol_violation, gave_up, respawn_guarded |
Dashboard Quick Reference
- Open:
hermes dashboard→ “Kanban” tab - Columns: triage → todo → ready → running → blocked → done (+ archived toggle)
- Drag-drop: Move cards between columns to change status
- Inline create: Click + on any column header
- Multi-select: Shift/ctrl-click cards for bulk actions (reassign, archive, status change)
- Card drawer: Click a card → edit title, assignee, priority, description (markdown), dependencies, comments
- Triage auto-decompose: Toggle Orchestration pill (Auto/Manual). Auto = dispatcher fans out triage tasks into specialist child tasks
- Live updates: WebSocket — changes appear instantly across all surfaces
- Lanes by profile: Toggle to group Running column by assignee
Key Config Options (~/.hermes/config.yaml)
kanban:
dispatch_in_gateway: true # dispatcher runs inside gateway
dispatch_interval_seconds: 60 # sweep interval
failure_limit: 2 # consecutive failures before auto-block
dispatch_stale_timeout_seconds: 14400 # 4h — reclaim stale runs
auto_decompose: true # auto-fan-out triage tasks
auto_decompose_per_tick: 3 # cap per tick
orchestrator_profile: "" # profile for decomposition (falls back to default)
default_assignee: "" # fallback for unknown profiles
dashboard:
kanban:
default_tenant: "" # preselect tenant filter
lane_by_profile: false # group running by assignee
include_archived_by_default: false
render_markdown: true
Workspace Types
| Kind | What It Is | Use For |
|---|---|---|
scratch | Fresh tmp dir, auto-GC’d on archive | One-off research, quick tasks |
dir:<absolute-path> | Shared persistent directory | Obsidian vaults, mail ops, per-account folders |
worktree | Git worktree (auto-created) | Coding tasks — isolated branch |
worktree:<path> | Git worktree at pinned path | Shared repo worktrees |
Common Pitfalls & Gotchas
- Gateway must run: Without
hermes gateway start, ready tasks sit idle.hermes kanban createwarns about this. - Assignees must be real profiles: The dispatcher silently fails on unknown assignee names. Use
hermes kanban assigneesto verify. - Workers use tools, not CLI: Don’t shell out to
hermes kanbanfrom inside a worker — it won’t exist in container backends. Use thekanban_*toolset. - Protocol violation: If a worker exits without calling
kanban_completeorkanban_block, the dispatcher auto-blocks the task. - Stale reclaim: Running >4h with no heartbeat in the last hour → task returns to ready. Call
kanban_heartbeatat least hourly. - Board isolation: Workers spawned for a task can only see their board. Cross-board linking is rejected.
- Single-host by design: No multi-host coordination. Run independent boards per host.
- Dashboard security: Plugin routes are unauthenticated (localhost by default). Don’t bind to 0.0.0.0 on shared hosts.
Source: Hermes Agent Docs — Kanban
