Safeguard
Supply Chain Security•

How Hermes Agent Learns: Memory, Skills, Session Search and Review

Hermes Agent learns through two capped memory files, self-written skills, SQLite session search and a background review. How each works and is gated.

Safeguard Security Team
45 min read

Hermes Agent does not retrain its model. It learns by writing text: two small memory files (MEMORY.md and USER.md) that load into every new session, Markdown skills it creates and patches with its skill_manage tool, and a full text index of past sessions it can search. A background review re-reads each conversation and decides what to save, and a curator prunes old skills.

All of those writes are on by default and ungated by default. The rest of this post walks through each mechanism from the Hermes documentation and source code, shows what a good agent-written skill looks like, lists every gate with its default value, and gives a step by step setup for a learning loop you can review and roll back. Every version, config key and default below was checked against the Hermes Agent repository on 23 October 2026, when the latest stable release was v0.22.5.

Key takeaways

  • No weights change. Hermes Agent "learns" by editing files on disk: ~/.hermes/memories/MEMORY.md (2,200 character cap), ~/.hermes/memories/USER.md (1,375 character cap) and skills under ~/.hermes/skills/. The model stays whatever model you configured.
  • Memory is a frozen snapshot. It loads into the system prompt at session start and does not change mid-session. A full store returns an error; nothing is silently dropped or auto-compacted.
  • Skills are procedural memory. The agent writes them with skill_manage (create, patch, delete, write_file, remove_file). A targeted patch is the preferred update.
  • A background review runs after turns and replays the conversation in a forked agent that can write memory and skills. It is on by default (auxiliary.background_review.enabled: true).
  • The curator prunes, it does not delete. Unused agent-created skills go stale after 14 days and are archived after 30. LLM consolidation is off by default.
  • Session search is a database query, not memory. Every session lives in ~/.hermes/state.db with SQLite FTS5; the docs say the session_search tool makes no LLM calls.
  • The gates exist but start open. memory.write_approval, skills.write_approval and skills.guard_agent_created all default to false. Turning the first two on stages every write for your approval.
  • Everything is auditable. Skill mutations land in an append-only ledger with per-file SHA-256 hashes, and hermes curator rollback <entry-id> undoes a single change.

The learning loop at a glance

Hermes Agent is Nous Research's open source agent (MIT licence, repository created 22 July 2025, public launch listed on nousresearch.com/releases as 25 February 2026). Its README describes "a closed learning loop": agent-curated memory with periodic nudges, autonomous skill creation after complex tasks, skills that improve during use, FTS5 session search, optional user modelling through Honcho, and compatibility with the agentskills.io standard.

Here is every moving part in one table.

MechanismWhere it livesWho writes itLoaded whenDefault gateHow you see it
Agent notes~/.hermes/memories/MEMORY.mdmemory tool, target memorySession start, frozenNone (memory.write_approval: false)cat the file, /journey
User profile~/.hermes/memories/USER.mdmemory tool, target userSession start, frozenNonecat the file, /journey
Skills~/.hermes/skills/<category>/<name>/SKILL.md plus support filesskill_manage, /learn, background review, curatorIndex in system prompt; body on demandNone (skills.write_approval: false)/skills, /journey, ledger
Session history~/.hermes/state.db (SQLite, FTS5)Hermes itself, every messageOn demand via session_searchNot applicablehermes sessions list
Background reviewForked agent after a turnWrites memory and skillsAfter turnsOn (auxiliary.background_review.enabled: true)Chat line, agent.log
CuratorBackground maintenance passArchives, optionally consolidatesEvery 7 days when idle 2 hoursOn, prune onlyhermes curator status

Version timeline for the learning features

Hermes ships several releases a week, so the exact release that introduced each behaviour matters when you read older guides. Dates below come from the GitHub release pages and releases feed and from nousresearch.com, fetched on 23 October 2026. Where a date comes from a blog post rather than a release, the table says so.

DateVersion or eventWhat changed for learningSource
22 Jul 2025Repository createdProject begins (pre-public)GitHub repository metadata
25 Feb 2026Public launchListed as "An autonomous agent that lives on your server, remembers what it learns, and gets more capable the longer it runs"nousresearch.com/releases
12 Mar 2026v0.2.0 (tag v2026.3.12)"First tagged release since v0.1.0"GitHub release page
1 Jul 2026v0.18.0 "Judgment" (tag v2026.7.1)/learn and /journey added; release notes say they "turned self-improvement into something you can see and steer"GitHub release page
2 to 4 Sep 2026Nous refactor run1,393 subagent refactor of the Hermes codebase, PR merged 4 SeptemberNous Research blog (self-reported)
3 Sep 2026Two CVE records publishedNeither concerns the learning loop; see the FAQCVE.org
23 Oct 2026v0.22.5Latest stable release at time of writingGitHub releases feed

Docs quoted here are the main branch versions of 23 October 2026; older releases may lack some keys, so check hermes --version against the docs for your version.

What are MEMORY.md and USER.md?

Hermes keeps two plain text files under ~/.hermes/memories/. The memory feature page describes them like this:

