v0.21.4 ships without release notes — here are ten changes already running on your machine


Saturday morning, you run hermes update, and the version jumps from v0.21.3 to v0.21.4. You open the release notes to find out what actually changed, and the page is a few paragraphs long with one line at the end saying the full write-up arrives with v0.22.0. That is not laziness: patch tags in the v0.21 cycle exist to give Docker images, Hermes Cloud and hosted deployments a stable anchor, and the curated documentation lands with the next minor version. The catch is that the behaviour already shipped to your machine will not wait for v0.22.0.

This post pulls out ten things from that window that are merged on main and are in this tag, each with a command you can run or a config block you can paste. None of them are internal refactors: three change your gateway topology, two change your output format or your bill, and the rest buy you back time immediately.

First, the accounting: why this tag exists

The release body is unusually direct about it. This is a patch tag that rolls up everything merged since v0.21.3 into a stable release for downstream consumers (Docker images, Hermes Cloud, hosted deployments), with full curated notes deferred to v0.22.0. Measured at commit 4b8a8134009a8727a289bcabeb0019fedd353128:

Metric Value (since v0.21.3)
Non-merge commits 5,071
Changed files 5,169 (+312,961 / −62,855)
Merged PRs 1,812
Closed issues 2,116

Docker users can pull the tag directly as nousresearch/hermes-agent:v2026.9.21; git installs still upgrade with hermes update. Everything below is ordered by how much it changes your day.

Ten things that already shipped

1. One gateway process per host, not one per profile

This is the biggest architectural convergence in the window: exactly one hermes gateway run process per host per OS user, serving every profile. The lifecycle verbs changed meaning with it. hermes -p X gateway run no longer starts a second process while the host gateway is live — it attaches: it prints the host gateway’s PID and served set and exits 0. hermes gateway start --all and restart --all now mean the one host multiplexer, and they never sweep away a gateway another profile is running.

The old switch gateway.multiplex_profiles: false is retired: it still parses, but it can no longer pin a second gateway process — it resolves exactly like an unset key, logs a warning, and points at the migration command. If you are upgrading from a per-profile topology, look at the plan before you touch anything:

hermes gateway migrate --multiplex --dry-run   # print the plan, blockers and the restarts it implies
hermes gateway migrate --multiplex             # converge for real (add --yes in non-interactive shells)

The step-by-step migration path, the three real incidents behind it (including a P1 that could delete the wrong profile’s MEMORY.md), and a post-upgrade checklist live in a separate post: One gateway per host: the multiplex-only migration. The earlier multiplex-by-default guide covers how the capability first landed.

2. Connectors: connect an app from inside the conversation

Connecting an app used to mean editing config, opening a browser and pasting keys. Now a user asks in chat to connect Notion and the backend runs the whole connection: it collects the values, shows the sign-in link, and the agent can call the new tool in the same turn. All three interactive clients draw the same setup step — a dialog in the desktop app, a callout in hermes --tui, a panel in the classic CLI. The repository ships a catalog of 65 reviewed MCP servers, 55 of which declare auth.type: oauth.

3. --format stream-json for machine-readable runs

One-shot runs can now emit JSONL:

hermes chat -q "Summarize this repository" --format stream-json

Every stdout line is one JSON object (system, text, tool_use, tool_result, result), diagnostics and the session_id: line stay on stderr, and the terminal result record carries exit_code, token stats and duration. It requires -q (or --query-file), implies quiet mode, and rejects --tui. The full event field table, the exit-code semantics (0 / 1 / 130, plus 75 for a Kanban worker) and how to consume it in a pipeline: Teaching CI to read Hermes: the stream-json event stream.

4. skills.auto_load pins skills into every new session

Three lines in config.yaml make those skills fully loaded at the start of every new session, not merely listed in the catalog:

skills:
  auto_load:
    - release-notes
    - qa-multilingual

It applies to CLI, TUI, gateway, cron and API agents, and it is profile-scoped. The injection resolves once per agent — model switches, compression and static-prefix restoration reuse the same rendered bytes — so your prompt cache stays intact. When to avoid it and how it dedupes against --skills: Pinning skills into every session.

5. mcp.discovery_concurrency stops the boot-time spawn storm

MCP discovery used to fan out with an unbounded asyncio.gather: eight stdio servers meant eight process trees spawning in the same instant, and in a multi-profile fleet every served profile ran its own pass. Connects are now bounded by mcp.discovery_concurrency, default 4, with 0 meaning unlimited:

hermes config set mcp.discovery_concurrency 2   # slower machines, tighter memory

The measurements in the PR (8 stdio servers): peak concurrency dropped from 8 to 4 at the default, with the pass taking 4.0 s → 5.6 s; setting it to 2 gave peak 2 and 13.2 s; 0 restored peak 8 and 3.5 s. You trade a slightly slower boot for no process storm.

6. hermes sessions set-journal-mode converts the store offline

