Hermes Agent

Hermes moves turn ownership into the database

Hermes proposes a database-backed cross-process turn lease, a handle registry for messaging running subagents and atomic WhatsApp auth-state persistence. Together the records move coordination and custody out of process memory and into durable, inspectable state.

← Back to homeOriginal source ↗

NousResearch/hermes-agent PR #84145 is the inspected primary source: “feat(state): DB storage layer for the cross-process turn lease (#67442).” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- NousResearch/hermes-agent PR #84145 was created 2026-08-11T22:56:24Z and was open at inspection; its title is “feat(state): DB storage layer for the cross-process turn lease (#67442).” - NousResearch/hermes-agent PR #83907 was created 2026-08-11T13:18:41Z and was open at inspection; its title is “feat: add subagent-handles plugin (handle registry + mid-flight messaging).” - NousResearch/hermes-agent PR #84180 was created 2026-08-12T00:50:42Z and was open at inspection; its title is “fix(whatsapp-bridge): persist auth state atomically so a full disk can't erase the paired session.” - The repository reported 229034 stars, 31106 open issues, default branch main, and last push 2026-08-12T00:56:47Z. - The latest tagged-release baseline checked was v2026.8.3 published 2026-08-03T16:57:52Z.

What changed

NousResearch/hermes-agent PR #84145 reports: What Adds the DB-level storage contract for the cross-process turn lease (#67442): a turn_leases table plus try_acquire_turn_lease / refresh_turn_lease / release_turn_lease / get_turn_lease_holder on SessionDB. Storage only. No consumer is wired in this PR, and it deliberately takes **no position** on lease policy — see "Why this is separable" below. Why gateway/turn_lease.py's SessionTurnLeaseRegistry (from #67401) serializes [load history → run → flush] within one process. It is per-process state, so it cannot see a CLI process and a gateway process sharing one session_id through CLI-continuity — the many-to-one route behind #64934. A DB row is the only thing both processes can observe. Opened at @webtecnica's request on #67442, who descoped a parallel storage attempt in favour of this one. Not speculative infrastructure per AGENTS.md:97 — two concrete consumers are on record, and that policy explicitly allows the consumer to ship separately: #67454's TurnLease async context manager (@webtecnica) calls exactly this API and will stack on top; @TheAngryPit's Codex App Server thread-continuity work needs the same substrate for ownership fencing. Design Shaped deliberately like the existing

NousResearch/hermes-agent PR #83907 reports: Summary Adds a subagent-handles plugin that wires the existing subagent_start/subagent_stop hooks into a usable registry and exposes mid-flight steering tools. What it does **subagent_start hook** → builds a SubagentHandle (subagent_id, session_id, goal, parent, role) in a thread-safe SubagentRegistry singleton **subagent_stop hook** → transitions the handle to done (kept for post-run inspection) **subagent_send(subagent_id, text) tool** → queue a follow-up message to a running child **cancel_subagent(subagent_id) tool** → abort a running child Key design points All four pieces share ONE module-level registry singleton — handles registered by hooks are immediately visible to the tools (no orphan instances) Handlers are defensive: missing kwargs log+return, duplicate registrations keep existing handle, exceptions never break the delegate loop child_role is extracted and stored on the handle (spec-compliant) Test Plan 28 tests passing: registry, hooks, tools, integration (hook-registered handle resolvable by sender), persister. Attribution Derived from in-session work by Michael Anselmi, reconciled 2026-08-11.

NousResearch/hermes-agent PR #84180 reports: The outage On 2026-08-09 09:25 a host's root filesystem hit 100% and the WhatsApp bridge lost its paired identity for ~17 hours. Baileys persists auth state with a bare writeFile() (lib/Utils/use-multi-file-auth-state.js), which is open(O_TRUNC) followed by write(). When the write failed with ENOSPC the truncate had **already happened**, leaving creds.json and 11 key files at 0 bytes. The damage then compounded silently. Baileys' reader treats an unparseable creds.json as "no creds" and calls initAuthCreds(), minting a **brand new identity**. The bridge came up unauthenticated, printed a QR code into a log nobody watches, and the gateway logged whatsapp connect timed out after 30s every five minutes. Nothing anywhere said "your credentials were erased". ENOSPC is just the cheapest way to hit this; EDQUOT/EIO/EFBIG have the same shape. The fix Two guarantees, both in the mechanism rather than in an operator remembering: 1. Writes are atomic.** Content goes to a temp file in the *same directory* (rename is only atomic within one filesystem), is fsync'd, then rename()d over the target. A reader sees the complete old

Why it matters

A multi-process agent cannot rely on one worker remembering who owns a turn. Leases, mid-flight messaging and auth state all need atomic transitions that survive crash, restart and disk pressure. The operator test is whether visible output, retained state and authority still describe the same event after retries, background work or restart.

Current

The primary record was open when captured on 2026-08-12. The tagged-release baseline was v2026.8.3 published 2026-08-03T16:57:52Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/NousResearch/hermes-agent/pull/84145. Supporting records are https://github.com/NousResearch/hermes-agent/pull/83907 and https://github.com/NousResearch/hermes-agent/pull/84180. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Use compare-and-swap ownership, make lease expiry observable, and test that a full disk or worker death cannot erase identity or create two active owners. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.