FilePurposeCharacter capRough token size
MEMORY.mdThe agent's own notes: environment facts, project conventions, tool quirks, lessons learned, completed work2,200About 800 tokens
USER.mdYour profile: name, role, timezone, communication preferences, pet peeves, skill level1,375About 500 tokens

Both caps are configurable as memory.memory_char_limit and memory.user_char_limit. Entries are separated by a section sign, and each store renders into the system prompt with a header showing its usage, for example a percentage and a "1,474/2,200 chars" count, so the model can see how close it is to the cap.

The frozen snapshot

At the start of every session, Hermes reads both files and injects them into the system prompt as a frozen block. The docs are explicit that this snapshot "never changes mid-session": a memory the agent writes at 10:00 is saved to disk immediately but is not visible to the model in that same session. It appears the next time a session starts. The reason given is performance: a stable system prompt keeps the provider's prompt cache warm.

This has two practical consequences.

  1. Learning needs session boundaries. On messaging platforms a chat is one continuous session that survives restarts, so fresh memories stay invisible until you run /new. The docs recommend /new at natural breaks such as a finished task or the start of a day.
  2. A poisoned entry also waits for the next session. The same frozen snapshot that keeps the cache warm means a bad memory written today shapes every session from tomorrow on, until someone removes it. That is the defender's reason to review memory writes rather than only watch the live chat.

The memory tool: add, patch, remove

The agent edits memory with a single memory tool. Every call names a target (memory or user) and carries one or more operations:

  • add a new entry.
  • patch one span inside an existing entry, using old_text to find the span and content as its replacement.
  • remove an entry, matched by a unique substring.

There is no read action, because the content is already in the system prompt. There is also no replace action any more. The docs say models misused it as find and swap and wiped other facts in multi-fact entries. Exact duplicate entries are rejected quietly with a "no duplicate added" message.

What happens when memory is full

Memory does not auto-compact. When an add would push a store over its cap, the tool fails with a structured error that states the current usage, the size of the new entry, how many characters over the limit it would be, and the current entries. The agent is then expected to issue one batch that removes or shortens stale entries and adds the new one; the cap is checked only on the batch result. The docs recommend consolidating once a store passes 80 percent, for example merging three "project uses X" entries into one.

Two agent processes must not share one Hermes home: the docs warn they "will compound each other's entries into state neither of them (nor you) authored." Give each agent its own profile (hermes -p work).

When does the agent decide to write a skill?

Skills are Hermes's procedural memory: longer instructions for a class of task, loaded only when relevant. The skills feature page says the system prompt asks the agent to record a non-trivial workflow with skill_manage, and lists what that covers in practice:

  1. It worked out a multi-step workflow worth repeating.
  2. It hit errors or dead ends and found the working path.
  3. The user corrected its approach.

In the current source (agent/prompt_builder.py on main, read 23 October 2026), the wording is short. The guidance block says "When you work out a non-trivial workflow, record it with skill_manage for future reuse." The skills index section adds that after difficult or iterative tasks the agent should offer to save a skill, and that if a skill it loaded "was missing steps, had wrong commands, or needed pitfalls you discovered" it should update it before finishing. A code comment in the same file records that an older, longer phrasing of this instruction was reworded after it caused provider errors, which is a useful reminder that these prompts are tuned empirically and change between releases.

Two periodic nudges back the prompt up. The example configuration in the repository (cli-config.yaml.example) sets:

memory:
  nudge_interval: 10          # remind the agent to consider saving memories every 10 user turns (0 = off)

skills:
  creation_nudge_interval: 15 # remind the agent to consider saving a skill every 15 tool-calling iterations (0 = off)

The background review, covered below, is the third path. It looks at the whole conversation after a turn and is told to be "ACTIVE": its prompt says most sessions should produce at least one skill update.

What a good agent-written SKILL.md looks like

A Hermes skill is a directory with a SKILL.md file and optional references/, templates/, scripts/, examples/ and assets/ folders. The frontmatter follows the agentskills.io specification, which requires a name (up to 64 characters, lowercase letters, digits and single hyphens, matching the directory name) and a description (up to 1,024 characters, saying what the skill does and when to use it). Hermes adds optional fields under metadata.hermes such as tags, category, platform restrictions and conditional activation.

The body Hermes expects has four sections: When to Use, Procedure, Pitfalls and Verification. The house standard for /learn output adds a description of 60 characters or fewer.

The docs and the background review prompt are unusually specific about quality. A skill should capture "lessons, not logs":

  • Procedure first, in the order the steps are done, with the commands and decision points that work.
  • A pitfall is a general rule plus one clause of why, attached to the step it affects, stated once.
  • No PR or issue numbers, dates, ticket IDs or quoted chat as content.
  • Always-on rules belong in SKILL.md; references/ holds a few topical files that get extended, never one file per session.
  • Do not restate what is already loaded every turn, such as the repository's AGENTS.md or tool schemas.
  • Fix a wrong sentence in place rather than appending "UPDATE: actually".

Here is an illustrative skill in that shape. It is our own example, not one shipped with Hermes.

---
name: postgres-migration-check
description: Run and verify a Postgres schema migration safely
version: 1.0.0
metadata:
  hermes:
    tags: [postgres, migrations]
    category: devops
