The core worker lifecycle (including the `kanban_create` fan-out pattern and the "decompose, don't execute" rule) is auto-injected into every kanban process via the `KANBAN_GUIDANCE` system-prompt block. This skill is the deeper playbook when you're an orchestrator profile whose whole job is routing.
Create Kanban tasks when any of these are true:
If *none* of those apply — it's a small one-shot reasoning task — use delegate_task instead or answer the user directly.
Your job description says "route, don't execute." The rules that enforce that:
Unless the user's setup has customized profiles, assume these exist. Adjust to whatever the user actually has — ask if you're unsure.
| Profile | Does | Typical workspace |
|---|---|---|
| researcher | Reads sources, gathers facts, writes findings | scratch |
| analyst | Synthesizes, ranks, de-dupes. Consumes multiple researcher outputs | scratch |
| writer | Drafts prose in the user's voice | scratch or dir: into their Obsidian vault |
| reviewer | Reads output, leaves findings, gates approval | scratch |
| backend-eng | Writes server-side code | worktree |
| frontend-eng | Writes client-side code | worktree |
| ops | Runs scripts, manages services, handles deployments | dir: into ops scripts repo |
| pm | Writes specs, acceptance criteria | scratch |
Ask clarifying questions if the goal is ambiguous. Cheap to ask; expensive to spawn the wrong fleet.
Before creating anything, draft the graph out loud (in your response to the user). Example for "Analyze whether we should migrate to Postgres":
T1 researcher research: Postgres cost vs current
T2 researcher research: Postgres performance vs current
T3 analyst synthesize migration recommendation parents: T1, T2
T4 writer draft decision memo parents: T3
Show this to the user. Let them correct it before you create anything.
t1 = kanban_create(
title="research: Postgres cost vs current",
assignee="researcher",
body="Compare estimated infrastructure costs, migration costs, and ongoing ops costs over a 3-year window. Sources: AWS/GCP pricing, team time estimates, current Postgres bills from peers.",
tenant=os.environ.get("HERMES_TENANT"),
)["task_id"]
t2 = kanban_create(
title="research: Postgres performance vs current",
assignee="researcher",
body="Compare query latency, throughput, and scaling characteristics at our expected data volume (~500GB, 10k QPS peak). Sources: benchmark papers, public case studies, pgbench results if easy.",
)["task_id"]
t3 = kanban_create(
title="synthesize migration recommendation",
assignee="analyst",
body="Read the findings from T1 (cost) and T2 (performance). Produce a 1-page recommendation with explicit trade-offs and a go/no-go call.",
parents=[t1, t2],
)["task_id"]
t4 = kanban_create(
title="draft decision memo",
assignee="writer",
body="Turn the analyst's recommendation into a 2-page memo for the CTO. Match the tone of previous decision memos in the team's knowledge base.",
parents=[t3],
)["task_id"]
parents=[...] gates promotion — children stay in todo until every parent reaches done, then auto-promote to ready. No manual coordination needed; the dispatcher and dependency engine handle it.
If you were spawned as a task yourself (e.g. planner profile was assigned T0: "investigate Postgres migration"), mark it done with a summary of what you created:
kanban_complete(
summary="decomposed into T1-T4: 2 researchers parallel, 1 analyst on their outputs, 1 writer on the recommendation",
metadata={
"task_graph": {
"T1": {"assignee": "researcher", "parents": []},
"T2": {"assignee": "researcher", "parents": []},
"T3": {"assignee": "analyst", "parents": ["T1", "T2"]},
"T4": {"assignee": "writer", "parents": ["T3"]},
},
},
)
Tell them what you created in plain prose:
I've queued 4 tasks:
- T1 (researcher): cost comparison
- T2 (researcher): performance comparison, in parallel with T1
- T3 (analyst): synthesizes T1 + T2 into a recommendation
- T4 (writer): turns T3 into a CTO memo
The dispatcher will pick up T1 and T2 now. T3 starts when both finish. You'll get a gateway ping when T4 completes. Use the dashboard or `hermes kanban tail` to follow along.
Fan-out + fan-in (research → synthesize): N researcher tasks with no parents, one analyst task with all of them as parents.
Pipeline with gates: pm → backend-eng → reviewer. Each stage's parents=[previous_task]. Reviewer blocks or completes; if reviewer blocks, the operator unblocks with feedback and respawns.
Same-profile queue: 50 tasks, all assigned to translator, no dependencies between them. Dispatcher serializes — translator processes them in priority order, accumulating experience in their own memory.
Human-in-the-loop: Any task can kanban_block() to wait for input. Dispatcher respawns after /unblock. The comment thread carries the full context.
Reassignment vs. new task. If a reviewer blocks with "needs changes," create a NEW task linked from the reviewer's task — don't re-run the same task with a stern look. The new task is assigned to the original implementer profile.
Argument order for links. kanban_link(parent_id=..., child_id=...) — parent first. Mixing them up demotes the wrong task to todo.
Don't pre-create the whole graph if the shape depends on intermediate findings. If T3's structure depends on what T1 and T2 find, let T3 exist as a "synthesize findings" task whose own first step is to read parent handoffs and plan the rest. Orchestrators can spawn orchestrators.
Tenant inheritance. If HERMES_TENANT is set in your env, pass tenant=os.environ.get("HERMES_TENANT") on every kanban_create call so child tasks stay in the same namespace.
When a worker profile keeps crashing, hallucinating, or getting blocked by its own mistakes (usually: wrong model, missing skill, broken credential), the kanban dashboard flags the task with a ⚠ badge and opens a Recovery section in the drawer. Three primary actions:
hermes kanban reclaim ) — abort the running worker immediately and reset the task to ready. The existing claim TTL is ~15 min; this is the fast path out.hermes kanban reassign --reclaim ) — switch the task to a different profile and let the dispatcher pick it up with a fresh worker.hermes -p model since profile config lives on disk; edit it in a terminal, then Reclaim to retry with the new model.Hallucination warnings appear on tasks where a worker's kanban_complete(created_cards=[...]) claim included card ids that don't exist or weren't created by the worker's profile (the gate blocks the completion), or where the free-form summary references t_ ids that don't resolve (advisory prose scan, non-blocking). Both produce audit events that persist even after recovery actions — the trail stays for debugging.
评论区