Files
agent-skills/devops/kanban-orchestrator/SKILL.md
Hermes Agent ccc63d1e70 first commit
2026-05-10 13:52:46 +08:00

8.4 KiB

name, description, version, metadata
name description version metadata
kanban-orchestrator Decomposition playbook + specialist-roster conventions + anti-temptation rules for an orchestrator profile routing work through Kanban. The "don't do the work yourself" rule and the basic lifecycle are auto-injected into every kanban worker's system prompt; this skill is the deeper playbook when you're specifically playing the orchestrator role. 2.0.0
hermes
tags related_skills
kanban
multi-agent
orchestration
routing
kanban-worker

Kanban Orchestrator — Decomposition Playbook

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.

Setup & Activation

Kanban is built into Hermes Agent (v0.12+). Verify it's ready:

hermes kanban stats          # shows per-status counts (works even when empty)
hermes kanban init           # create kanban.db if missing (idempotent)

Config (~/.hermes/config.yaml):

kanban:
  dispatch_in_gateway: true        # auto-dispatch tasks in gateway process
  dispatch_interval_seconds: 60    # how often dispatcher checks for new work

No separate activation step — once the config exists and gateway is running, the dispatcher loop handles claim → spawn → heartbeat → complete automatically.

When to use the board (vs. just doing the work)

Create Kanban tasks when any of these are true:

  1. Multiple specialists are needed. Research + analysis + writing is three profiles.
  2. The work should survive a crash or restart. Long-running, recurring, or important.
  3. The user might want to interject. Human-in-the-loop at any step.
  4. Multiple subtasks can run in parallel. Fan-out for speed.
  5. Review / iteration is expected. A reviewer profile loops on drafter output.
  6. The audit trail matters. Board rows persist in SQLite forever.

If none of those apply — it's a small one-shot reasoning task — use delegate_task instead or answer the user directly.

The anti-temptation rules

Your job description says "route, don't execute." The rules that enforce that:

  • Do not execute the work yourself. Your restricted toolset usually doesn't even include terminal/file/code/web for implementation. If you find yourself "just fixing this quickly" — stop and create a task for the right specialist.
  • For any concrete task, create a Kanban task and assign it. Every single time.
  • If no specialist fits, ask the user which profile to create. Do not default to doing it yourself under "close enough."
  • Decompose, route, and summarize — that's the whole job.

The standard specialist roster (convention)

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

Decomposition playbook

Step 1 — Understand the goal

Ask clarifying questions if the goal is ambiguous. Cheap to ask; expensive to spawn the wrong fleet.

Step 2 — Sketch the task graph

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.

Step 4 — Complete your own task

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"]},
        },
    },
)

Step 5 — Report back to the user

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 <id> to follow along.

Common patterns

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.

Pitfalls

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.