---

# Postgres migration check

## When to Use
Before applying any schema migration to the staging or production database.

## Procedure
1. Confirm the target: `psql "$DATABASE_URL" -c 'select current_database();'`
2. Take a schema-only dump first: `pg_dump --schema-only "$DATABASE_URL" > pre_migration.sql`
3. Run the migration tool in dry-run mode and read the planned statements.
4. Apply the migration.
5. Run the project test suite against staging.

## Pitfalls
- Check for long-running transactions before step 4; an ALTER TABLE waits on their locks and blocks every writer behind it.
- Never run step 4 from a shell that still points at production after a staging test; re-run step 1 every time.

## Verification
`psql "$DATABASE_URL" -c '\d+ <table>'` shows the new columns, and the test suite passes.

The advisory linter

skill_manage lints creates, SKILL.md patches and references/ writes against three rules: incident-log-shape (a body dense with PR or issue numbers), references-sprawl (more than 60 reference files) and oversized-body (a body past about 24,000 characters). The docs say they warn and never block a write, so treat them as hygiene, not a security control.

How does skill_manage work?

skill_manage is the single tool the agent uses to change its own skills. The actions, from the skills feature page:

ActionUse forKey parameters
createNew skill from scratchname, content (the whole SKILL.md), optional category
patchTargeted fix (preferred)name, old_string, new_string
patch with contentFull structural rewrite (edit is the legacy alias)name, content
deleteRemove a skillname
write_fileAdd or update a support filename, file_path, file_content
remove_fileRemove a support filename, file_path

Why a targeted patch is preferred

The docs give the token reason: only the changed text is sent. Two more reasons matter for security.

  • A small diff is reviewable. With skills.write_approval on, you approve from a gist and a unified diff; three changed lines are easy to read, a full rewrite is not.
  • A small diff cannot quietly drop content. A whole-file rewrite can lose a pitfall, a verification step or a warning without anyone noticing. A patch changes only the span it names.

The tool is also strict about shape. Each action has its own text slot (content, new_string or file_content). An operation that carries another action's slot is rejected before any operation in the batch is applied, so a malformed batch fails as a whole rather than half applying.

Read before write, and what pinning protects

The background review prompt says skill_manage enforces a read-before-write rule during review: before the review patches an existing SKILL.md or overwrites an existing support file, it must load that exact file with skill_view in the same review. Content quoted earlier in the conversation does not count. Creating a new skill or adding a new support file needs no prior read.

Pinning is narrower than many readers expect. The curator page says pinning protects a skill from deletion: the curator skips it and skill_manage refuses delete. But "Patches and edits still go through, so the agent can improve a pinned skill's content." The review prompt says the same thing from the other side: hand-written, installed, bundled and pinned skills are "all yours to improve." If you want a skill the agent cannot change, pinning is not enough. You need skills.write_approval: true, a read-only file, or a skill directory the agent does not own (see project-local skills below).

What do the background review and the curator do?

These are the two parts of the loop that run without you asking.

The background review

The module docstring in agent/background_review.py describes it plainly: after a turn, the agent "may spawn a daemon thread that replays the conversation snapshot in a forked AIAgent and asks 'should any skill/memory be saved or updated?'". The fork inherits the parent's provider, model, credentials and cached system prompt so it can reuse the prompt cache. The main conversation is never touched.

The review has three prompts (memory only, skills only and combined). From the source, the skill review looks for four signals:

  • The user corrected your style, tone, format or verbosity.
  • The user corrected your workflow or the order of steps.
  • A non-trivial technique, fix, workaround or debugging path emerged.
  • A skill loaded in this session turned out to be wrong, incomplete or outdated.

It then prefers, in order: patch a skill that was loaded in this session, patch an existing class-level umbrella skill, add a support file under an existing skill, and only then create a new class-level skill. It is told never to delete a skill and to leave overlap to the curator.

The prompt also lists what not to save, which is good practice for any agent memory:

  • Environment-dependent failures such as missing binaries or unconfigured credentials.
  • Negative claims about tools ("X does not work"), which "harden into refusals the agent cites against itself for months."
  • Transient errors that resolved during the session.
  • One-off task narratives.
  • Unresolved failures written up as if they were a working method.

The memory review routes each fact to one store: who you are goes to USER.md, facts about the environment go to MEMORY.md, never both.

The review runs with a tool whitelist: memory, skill management and read-only file tools by default. extra_tools can add named tools the parent already has; the default list is empty.

Configuration keys, all under auxiliary.background_review (the docs warn that a top-level background_review: block is not read):

KeyDefaultWhat it does
enabledtruefalse stops automatic post-turn forks; manual /refine still works
provider, modelauto (main chat model)Route the review to another model; the docs report about 3 to 5 times lower cost in their own testing
max_input_tokensUnset: 75 percent of the review model's context window, capped at 600,000Caps the total replayed input tokens for one review
extra_toolsEmpty listOpt in additional tools by name

Every review's token use is recorded in session_model_usage with task='background_review', and a completion line goes to agent.log.

