Holographic, a long-term memory provider for Hermes Agent, has moved out of the core into a separate plugin: on 11 October 2026 Nous Research merged this change into main. If you already use holographic, you can upgrade Hermes without moving your accumulated facts and settings by hand. Below, step by step, is what to do before and after hermes update. I’ll be maintaining the plugin from now on: the team accepted my fork into the official Hermes plugin catalogue.
This isn’t a new memory service: the database file is the same, and the facts you’ve built up don’t need moving. An existing component has got its own maintained repository and a person responsible for its further development. Below: installation, how the memory works and how it pairs with hermes-dreaming. Search by meaning, the reranker and merging duplicates are covered in the follow-up.
As of 30 October 2026 the latest holographic release is 0.23.1, and the Hermes catalogue has 0.22.0 pinned. For dreaming it’s 3.8.0 and 3.7.1 respectively. One limitation is worth knowing in advance: after the first merge of facts with merge, holographic versions below 0.19.0 can’t write to the database, so rolling back below that version switches memory off. The details are in the section on fact history.
The agent’s two memories and why you need holographic
Hermes has two different memories. The first is the MEMORY.md and USER.md files. They go into every agent turn in full, so they have a hard character limit: once a file hits the ceiling, new entries no longer get in. The agent edits them itself with the memory tool.
The second is an external provider such as holographic. It stores thousands of separate facts in an SQLite database and injects only the few that are needed into a turn, usually up to five. Facts have search, a trust score and, in recent versions, a history.
This kind of memory breaks quietly in two ways. Useful things never reach memory: a person said something important, and the agent didn’t write it down. And memory fills up with stale entries: facts change, but the entries stay. Holographic stores and finds the facts that have been written. Hermes-dreaming, covered below, picks out what matters for persistent memory each night and reviews what’s gone stale; extracting candidates from conversations runs as a separate dreaming job. I went through how all the layers of Hermes memory relate to each other in the article on Hermes Agent memory and choosing a provider.
How holographic works
Holographic stores separate facts in a local SQLite database and helps pick the ones relevant to the current message. For example, when you ask about a project, it can bring up the decisions linked to it instead of loading the whole conversation history into the context. Search runs over saved entries: automatic extraction of facts from conversations is off by default.
Holographic doesn’t replace the whole Hermes memory system: it’s a pluggable provider for storing and extracting facts. All its memory is one SQLite file, and in its default mode the plugin makes no external calls at all. The provider combines word search, links between entities and HRR, a mathematical way of representing links in vectors. Inside there are four mechanisms:
- FTS5 full-text search with word forms, word stems and n-grams: short sequences of characters used to search text in languages without spaces.
- Trust in facts. The agent rates whether a fact helped through
fact_feedback, and the trust score shifts. A fact whose trust falls below themin_trust_threshold(0.3 by default) stops being recalled. - Entities with aliases. The agent can write “X aka Y”, and both names will lead to the same facts. Names work not only in Latin script but in any alphabet with capital letters.
- HRR, holographic reduced representations, which gave the plugin its name. It’s a way of encoding links between facts and entities as vectors without a language model; the numpy library isn’t required for it.
In the basic mode it needs no API key, no network and no language model calls. Requests to a separate server appear if you switch on search by meaning (embeddings: on) or the reranker (rerank: on); both are off by default. That doesn’t mean the whole agent works offline: the facts it finds go into the context of whatever model you use in Hermes. Storing data locally and having it processed by a cloud model are different questions.
How to upgrade Hermes Agent without losing memory
If memory.provider: holographic is set in the config, the plugin is meant to install automatically from the catalogue on hermes update or when the agent starts after moving to code where the built-in copy has been removed. The change was merged on 11 October and went into the Hermes v0.21.7 release of 12 October; the notes on Hermes 0.22 mention separately the move of memory providers into the catalogue and the new holographic maintainer.
The memory_store.db database with your facts and the plugins.hermes-memory-store settings are kept. The provider name stays the same too. There’s no need to create an empty database, rewrite facts by hand or switch to another provider just because this one has left the core.
The automatic migration is in Hermes v0.21.7 and every newer version. If your installed version is older and still contains the built-in holographic, the built-in copy is used.
The migration mechanism is designed to keep your data, but before upgrading a system with valuable memory I still recommend four steps:
- Make a backup. The simplest way is the
hermes backupcommand: it takes a consistent snapshot of the database even while the agent is running. If you copy by hand, stop Hermes first, then save the database (memory_store.dbby default, or the path fromdb_path) andconfig.yaml. - Check the version. Make sure the migration is included in the Hermes version you’ve chosen.
- Upgrade with
hermes update. - Check memory. Ask the agent to find a fact that was definitely saved before the upgrade.
If memory did switch off after the upgrade, the plugin’s README has a separate section, “Memory went off after hermes update”, that goes through the causes.
For installations made from the URL of the old Nous Research repository, a migration to the maintained catalogue entry has also been added. For such installations, the archived repository’s README also suggests a one-off reinstall from the catalogue: hermes plugins remove holographic && hermes plugins install holographic. The database and settings are kept.
How to install holographic from scratch
Here’s holographic in the official Hermes catalogue: it shows the maintained repository, the pinned version, the Hermes requirements and the known limitations. As of 30 October 2026 the entry points to 0.22.0 and requires Hermes 0.21.5 or newer. That’s the plugin’s minimum compatibility, not the version number that guarantees the automatic migration.
The automatic migration installs the version pinned in the catalogue at the moment of migration. hermes plugins list shows which version you have. If it’s older than the one pinned in the catalogue, reinstall the plugin: hermes plugins install holographic --force. The memory_store.db database and the settings are left untouched.
For a new installation, the provider documentation suggests:
hermes plugins install holographic
hermes config set memory.provider holographic
The other option is to run hermes memory setup and choose holographic. If the provider is already set up, don’t take these commands as a mandatory manual migration: existing users get an automatic one.
To install a specific release rather than the one pinned in the catalogue, the README suggests passing the full commit hash: hermes plugins install holographic --ref <40-character hash> --force. The release hashes are on the repository’s releases page.
The latest version and all releases are in the holographic repository. How Hermes plugins and skills work in general, and where to install them from, I covered in a separate article.
Mirroring built-in memory entries into holographic is also off by default: the plugin doesn’t promise to remember everything that was ever said on its own.
Why holographic left the Hermes core
The move was originally planned for 15 October. For holographic it happened earlier: a dedicated maintainer turned up, and the catalogue entry passed review. The PR removing the built-in copy has already been merged into main.
The old Nous Research repository has been archived and points users to my fork. That keeps a clear route for anyone who installed the earlier standalone copy.
A plugin outside the core can be developed independently of core releases. But installing from the catalogue uses the pinned commit, not the latest state of my main branch: new versions arrive once the pinned commit is updated in the Hermes catalogue.
The fork’s path over two weeks looked like this. 2 October: version 0.1.1, a copy of what was in the core. 10–12 October: versions 0.2–0.6, with search fixes, a relevance filter, languages and keywords. 12 October: 0.7 and 0.8, with a database per chat, fact history and real deletion. 13 October: 0.9–0.13, bringing 18 languages with dictionaries, a code audit and fact checks on read.
The development map: separate memory per chat (0.7.0), fact history and “forget” (0.8.0), search in 18 languages with dictionaries (0.9–0.11), checks on write and on read (0.12–0.13), search by meaning (0.14), fact provenance (0.15), entity clean-up (0.16–0.17), an experimental reranker (0.18), merging duplicates while keeping history (0.19), a log of task outcomes (0.20), a token limit on the recall block (0.21), names that follow the fact text (0.22), and honest trust for corrected text (0.23). Old tool calls still work, but database file compatibility after merge has changed; more on that below.
My Hermes Field Notes plugin has already been through the catalogue in a similar way. The responsibility here is different: the changes affect not just a tool but the memory a user has built up.
What improved after leaving the core
The first thing I did was run version 0.1.1, the one that shipped in the core, on a synthetic database of 200 facts about 20 people, and then I got to work on search. The results from the version 0.2.0 changelog:
probe, search for facts about an entity: precision among the top five results rose from 0.02–0.04 to 1.00.reason, search across several entities at once: the right fact now lands in the top five in 15 cases out of 15, against one before.- HRR in search now tells facts apart: about 0.69 for on-topic facts against 0.51 for the rest.
- The retrieval counter
retrieval_countnow counts how many times a fact has been handed to the model. - Entity names are recognised in any alphabet with capital letters, not just Latin script.
- FTS5 errors are written to the log as a warning.
Later, together with dreaming, writing facts from cron jobs was set up as well; the details are in the section on how the plugins work together.
How holographic recalls before a reply
Before each agent turn the provider picks facts for the message by itself. The order is:
- Small talk is cut off. A message made up only of greetings, thanks and “ok, thanks” recalls nothing.
- Words are broken down into keys: word forms, stems, words sharing a root, n-grams.
- Candidates are gathered from the FTS5 index, by n-grams, and by a word scan where the index can’t help.
- Relevance filter. A fact passes if it covers a large enough share of the words in the message (
prefetch_min_coverage, 0.3 by default), with rare words weighing more than common ones. - No repeats. A fact already shown within the last few turns (
prefetch_repeat_turns, 6 by default) isn’t injected again. - Up to five facts go into the turn, plus facts about the entities named in the message. Since 0.21.0 the whole block can be capped at an approximate number of tokens (
prefetch_max_tokens, off by default): a fact line that doesn’t fit drops out entirely, because cutting it at the limit could lose a “not”, a condition or a date. The long-standing cap of 300 characters per block line applies with or without the limit.
Facts arrive in a separate block marked as saved data, not instructions. Each line looks roughly like - #12 [0.5] fact text: the number is there so the model can rate the fact through fact_feedback, and the brackets hold the trust score.
Since version 0.14.0 the holographic block in the system prompt contains no live numbers. It used to show the number of facts, which changed with every new entry, and the model’s prompt cache was reset with every new session: in one installation that cost about 21,000 tokens of rereading. Now the line is constant and the cache works.
Since version 0.6.2 holographic by default passes Hermes a line saying how many memories were pulled in for the reply; in Telegram it arrives as a separate message in English. The built-in copy didn’t do this. It’s switched off with recall_indicator: false in plugins.hermes-memory-store and has no effect on search itself. Like the plugin’s other settings, it’s read when the gateway starts: the change takes effect after a restart.
Tools: fact_store and fact_feedback
The agent has two tools available, and a third can be switched on if you want it. In holographic 0.23.1, fact_store knows 26 actions:
- writing:
add,update,change,end,correct,revert,merge,forget,remove; - search:
search,probe,reason,related,contradict,history; - maintenance:
list,stats,export,review,enrich; - names and entities:
entities,alias,rename,delete_entity,split,rebuild_entities; the last four arrived in 0.16–0.17.
The second tool, fact_feedback, rates whether a fact helped.
The third, fact_experience, arrived in 0.20.0 together with the task outcome log and only works if you set experience: on. The log records which fact versions the agent actually received in a search or before a reply, and the agent’s report on whether they helped or let it down. This is a record kept separately from trust: a fact that’s true but out of place no longer has to be “punished” with a truthfulness score, and the log changes neither trust, nor provenance, nor ranking. The agent’s report isn’t confirmation from a person. Entries are kept for up to 30 days and no more than 1,000 attempts per database, and forget on a fact also deletes the entries linked to it. Since 0.23.1 the text of an expired entry is wiped from the database file straight away, even if the database stays open for a long time, rather than on the next open.
On add the plugin replies with hints: similar entries (similar), possible contradictions (possible_conflicts) and past versions of the same fact (past_versions). The decision stays with the agent.
When adding a fact, the agent can pass keywords: synonyms, words with a different root, translations. That way a fact can be found by a word that isn’t in it, with no model at all; the second route is the optional search by meaning. Keywords are stored next to the fact and don’t go into the injected block.
Old prompts keep working: add supersedes=X now means change X, update content= means correct, and remove means forget.
Fact history
Since version 0.8.0 every fact has a history, and the actions distinguish why a fact stopped being current:
change: the world changed. The old text becomes a past version of the same fact, and the number is kept;end: no longer true, and there’s no replacement;correct: it was a mistake. The corrected text becomes current, and the mistaken version doesn’t come back even in queries about the past. Since 0.23.0 the new text doesn’t inherit what the mistaken one earned: it starts with the trust its provenance gives it, without usefulness marks or confirmations. A statement a person confirmed no longer counts as confirmed once the agent has rewritten it;revert: roll back the last edit;forget: erase. More on that below.
Search accepts as_of=YYYY-MM-DD and answers what was true on that date. Facts for which that can’t be said go in a separate list: the plugin doesn’t make up dates, and a fact without an explicit start date counts as true from the day it was written.
Each version records where it came from: platform, chat type, chat and thread, session, author of the turn. Chat names aren’t stored. Ordinary recall sees only the present; past versions sit in a separate table and a separate index.
Names follow the text. Since 0.22.0, when the text changes through change, correct or update, a new entities list replaces the previous names, and without a list, a name that the old text mentioned and the new one no longer does is removed. Before, the fact “Leo’s guitar teacher is Ben Cole”, rewritten to “…Omar Reid”, could still be found by the name Ben Cole. revert also brings back the names of the version it rolls back to.
Since 0.23.0, ratings through fact_feedback don’t make a fact “younger”: its age is counted from when the current version was written. This only matters if time decay is switched on (temporal_decay_half_life, off by default): before, a single rating could lift a ten-day-old fact above ones written later.
Since 0.19.0 there’s a separate action for duplicates: merge {fact_id: <keep>, from: [<copy>]}. The copy drops out of search and recall, but its history, sources and confirmations are kept under its own number and can be seen from the history of the fact that was kept. This is a merge, not a deletion: there’s no separate command to undo a merge. The expect parameter lets you merge only the versions the person saw when agreeing to it; if the fact has changed in the meantime, the operation writes nothing and replies changed_since.
Make a backup before your first merge. It’s the first merge that raises the history schema version to 2. After that, holographic 0.15–0.18 refuses to write to this file with a HistoryTooNew error, and the main agent’s memory switches off. To go back you need version 0.19.0 or newer, or a copy of the database from before the merge. You mustn’t change the schema number by hand. The catalogue currently serves 0.22.0, so the risk arises if you manually roll back by hash to a version older than 0.19.0.
How “forget” works
forget in holographic doesn’t just remove a fact from results; it also starts a physical clean-up of the file:
- The fact, all its versions, links and orphaned entities are deleted.
- Both FTS indexes are rebuilt: deletion in FTS5 leaves words in old segments.
- The file is rewritten with
VACUUMwithsecure_delete, and the WAL journal is reset. - A “tombstone” remains: an internal marker for the deleted fact, with its number and an HMAC-SHA256 of the normalised text, without the text itself. The key for the hash is 16 random bytes, different for each database.
If another process is holding the file at that moment, the rewrite and journal clean-up steps are postponed: the reply says scrub: "pending", and the clean-up is retried on the next database open or the next forget. In a database with a DELETE journal, another reader can also derail the commit itself: then nothing changes, no tombstone is written, and forget has to be repeated.
The tombstone is there so that auto-extraction doesn’t bring the fact back from old messages, and so that other tools, dreaming for example, can clean out their own copies by number. Since version 0.12.0 deletion doesn’t wait for other readers of the database: before, memory switched off for about 11 seconds while it did.
If the fact was merged with others, forget on the kept fact also deletes the attached copies. Deleting only a copy erases its history, but the main fact remains, and the tool says so.
What forget doesn’t reach: the Hermes session database, Git history, external dumps and backups, including hermes backup. They have to be cleaned separately. A successful deletion from the store doesn’t prove the text has disappeared from every archive.
Separate memory per chat
The scope parameter (since version 0.7.0) decides how many databases the agent has:
profile: onememory_store.dbdatabase, as before;chat: a database of its own for each chat in theholographic-chats/folder;thread: a database of its own for each forum topic;user: a database of its own for each person inholographic-users/, by the author of the turn.
You need this when one bot serves several unrelated groups: the provider pulls facts into every reply by itself, and without isolation it could retell to one group what was said in another. Isolation is done with a separate file per chat rather than a chat_id column: facts turn up in the index, in n-grams, in entities and in HRR vectors, and a single missed filter would mean a leak. If there’s no chat (CLI, cron, a subagent), nothing is read or written in these modes.
Search by meaning: optional, since version 0.14
Word search finds facts that share something with the question. For questions worded quite differently, 0.14.0 added search by meaning through embeddings. It’s off by default and is switched on in plugins.hermes-memory-store:
embeddings: on
embedding_url: https://api.openai.com/v1
embedding_model: text-embedding-3-small
embedding_key_env: OPENAI_API_KEY
Any OpenAI-compatible embeddings API will do: OpenAI, Gemini or a local server such as Ollama. embedding_key_env takes the name of an environment variable, not the key itself. With a cloud service, the texts of facts and messages go to it; with a local server, everything stays on your machine.
How it works:
- Words remain the foundation. Meaning reorders the facts found by words and can add one more, at the end and marked
(by meaning), but only if it clearly stands out from the rest.fact_store searchappends the facts closest in meaning after the word matches. - The turn barely waits. The message vector is requested before the reply with a 3-second timeout, and the fact vectors after the reply, in the background. On any error the plugin falls back to word search.
- Secrets aren’t sent. Facts and messages that look like keys, passwords or authorisation headers don’t go to the embeddings server.
forgetalso deletes the fact’s vector, and once the feature is switched off, all vectors are wiped.
On a synthetic set of 100 facts in five languages, rephrased questions found the right fact before the reply in 54 cases out of 67 with text-embedding-3-small and in 59 with gemini-embedding-001, against 22 with words alone. Small talk still recalls nothing.
Search by meaning is part of the catalogue version. How it was fine-tuned on live databases, with bge-m3, slow local servers and a rule for when a fact found by meaning can be shown next to word matches, is in the follow-up.
The reranker: less noise, with caveats
Since 0.18.0 you can switch on a second stage: a separate model reads the message together with the facts found and changes their order. It’s off by default and remains experimental. On the maintainer’s test set of 126 questions, about 40% fewer irrelevant facts made it into the top five, but in one run one needed fact was lost, and with embeddings, two. There’s no promise here of finding more.
With rerank: on, the message and the candidate texts go to the configured rerank_url. llama-server has been tested; you need a Cohere-format response without authorisation, because the client doesn’t send a key. On an error or timeout, the results stay as they would be with the reranker off. 0.19.2 fixed background reranker and embeddings requests that hung when a server was too slow to send headers. Since 0.22.2 a slow server is sent as many candidates as it can score in half the timeout, so a large set no longer gets cut off by time or puts the server on pause. Setup and benchmark results are in the follow-up.
18 languages without a model or network
The plugin understands 18 languages without turning to a model or the network:
- Snowball stemmers, algorithms that cut endings off a word and extract the stem, for English, Russian, Spanish, French, Portuguese, Indonesian, German, Hindi, Italian, Turkish, Polish and Dutch;
- Arabic: Larkey’s light stemmer alongside Snowball; Bengali: a stemmer of its own;
- Chinese, Japanese, Korean and Thai: through character n-grams.
The language of Latin-script text is detected by function words. Dictionaries come bundled:
- DerivBase.Ru: Russian words sharing a root, Apache-2.0;
- Open English Wordnet: English words sharing a root, CC BY 4.0;
- jieba: Chinese words, MIT, and OpenCC: traditional script mapped to simplified, Apache-2.0;
- SudachiDict: variant Japanese spellings such as 子ども and 子供, Apache-2.0;
- Wikidata Lexemes: German compound words and verb forms in German and Spanish, CC0.
A match by root, dictionary form or part of a compound word weighs 0.6 of an exact match and never recalls a fact on its own. On my blind Russian set of 12 questions with a word sharing the root, search found the right fact in 92% of cases against 75% in 0.8.0, and pulled it into the reply by itself in 67% against 42%. Dictionaries load the first time a language is encountered; the heaviest, Chinese, takes about 0.2 seconds and 30 MB.
In practice it looks like this. It finds: Маши, an inflected form of the Russian name Masha, matches a fact about Машу, another form of the same name; German Zahnarzttermin matches “Termin beim Zahnarzt”; Spanish fue matches the verbs ir and ser, with a weight of 0.6; İstanbul matches ISTANBUL; 引越し matches 引っ越し; traditional 學校 matches simplified 学校. It doesn’t confuse: 和服, kimono, isn’t found in the phrase 我和服务员, “I and the waiter”; German Hochzeit and Zeit, Matrose and Rose are different words; media isn’t taken for Indonesian dia; a Japanese question in kana about 手紙, a letter, no longer finds Chinese 手纸, toilet paper. The reverse direction remains a problem for now: a question made up only of kanji can’t be told apart from Chinese.
Search can still miss with words that aren’t in the dictionary: for example, it doesn’t link the Russian adjective дачный with the noun дача, a country cottage.
What the plugin won’t let into memory
On write, holographic refuses the following and explains why:
- instructions to the model such as “ignore previous…”;
- passwords, keys, tokens and PIN codes together with their value (since 0.12.0), and since 0.14.5, even without the word “password”, keys, bot tokens and JWTs recognised by their shape; since 0.15.2, values of variables such as
OPENAI_API_KEY; - Markdown and HTML images (since 0.13.0): they’re a leak channel, because the client requests the image address by itself, and data can travel out in it;
- role markup, tool JSON and invisible characters.
Since 0.22.1 this check is about 30 times faster on long texts, and its decisions are the same: it gets through a megabyte of Russian text in 0.3 seconds instead of 9.
Since version 0.13.0 a fact is checked once more before being injected into a reply. A fact written before the rules appeared that doesn’t comply with them isn’t recalled, and this is written to the log once. Search and history show it so that it can be fixed.
Write permissions are split. Explicit calls from cron write if cron_writes is on; automatic writing in cron is off by design. Subagents and internal compression contexts only read.
Hermes-dreaming: memory’s nightly sleep
My second memory plugin, hermes-dreaming, works in tandem with holographic and deals with the second failure: memory that fills up with stale entries and never gets what matters. Holographic stores facts and finds the ones needed for a reply, while dreaming decides each night which of the things said are worth locking in: it checks candidates against what people actually said on different days, and wakes the agent only when there’s work to do. The default fact source is precisely the holographic store.
By default the nightly pass is a deterministic Python script using only the standard library: it doesn’t call a model or write to memory, and it wakes the agent when there’s something to decide. The idea comes from dreaming in OpenClaw. Since version 3.3 you can switch on a cloud judge, and then the script sends permitted “fact – message” pairs to a separate decision model. Dreaming 3.4 brought proposals to merge duplicates through holographic 0.19; without an answer from a person, the nightly pass doesn’t merge them. Since 3.5 the installer updates the cron jobs itself, and since 3.8 only what a person said or confirmed is carried over into persistent memory. The details are in the follow-up on dreaming.
One night goes like this:
- Input: facts from holographic, people’s messages from the Hermes session database, and the
MEMORY.mdandUSER.mdfiles. - Confirmation. A candidate for memory has to come from people on different days. Cron messages, links and the dreaming threads themselves don’t count.
- Check against memory: duplicates, aliases, “the same thing but with different numbers”.
- Quarantine: secrets and injection attempts are cut off, and events with a date expire.
If there’s no work, the pass replies {"wakeAgent": false}, and the model doesn’t start at all. If there is, the agent gets one turn, writes with the memory tool and makes no more than six edits and three new entries a night. Candidate scoring uses six weights from OpenClaw; dates and events are read in 15 languages, and Chinese, Japanese, Korean and Thai through n-grams.
For this turn the agent gets:
- candidates for writing: write or reject, there’s no third option. An agent’s conclusion that nobody has confirmed doesn’t become a candidate: if people repeated it on different days, dreaming suggests asking for confirmation;
- stable information about the person, for
USER.md; - conflicts, the same subject with different numbers: replace or ask;
- stale entries, with the question “still current?”; it isn’t allowed to delete them on its own;
- a warning if a memory file is at 85% of its limit or more, to fold similar entries together;
- quarantine in a single line, without retelling the contents;
- alarms about memory loss.
Every candidate comes with quotes from people and the nearest memory entry with its verbatim text, so that memory replace hits exactly. Facts that a person rejected are handed to the agent by dreaming with a ready-made fact_feedback call, so that the rejection also teaches holographic search. Keywords for facts are optional (keywords.enabled): a few facts a night come with a ready-made fact_store update call, and dreaming won’t wake the model just for that.
No question is asked forever
The main thing dreaming has learned from live data is not to ask the same question over and over. A rejected fact used to end up neither in persistent memory nor in any filter, so it came back as a candidate every night: in one real case the agent asked the same thing about a long-closed topic 12 times in five weeks. Now it works like this:
- The reject list stores rejected items by text, not by number. Since 2.7.0 asking again is possible after six months (
reject_reask_days, 180 days) if the fact has been said again: a new entry in the database and a mention by a person after the rejection. - Pauses. New facts, conflicts and “still current?” questions are shown no more often than once every 14 days. An entry that survives the “still current?” question counts as confirmed and rests for 90 days. The countdown starts only after the agent answers: a night that breaks off halfway will show the same thing again.
- Conflicts are caught by numbers, dates, months and, since 2.7.0, days of the week: “ballet has moved to Tuesday” is an update.
- The loss watchdog raises the alarm if more than 25% of memory entries or characters disappear.
- Probes (since 2.7.0) are phrases that must stay in memory, for example “peanut allergy”. If one goes missing, there’s one alarm.
- Duplicates in the database are checked sensibly: two dates of the same event aren’t a duplicate.
How holographic and dreaming work together
I built the new versions of both plugins together. In holographic 0.8.0, cron jobs can once again write facts through explicit calls (the cron_writes parameter, on by default): since 0.2.0 writing from cron had been closed, and it was reopened with a separate parameter for dreaming’s nightly extraction. Auto-extraction and mirroring in cron are still off.
In dreaming 2.4.0 a person’s answers control fact history: “that’s no longer true” closes a fact, “that was a mistake” marks it as wrong, “forget” erases it. A separate job without a language model cleans copies of forgotten facts out of dreaming’s own diary, reports and internal lists every 15 minutes. Since 2.5.0 dreaming compares words in every language holographic reads.
The roles are split like this:
- holographic stores facts and their history;
- the dreaming script opens the database read-only, checks facts against people’s conversations and proposes changes;
- the agent in cron applies the decisions: it writes memory with the
memorytool, and in holographic throughfact_store, turning “that’s no longer true”, “that was a mistake” and “forget” intoend,correctandforget; - a separate job deletes internal copies of forgotten facts.
There are three links between the plugins:
cron_writes: without it cron couldn’t write a single fact;- tombstones and clean-up: dreaming reads the table of forgotten facts and wipes copies by number in its cache, the dreaming diary and the cron logs;
- feedback: trust scores and the keywords that facts are missing.
The contract between them is the file names, the tables of facts and of forgotten items, and the plugins.hermes-memory-store settings key.
The pairing has a boundary. With scope: user, chat or thread, facts sit in separate files: the nightly pass doesn’t read them by default, otherwise it would carry one chat’s facts into memory that everyone sees, and a cron job without a chat context doesn’t write there either. With cron_writes: false, writing from cron is closed too. Since 2.5.3 dreaming names the reason in the report and doesn’t wake the model for extraction, while the other nightly checks work as usual.
Since version 2.6.0 dreaming can also work with the databases of individual chats (chat_stores, off by default). In read mode, each database appears in the report only as numbers, with no text and no fact numbers. In promotion mode, facts from the selected chats take part in the pass, but each is confirmed only by messages from its own chat. Such facts are marked with a number like <database>#17 and go only into memory, never into fact_store. “Forget” has to be said in that same chat. Whatever is written to shared memory will be seen by every chat, which is worth remembering, promotion included.
How to install the pair
Holographic comes from the catalogue. If the plugin is already installed, add --force to the install command to update it to the pinned version: nightly extraction needs 0.8.0 or newer.
hermes plugins install holographic
hermes config set memory.provider holographic
Dreaming:
hermes plugins install hermes-dreaming
hermes plugins enable hermes-dreaming
python3 ~/.hermes/plugins/hermes-dreaming/skills/dreaming/scripts/install.py
install.py lays out the internal scripts, creates ~/.hermes/dreaming.json from the example and does a trial run. Next comes the part nobody will do for you: list your trusted groups in trusted_chat_ids. There’s no need to duplicate the time zone: it’s taken from the Hermes settings. While the list is empty, no group chat confirms facts. If a trusted chat is a forum, list in excluded_threads the threads where it’s not people talking: the agent’s notifications, bridges, automatic cards.
The cron jobs are created with the Hermes interpreter, first as a dry run:
~/.hermes/hermes-agent/venv/bin/python \
~/.hermes/plugins/hermes-dreaming/skills/dreaming/scripts/install_cron.py --deliver local --dry-run
If you’re happy with the plan, repeat without --dry-run. Three jobs will appear: dreaming itself, fact extraction (running it once a week is enough) and the clean-up of forgotten facts every 15 minutes. After every plugin update, run install_cron.py --upgrade (first with --dry-run) and install.py --check: the first updates the internal scripts and the standard job instructions, the second checks the installation without changing anything. You need Hermes 0.21 or newer.
The dreaming README recommends installing from the catalogue rather than from a link. As of 30 October the catalogue serves dreaming 3.7.1, and the latest release is 3.8.0. Holographic is the default fact source, but an export to SQLite or JSONL works too. Nightly extraction needs holographic 0.8.0 or newer; merging duplicates needs holographic 0.19.0+ and dreaming 3.4.0+. Since dreaming 3.5.0 the installer updates the standard instructions of existing cron jobs itself and leaves manually edited ones alone, with a warning. The procedure is in the follow-up.
What to bear in mind when using it
- Rephrasing. Without a model, a rephrasing with no words in common is linked by the keywords the agent adds to a fact: synonyms, words with a different root, translations; since version 0.14 you can switch on search by meaning. Words sharing a root are found through the dictionary; if a pair isn’t in the dictionary, as with
дачныйandдача, keywords come to the rescue. - Large databases. For languages where search works by a word scan, the first such search after startup goes through every fact: with 20,000 facts that’s 4–6 seconds. A persistent key index is planned for larger databases.
scope: userin dreaming. Messages in the Hermes database have no author, so in a group the session owner counts as the author.- Days of the week are read by dreaming only as full words; abbreviations like Tue and Wed aren’t supported yet.
forgetwipes a fact from the holographic database; dreaming removes its own internal copies. The Hermes session database, Git history and external archives are cleaned separately.
A possible contradiction is a hint for the agent, not an automatically established truth: the decision stays with it. For me, the quality of a component like this is above all about how relevant its memories are. Storing an entry isn’t enough: you have to retrieve it at the right moment and not clutter every reply with facts that have nothing to do with it.
Who maintains holographic
The original holographic was created by dusterbloom; the provider already shipped inside Hermes. My role is to maintain and develop its standalone version after it left the core.
What went into the catalogue is my fork, itpartypattaya/hermes-plugin-holographic. As of 30 October the official catalogue records version 0.22.0, commit ff558dd and maintainer itpartypattaya. It includes search by meaning, entity clean-up, the experimental reranker, merging duplicates, the task outcome log and the token limit on the recall block. The repository’s latest release is 0.23.1.
Development happens in my holographic repository. What arrived in versions 0.14 to 0.23, and how users with Chinese and Russian databases take part in it, is in the follow-up. If you find a bug, the best report is an example: which fact was saved, which query didn’t find it and what you expected to see. Just leave out personal data and the contents of your whole database: a public issue shouldn’t become yet another store of your memory.
FAQ
Will my facts disappear after hermes update? No, if memory.provider: holographic is set in the config: the update installs the plugin from the catalogue and keeps your existing memory_store.db and settings. It’s still worth making a backup before the upgrade.
Do I need to do anything by hand? If you used the built-in provider, you don’t need to move any facts. hermes plugins list shows the installed version; hermes plugins install holographic --force installs the one pinned in the catalogue. As of 30 October that’s 0.22.0. If you’ve already used merge, don’t roll back below 0.19.0 without restoring the database from before the merge. For anyone who installed the old Nous Research repository from a link, the README recommends a one-off reinstall from the catalogue.
Which version do I have after the automatic migration? The one pinned in the catalogue at the moment of migration; as of 30 October that’s 0.22.0, while 0.23.1 has been released in the repository. The hermes plugins list command shows your version.
Does holographic work without internet access? The basic mode does. Search by meaning and the reranker send texts to the servers you choose; with local servers these features also manage without internet. Either way, the facts found go into the context of the Hermes model, and if that model runs in the cloud, it’s the one processing the data.
Does holographic work together with hermes-dreaming? Yes, holographic is dreaming’s default fact source. Nightly extraction needs holographic 0.8.0 or newer, and history and forgetting also need dreaming 2.4.0 or newer; the latest versions are in the holographic and hermes-dreaming repositories.





