Mnemosyne
Purpose
Primary agent memory store for Hermes.
Current Configuration
- Provider:
mnemosyne - Enabled: true
- Auto sleep: true
- Default scope:
session - Memory char limit: 5000
- User char limit: 3000
- Vector type: int8
- Profile isolation: true
- Shared surface read: true
- Shared surface path:
data/shared/mnemosyne.db - Skip contexts: cron, flush, subagent, background, skill_loop
- Reflect max calls per session: 3
- Sync roles: user
- Flush every: 6 turns
- Embedding model:
BAAI/bge-small-en-v1.5(384 dims) - Embeddings via API: false (local fastembed)
Database Stats (2026-08-02)
| Table | Rows | Notes |
|---|---|---|
working_memory | 1,476 | Active memories |
episodic_memory | 458 | Consolidated summaries |
memory_embeddings | 158 | Only working memories — 0 episodic |
memory (legacy) | 2,181 | Old table, not migrated |
vec_working | 159 | Vector index rows |
| Shared surface | 0 | Empty — cross-agent sharing not functional |
Known Issues
Vector embedding coverage gap
- Only 159/1,476 working memories (10.8%) have vector embeddings
- 0/458 episodic memories have embeddings
- Semantic search (
mnemosyne_recall) falls back to FTS5 keyword matching for ~90% of working and 100% of episodic memories - This means recall quality is degraded — vector similarity can only search a tiny fraction of the memory store
- Root cause: The embedding pipeline (fastembed) never processed the bulk of memories. The
vec_workingtable was rebuilt once (Jul 18) but only captured 159 rows. - Fix needed: Backfill embeddings for all working and episodic memories. This requires running the embedding pipeline across the full dataset.
Profile isolation chosen over shared surface
|- The ops profile was enabled with mnemosyne on 2026-08-02
|- Decision: profile_isolation: true was set on ops, giving each profile its own independent memory bank — zero cross-contamination
|- data/shared/mnemosyne.db exists with 0 rows; cross-profile sharing is intentionally unused
|- This means Tusk (ops) and Rhino (default) do not share memories, which is the desired behaviour
|- Config in ~/.hermes/profiles/ops/config.yaml: memory.mnemosyne.profile_isolation: true, allow_tool_override: false, shared_surface_read: false
|- Verified end-to-end on 2026-08-02: memory writes land correctly in both profiles independently
Legacy table not migrated
- 2,181 rows in the old
memorytable are not in the newworking_memory/episodic_memorysystem - These are only accessible via the legacy
memorytool, not viamnemosyne_recall
Known Management Jobs
- Mnemosyne Auto-Consolidate every 30m — script:
consolidate_mnemosyne.sh, mode: no-agent - Mnemosyne DB Backup weekly Sunday 03:00 — script:
mnemosyne-backup.sh, mode: no-agent - Mnemosyne Health Monitor every 12h — skill:
mnemosyne-operations, reports only on exception - Mnemosyne Watchdog every 15m — script:
mnemosyne-watchdog.py, mode: no-agent
History and Evidence
- 2026-08-01 incident: Automatic conversational capture was broken by stringified structured YAML, especially
sync_roles: "['user']". Fixed by rewriting with native YAML types. See 2026-08-01-mnemosyne-capture-failure. - 2026-08-01 cleanup: Legacy always-injected memory reduced from 8,013 bytes to 4,998 bytes (memory) and 2,958 bytes (user).
- 2026-07-29 incident:
memory.mnemosyne.tools: Nonecaused schema loading warnings. Fixed by removing the line. See 2026-07-29-mnemosyne-relay. - 2026-07-29 relay scope corruption:
RuntimeError: scope handle is not at the top of the stack— 3 occurrences, self-resolved.