PLATFORM_SPEC.md — Hermes Agent (Nous Research)¶
New to gald3r on this platform? Start at Use gald3r with Hermes Agent for a short overview before the full breakdown below.
Hermes Agent is Nous Research's self-improving, channel-native AI agent — a CLI plus a
multi-platform gateway (Telegram, Discord, Slack, WhatsApp, Signal, Email). Its headline traits
are an autonomous learning loop, agent-curated Skills created from experience, and persistent
memory across sessions. All state lives under ~/.hermes/ (or $HERMES_HOME;
%LOCALAPPDATA%\hermes on native Windows). As of June 2026 Hermes natively supports five of
the six gald3r-relevant primitives — Skills (agentskills.io-compatible SKILL.md), Rules /
instruction files (it auto-loads AGENTS.md / CLAUDE.md / SOUL.md into the system prompt),
MCP, Hooks (a native shell-hook block in config.yaml with 17+ lifecycle events, plus gateway
+ plugin hook systems), and native subagents (the delegate_task model). Commands are the
only partial primitive (built-in slash commands + skills-as-/skill-name; no user-authored non-skill
command file). This is near-full parity with the Cursor reference.
Authoring path: UPDATE. Verified 2026-06-20 against the live GitHub repo + hosted docs (see
Verification Evidence). This supersedes the stub (last_doc_scan: never, status: ❓, all
cells ❓, wrong docs_url: https://hermes.dev), which made no capability claims. The correct docs
host is hermes-agent.nousresearch.com/docs + the NousResearch/hermes-agent GitHub repo.
Correction (2026-06-20 re-verify): an earlier pass of this spec claimed Hooks were "not documented (the one real gap)" and told users to fold SessionStart guardrails into
AGENTS.mdbecause there was no hook. That was wrong. Hermes ships a native hooks system — documented at…/docs/user-guide/features/hooks— including a shell-hook block in~/.hermes/config.yamlwith 17+ lifecycle events andpre_tool_calltool-call blocking. The Hooks cell is now ✅ NATIVE and the tier is re-derived to near-full parity (see below).Distribution opportunity (headline): Hermes Skills use the agentskills.io open
SKILL.mdstandard in a folder-per-skill layout (<skill>/SKILL.md+ optional scripts/references) — the same standard gald3r already ships (g-skl-*/SKILL.md). gald3r's skills are structurally portable onto Hermes: drop them under~/.hermes/skills/<category>/<name>/SKILL.mdand they appear in the skills index and as/<name>slash commands. Hermes adds optionalmetadata.hermes.*frontmatter fields (tags, requires_toolsets, config, …) on top of thename/descriptionbaseline, so a baselineSKILL.mdloads unchanged; only Hermes-specific tuning needs the extra keys.Platform truth — instruction file: Hermes auto-injects a set of context files into the system prompt at session start —
SOUL.md,.hermes.md,AGENTS.md,CLAUDE.md, and.cursorrules. gald3r'sAGENTS.mdis therefore read natively (no migration step required), which makes Hermes anAGENTS.md-first-class platform like Codex/Cursor — not aCLAUDE.md-only platform like Claude Code.SOUL.mdis the persona slot (#1 in the system prompt).
1. Folder Hierarchy¶
~/.hermes/ ← all state (or $HERMES_HOME; %LOCALAPPDATA%\hermes on Windows)
├── config.yaml ← main config (model, toolsets, memory, compression, MCP)
├── .env ← secrets only (API keys, bot tokens, passwords)
├── auth.json ← OAuth provider creds (Nous Portal, etc.)
├── SOUL.md ← persona / agent identity (system-prompt slot #1, auto-loaded)
├── memories/
│ ├── MEMORY.md ← session memories (auto-loaded)
│ └── USER.md ← user profile (auto-loaded)
├── skills/ ← Agent Skills, organized by category
│ ├── <category>/<name>/SKILL.md ← e.g. devops/deploy-k8s/SKILL.md, research/arxiv/SKILL.md
│ └── openclaw-imports/ ← skills migrated from OpenClaw
└── hermes-agent/ ← git checkout (source install)
<project-root>/ ← project-local context files Hermes auto-injects (if present)
├── AGENTS.md ← auto-loaded into system prompt (NATIVE — no migration needed)
├── .hermes.md / CLAUDE.md / .cursorrules ← also auto-injected context files
Hermes resolves a bundled skills set (in the repo skills/) plus an optional set
(optional-skills/, same structure) and the user ~/.hermes/skills/ tree. External skills added
as taps (hermes skills tap add owner/repo) appear in the index identically to local skills.
gald3r writes: project AGENTS.md; skills under ~/.hermes/skills/<category>/g-skl-*/SKILL.md
(user-global) or a project skills tree published as a tap; optionally SOUL.md for persona.
Hermes owns: config.yaml / .env / auth.json schemas, the ~/.hermes/ memory store, the
skill index + security scanning, and gateway state.
2. AI Instruction File — ✅ NATIVE (AGENTS.md auto-loaded)¶
Hermes auto-injects automatic context files into the system prompt at session start:
SOUL.md, .hermes.md, AGENTS.md, CLAUDE.md, and .cursorrules. gald3r's shared
cross-platform AGENTS.md is read natively — no CLAUDE.md import shim and no migration command
required (this corrects the README's "migration flag" phrasing, which refers to importing OpenClaw
state, not to whether AGENTS.md is read). SOUL.md is the dedicated persona slot (#1).
Context files are subject to truncation limits (config.yaml memory settings).
Source: https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/configuration.md
3. Agents Support — ✅ NATIVE (subagents via delegate_task)¶
- Hermes spawns subagents through the documented
delegate_tasktool (tools/delegate_tool.py): it creates a subagent with an isolated context + terminal session, and the parent waits synchronously for the child's summary before continuing its loop. Single mode passesgoal(+ optionalcontext,toolsets); batch/parallel mode passestasks: [...], each task getting its own concurrent subagent. - Concurrency and depth are bounded in
config.yaml:delegation.max_concurrent_children(default 3),delegation.max_spawn_depth(default 2), plusdelegation.child_timeout_seconds,delegation.orchestrator_enabled(default true), anddelegation.inherit_mcp_toolsets. Subagents carry a role:leaf(default focused worker, cannot itself calldelegate_task) ororchestrator(retainsdelegate_task). - No documented standalone agent-definition file (no
.hermes/agents/*.md|toml) — subagents are spawned on demand viadelegate_task, not declared as gald3r-styleg-agnt-*markdown files. gald3rg-agnt-*definitions have no direct file mapping; their behavior is best delivered as Skills (which adelegate_tasksubagent can invoke) rather than as declared agent files. - Sources: https://github.com/NousResearch/hermes-agent/blob/main/AGENTS.md (
delegate_task/delegation.*config) · https://github.com/NousResearch/hermes-agent (README — subagents)
4. Skills Support — ✅ NATIVE (agentskills.io standard) — gald3r distribution opportunity¶
- A skill is a directory containing a
SKILL.mdwith YAML frontmatter — the agentskills.io open standard (folder-per-skill, optionalscripts/references/assets/). Hermes loads skill bodies on demand (progressive disclosure), keeping token use low; names+descriptions index at startup. - Location:
~/.hermes/skills/<category>/<name>/SKILL.md(user), bundledskills/(repo),optional-skills/(same structure). External taps (hermes skills tap add owner/repo) merge in. - Frontmatter: only
name+descriptionare required (matching the agentskills.io baseline).version,author,licenseare optional / recommended (best-practice for published/tapped skills, not mandatory to load). Also optional:platforms,metadata.hermes.{tags,related_skills,requires_toolsets,requires_tools,fallback_for_*,config, blueprint},required_environment_variables,required_credential_files. A gald3r baselineg-skl-*/SKILL.md(which already carriesname+description) therefore loads as-is; addingversion/author/licenseis recommended polish for distribution, not a requirement. - Invocation: every skill is exposed as a
/skill-nameslash command and via the system-promptskills_list/skill_viewindex — identical for local, optional, and tapped skills. - Publishing:
hermes skills publish skills/my-skill --to github --repo owner/repo; consumers add withhermes skills tap add owner/repo. Hub-installed skills are security-scanned before use. - gald3r impact:
g-skl-*/SKILL.mdare directly portable (same folder-per-skill +SKILL.mdstandard already used by Claude/Codex/OpenCode/Cursor). A gald3r tap (hermes skills tap add <gald3r-skills-repo>) is the natural distribution channel onto Hermes. - Sources: https://hermes-agent.nousresearch.com/docs/user-guide/features/skills · https://hermes-agent.nousresearch.com/docs/developer-guide/creating-skills · https://github.com/NousResearch/hermes-agent/blob/main/skills/research/arxiv/SKILL.md (live example)
5. Commands / Workflows — ⚠️ PARTIAL (built-in slash commands + skills-as-commands)¶
- Built-in slash commands (CLI + messaging):
/new,/reset,/model [provider:model],/personality [name],/retry,/undo,/compress,/usage,/insights [--days N],/skills,/stop,/platforms,/status,/sethome. - User-defined invocable workflows are delivered as Skills — each skill is automatically a
/skill-namecommand. There is no separate user-authored command file (no.hermes/commands/, no prompt-template directory). - gald3r impact:
@g-*//g-*workflows map to Skills (preferred and only) path — they surface as/<name>once installed as skills. No 1:1 command-file analog → mark ⚠️ partial (works, but only via the skills route, not a dedicated command primitive). - Source: https://github.com/NousResearch/hermes-agent (README — slash command list) + skills docs
6. Hooks System — ✅ NATIVE (config.yaml hooks: shell hooks, 17+ events, blocking)¶
- Hermes ships a native hooks system — three coordinated subsystems: shell hooks (declared in
~/.hermes/config.yamlunder ahooks:block), gateway hooks (~/.hermes/hooks/<name>/withHOOK.yaml+handler.py), and plugin hooks (ctx.register_hook()in a plugin'sregister()). For gald3r, the shell-hook block is the relevant surface. - Shell-hook config (
~/.hermes/config.yaml): ```yaml hooks: pre_tool_call:- matcher: "terminal" # regex against tool name command: "/path/to/guard.sh" # receives JSON payload on stdin timeout: 10 # seconds ```
- Payload: JSON over stdin, e.g.
{"hook_event_name":"pre_tool_call","tool_name":"terminal","tool_input":{...},"session_id":"…","cwd":"…"}. - 17+ lifecycle events:
pre_tool_call,post_tool_call,pre_llm_call,post_llm_call,on_session_start,on_session_end,on_session_finalize,on_session_reset,subagent_stop,pre_gateway_dispatch,pre_approval_request,post_approval_response,transform_tool_result,transform_terminal_output,transform_llm_output, plus gateway-only eventsgateway:startup,session:start/:end/:reset,agent:start/:step/:end, andcommand:*(wildcard per slash command). - Tool-call blocking: only
pre_tool_callcan block — return{"action":"block","message":"…"}(equivalently{"decision":"block","reason":"…"}) and Hermes short-circuits the tool, returningmessageto the model as the tool error. This is a real PreToolUse-equivalent gate. - Reliability caveat (honest): all hook subsystems are non-blocking on error — malformed JSON,
non-zero exit, or timeout in a shell hook is caught and logged, never aborting the agent loop.
So a hook that fails (vs. one that explicitly returns
block) does not halt the tool; a guardrail must succeed and explicitly emit the block action to enforce. (Community issues also report hooks not always firing in some builds — treat hard enforcement as best-effort and verify with an install test.) - gald3r impact:
g-hk-*.pylifecycle hooks do map onto Hermes via theconfig.yamlhooks:block — wire a SessionStart-style.gald3r/context injector ontoon_session_startand a PreToolUse-style guardrail ontopre_tool_call(returning theblockaction for hard gating). Because Hermes shell hooks run an arbitrary command, point them directly atpython <path>(post- Python port; no PowerShell involved, no wrapper needed). Folding guardrails intoAGENTS.md(§2) remains a useful belt-and-suspenders layer, but is no longer the only option — nativepre_tool_callblocking is available. - Sources: https://hermes-agent.nousresearch.com/docs/user-guide/features/hooks · https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/hooks.md
7. Rules / Memory — ✅ NATIVE¶
- Rules/instructions: carried by the auto-loaded context files (
AGENTS.md,SOUL.md,.hermes.md,CLAUDE.md,.cursorrules— §2). gald3rg-rl-*always-apply rules fold intoAGENTS.mdand load natively each session. - Memory: persistent
~/.hermes/memories/MEMORY.md+USER.md, auto-loaded; plus the self-improving loop that writes new skills from experience. Memory limits / context truncation are tuned inconfig.yaml. - Enforcement caveat (platform truth): like every prose-instruction surface,
AGENTS.md/SOUL.mdare advisory context, not hard enforcement on their own. Unlike the earlier (incorrect) assessment, Hermes does have apre_tool_callhook (§6) that can upgrade a constraint to a hard, blocking gate — but the hook must succeed and explicitly emit{"action":"block",…}, and hook errors are swallowed (non-blocking-on-failure). So treat prose constraints as best-effort, and add apre_tool_callshell hook when a constraint must be hard-enforced. - Source: https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/configuration.md
8. MCP Support — ✅ NATIVE¶
- Model Context Protocol client — "connect any MCP server for extended capabilities." Config
lives under the
mcp_servers:key (YAML, inconfig.yaml): per-server stdio (command,args,env) or HTTP (url,headers), plusenabled,timeout,connect_timeout, and tool-filtering / utility-tool-policy options. - MCP ships with the standard install; the optional extra is
uv pip install -e ".[mcp]". Node.js / npx required for npm-based MCP servers. - gald3r MCP servers (e.g.
gald3r_dockerstdio/HTTP tools) wire viamcp_servers:in~/.hermes/config.yaml. - Sources: https://github.com/NousResearch/hermes-agent/blob/main/website/docs/reference/mcp-config-reference.md · https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp
9. Gateways / Surfaces — channel-native multi-platform¶
- Gateway:
hermes gateway setup(interactive wizard) +hermes gateway start/run/install. Surfaces: Telegram, Discord, Slack, WhatsApp, Signal, Email ("20+ platforms" claimed), with streaming tool output and cross-platform conversation continuity. - gald3r impact (Q5): gald3r's status outputs (
TASKS.md,/g-status) are markdown, which renders fine in CLI and degrades acceptably in chat surfaces (Telegram/Slack render a markdown subset; long tables truncate). For chat gateways, prefer the summarized status forms over rawTASKS.mdtable dumps; the--json/--toonoutput skills (g-skl-json-output / g-skl-toon-output) are better suited to gateway/agent-to-agent handoff than wide markdown tables. No hard reformatting is required for CLI; chat surfaces benefit from summarization. - Source: https://github.com/NousResearch/hermes-agent (README — gateway) + gateway docs
Parity vs. Cursor Reference¶
Hermes reaches near-full parity with the Cursor reference (g-skl-platform-cursor): native
Skills, Rules/memory, MCP, and Hooks, plus native subagents (the delegate_task model) and an
AGENTS.md-native instruction file. Commands are the only partial primitive (skills-as-commands
only, no separate command-file primitive). Hermes's distinctive strengths are the
agentskills.io-standard Skills (directly reusing gald3r's SKILL.md artifacts), the
self-improving skill-creation loop, and the channel-native gateway (Telegram/Discord/Slack/…).
Platform-specific truths to honor:
- Instruction file is AGENTS.md-native (auto-injected alongside SOUL.md/CLAUDE.md/
.cursorrules) — ship AGENTS.md; optionally add SOUL.md for the gald3r persona.
- Hooks are native — wire g-hk-* SessionStart/PreToolUse logic onto the config.yaml hooks:
block (on_session_start, pre_tool_call, …); pre_tool_call can hard-block a tool via
{"action":"block",…}. Hook failures are swallowed (non-blocking-on-error), so a guardrail must
succeed and explicitly emit the block action to enforce.
- Skills need only name+description; version/author/license are optional/recommended
(a baseline gald3r SKILL.md loads as-is — adding the three is distribution polish).
- Distribute gald3r skills as a tap (hermes skills tap add owner/repo); state lives in
~/.hermes/ (config.yaml + .env, not a .hermes/ project tree).
Hook System¶
- Type: ✅ native — shell hooks (
config.yamlhooks:block) + gateway hooks (~/.hermes/hooks/<name>/HOOK.yaml+handler.py) + plugin hooks (ctx.register_hook()) - Config file:
~/.hermes/config.yaml(shell hooks, underhooks:) - Events available: 17+ — incl.
pre_tool_call,post_tool_call,pre_llm_call,post_llm_call,on_session_start,on_session_end,on_session_finalize,on_session_reset,subagent_stop,transform_*, plus gatewaysession:*/agent:*/command:* - Event payload format: JSON over stdin (
hook_event_name,tool_name,tool_input,session_id,cwd, …) - Blocking:
pre_tool_callmay return{"action":"block","message":"…"}to short-circuit a tool - Reliability caveat: hooks are non-blocking on error — a failing hook is logged, not enforced;
only an explicit
blockaction gates a tool (verify firing with an install test) - gald3r hook files:
g-hk-*.pymap natively — wire SessionStart logic ontoon_session_startand PreToolUse logic ontopre_tool_callby invokingpython <path>directly (no shell wrapper needed, post- Python port)
Atypical Handling¶
- No
.hermes/project config tree — all state is user-global under~/.hermes/(config.yaml+.env+auth.json+skills/+memories/). Project-local influence is via the auto-injected context files (AGENTS.md/.hermes.md/CLAUDE.md/.cursorrules) only. - Skills ARE the command system — there is no separate command-file primitive; every skill is a
/skill-name. Distribute and update via taps +hermes skills publish/tap add. - Lean skill frontmatter — only
name+descriptionare required (agentskills.io baseline);version/author/license/platforms/metadata.hermes.*are optional/recommended. - Hooks live in
config.yaml— not in a per-IDE hooks directory; the gald3rg-hk-*logic is wired via thehooks:block (shell command + JSON-stdin), withpre_tool_callblocking. Deterministic control is via hooks +delegate_tasksubagents. - Gateway-first — the same agent runs in Telegram/Discord/Slack/WhatsApp/Signal/Email; prefer
summarized status output (or
--json/--toon) over wide markdown tables in chat surfaces.
gald3r Integration Notes¶
- Ship
AGENTS.mdas the instruction surface — Hermes auto-injects it (noCLAUDE.mdshim, no migration step). Foldg-rl-*always-apply rules into it. - Wire
g-hk-*.pyhooks viaconfig.yaml: map SessionStart.gald3r/injection ontoon_session_startand PreToolUse guardrails ontopre_tool_call(return{"action":"block",…}to hard-gate). Invokepython <path>directly (no shell wrapper needed, post- Python port); remember hook failures are swallowed, so the guardrail must succeed and emit the block action to enforce. - Distribute gald3r Skills as a Hermes tap: publish
g-skl-*/SKILL.mdto a repo, thenhermes skills tap add <repo>; they index + surface as/<name>natively. A baselineSKILL.md(name+description) loads as-is;version/author/licenseare optional distribution polish. - MCP wires via
mcp_servers:in~/.hermes/config.yaml(stdio/HTTP). - Subagents spawn via
delegate_task(goal/tasks:[...], bounded bydelegation.*); there are no declared subagent files — deliverg-agnt-*behaviors as Skills. - Do NOT expect: a
.hermes/project tree or declared subagent/agent files. - Re-verify on the next
@g-platform-scan-docs hermes(crawl_max_age_days: 14; docshttps://hermes-agent.nousresearch.com/docs+github.com/NousResearch/hermes-agent).
Capability Summary¶
| Hooks | Rules | Skills | Commands | MCP | Docs Fresh |
|---|---|---|---|---|---|
| ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ |
Legend: ✅ verified working · ⚠️ partial / Cursor-generic · ❌ not supported · ❓ untested.
Overall platform status: ✅ — near-full parity. Five of six primitives native —
Hooks/Rules/Skills/MCP (+ delegate_task subagents, AGENTS.md-native instruction file); Commands
is the only partial primitive (skills-as-/skill-name, no command-file). This corrects an earlier
pass that wrongly marked Hooks absent. Honest, re-verified state as of the 2026-06-20 live docs crawl
(hooks + skills-frontmatter facts re-fetched).
Verification Evidence (live crawl 2026-06-20)¶
| Capability | How verified | Source |
|---|---|---|
| Instruction file | Auto-loaded context files incl. AGENTS.md/SOUL.md/CLAUDE.md/.cursorrules injected into system prompt at start; SOUL.md = persona slot #1 |
github.com/NousResearch/hermes-agent .../user-guide/configuration.md |
| Skills | Folder-per-skill SKILL.md (agentskills.io), ~/.hermes/skills/<cat>/<name>/; on-demand load; /skill-name; taps; security-scanned |
hermes-agent.nousresearch.com/docs/user-guide/features/skills + /developer-guide/creating-skills |
| Skill frontmatter | only name+description required; version/author/license/platforms/metadata.hermes.* optional/recommended |
hermes-agent.nousresearch.com/docs/developer-guide/creating-skills + /user-guide/features/skills (re-fetched 2026-06-20) |
| Commands | built-in slash set (/new,/model,/skills,/personality,…) + every skill = /skill-name; no user command-file primitive |
github.com/NousResearch/hermes-agent (README slash-command list) |
| Agents | delegate_task tool (isolated context+terminal; goal or batch tasks:[...] concurrent); config delegation.max_concurrent_children/max_spawn_depth; roles leaf/orchestrator; no declared agent file |
github.com/NousResearch/hermes-agent/blob/main/AGENTS.md |
| Hooks | Native: config.yaml hooks: shell hooks (JSON-stdin) + gateway + plugin hooks; 17+ events; pre_tool_call blocks via {"action":"block",…}; non-blocking on hook error |
hermes-agent.nousresearch.com/docs/user-guide/features/hooks + .../website/docs/user-guide/features/hooks.md (re-fetched 2026-06-20) |
| Rules / Memory | AGENTS.md/SOUL.md rules (auto-injected) + ~/.hermes/memories/MEMORY.md+USER.md; self-writes skills |
.../user-guide/configuration.md |
| MCP | mcp_servers: (YAML, in config.yaml) — stdio (command/args/env) or HTTP (url/headers) + enabled/timeout; .[mcp] extra; npx for npm servers |
.../reference/mcp-config-reference.md + /user-guide/features/mcp |
| Config files | ~/.hermes/config.yaml (settings) + ~/.hermes/.env (secrets) + auth.json; $HERMES_HOME/%LOCALAPPDATA%\hermes |
.../user-guide/configuration.md + README |
| Gateways | hermes gateway setup/start; Telegram/Discord/Slack/WhatsApp/Signal/Email |
github.com/NousResearch/hermes-agent (README) |
| Docs host | Correct host is hermes-agent.nousresearch.com/docs + github.com/NousResearch/hermes-agent (stub's https://hermes.dev was wrong) |
live fetch 2026-06-20 |
Reference page — canonical source: g-skl-platform-hermes/PLATFORM_SPEC.md in the engine repo, generated by scripts/generate_platform_support_docs.py. Pages marked curated are hand-assessed and not yet live-verified.