In gateway chats, display.memory_notifications (default on) prints a short line such as "Skill 'foo' patched"; verbose adds a preview; off hides the line, but the docs stress the review "still runs and still writes."

The curator

The curator is a background maintenance pass for agent-created skills only. It is triggered by an inactivity check rather than cron. With the defaults, it runs when at least 7 days (interval_hours: 168) have passed since its last run and the agent has been idle for 2 hours (min_idle_hours: 2).

A run has two phases:

  1. Automatic transitions, no LLM. Skills unused for 14 days (stale_after_days) become stale; skills unused for 30 days (archive_after_days) move to ~/.hermes/skills/.archive/. Pinned skills and skills referenced by cron jobs are skipped.
  2. LLM consolidation, off by default. With curator.consolidate: true, a forked agent surveys agent-created skills and can keep, patch, merge them into umbrella skills, or archive them.

The curator "never auto-deletes"; the worst outcome is archival, which hermes curator restore undoes. Hub-installed skills are always off limits. Bundled skills are archived only if you opt in with curator.prune_builtins: true.

One detail surprises people. "Agent-created" has a narrow meaning. The curator docs say only the background review fork sets the agent-created marker. Skills the foreground agent creates during a conversation, including with /learn, are recorded as created_by: learn and the curator leaves them alone. Run hermes curator status to see the managed and unmanaged counts.

Before a consolidation pass, Hermes snapshots ~/.hermes/skills/ as a tar.gz under .curator_backups/ (two kept by default).

The ledger

Every skill mutation, whoever makes it, appends one line to ~/.hermes/skills/.curator_ledger.jsonl. Each entry records the actor (curator, agent or user), the action, evidence such as the triggering session id, and before and after manifests with a SHA-256 hash per file. File contents are stored by hash under ~/.hermes/.curator_backups/blobs/. That is enough to answer "who changed this skill, when, and from what session", and to undo one change. The ledger is "telemetry, never a gate": if writing an entry fails, the mutation still happens. It is capped at 5 MB by default (skills.ledger_max_bytes), after which old entries can be dropped, so copy it somewhere durable for a long audit trail.

Seeing and steering it: /learn, /journey and /refine

Hermes v0.18.0 (1 July 2026) added two commands aimed at making the loop visible.

  • /learn turns something you point at into a skill: a local directory, a URL, the workflow you just walked through, pasted notes, or a whole book or docs corpus. Large sources become "knowledge-base skills" with a lean SKILL.md, an index, and one distilled file per chapter or topic under references/. The docs say the distillation "never reproduces passages of the source text." /learn has no tool of its own: it builds a prompt and the agent saves the result with skill_manage, so skills.write_approval applies.
  • /journey (also hermes journey, hermes learning or hermes memory-graph) shows a timeline of saved skills and memory entries. A skill appears once it has a learning signal: created by /learn or a foreground skill_manage create, created by the background review, or used at least once. You can prune and correct from it: hermes journey list, hermes journey edit <node>, and hermes journey delete <node>, which archives skills (restorable) and removes memory chunks.

How does session search complement memory?

Memory holds the few facts that should always be in context. Session search is for everything else. All CLI and messaging sessions are stored in ~/.hermes/state.db, a SQLite database in WAL mode with three key tables: sessions (metadata), messages (full history including tool calls) and messages_fts, an FTS5 virtual table. SQLite's own documentation describes FTS5 as "an SQLite virtual table module that provides full-text search functionality", with built-in bm25(), highlight() and snippet() functions for ranking and excerpts.

The session_search tool has four calling shapes, chosen by which arguments are set:

ShapeArgumentsReturnsTypical time (docs)
DiscoveryqueryTop sessions by FTS5 rank, deduplicated by lineage; the top hit gets bookends and about five messages either sideTens of milliseconds
Scrollsession_id, around_message_id, windowA window of messages around an anchor1 to 2 ms
Readsession_idThe whole session, or a bounded head and tailNot stated
BrowseNo argumentsRecent sessions, newest firstNot stated

Queries use standard FTS5 syntax (keywords, quoted phrases, OR, NOT, prefixes such as deploy*).

The agent is prompted to use it when "the user references something from a past conversation or you suspect relevant prior context exists", with typical triggers such as "we did this before", "last time" or "as I mentioned".

A disagreement in the sources. The README's feature table, read on 23 October 2026, still says "FTS5 session search with LLM summarization for cross-session recall." The current sessions and memory pages say the opposite: the tool "makes no LLM calls and returns views of actual messages from the DB rather than generating summaries." We describe the behaviour from the feature pages, which are more specific and more recently edited, and flag the README line as likely out of date.

Two notes follow from "everything is stored":

  • Retention. Auto-prune is off by default. When on, ended sessions inactive for sessions.retention_days (default 90) are removed at startup.
  • Backups hold everything. hermes sessions export writes every stored row, including compacted turns and messages removed by rewind or edit. Use --redact to strip API keys and tokens, and prefer --format md or html when sharing a conversation.

What is user modelling in Hermes, and what personal data is stored?

"User modelling" in Hermes has two layers, and it helps to keep them apart.

