AgentsOpen SourceFreeActiveMachine-verified· intermediate · ~10 min setup

Hermes Kanban: The Idempotent Nightly Review

A task that files itself onto the board every night and never double-books.

by Shilpa Mitra· verified 11d ago· v1.0.0

Run this workflow

CI-verified, 4/4 fixtures passing.

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.x

Side 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. 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. 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 11d ago
  • key-formatregextimeout 60s · max $0

    Expected: nightly-ops-[0-9]{4}-[0-9]{2}-[0-9]{2}

  • idempotentcontainstimeout 60s · max $0

    Expected: idempotent OK: repeat returned same id

  • no-duplicatecontainstimeout 60s · max $0

    Expected: cards titled Nightly ops review: 1

  • clean-exitexit_codetimeout 60s · max $0

    Expected: 0

Results

The 'set it and forget it' pick from the WebAfterAI guide.

Liked this workflow?

Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).