--- name: hermes-memory-config description: "Configure, inspect, and tune Hermes holographic memory across profiles. Covers the two-layer config structure, auto-creation behavior, undocumented tuning knobs, and bulk profile operations." version: 1.0.0 --- # Hermes Memory Configuration Covers the holographic memory provider: configuration layers, auto-creation behavior, tuning knobs, and bulk operations across profiles. ## Two-Layer Configuration Holographic memory has TWO config layers, not one. ### Layer 1: `memory:` block (in every profile's config.yaml) These are the built-in memory settings, identical across all profiles by default: - `provider: holographic` - `memory_enabled: true` - `user_profile_enabled: true` - `write_approval: false` - `memory_char_limit: 2200` - `user_char_limit: 1375` - `flush_min_turns: 6` - `nudge_interval: 10` Set via `hermes config set memory. ` or by editing config.yaml directly. ### Layer 2: `plugins.hermes-memory-store:` block (OPTIONAL — absent by default) These are holographic-specific plugin settings. When the block is absent, all values fall back to defaults baked into the plugin code at `plugins/memory/holographic/__init__.py`: | Key | Default | Documented | Description | |-----|---------|------------|-------------| | `db_path` | `$HERMES_HOME/memory_store.db` | yes | SQLite database path | | `auto_extract` | `false` | yes | Auto-extract facts at session end | | `default_trust` | `0.5` | yes | Default trust score for new facts | | `hrr_dim` | `1024` | yes | HRR vector dimensions | | `hrr_weight` | `0.3` | **no** | HRR weight in retrieval scoring | | `temporal_decay_half_life` | `0` (disabled) | **no** | Half-life in seconds for temporal decay | | `min_trust_threshold` | `0.3` | **no** | Minimum trust filter for search results | The last three keys are read from config in `initialize()` but are NOT listed in `get_config_schema()`. They are hidden knobs — they work, but you won't find them in `hermes memory setup` or the README. To set any of these, add a `plugins:` block to the profile's config.yaml: ```yaml plugins: hermes-memory-store: auto_extract: true default_trust: 0.7 hrr_dim: 2048 hrr_weight: 0.5 temporal_decay_half_life: 86400 min_trust_threshold: 0.5 ``` ## DB Auto-Creation The holographic SQLite database (`memory_store.db`) is created lazily on first use. No manual setup step is needed: 1. `HolographicStore.__init__()` resolves `db_path` (defaults to `$HERMES_HOME/memory_store.db`) 2. Creates parent directories if missing 3. Opens the SQLite file (creates it on first open) 4. Runs `CREATE TABLE IF NOT EXISTS` for all holographic tables: `facts`, `entities`, `fact_entities`, `memory_banks`, plus FTS5 virtual table and triggers The DB materializes on the first memory operation (fact store add/search, or the `on_session_end` hook when `auto_extract` is on). Profiles with `memory.provider: holographic` set but no `memory_store.db` file are fine — the DB appears on first touch. ## Inspecting Across Profiles To check which profiles have the DB and whether the schema is correct, use Python (the `sqlite3` CLI may not be installed): ```python import sqlite3, os base = os.path.expanduser("~/.hermes/profiles") for name in sorted(os.listdir(base)): dbp = os.path.join(base, name, "memory_store.db") if not os.path.exists(dbp): print(f"{name}: no DB file") continue c = sqlite3.connect(dbp); cur = c.cursor() cur.execute("SELECT name FROM sqlite_master WHERE type='table'") tabs = [r[0] for r in cur.fetchall()] c.close() holo = any(t in tabs for t in ("facts","entities","fact_entities","memory_banks")) print(f"{name}: holographic={holo} tables={tabs}") ``` To check which profiles have the provider set and what tuning keys are present: ```bash # Provider setting for p in ~/.hermes/profiles/*/config.yaml; do name=$(basename $(dirname "$p")) prov=$(grep -A8 "^memory:" "$p" | grep "provider" | head -1) echo "$name: $prov" done # Tuning keys (plugins.hermes-memory-store) for p in ~/.hermes/profiles/*/config.yaml; do name=$(basename $(dirname "$p")) keys=$(grep -A10 "hermes-memory-store" "$p" 2>/dev/null | grep -E "auto_extract|default_trust|hrr_dim|hrr_weight|temporal_decay|min_trust") [ -n "$keys" ] && echo "=== $name === $keys" done ``` ## Memory vs Fact Store Boundary (MANDATORY) **MEMORY.md is for behavioral directives and environment conventions only.** All factual claims about people, projects, and entities go to `fact_store`. | Store | What goes there | Examples | |-------|----------------|----------| | `memory` (MEMORY.md) | Behavioral directives, environment conventions, tool quirks, workflow rules | "User prefers concise responses", "Project uses pytest with xdist", "Memory is for directives only" | | `fact_store` | Factual claims about people, projects, entities, relationships | "Daughter's name is Zoe", "openz profile has its own TELEGRAM_BOT_TOKEN", "Qdrant runs on 10.0.0.22:6333" | When migrating facts from memory to fact_store: remove the memory entry and add the fact via `fact_store(action='add', ...)`. Do both in the same operation batch when possible. ## Bulk Profile MEMORY.md Operations To add a line to all profiles' MEMORY.md files: 1. `search_files` to find all `MEMORY.md` files under `~/.hermes/profiles/` 2. For each profile, read the file, then write or patch with `cross_profile=True` 3. The `memory` tool only writes to the current profile — use `write_file` or `patch` with `cross_profile=True` for other profiles ## MEMORY.md Pollution Defense The first line of every MEMORY.md says "Get explicit permission before modifying MEMORY.md or USER.md" — but this is only a prompt-level request. Weaker models ignore it and write behavioral directives directly into MEMORY.md. **Defense: enable the write-approval gate.** Set `memory.write_approval: true` in config.yaml. All memory writes are then staged to `/pending/memory/.json` for user review instead of auto-committed. Review with `/memory pending`. See `references/write-approval-gate.md` for full mechanism details. To apply across all profiles, set in the base config (`~/.hermes/config.yaml`) so it propagates to profiles that don't override it. ## SOUL.md for Subagents By default, subagents spawned via `delegate_task` get the hardcoded `DEFAULT_AGENT_IDENTITY`, not your SOUL.md. The official docs confirm: "This fallback also applies when `skip_context_files` is set (e.g., in subagent/delegation contexts)." **Fix:** add `load_soul_identity=True` to the subagent `AIAgent(...)` call in `tools/delegate_tool.py`. The cron scheduler already uses this pattern. See `references/soul-subagent-fix.md` for the exact patch. ## Standard MEMORY.md Directives Every profile's MEMORY.md should carry these three directives: 1. `MEMORY.md is for behavioral directives and environment conventions only. All factual claims about people, projects, and entities go to fact_store. Get explicit permission before modifying MEMORY.md or USER.md.` 2. `Stay in \`~/workspace/\`. No cross-profile access without explicit direction.` 3. `Default to discuss. Act only on explicit direction. File modifications require "do it", "apply", or "go" from the user. Discussing is never permission to act.` Exception: the telegram profile uses `/workspace/telegram` instead of `~/workspace/telegram`. ## Pitfalls - **Config is per-profile, not global — but base config inheritance works.** Setting `plugins.hermes-memory-store` in one profile's config.yaml does NOT affect other profiles. However, setting it in the base `~/.hermes/config.yaml` DOES propagate to all profiles that don't override it. The base config is the parent; per-profile configs inherit from it. To set a global default, write to `~/.hermes/config.yaml`; to override for a specific profile, write to that profile's config.yaml. - **Undocumented keys are silently ignored if misspelled.** `hrr_weight` works; `hrr_weigth` does nothing and raises no error. - **`hermes memory setup holographic` only sets `memory.provider`.** It does NOT create the `plugins.hermes-memory-store` block. You must add that manually or via `hermes config set`. - **The DB file is SQLite.** Inspect it with Python's `sqlite3` module. The `sqlite3` CLI may not be installed on the host. - **Do not act without explicit direction.** The user prefers discuss-first workflow. When workshopping wording or plans, do NOT jump to execution — wait for a clear go-ahead like "do it" or "apply to all." The "Default to discuss" directive in MEMORY.md reinforces this, but the agent must also follow it in practice. - **Holographic-specific settings live under `plugins.hermes-memory-store:`, NOT under `memory:`.** The `memory:` block only holds provider-agnostic built-in settings (provider, memory_enabled, write_approval, char limits, flush/nudge intervals). Holographic-specific knobs — `auto_extract` (the "auto-save" equivalent), `default_trust`, `hrr_dim`, `hrr_weight`, `temporal_decay_half_life`, `min_trust_threshold` — all live under `plugins.hermes-memory-store:`. When the user asks about "auto-save" or any holographic tuning, check BOTH layers. Searching only `memory:` and concluding a flag doesn't exist is wrong — it's in the plugin layer. ## Support Files - `references/holographic-plugin-internals.md` — Code-level findings from plugin source inspection: config loading, initialization flow, undocumented keys, and schema details.