The built-in layer is USER.md. The memory docs list what belongs there: name, role, timezone, communication preferences, things to avoid, workflow habits and technical skill level. The background review's routing block is broader: USER.md is for "who the user is: persona, preferences, communication and work style, personal details they revealed, and expectations." By default the agent saves to it "proactively" and you do not need to ask.

The optional layer is an external memory provider. The README highlights "Honcho dialectic user modeling." The current Honcho docs page says Honcho is now a catalog plugin maintained by Plastic Labs, installed with hermes plugins install honcho and configured with memory.provider: honcho. Honcho's README describes it as "memory infrastructure for building stateful agents", available managed or self-hosted. Per the Hermes docs, after conversation turns (every 2 turns by default, dialecticCadence) Honcho "analyzes the exchange and derives insights about the user's preferences, habits, and goals", which accumulate server-side as conclusions, a user representation and a peer card. External providers run alongside the built-in files rather than replacing them.

What personal data can end up stored, by location:

StoreWhat it can containWhere it lives
USER.mdProfile facts the agent decided to keep, including personal details you mentionedYour machine, ~/.hermes/memories/
MEMORY.mdPaths, hosts, project names, completed work with datesYour machine
state.dbEvery message, tool call and tool output from every sessionYour machine
SkillsYour preferences embedded in procedures, by designYour machine, ~/.hermes/skills/
External providerDerived conclusions and representations of youThe provider's server, or your self-hosted one
Model providerEverything sent in prompts, including the memory snapshotYour configured LLM provider, under its terms

On a shared host or a gateway several people message, treat ~/.hermes as personal data, and give each person their own profile.

What scanning and gating exist on memory and skill writes?

This is the part most readers come for. The table lists every control we found in the docs, with its default on 23 October 2026.

ControlApplies toDefaultWhat it does
Memory content scanEvery memory writeAlways onBlocks entries matching prompt injection, credential exfiltration or SSH backdoor patterns, or containing invisible Unicode
memory.write_approvalMemory writes, foreground and backgroundfalseWhen true, CLI writes prompt inline and all other writes (gateway, scripts, background review) are staged for /memory pending
skills.write_approvalEvery skill_manage writefalseWhen true, every create, patch, delete, write_file and remove_file is staged under ~/.hermes/pending/skills/ for /skills pending, diff, approve, reject
skills.guard_agent_createdAgent skill writesfalseContent scanner for dangerous keyword patterns; flagged writes become an approval prompt. Turned off by default because legitimate workflows touching ~/.ssh/ or API key variables tripped it too often
skill_manage linterCreates, SKILL.md patches, references writesAlways onAdvisory only; never blocks
PinningDelete onlyOff per skillBlocks curator archival and agent delete; does not block patches
Project skill trustRepo .hermes/skills, .agents/skillsNot trustedSkills load only after hermes skills trust; dangerous ones are quarantined at scan time and rescanned when content changes
Skills Hub install scanHub, GitHub and URL installsAlways onScans the quarantined bundle; records source URL, content hash, scanner version and findings in skills/.hub/lock.json; --force cannot override a "dangerous" verdict
Context file scanAGENTS.md, SOUL.md and similarAlways onHeuristic checks for injection, hidden comments, secret reads, exfiltration and invisible Unicode
Background reviewPost-turn learningOnDisable with auxiliary.background_review.enabled: false
CuratorAgent-created skillsOn, prune onlyConsolidation opt-in; never deletes
LedgerAll skill mutationsOnTelemetry, not a gate; 5 MB cap by default

Three observations from reading these together.

Scanning is pattern based. The security docs say of the context file scanner that its patterns "are heuristics, not semantic intent detection." The memory scan and the agent-created skill guard are described in the same terms. A carefully worded instruction that contains no obvious pattern can pass. See our post on the limits of static scanners for AI agent skills.

The approval gates are the strong control, and they are off by default. With both write_approval keys on, nothing the agent learns reaches disk without a human yes. The docs themselves recommend this for "small models that misjudge what they learned, secure environments, or just wanting eyes on the self-improvement loop."

The background review stages some changes even with the gate off. The memory docs note that a staged patch or remove from the background review records the full entry it targets, that "the background review stages these even with the gate off", and that approval is refused if the target changed after staging.

Step by step: a learning loop you can review and roll back

This walkthrough keeps Hermes's learning on but puts a human and version control in the loop. It assumes a working install (hermes setup and hermes doctor pass). Commands are from the Hermes docs; the git steps are standard git.

Step 1: back up the current state

Before changing anything, take copies. Several later steps change or delete agent state.

# Snapshot everything Hermes has learned so far
hermes curator backup --reason "before-learning-review-setup"
tar czf ~/hermes-learning-backup-$(date +%Y%m%d).tgz \
  ~/.hermes/memories ~/.hermes/skills ~/.hermes/config.yaml

# Export sessions with secrets redacted
hermes sessions export ~/hermes-sessions-$(date +%Y%m%d).jsonl --redact

Step 2: turn on the approval gates and the content guard

Edit ~/.hermes/config.yaml:

memory:
  write_approval: true          # stage or prompt every memory write
skills:
  write_approval: true          # stage every skill write under ~/.hermes/pending/skills/
  guard_agent_created: true     # pattern scan on agent skill writes
  project_discovery: true       # keep repo skills discoverable, but untrusted until you trust them