If you configure database.journal_mode: delete while state.db is already in WAL mode, Hermes will never live-downgrade it — the gateway, dashboard or cron may hold uncheckpointed commits, and downgrading underneath them destroys those commits. The only escape used to be a hand-run PRAGMA. Now there is a command:

hermes sessions set-journal-mode delete                          # WAL -> rollback journal
hermes sessions set-journal-mode wal                             # back to WAL
hermes sessions set-journal-mode delete --db ~/.hermes/kanban.db # another Hermes store

It scans for holders first, refuses while any process (or its -wal/-shm sidecars) still has the file open, names each pid — command: path, and reads the header bytes back to verify the new mode. It also refuses outright on Windows, where the holder scan is unavailable, and refuses to enable WAL on a cross-VM filesystem (virtiofs/9p). Background: doctor and live WAL writers and state.db WAL inside Docker.

7. Unauthorized DMs can be politely declined

The gateway had two answers for an unauthorized DM: pair (send them through pairing) or ignore (drop it). There is now a third, with custom wording:

gateway:
  unauthorized_dm_behavior: decline
  unauthorized_dm_decline_message: "This bot is private. Ask the owner for an invite."

You can also override it per platform in that platform’s extra block. For a personal assistant reachable on a public channel, this is more professional than silence: the sender learns that the message arrived and why it was not answered.

8. session_search gained a time window and a relaxed retry

Cross-session recall now takes after / before bounds, either ISO dates or relative durations (7d, 24h, 2w):

  • after="7d" — only sessions started within the last week;
  • before="2026-09-01" — only history up to September 1 (a date-only value means midnight UTC that day);
  • the relative form before="7d" means older than a week, not the last week — easy to get backwards.

Recall also retries once with relaxed OR matching when strict matching finds nothing, so a vague “I think I mentioned the deployment thing” lands more often. The index itself was rebuilt as a fast no-LLM path earlier (see session boundaries); this fills in the time dimension.

9. A stack of small desktop wins

  • Chat/UI font picker — choose a font for the transcript and the interface separately, including readability faces like OpenDyslexic.
  • Minimize to tray — opt-in: minimizing hides windows without destroying renderers or stopping work; Close, Alt+F4 and Cmd+Q keep their existing behaviour, and the tray offers Show Hermes / Quit Hermes.
  • Tap to summon HUD — tap and release Cmd+Option on macOS, Ctrl+Alt on Windows/Linux X11, to bring the HUD forward from another app (off by default, saved per device, both keys must be released within 500 ms).
  • Per-chat status drawer — a ridge above the composer hides the status stack and git row together; each conversation remembers its choice.
  • Plugin uninstall from the Plugins hub, plus one-click local engine updates.

10. Catalog updates: video models and plugin pages

The FAL video family picked up LTX 2.5 (Lightricks’ open audio-video model: native audio, up to 20 s / 4K for image-to-video, camera-motion presets) and Kling O3 Standard (Kuaishou: multi-shot native storytelling, optional audio, 3–15 s). The plugin catalog gained a dozen community plugins (tailscale, ssh, shodan, terminal, rss, resetwatch, done-bell, kiwi, cognee and more), and every catalog plugin and author now has its own page, with the README pinned to a reviewed commit.

Worth knowing, no action needed

The same window also narrowed a batch of edges: hermes -p X update now restarts the host gateway once for the whole machine, with the notice reaching every served profile (#118108); Desktop attaches to the running host backend instead of spawning one per profile (#118246); named profiles read the root profile’s auth.json again, fixing the post-update No Codex credentials stored failures (#118373); a post-update notice addressed to a platform that never connects stops retrying instead of logging every 2 seconds forever (#118312); a managed-gateway 429 on image_generate or FAL video is reported as a rate limit and retried once instead of telling you to switch models or set FAL_KEY (#118311); and the auto-title call no longer races the reply on a single-slot self-hosted model server (#117494).

Five minutes of verification after upgrading

hermes version                        # expect v0.21.4 (tag v2026.9.21)
hermes doctor                         # storage / gateway topology warnings first
hermes gateway status                 # who serves which profiles
hermes gateway migrate --multiplex --dry-run   # upgrades from a per-profile topology: read the plan

If you run more than one profile on the box, item 1 is the one worth your time: it is simultaneously a security boundary (profiles stop reading each other’s credentials) and an availability one (one gateway restart per update instead of one per profile).

The short version

A patch tag without curated notes is normal; “no release notes” is not the same as “nothing changed”. The parts of this window worth your attention are the gateway topology convergence and the profile isolation fixes — the first decides how many processes run on your box, the second decides whether one profile can read another’s keys and memory. The rest (structured output, pinned skills, MCP boot concurrency, journal-mode conversion) are the kind of change you adopt the moment you know they exist. The full curated write-up ships with v0.22.0 and covers everything since v0.21.0; for the tag itself, see our v0.21.4 release page.