Its been a while since I wrote a blog post. Last one was the Sibyl reproduction on June 9. Before that, the universal memory layer post. Before that, the v3.1 release on May 26.
Between May 26 and June 18, we shipped nine releases. None of them got a blog post. That is the backlog this post is here to close.
I am not going to pretend each release deserves its own 800 word essay. Some of them are fixes. Some are infrastructure. But there are real features in here: owner-scoped canonical facts, a holographic memory importer, a bidirectional sync engine with optional encryption, and the headline: an L3 persona layer that survives past the working-memory TTL. All of that shipped in three weeks. Worth catching up on.
The full changelog is in CHANGELOG.md on GitHub. This post is the human-readable version with the why.
The Quick Map
| Version | Date | Headline |
|---|---|---|
| v3.1.2 | 2026-05-28 | Patch: preferred embedding env vars |
| v3.3.0 | 2026-06-01 | sync_roles, fact recall in default path, hardcoded 384 fixes |
| v3.4.0 | 2026-06-01 | Multilingual ST dimensions, Unicode tokenization |
| v3.5.0 | 2026-06-10 | Housekeeping: CI docs-check, packaging |
| v3.6.0 | 2026-06-10 | Canonical facts, holographic importer, embedding fallback |
| v3.7.0 | 2026-06-13 | Usage-driven working memory decay |
| v3.8.0 | 2026-06-15 | Sync engine, reindex, vec_working, sleep orphan recovery |
| v3.9.0 | 2026-06-18 | Sync deploy tooling, fact_recall relevance, audit rename |
| v3.10.0 | 2026-06-18 | L3 persona layer |
Now the deep cuts. Grouped by what they actually do, not by version number, because the same theme runs across several releases.
Canonical Facts and the Holographic Importer (v3.6.0)
v3.6.0 shipped the two features that changed how Mnemosyne handles long-running agent identity.
Owner-scoped canonical facts solve a problem that sounds small until
you hit it: "what is this user's preferred name" should not be three
separate memories that drift over time. It should be one slot with a
history. New mnemosyne_remember_canonical
and mnemosyne_recall_canonical
tools store facts in a single-source-of-truth table. Restating a stable
self-fact is a no-op. A new value supersedes the old one, preserved as
history. One SQLite table plus a partial unique index. No new
dependency. No FTS table. Add it to your stack and existing tables stay
exactly where they are.
The holographic memory importer is the other v3.6.0 piece. If you have
data in Hermes' holographic memory plugin
(~/.hermes/memory_store.db),
Mnemosyne can read it directly now. Content, category, tags, trust
scores, timestamps, entity links: all preserved. Trust scores map to
Mnemosyne importance (both 0-1). Run with
--from holographic
and a dry-run flag so you can preview before committing.
Tool count jumped from 23 to 25 with canonical. Holographic adds zero tools, just an importer.
Memory That Outlives the Working Window (v3.7.0)
Until v3.7.0, working memory TTL was hardcoded at 24 hours. Recall something important, sleep, and the agent forgot it the next day unless it had been promoted to episodic.
v3.7.0 fixed that with usage-driven decay. Default TTL bumped to 168
hours (a week). Frequently recalled items get their TTL bumped on each
recall, capped at
MNEMOSYNE_WM_BUMP_CAP_HOURS
(default 24h per bump). You can also pin specific memory IDs with
MNEMOSYNE_WM_PINNED_IDS
so sleep consolidation skips them entirely.
v3.7.0 also re-applied the temporal-triple lifecycle
(supersede,
valid_until,
end)
that had silently disappeared from v3.5.0 and v3.6.0 despite appearing
merged. New mnemosyne_triple_end
tool exposed for explicit lifecycle management.
The Sync Engine (v3.8.0 and v3.9.0)
This is the biggest chunk. Bidirectional memory sync shipped across two releases and is worth its own paragraph.
v3.8.0 introduced the SyncEngine protocol: event-log-based delta sync
between Mnemosyne instances using an append-only
memory_events
table with conflict detection. Stdlib-only HTTP sync server (no
FastAPI dependency). New CLI commands:
mnemosyne sync,
sync-serve,
sync-status,
sync-generate-key.
Optional client-side encryption via Fernet/XSalsa20 with passphrase or
key-manager key sources. Causal version chains for conflict resolution.
Tutorial, troubleshooting guide, and deploy configs (Docker, Caddy,
Fly.io) all included.
v3.9.0 made sync actually usable in production. The standalone Hermes
plugin learned upgrade,
cleanup, and a smarter
status
with Python version mismatch warnings. Sync tool schemas were added
to both the Hermes provider and the standalone plugin, bringing total
tool count from 25 to 28.
v3.9.0 also fixed the silent-fail where fact_recall
collapsed all facts from the same path into one score. Now it preserves
FTS rank order and scores with
relevance * confidence.
Opt-in via MNEMOSYNE_FACT_RECALL_ENABLED.
And one nasty table collision fix that was hiding in v3.9.0: the audit
log was creating a table called
memory_events,
same name as the sync engine's event log, different schema. INSERTs
silently failed. Audit log is now
audit_log. Sync
keeps memory_events. Both
happy.
The Persona Layer (v3.10.0)
Headline of the whole sprint. v3.10.0 ships the L3 persona layer: an
always-on behavioral rules tier that survives past the 24-hour
working-memory TTL. New
memoria_persona
SQLite table with tiered retention:
permanent,
long_term,
working.
Four new tools:
mnemosyne_persona_promote,
mnemosyne_persona_demote,
mnemosyne_persona_list,
mnemosyne_persona_reinforce.
Auto-injection into the system prompt via
persona.md.
Reads ~/.hermes/memory/persona.md
and includes it in the system_prompt_block()
of the Hermes provider. Mtime-cached for hot-path efficiency. Token
cap enforced via
MNEMOSYNE_PERSONA_TOKEN_CAP
(default 1500). Five trigger conditions match the Hy-Memory
PersonaTrigger pattern: explicit request, cold start, recovery,
threshold (default 50 new memories), daily sync window.
Default OFF. Opt-in with
MNEMOSYNE_PERSONA_ENABLED=true.
Schema migration is additive. Existing tables untouched. No breaking
changes to mnemosyne_remember or
mnemosyne_recall.
Tool count: 28 to 32.
Full deep-dive on persona is in the next post. This one is the catch-up. The persona gets its own essay.
The Smaller Stuff Worth Knowing
A few items that did not get their own headline but matter for production users.
v3.1.2: embedding env vars
MNEMOSYNE_EMBEDDING_API_URL and
MNEMOSYNE_EMBEDDING_API_KEY
are now the preferred names. Old
OPENROUTER_BASE_URL and
OPENROUTER_API_KEY still work
as fallbacks. Restores the v2.8.x naming convention (issue
#193).
v3.3.0: sync_roles and the 384-dim bug
sync_turn() now checks
memory.mnemosyne.sync_roles
before persisting conversation turns. Default
["user", "assistant"] preserves
existing behavior. Set to ["user"] for
user-only autosave, or [] to disable
autosave entirely while keeping explicit remember calls working.
Contributed by bitr8, closes
#209.
Also in v3.3.0: a hardcoded embedding dimension bug. The
EMBEDDING_DIM constant was
hardcoded to 384 across three files (binary_vectors.py, shmr.py,
polyphonic_recall.py), silently truncating larger embeddings (1024-dim
multilingual-e5-large, for example) and losing up to 62.5% of vector
information. Now derived from
mnemosyne.core.embeddings.EMBEDDING_DIM
at import time with a 384 fallback. PR
#200
by Whishp.
And a plugin path shadowing bug: Hermes adds
~/.hermes/plugins/ to
sys.path, so a symlink named
mnemosyne resolved before the
actual mnemosyne-memory pip package,
causing ModuleNotFoundError. The
try/except swallowed it silently. Renamed to
hermes-mnemosyne (issue
#212).
v3.4.0: Unicode tokenization for non-English recall
Until v3.4.0, recall lexical gates stripped diacritics inside tokens.
Words like Stoßlüften,
Bürgeramt, and
Primärquellen got split into
ASCII fragments and lost recall matches. Fixed.
v3.5.0: housekeeping
v3.5.0 was a docs and CI release. No user-facing behavior change. The docs-check CI job landed. Packaging metadata got polished. That is the whole release.
v3.8.0 standalone plugin tools
The standalone mnemosyne-hermes
plugin got a new upgrade command
with smart install-method detection (pipx, uv-tool, pip). Version
comparison. Auto re-register after upgrade. PR
#319.
Plus a cleanup command with
dry-run support (PR
#317)
and a status that reports
Hermes Python version with mismatch warnings (PR
#316).
v3.8.0: vec_working and reindex
Working-memory vectors moved to a dedicated sqlite-vec table,
vec_working, with
memory_embeddings as a
compatibility fallback. New mnemosyne reindex
command (issue
#308,
PR by @Milgauss) rebuilds all vectors after an embedding model or
dimension change. Auto-backup first, with
--dry-run,
--model,
--no-backup, and
--yes flags. Synchronous and
blocking, with a duration warning.
Honest Footnote on the CHANGELOG
Full transparency: the CHANGELOG.md on
main is not perfectly aligned
with the git tag history. v3.5.0 and v3.8.0 do not have their own
CHANGELOG sections. The major sync engine / reindex / vec_working work
that shipped in v3.8.0 is currently documented under the v3.9.0
heading. The actual shipped code is in the tags. If you want the
source-of-truth diff for v3.8.0 specifically,
git log v3.7.0..v3.8.0 --no-merges
has it. PR to clean up the CHANGELOG accepted with thanks.
Contributors This Run
Shipped between May 26 and June 18 with help from:
- Denis H (12 commits): vec_working dedicated table, get_context hot path split, vec_working migration diagnostics, HERMES_HOME resolution, embedding-dim mismatch guard
- Milgauss (11 commits):
mnemosyne reindexcommand, fact_recall relevance scoring, recovery DB path resolution, sqlite-vec embedding-dim guard - Whishp (6 commits): hardcoded 384-dim bug fixes across binary_vectors.py, shmr.py, polyphonic_recall.py, plus Russian FTS5 fallback and multilingual named_months regex capture groups
- phin (5 commits): Hermes structured memory tool routing, canonical fact tools wired in active adapter, optional local LLM fallback log fix
- achrllrogia45 / Hilman Nur Firdaus (4 commits): unified recall merging shared surface results, collaborative memory validation with attestation chain, memory audit log for mutation traceability, tags and scope unification RFC
- Ciro Barbato (3 commits): LLM completions client retry with backoff using real token usage stats, Phase 2 LLM-based episodic conflict resolution, repository metadata
- nzperryus-cyber (2 commits): PF classification branch in
_classify_ability(#241), English preference regex widening for 2P/3P/structural (#242) - mia-fourier (2 commits): MNEMOSYNE_EMBEDDING_API_URL independent of OPENROUTER_BASE_URL (PR #206)
- flooryyyy (2 commits): UTF-8 sanitization in episodic_memory to prevent OperationalError crashes, MNEMOSYNE_EMBEDDING_API_URL/KEY as preferred env var names
- WXBR (2 commits): relevance-before-importance test that locks the v3.6.0 invariant, Hermes prompt routing fix
- val-spc: explicit opt-in for non-OpenAI OpenRouter embedding models
- scubamount: LLM model fallback chain for remote summarization
- qiniancs: manually normalize embeddings before int8 quantization
- bunnyfu: full import path for Mnemosyne class in profile isolation (#331)
- chinesewebman: sqlite-vec virtual table transaction commit fix
- bitr8:
sync_rolesconfig for role-based autosave filtering (closes #209) - Joao Fernandes: installation script link fix in hermes-mcp.md (PR #201)
You shipped real code into production for other people to use. That is the whole game. Thank you.
Where That Leaves Us
Mnemosyne now has 32 tools, canonical facts for stable self-knowledge, a working memory TTL that respects actual usage, a bidirectional sync engine with optional client-side encryption, and a persona layer that survives past the working window. That is a lot of memory system for one sprint.
The persona layer deserves its own writeup because it changes how the
agent shows up over time. That is next. Install it with
pipx install mnemosyne-memory
and turn on the persona tier with
MNEMOSYNE_PERSONA_ENABLED=true.
Or read the
deep-dive
first and decide if it is for you.
Same Discord, same repo, same direction. Just more blog posts going forward. Promise.