display:
  memory_notifications: verbose # show a preview of each learned change in gateway chats
curator:
  enabled: true
  consolidate: false            # keep LLM consolidation off until you trust the review
  backup:
    enabled: true
    keep: 5                     # keep more snapshots than the default of 2
auxiliary:
  background_review:
    enabled: true
    max_input_tokens: 48000     # cap the cost of one review
    extra_tools: []             # no extra tools for the unattended review

You can also toggle the gates at runtime with /memory approval on and /skills approval on, which persist the setting.

Step 3: put the skills directory under git

The curator ledger records hashes, but a git history gives you diffs, blame and an off-machine copy.

cd ~/.hermes/skills
git init
printf '.curator_backups/\n.hub/quarantine/\n' > .gitignore
git add -A
git commit -m "Baseline: skills before review gating"

Push it to a private repository you control. Do not commit ~/.hermes/.env or anything under ~/.hermes that holds credentials.

Step 4: review staged writes as part of your routine

At the end of a working session, or when a notification appears:

/memory pending
/memory approve <id>
/memory reject <id>

/skills pending
/skills diff <id>
/skills approve <id>
/skills reject <id>

Read the full diff on the CLI or in ~/.hermes/pending/skills/<id>.json; the docs note diff output is truncated in chat bubbles. What to look for in a skill diff:

  • New commands that fetch from the network, pipe to a shell, or touch credentials, SSH keys or cloud metadata.
  • New scripts/ files. A script is code, and it will run with the agent's permissions.
  • Instructions that widen scope ("always", "for every task", "regardless of") or tell the agent to skip a check.
  • Preferences that look like they came from a web page or file rather than from you.

After approving, commit:

cd ~/.hermes/skills && git add -A && git commit -m "Approved skill changes $(date +%F)"

Step 5: audit with the ledger and the journey

hermes curator status
hermes curator ledger --limit 50
hermes curator ledger --skill postgres-migration-check
hermes journey list

Step 6: undo a bad change

Warning: the commands below change agent state. Take a fresh backup first.

hermes curator backup --reason "before-rollback"
cp -a ~/.hermes/memories ~/.hermes/memories.bak-$(date +%Y%m%d%H%M)

Then undo exactly one skill mutation from the ledger, or restore a whole snapshot:

hermes curator rollback <entry-id>   # restore one mutation's before-state
hermes curator rollback --list       # list whole-tree snapshots
hermes curator rollback --id <ts>    # restore a specific snapshot (takes a pre-rollback snapshot first)

For a bad memory entry, use hermes journey delete <node> (memory chunks are removed, not archived) or edit the file directly in $EDITOR with hermes journey edit <node>. Start a new session afterwards so the corrected snapshot loads.

Step 7: keep repo skills under code review

For procedures a team shares, put them in the repository's .hermes/skills/ or .agents/skills/ directory, review them through pull requests, and trust the repository explicitly:

cd ~/code/myproject
hermes skills trust

The curator never modifies project skills and new agent-created skills never land there, so the only way they change is through your normal review process.

How does this map to the research it borrows from?

Hermes does not cite papers in its docs, so this mapping is ours. The three papers below are the clearest ancestors of its design, read from their arXiv abstracts on 23 October 2026.

PaperarXiv ID, first versionWhat changes as the agent "learns"EvaluatorResult in the authors' own terms
Voyager: An Open-Ended Embodied Agent with Large Language Models (Wang et al.)2305.16291, 25 May 2023An ever-growing library of executable code skills, plus an automatic curriculum; no fine-tuningThe Minecraft environment, execution errors and a self-verification step3.3x more unique items, 2.3x longer distances, tech tree milestones up to 15.3x faster than prior methods, and reuse of the skill library in a new world
Reflexion: Language Agents with Verbal Reinforcement Learning (Shinn et al.)2303.11366, 20 Mar 2023Verbal reflections stored in an episodic memory buffer; "not by updating weights"Task feedback signals (scalar or free text, external or self-generated)91 percent pass@1 on HumanEval, and gains over a baseline agent on decision-making, coding and reasoning tasks
MemGPT: Towards LLMs as Operating Systems (Packer et al.)2310.08560, 12 Oct 2023Memory moved between a small in-context tier and larger external tiers, managed by the modelDocument analysis beyond the context window, and multi-session chatAgents that "remember, reflect, and evolve dynamically through long-term interactions" in multi-session chat

The parallels:

  • Skills are Voyager's skill library, in Markdown. Voyager grew a library of code skills retrieved by description; Hermes stores SKILL.md procedures retrieved through a description index, loading full bodies only on demand.
  • Pitfalls and the background review are Reflexion-style reflection. Reflexion turns feedback into written lessons that shape the next attempt. Hermes's review turns corrections and dead ends into pitfalls attached to a procedure.
  • Memory plus session search is a two-tier memory hierarchy, like MemGPT. A small, always-loaded tier (MEMORY.md and USER.md) and a large tier fetched on demand (state.db).

