Hermes Kanban: The Idempotent Nightly Review
A task that files itself onto the board every night and never double-books.
Run this workflow
CI-verified, 4/4 fixtures passing.
Build this with your agent
One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.
Intended Use
Anyone who wants a recurring Hermes task triggered from system cron or a webhook, where a dated idempotency key guarantees repeat triggers never create duplicate cards.
Not for
- One-off tasks (no need for an idempotency key)
- Schedules you'd rather manage inside another orchestrator
The Stack
Tested Against
hermes@0.15node@20.xSide effects & data flow
- Network
- your LLM provider, only in the non-CI worker step
- Writes
- ~/.hermes/kanban.db (the board)
- Credentials
- LLM provider key (hermes setup), for the review step only
Data privacy
- your LLM provider, only in the non-CI worker step ← the notes/state the review reads (retention: per that provider's API policy)
Prerequisites
- Hermes Agent (MIT): `curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash`
- `hermes setup` (LLM provider — only to run the review itself)
- cron (or any nightly trigger) calling the create command
- Node 20+ (used here to read the --json board state)
Steps
- 1
Create with a dated idempotency key, twice
The trick that makes a cron/webhook trigger safe: call create with `--idempotency-key "nightly-ops-$(date -u +%F)"`. CI calls it twice with the same key and asserts the second call returns the SAME task id (no duplicate) — an un-fakeable property of the board.
hermes kanban init >/dev/null mkid() { node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>process.stdout.write(JSON.parse(s).id))'; } KEY="nightly-ops-$(date -u +%F)" echo "idempotency key: $KEY" ID1=$(hermes kanban create "Nightly ops review" --assignee ops --idempotency-key "$KEY" --max-runtime 30m --json | mkid) ID2=$(hermes kanban create "Nightly ops review" --assignee ops --idempotency-key "$KEY" --max-runtime 30m --json | mkid) if [ -n "$ID1" ] && [ "$ID1" = "$ID2" ]; then echo "idempotent OK: repeat returned same id $ID1"; else echo "DUPLICATE: $ID1 vs $ID2"; exit 1; fi hermes kanban list --json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const o=JSON.parse(s);const t=Array.isArray(o)?o:(o.tasks||o.items||[]);console.log("cards titled Nightly ops review: "+t.filter(x=>x.title==="Nightly ops review").length)})' - 2
Schedule it (cron) and run the review (worker step, not CI)
Add a line like `0 3 * * * hermes kanban create "Nightly ops review" --assignee ops --idempotency-key "nightly-ops-$(date -u +%F)" --max-runtime 30m` to crontab. The dated key makes re-triggers safe; `--max-runtime` caps a stuck worker. The review itself runs a model, so CI doesn't run it.
Eval, 4 fixtures
Last passed: verified todaykey-formatregextimeout 60s · max $0Expected:
nightly-ops-[0-9]{4}-[0-9]{2}-[0-9]{2}idempotentcontainstimeout 60s · max $0Expected:
idempotent OK: repeat returned same idno-duplicatecontainstimeout 60s · max $0Expected:
cards titled Nightly ops review: 1clean-exitexit_codetimeout 60s · max $0Expected:
0
Results
The 'set it and forget it' pick from the WebAfterAI guide.
Did this work for you?
Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.
Related workflows
- One shared memory for every coding agent: prove the configs actually point at the same server
- Validate a WrenAI semantic model's references before an agent queries through it
- Wire the DeepWiki MCP into your agent so it looks up repos instead of hallucinating
- Verify an agent-skills plugin before you ship or install it
- WebMCP: declare a site's agent tools, and gate the ones that spend money
- Wire GLM-5.2 into Hermes: valid route, 64k-context check, no key in config
Liked this workflow?
Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).