Hermes v0.20.3: The Resilience Patch — Cron Jobs That Heal Themselves


Your cron job died at 3am. No error, no notification — the scheduler panel showed everything “healthy”, and you only found out at 9am when the data was stale. This isn’t hypothetical: on 2026-08-14, Hermes’ own hosted fleet missed 4 consecutive nightly runs, and the only trace was a single unremarkable WARNING buried in a log file. v0.20.3 (tag v2026.8.16.2) is the patch for exactly this class of problem: it teaches Hermes to notice its own failures and fix them instead of leaving you the mess.

The window merged roughly 125 PRs and 250 commits. The official notes promise full curated docs with v0.21.0 — but the most valuable parts of this patch are easy to explain right now.

Cron: from “dies silently” to “heals itself”

Start with the part that hurts most. Hermes’ scheduler used to have several ways to die “healthy” — every one of them could stop jobs for hours or days while the system looked fine:

  • File-descriptor exhaustion (EMFILE): the ticker treated every lock error as “someone else holds the lock”, so an fd-exhaustion on the lock file was recorded as a successful tick — and no job ever ran again;
  • Wedged jobs: a job that errored once had its next_run_at parked in the future, invisible to every sweep, surviving gateway restarts;
  • Missed external-provider fires: when a hosted cron like Chronos never delivered a fire, the job stayed parked in the past forever.

v0.20.3 fixes all three. EMFILE is now reported honestly and the ticker attempts best-effort fd reclamation (exponential backoff, capped at 15 minutes); wedged jobs re-arm automatically on the next tick — respecting the cron expression, so a weekday-only schedule never fires on Saturday; and fires missed by external providers are caught up locally by the gateway after a grace window.

The catch-up window is configurable:

cron:
  misfire_grace_minutes: 10   # default 10; 0 or negative disables catch-up

Just as important, missed runs are finally visible. Every failed fire stamps a last_fire_error on the job record, shown as a red ⚠ Missed scheduled fire: line in hermes cron list, plus the dashboard and the agent’s own cronjob list tool output; the next successful run clears it. Instead of digging through logs to find out whether a job ran, you run:

hermes cron list

If you use an external cron provider (Chronos / hosted managed cron), run that once after upgrading to confirm nothing is pending. For the full picture of scheduling, monitoring, and preflight checks, see our complete cron automation guide.

MCP: speaking the 2026-07-28 stateless protocol

This window also landed the MCP 2.x SDK migration and end-to-end support for the stateless protocol published on 2026-07-28 — in plain terms, the new generation of MCP servers no longer requires an initialize handshake, and Hermes connects to them out of the box.

Each MCP server can declare a protocol key:

mcp:
  servers:
    my-server:
      url: https://example.com/mcp
      protocol: auto   # auto (default): try the legacy handshake, fall back to server/discover

auto costs the existing fleet zero extra round-trips, stateless probes discover-first, and legacy disables the fallback entirely. Two spec details are handled too: ttlMs/cacheScope cache hints from tools/list flow into a TTL’d schema cache, and OAuth registration follows the new spec (native application_type + RFC 9207 iss validation). More MCP configuration depth lives in our MCP context variables guide.

New providers: CommandCode and Muse Spark

Two provider additions in this window:

CommandCode (commandcode.ai) is now a first-class provider — one key covers 30+ open and closed models across the GOAT/Pro/Max/Provider plans:

hermes setup   # or set manually
export COMMANDCODE_API_KEY="your-key"
hermes --provider commandcode

Prefer Anthropic’s Messages API? The commandcode-anthropic profile speaks it with the same key. And on main (not yet in any release tag), the Meta Model API (Muse Spark) joins as a built-in plugin — --provider meta-ai works out of the box with MODEL_API_KEY auth (the META_API_KEY alias works too), offering muse-spark-1.2 and muse-spark-1.2-contributor.

Undo buttons for agent edits: /worktree and /rollback

Two Copilot-CLI-inspired commands arrived to calm the “the agent trashed my repo” anxiety.

/worktree new opens an isolated git worktree mid-session, no restart:

/worktree new my-experiment

Hermes creates .worktrees/my-experiment/ inside the repo (branch based on a freshly-fetched remote tip) and retargets the session’s terminal and file operations into it. When you’re done, the tree is kept only if it has unpushed commits, exactly like hermes -w. /worktree alone shows the active tree; /worktree list lists them all.

/rollback now defaults to safe restore: Hermes keeps a per-project ledger of every file it wrote (sha256 of each landed write), so a rollback reverts only agent-authored changes, deletes agent-created files, and preserves your hand-edits. Pass --all or --force to restore everything, and skipped files are reported with a hint. If the agent mangled a file you’d also edited by hand, this is the difference between a rescue and a disaster.

Upgrade

hermes update

Then run hermes doctor to verify the install and restart the gateway (hermes gateway). If you use an external cron provider, check hermes cron list once — make sure there’s no backlog.

The complete change list is in the v0.20.3 release notes; the previous patch’s connection-registry and MCP deep-link highlights are in our v0.20.2 breakdown.