What is different matters as much:

  • No benchmark, no ground truth. Voyager had Minecraft and Reflexion had unit tests to say whether a lesson was right. Hermes's evaluator is the conversation: a user correction or the agent's own judgment that a path worked. The review prompt tries hard to avoid saving unverified methods, but nothing outside the model checks a skill before it is used.
  • The library persists across real work and real users. Research agents reset between experiments. A Hermes skill written in March can shape a deployment in October.
  • Skills can carry scripts. Voyager's skills were code run inside a game. A Hermes skill's scripts/ folder runs on your machine or in your sandbox, with whatever access the terminal backend allows.

None of the three papers studied adversarial inputs to a persistent skill library or memory, and Hermes has not published an evaluation of its learning loop's accuracy. Our post on agent memory poisoning and memory hardening covers the research that does.

What did Nous report from "Refactoring Hermes with 1,393 agents"?

In a September 2026 post on the Nous Research blog, Teknium describes asking his everyday Hermes agent to clean up the Hermes codebase. Everything in this section is self-reported by Nous; we have not reproduced it.

What the post reports:

  • The run started on 2 September 2026, lasted about nineteen active hours, dispatched 1,393 subagents and reached 218 running at once. The PR merged on 4 September after a restart, a continuation session and two rounds of community review.
  • Non-test Python source fell by 34.4 percent, from 1,063,826 lines to 698,363. Files over 5,000 lines fell from 37 to 6; functions over 300 lines from 192 to 2; the largest gateway file from 34,847 lines to 5,512.
  • The estimated model cost was about $19,300 for the main run, or roughly $25,000 with follow-up sessions, excluding human review time. The post compares this with a staffing estimate of $150,000 to $1.8 million for manual work.
  • A simulated lookup of 4,000 symbols returned on average 993 tokens instead of 2,218.

What it says about learning: the author's hermes-agent-dev skill "grew out of my everyday work on the repository." When a procedure was worked out or a mistake corrected, Hermes saved the lesson automatically; by the time of the refactor the skill carried instructions on preparing a PR, shortcuts to avoid and how to verify a change. The author shares the skill with other engineers, whose agents install and adapt it.

What the post itself flags as limits, to its credit:

  • Reviewers caught real regressions the tests missed: public names removed because they had no callers inside the repository, and an automated rewrite that changed exception handling at roughly 65 sites. Further fixes followed after merge.
  • The lookup numbers are "lookup costs; we didn't measure agents completing engineering tasks." The median lookup actually returned more tokens.
  • Splitting files increased module count and import dependencies, and some entry points took longer to import.

How to read self-reported results

  • Ask what was measured. Line counts and lookup tokens were; ease of future changes was not.
  • Ask who measured it. The product team, on its own codebase, with its most experienced user.
  • Separate the learning claim from the scale claim. The post shows a long-lived skill carrying a maintainer's procedures into a large job. It does not show how much of the result came from the skill rather than the model, the orchestration or human review.
  • Notice the supply chain lesson. A skill shared across a team is a shared dependency and deserves the same review and versioning as code.

Threats to the learning loop, and the matching controls

Every learning mechanism is a place where untrusted content can become a persistent instruction. OWASP's description of indirect prompt injection is the starting point: content from "external sources, such as websites or files" can alter a model's behaviour. A learning loop adds persistence: the altered behaviour can be written down and replayed in later sessions.

ThreatMechanism in HermesBuilt-in controlDefaultWhat to add
A web page or file nudges the agent to save a false "preference"Foreground or background memory writeMemory content scanOnmemory.write_approval: true; review USER.md weekly
A learned skill gains a risky command or scriptskill_manage patch or write_fileAdvisory linter; optional guardGuard offskills.write_approval: true, guard_agent_created: true, git diffs, review new scripts/
A cloned repository ships hostile project skillsProject-local skillsTrust prompt plus scan-time quarantineUntrusted until trustedTrust only repos you review; keep project skills in PR review
A third-party skill is installed with hidden behaviourSkills Hub, GitHub or URL installInstall scan, lock file with hashes, quarantineOnPrefer reviewed sources; pin and diff updates
A bad lesson spreads through a shared team skillSkill shared across engineersNone specificNot applicableTreat shared skills as code: repo, review, signed commits
Sensitive data accumulates in historystate.db, exports--redact on exportAuto-prune offRetention policy, disk encryption, redacted exports
Silent learning on a messaging gatewayBackground reviewChat notificationonverbose notifications; staged writes

Two related posts go deeper: AI agent memory security risks and whether an AI agent skill file can give shell access.

Where Safeguard fits, honestly

Safeguard does not scan, govern or monitor Hermes Agent, and Hermes is not a Safeguard integration or partner. The honest connection is narrower. A learning agent produces software artifacts: skills with scripts, code it writes into your repositories, and packages it installs while working. Those artifacts flow into codebases and container images like any other code. Safeguard generates and analyses SBOMs (SPDX and CycloneDX) for repositories and images, matches components against vulnerability data, applies policies and gates in CI, and supports attestation and signing (SLSA, Sigstore, in-toto). That is useful for whatever an agent changes in your projects, whichever agent it is. It does not review memory entries or skill prose, and it makes no claim to detect malicious skills.

