Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/Ufonik88/EntropicMem itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 22, 2026EntropicMem: Standalone Agent Memory System
A self-contained knowledge engine for Hermes Agent. SQLite memory, Markdown vault, visual graph, and a 36-command knowledge loop. Install from the Hermes plugin catalog or via
/learn.
Public repo. Never commit personal data: real names beyond the maintainer handle, home paths, emails, IPs, employer or client details, or memory/graph exports. See CONTRIBUTING.md for the rule and the pre-commit checklist.
What It Is
A Hermes Agent memory provider and skill delivering a complete, standalone knowledge system:
| Component | What it does |
|---|---|
| Memory engine | Durable facts with FTS5 search, dedup, versioning, audit log, quarantine |
| Episodic memory | Session summaries with time-windowed recall |
| Knowledge triples | Subject, predicate, object graph with neighbors, paths, inconsistency checks |
| Embeddings | Optional all-MiniLM-L6-v2 vectors with hybrid FTS and vector recall. Opt-in (embeddings_enabled: true), because first use downloads the model. The v3 line adds a fail-soft query-embedding seam behind embeddings.enabled (EM-412) |
| Vault | Human-browsable, linked, domain-organized Markdown notes |
| Index | Vault FTS5 plus graph edges powering cited retrieval |
| Visual graph | Self-contained D3 galaxy HTML export with lazy wikilink resolution |
| MemoryProvider plugin | 9 entropicmem_* tools and 6 lifecycle hooks wired into Hermes |
The v3 Line (In Development)
The storage and retrieval core is being rebuilt under plugins/entropicmem/scripts/em/ (schema v3, typed config). It lands behind flags and v3 stores; the v2 path above is unchanged until the owner-gated cutover. What has landed so far:
| Card | What it is |
|---|---|
| EM-407 | Typed config (em/config.py): one defaults source for the provider, the CLI and the dashboard schema |
| EM-212 | Plugin namespace isolation: the six shared-name engine modules moved under em_internal/ |
| EM-303 | Embedding backends, async embedding jobs and the vector cache: fastembed / sentence-transformers / openai_compat, model identity in meta.embedding_model, stale-model skips surfaced in search diagnostics |
| EM-410 | Cron & worker: the provider runs a background JobWorker — gated on jobs.run_in_primary / jobs.run_in_cron, bounded by jobs.cron_budget_s, held off while a turn's prefetch is in flight |
| EM-412 | Query embedding wired into the v3 read paths behind embeddings.enabled: one fail-soft seam (em/embeddings/query.py) serves the tool search path, PrefetchService and the facade's flag-on recall |
How the query-embedding seam works (EM-412). The provider builds one QueryEmbedder per session — only when embeddings.enabled is on and the store is v3 — and hands it to the three read sites. Every call runs the backend on a short-lived daemon thread the seam joins for at most timeout_s, default 20 s (matching openai_compat's per-call socket timeout, so the local backends gain the hard bound they shipped without). A raise, a timeout or an unavailable service returns None and the caller serves the lexical result — hard fail-soft, so an embed can neither break nor stall a search. A call arriving while a previous embed is still running past its bound fast-fails instead of queueing behind it, so a hung backend costs one bound, not one per search. Calls are counted per session and summarized at shutdown, so a potentially paid backend's usage stays visible. With the flag off — or on a v2 store — no backend is selected and the served paths are byte-identical.
Status and what's next: MASTER_TODO.md and docs/plan/REMAINING_PLAN.md.
Screenshots
| Graph galaxy view: the D3 visual graph colored by domain or community. | |
| Note modal: full note body with wikilink navigation and tag chips. | |
CLI recall: fact search with explainable why_retrieved reason tokens. | |
| Timeline: chronological fact and episode view with date filters. | |
| Prefetch context: relevance-filtered facts injected into a turn. |
Install
Option A: Hermes plugin catalog (recommended)
hermes plugins install entropicmem
Then wire the provider in ~/.hermes/config.yaml and bootstrap a vault:
memory:
provider: entropicmem
python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py init
Full detail: docs/SELF_INSTALL.md.
Option B: /learn skill flow
/learn https://github.com/Ufonik88/EntropicMem
The agent fetches the repo, installs the skill and plugin, bootstraps the vault, and smoke-tests in one pass. Follow skills/entropicmem/SETUP.md for the bootstrap checklist.
Quickstart
All commands run through the engine CLI under the plugin directory, python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py:
python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py init # Bootstrap vault + memory engine
python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py ingest "https://..." # One chunked note under Sources/ (+ pending claims)
python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py query "topic" --top-k 10 # Cited vault search
python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py recall "durable fact" # Memory engine search
python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py remember "durable fact" # Store in memory engine
python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py graph export --format html # Galaxy graph (./export/graph.html)
Repository Layout
EntropicMem/
├── plugins/entropicmem/ # Hermes MemoryProvider (9 tools, 6 hooks) + engine
│ ├── __init__.py # Thin host shell (register + MemoryProvider import)
│ ├── config_schema.py # Dashboard config schema (flat_json; EM-407)
│ ├── _backend.py # Path resolution helpers
│ ├── plugin.yaml # Catalog manifest
│ ├── scripts/ # Engine + CLI (stdlib-only core)
│ │ ├── memory_engine.py # SQLite FTS5 memory engine
│ │ ├── vault.py # Markdown vault operations
│ │ ├── index.py # Vault FTS5 index + graph edges
│ │ ├── retrieval.py # Composed retrieval stack
│ │ ├── em/graph/ # Graph model, renderers + viewer assets (EM-605)
│ │ ├── graph_static.py # Hardened stdlib server for `graph serve`
│ │ ├── policy.py / pii.py # Write policy + PII redaction
│ │ ├── embeddings.py # Vector search (optional)
│ │ ├── em/ # v3 storage + retrieval core + typed config (in development)
│ │ ├── em_internal/ # The six shared-name engine modules (EM-212)
│ │ └── entropicmem.py # CLI
│ └── README.md # Plugin quick reference
├── skills/entropicmem/ # /learn skill: instructions + references + templates
│ ├── SKILL.md # Agent instructions (loaded by /learn)
│ ├── SETUP.md # First-run bootstrap checklist
│ ├── references/ # Agent-facing docs (memory model, integration)
│ └── templates/vault/ # Seed vault skeleton used by `init`
├── scripts/graph_server/ # FastAPI graph server (Host allowlist, CSP, token)
├── evals/ # Eval framework: ci + hard suites, baselines, perf bench
├── benchmarks/ # Frozen recall benchmark (corpus, probes, runner)
├── docs/ # User-facing docs (see index below)
├── tests/ # 2,000+ tests
└── .github/workflows/test.yml # CI: pytest (3.10 to 3.13) + ruff + plugin validate
The engine lives under plugins/entropicmem/scripts/ so the plugin directory is self-contained: a catalog install (hermes plugins install entropicmem) carries the full engine with it. The skill directory holds only instructions, references, and vault templates.
Configuration
All settings live under plugins.entropicmem in ~/.hermes/config.yaml. Every key is optional; the schema is declared in plugins/entropicmem/config_schema.py and its defaults come from the typed model in plugins/entropicmem/scripts/em/config.py (EM-407). Dashboard-written settings arrive as $HERMES_HOME/entropicmem/config.json (flat JSON; one step in the read order).
plugins:
entropicmem:
vault_path: ~/.hermes/entropicmem/vault
memory_db: ~/.hermes/entropicmem/memory.db
prefetch_token_budget: 1500
| Key | Default | What it does |
|---|---|---|
vault_path | ~/.hermes/entropicmem/vault | Vault directory for Markdown notes |
index_db | ~/.hermes/entropicmem/index.db | Vault index SQLite path (FTS + graph edges) |
memory_db | ~/.hermes/entropicmem/memory.db | Memory engine SQLite path (facts, episodes, triples) |
min_relevance_score | 0.35 | Minimum combined relevance for prefetch injection (0.0 to 1.0) |
max_prefetch_results | 5 | Maximum facts injected per turn |
prefetch_token_budget | 1500 | Maximum characters of prefetch context per turn |
dedup_window | 5 | Do not repeat a fact within N turns |
enabled_domains | [] | Domains to draw prefetch from (empty means all) |
high_relevance_threshold | 0.7 | High tier for progressive disclosure |
medium_relevance_threshold | 0.4 | Medium tier for progressive disclosure |
context_window_turns | 3 | Recent turns used to build the context-aware query |
context_query_mode | current | Enhanced query: current (query only) or concat (prior user turns) |
progressive_disclosure | false | Tiered relevance caps in prefetch (max 2/3/5) |
max_context_query_length | 1000 | Maximum length of the context-enhanced query |
cache_conversation_context | true | Cache prefetch results with conversation awareness |
cache_ttl_seconds | 300 | Prefetch cache TTL |
auto_extract_enabled | false | Background regex fact extraction per turn (off by default) |
session_end_capture | true | Flush a session digest episode when a session ends |
turn_cadence_flush_turns | 40 | Flush a partial digest every N turns (0 disables) |
turn_cadence_min_interval_sec | 1800 | Minimum seconds between cadence digest flushes |
session_extract_pending | true | Run quarantine-first extraction at session end |
core_memory_enabled | true | Inject Core Memory (Persona / User Profile); where is set by core_inject_mode |
core_inject_mode | system_prompt | system_prompt: Core Memory goes into the system prompt once and prefetch carries only a change delta; prefetch: legacy full block every turn |
core_memory_writable | false | Allow entropicmem_profile to modify Core Memory (legacy alias entropicmem_patch_core) |
prefetch_denied_sources | ["auto_extracted", "test"] | Fact source tags excluded from prefetch (add your own internal tags in config) |
locale_packs | [] | Opt-in region-specific PII patterns (e.g. ["za"]); empty scans the generic patterns only |
owner_user_ids | [] | Gateway user_ids that own this profile; any other user runs in guest mode (no sensitive/secret facts, no guest_hidden_domains). Empty = shared pool with a one-time warning. Interim guard, not full per-user isolation |
guest_hidden_domains | ["People", "Finance"] | Domains never prefetched for guest users |
allow_agent_consolidate | false | Previously let the entropicmem_consolidate tool archive for real; the tool path previews only now (entropicmem_review → consolidate_preview), so the real consolidate stays CLI-only (entropicmem consolidate --confirm) |
mirror.background_review | false | Also mirror built-in memory writes whose origin is background_review |
extraction_timeout | 5.0 | Maximum seconds for background extraction per turn |
decay_enabled | true | Temporal decay scoring in recall |
decay_half_life_days | 90 | Half-life for memory decay |
decay_floor | 0.5 | Minimum decay factor; non-durable facts are never erased |
evergreen_domains | ["People"] | Domains whose facts never decay |
touch_on_inject | true | Bump last_accessed for injected facts (background write) |
reinforcement_boost | 0.1 | Score boost per fact access (capped) |
reinforce_on_recall | false | Bump access count on recall hits |
embeddings.enabled | false | v3 line: opt the query-embedding seam into the read paths (EM-412); off = byte-identical v2 behavior |
embeddings.backend | auto | v3 line: auto (first available), fastembed, sentence_transformers, openai_compat, none |
embeddings.model | BAAI/bge-small-en-v1.5 | v3 line: the embedding model; switching it queues an embed_backfill job |
jobs.run_in_primary | true | v3 line: run the background JobWorker in the primary process (EM-410) |
jobs.run_in_cron | true | v3 line: run the JobWorker from the cron worker |
jobs.cron_budget_s | 120 | v3 line: wall-clock budget for one cron job run (5–3600) |
Smart context details (how relevance scoring, dedup, and progressive disclosure work): skills/entropicmem/references/HERMES_INTEGRATION.md.
Memory Model
Five cooperating layers, full model in docs/MEMORY_MODEL.md:
| Layer | Where | Purpose |
|---|---|---|
| Hot cache | Wiki-Cache.md | Instant orientation each session |
| Facts | ~/.hermes/entropicmem/memory.db | Durable facts, episodes, triples, embeddings |
| Vault | Markdown files | Human-browsable, linked, domain-organized |
| Index | ~/.hermes/entropicmem/index.db | Vault FTS5 + graph edges for retrieval |
| Graph | export/graph.html | D3 galaxy visualizer |
Explainable recall: every recall(), recall_with_relevance(), and recall_hybrid() hit carries a why_retrieved field, a deterministic list of reason tokens (exact, fts, vector, recency, importance, triple, domain; the LIKE fallback path also reports fts) so you can audit why a fact surfaced. The entropicmem_search tool exposes it in its JSON output (why; the legacy why_retrieved key and the entropicmem_recall alias name are kept for one minor version).
Recall benchmark: run PYTHONPATH="plugins/entropicmem/scripts" python3 benchmarks/run_recall_bench.py to measure precision@5 and MRR against a frozen 98-fact corpus with 20 probes. CI enforces a floor (precision@5 >= 0.50, MRR >= 0.50).
Commands
37 top-level commands in 10 groups. Full reference: docs/CLI_REFERENCE.md. Invocations use python3 ~/.hermes/plugins/entropicmem/scripts/entropicmem.py <command>.
| Group | Commands |
|---|---|
| Vault & knowledge | init, ingest, ingest-pile, query, note, research, lint, moc, hotcache, open, vault lint |
| Memory engine | remember, recall, forget --confirm, memory stats/list/project/reindex (stats shortcut), extract, reinforce, history, consolidate --confirm |
| Episodic & triples | episode add/list/stats, triple extract/list/stats/neighbors/path/inconsistencies |
| Index & graph | index rebuild/refresh/status, graph export/serve/show |
| Vectors & time | embed --rebuild, timeline |
| Security | security enable/disable/status, patch-core |
| Portability | export, import |
| Provenance & sync | migrate, shared-init, publish, pull |
| Governance | audit, pending list/promote/discard |
| Jobs | worker run |
Hermes Integration
# ~/.hermes/config.yaml
memory:
provider: entropicmem
- Interactive tools (nine):
entropicmem_remember,entropicmem_search,entropicmem_update,entropicmem_forget,entropicmem_timeline,entropicmem_entity,entropicmem_profile,entropicmem_review,entropicmem_stats, plus the built-inmemorytool. The legacy names (entropicmem_recall,entropicmem_query,entropicmem_patch_core,entropicmem_get,entropicmem_consolidate) route through an alias map for one minor version and reportdeprecated_toolin their responses. - Prefetch injection: relevant facts are prefetched into
<memory-context>each turn. These are system-injected context, not user input. - Lifecycle hooks (6):
on_memory_writemirrors built-inmemorytool writes into the engine;on_session_switchtracks session state and resets caches — a rewound switch (host/undo) queues aretract_turnsjob that soft-deletes the undone turn's turn-stamped memories (restorable throughentropicmem_review);on_session_endwrites an extractive session digest episode (idempotent per session) and runs quarantine-first extraction;on_turn_startflushes a partial digest every N turns for always-on sessions;on_pre_compresscheckpoints a standing-constraints digest before context compression (fail-closed checkpoint API v2);on_delegationrecords a redacted delegation episode and, on v3 stores, queues extraction over it with a 0.6 confidence cap. Config underplugins.entropicmem(session_end_capture,turn_cadence_flush_turns,turn_cadence_min_interval_sec,session_extract_pending), see docs/ARCHITECTURE.md. - Cron: Hermes cron runs execute with memory writes disabled; persist durable facts through the CLI or the MemoryEngine API (deterministic, no LLM), never through interactive memory tools.
- Full integration guide: skills/entropicmem/references/HERMES_INTEGRATION.md.
Security
- Write policy: secret and credential content is blocked. High-confidence
api_key/passwordfindings are auto-redacted; other PII types are recorded as warn-only findings. Auto-extracted facts are quarantined as pending until promoted. - Prompt-injection screen: vault retrieval and prefetch,
recall, andgettool payloads pass a local injection screen. Flagged content ships with a prominent warning marker rather than being dropped (flag-with-warning, fail-open by design: if the screen itself fails, text ships unmarked). - Vault path containment: vault writes are confined to the resolved vault root.
- Graph viewer: note markdown is sanitized against stored XSS (rendered HTML from
markedand lazy-fetched bodies pass a client-side sanitize pass). - Graph server: loopback-only bind enforced at startup; a non-loopback bind is refused unless
ENTROPICMEM_GRAPH_EXPOSE=1explicitly opts in, and read endpoints then require theX-EntropicMem-Tokenheader./refreshalways requires the token. The token isENTROPICMEM_GRAPH_TOKENor, when unset, a random per-run token written owner-only to~/.hermes/entropicmem/graph_server.token. A Host-header allowlist (DNS-rebinding guard) and a strict Content-Security-Policy apply to every response.entropicmem graph serve(stdlib, no token) enforces the same bind rule, Host allowlist and CSP, and serves onlygraph.html/graph.json. See docs/VISUALIZER.md. - Destructive gates:
forgetandconsolidaterequire--confirm; both auto-backup before running. - Audit log: every write is append-only audited.
- Backups: AES-256-CBC encrypted before cloud upload. See docs/BACKUP_RESTORE.md.
Network Access
EntropicMem's memory engine, vault and Hermes integration run locally and make no network calls. These are the exceptions, and each is either opt-in or triggered by you:
| What | When | Where it connects |
|---|---|---|
| Vector embeddings | only with embeddings_enabled: true (provider) or ENTROPICMEM_EMBEDDINGS=1 (CLI), or the CLI's query --semantic | first use downloads all-MiniLM-L6-v2 from Hugging Face |
| v3 query embedding | with embeddings.enabled on a v3 store (EM-412) | first use downloads the configured model (default BAAI/bge-small-en-v1.5) from Hugging Face |
ingest <url> | when you ingest a URL | that URL, and redirects only to validated public hosts (never loopback, private or metadata addresses) |
Graph HTML (graph export) | when you open the exported file | the browser loads D3 (d3js.org), marked (cdn.jsdelivr.net) and fonts (fonts.googleapis.com, fonts.gstatic.com) |
graph serve / graph server | when you start it | none outbound; serves on loopback only by default |
| Encrypted backup upload | when you run the backup job | your configured rclone remote |
Also: the shared publish store lives at $HERMES_HOME/entropicmem-shared/ (the root home in profile mode), and graph export writes to ./export in the current directory unless you pass --output-dir.
Known Limitations (2.8.x)
- Synonym / paraphrase recall. Retrieval is lexical (FTS5) unless the optional semantic stack is installed and enabled (
embeddings_enabled: true). A query that shares no words with the stored fact ("what city am I based in?" against "The user lives in Cape Town") returns nothing. The hard eval suite's ageing category scores 0.733 recall@5 for exactly this reason; semantic retrieval is Sprint 3 (EM-303). - Per-user isolation.
owner_user_idsis an interim owner/guest guard. Fully scoped per-user storage (Alice cannot recall Bob's facts) is Sprint 4. - Prefetch is synchronous.
queue_prefetchis a no-op; prefetch runs inline on the caller (async prefetch is Sprint 4). - Episodes are stored but not recalled. Session digests land in the timeline, but
recall()does not surface them yet (Sprint 3). - Validator warnings.
hermes plugins validateprints two "declared but not registered" warnings forprovides_tools/provides_hooks. They are kept on purpose: the Hermes catalog review verifies the plugin against those lists, and the warnings come from the validator not seeing tools a MemoryProvider exposes throughget_tool_schemas().
These are pinned by strict xfail tests in tests/regressions/test_findings_v27.py, which will start failing (xpass) once each is fixed. On the v3 line, semantic retrieval (EM-303), episodes in recall and async prefetch (EM-403) have landed; per-user isolation remains open.
Documentation
| Doc | Content |
|---|---|
| SETUP.md | First-run bootstrap checklist |
| docs/SELF_INSTALL.md | Catalog and /learn install, verification, uninstall |
| docs/MEMORY_MODEL.md | The five-layer memory model + write policy |
| docs/ARCHITECTURE.md | Component architecture, storage layout, data flow, and the v3 em/ storage core |
| docs/V3_FOUNDATIONS.md | The v3 storage core: layers, the ten invariants, recipes, repo guards, recorded deviations |
| docs/CLI_REFERENCE.md | All commands and subcommands |
| docs/VISUALIZER.md | Graph UI: zoom, overlays, wikilink resolution, security model |
| docs/BACKUP_RESTORE.md | Encrypted backup + restore drill |
| MASTER_TODO.md | Start here (agents and humans): where the project is, what is in flight, what is next, the gates, and the document-control rule |
| docs/MARKETPLACE.md | The Hermes Marketplace entry: the pin-is-the-release rule, the owner-gated release procedure, catalog PR mechanics, and the pitfalls |
| docs/plan/REMAINING_PLAN.md | Project status (§2 state, §11 how to pick it up), what is left of the v3 plan, and the rules for doing it in small chunks |
| docs/plan/NEXT_CHUNK.md | The single next development chunk, planned one ahead (Part A is the chunk that just landed) |
| docs/BACKFILL_PROCEDURE.md | Opt-in shared-store backfill for multi-profile sync |
| skills/entropicmem/references/HERMES_INTEGRATION.md | MemoryProvider wiring + smart context |
| CONTRIBUTING.md | Public-repo rules + commit checklist |
| CHANGELOG.md | Release history |
| benchmarks/run_recall_bench.py | Recall benchmark runner (precision@5 / MRR) |
Requirements
- Python 3.10+ (stdlib only for the core path)
- Optional:
sentence-transformersfor semantic search,graphvizfor DOT export,fastapi+uvicornfor the graph server
License
MIT