Common mistakes

  • Assuming "learning" means training. Nothing in this loop changes model weights. If you switch models, the memory and skills come with you; so do any mistakes in them.
  • Leaving both write_approval keys at their defaults on a shared or unattended agent. On a gateway or cron host, the background review writes without anyone watching.
  • Treating display.memory_notifications: off as "learning off". It only hides the chat line. Use auxiliary.background_review.enabled: false to stop automatic reviews.
  • Thinking a pin freezes a skill. Pinning blocks deletion and archival, not patches.
  • Never running /new on messaging platforms. Fresh memories stay invisible and the loop barely runs.
  • Pointing two agents at one Hermes home. Their memories compound into state nobody wrote.
  • Approving skill writes from the one-line gist alone. Read the full diff, especially for new scripts/ files.

FAQ

How does Hermes Agent learn?

It writes text, not weights. It saves short facts to MEMORY.md and USER.md, writes and patches Markdown skills with skill_manage, and searches past sessions in a SQLite FTS5 database. A background review re-reads conversations to decide what to save, and a curator archives skills that go unused.

Does Hermes Agent train or fine-tune its own model?

No. The learning loop changes files under ~/.hermes. The model is whichever provider and model you configured. Nous Research does train the separate Hermes model family, but that is a different product from the agent's learning loop.

What happens when Hermes Agent memory is full?

The write fails with an error that shows current usage and entries. The agent must remove or shorten entries and add the new one in a single batch. Memory never auto-compacts or silently drops entries. You can raise the caps with memory.memory_char_limit and memory.user_char_limit, at a token cost in every prompt.

How do I stop Hermes Agent from saving skills without asking?

Set skills.write_approval: true in ~/.hermes/config.yaml or run /skills approval on. Every skill write is then staged for /skills pending, /skills diff, /skills approve or /skills reject. Do the same for memory with memory.write_approval: true.

Can I turn off the Hermes Agent background review?

Yes. Set auxiliary.background_review.enabled: false. You can still run a review by hand with /refine. You can also lower its frequency through memory.nudge_interval and skills.creation_nudge_interval, or route it to a cheaper model.

Is Hermes Agent's memory safe from prompt injection?

Memory writes are scanned for injection, exfiltration and SSH backdoor patterns and for invisible Unicode, but the scanning is pattern based. The stronger control is human approval of writes, plus regular review of USER.md, MEMORY.md and skill diffs.

How do I undo something Hermes Agent learned?

For skills, use hermes curator rollback <entry-id> to undo one ledgered change or hermes curator rollback --id <ts> to restore a snapshot. For memory, use hermes journey delete <node> or edit the file. Back up first, and start a new session afterwards.

What is the difference between Hermes Agent and the Hermes models?

Hermes Agent is Nous Research's open source agent software, which runs on many model providers. The Hermes models are Nous Research's open-weight language models. You can use the agent without the models and the models without the agent.

Has Hermes Agent had security vulnerabilities?

Two CVE records were published on 3 September 2026: CVE-2026-71963, an OS command execution issue through git configuration in a repository, affecting 0.18.2 through 0.21.0, and CVE-2026-85105, a session authorization bypass reported against 0.18.0. Neither is in the learning loop. We cover them in our posts on CVE-2026-71963 and CVE-2026-85105.

Fix it without waiting for upstream

A learning agent does more than remember: it installs packages, writes scripts into skills and edits code in your repositories, and all of that becomes part of the software you ship. The agent's own dependency tree, plugins and skill scripts are open source components that receive CVEs like any other, so the patching gap below applies to them too.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The Safeguard MCP server can be one of the tools an AI assistant uses, so supply chain questions get answered from real SBOM and vulnerability data rather than from the model's memory. This demo shows adding Safeguard from Claude's connector directory, signing in with OAuth and choosing which tools Claude may call. The same per-tool choice is the principle this post argues for in an agent's learning loop: decide up front what an assistant is allowed to touch.

Click through it at your own pace, or open it full screen.

The Safeguard CLI is an assistant that edits code and runs commands, and it asks before each command. In this session it fixes a lodash CVE: it reads the finding and advisory, edits package.json, runs npm install and npm test with approval, and pushes nothing. Approve-before-write is the same pattern as Hermes's write_approval gates, applied to dependency fixes.

Click through it at your own pace, or open it full screen.

If your agents run on your own hardware, scanning should too. This demo sets up the Safeguard runner on your own machine, approves it with a device code and scans from the terminal, which suits a repository an agent has just changed or a skills repository you version with git.

Click through it at your own pace, or open it full screen.

To try it on your own code, download Safeguard or read the CLI documentation.

Quick check

A Hermes agent saves a new memory during a session. When does the model first see it in its system prompt?

At the start of the next session. Memory is injected as a frozen snapshot at session start; writes go to disk immediately but do not change the running session's system prompt.

You pinned a skill. Can the agent's background review still change it?

Yes. Pinning blocks deletion and curator archival, but patches and edits still go through. To require approval for every change, set skills.write_approval: true.

Sources

Last reviewed: 23 October 2026. Hermes Agent ships several releases a week; check the docs for your installed version before relying on any default or config key above.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.