feat: add home-assistant-dashboard-conventions skill + update multiple skills
- New: smart-home/home-assistant-dashboard-conventions (Mushroom cards, view tabs, no Bubble Cards) - Updated: rke2, ceph, galera, proxmox, brainstorming, compound-learning, 1password-cli, smart-home-automation skills - New references: ceph-cluster-administration, docker-volume-forensics, ceph-crush-weight, ceph-ec-mixed-size
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
# Hermes Memory System Architecture (2026-07-14)
|
||||
|
||||
## Overview
|
||||
|
||||
Hermes has two persistent memory stores injected into the system prompt:
|
||||
|
||||
- **MEMORY.md** — agent's personal notes (environment facts, infrastructure
|
||||
topology, tool quirks). Default limit: 2,200 chars.
|
||||
- **USER.md** — what the agent knows about the user (preferences, style,
|
||||
communication rules). Default limit: 1,375 chars.
|
||||
|
||||
Both files live at `~/.hermes/memories/` and use `§` (section sign) as
|
||||
entry delimiter: `\n§\n` between entries.
|
||||
|
||||
## Config
|
||||
|
||||
```yaml
|
||||
# ~/.hermes/config.yaml
|
||||
memory:
|
||||
memory_enabled: true
|
||||
user_profile_enabled: true
|
||||
memory_char_limit: 2200
|
||||
user_char_limit: 1375
|
||||
nudge_interval: 10
|
||||
```
|
||||
|
||||
Adjust limits:
|
||||
```bash
|
||||
hermes config set memory.user_char_limit 3000
|
||||
hermes config set memory.memory_char_limit 4000
|
||||
# Takes effect on next /reset or gateway restart
|
||||
```
|
||||
|
||||
## System Prompt Injection Pipeline
|
||||
|
||||
### 1. Loading (once per session)
|
||||
|
||||
`agent_init.py` creates a `MemoryStore` instance and calls
|
||||
`load_from_disk()`. This reads both `.md` files, splits on `§`, deduplicates
|
||||
entries, and creates a **frozen snapshot**.
|
||||
|
||||
### 2. Frozen Snapshot (prefix-cache invariant)
|
||||
|
||||
```python
|
||||
self._system_prompt_snapshot = {
|
||||
"memory": self._render_block("memory", sanitized_memory),
|
||||
"user": self._render_block("user", sanitized_user),
|
||||
}
|
||||
```
|
||||
|
||||
The snapshot is **never mutated mid-session** — even when `memory()` tool
|
||||
calls write new entries to disk. This keeps the system prompt byte-stable,
|
||||
preserving the LLM prefix cache across all turns.
|
||||
|
||||
### 3. Injection Point
|
||||
|
||||
`system_prompt.py` injects both blocks into the **volatile tier** of the
|
||||
system prompt (alongside date, model, provider):
|
||||
|
||||
```python
|
||||
if agent._memory_enabled:
|
||||
mem_block = agent._memory_store.format_for_system_prompt("memory")
|
||||
volatile_parts.append(mem_block)
|
||||
if agent._user_profile_enabled:
|
||||
user_block = agent._memory_store.format_for_system_prompt("user")
|
||||
volatile_parts.append(user_block)
|
||||
```
|
||||
|
||||
### 4. Rendered Format
|
||||
|
||||
```
|
||||
════════════════════════════════════════════
|
||||
MEMORY (your personal notes) [100% — 2,217/2,200 chars]
|
||||
════════════════════════════════════════════
|
||||
entry1
|
||||
§
|
||||
entry2
|
||||
§
|
||||
...
|
||||
|
||||
════════════════════════════════════════════
|
||||
USER PROFILE (who the user is) [86% — 1,184/1,375 chars]
|
||||
════════════════════════════════════════════
|
||||
entry1
|
||||
§
|
||||
entry2
|
||||
...
|
||||
```
|
||||
|
||||
### 5. Threat Scanning
|
||||
|
||||
Each entry is scanned for prompt-injection patterns at load time
|
||||
(`_sanitize_entries_for_snapshot`). Matches are replaced with
|
||||
`[BLOCKED: ...]` in the snapshot, but the original text remains in the
|
||||
live file so the user can inspect and delete it.
|
||||
|
||||
## System Prompt Tiers
|
||||
|
||||
```
|
||||
STABLE (byte-stable, cached for entire session)
|
||||
1. SOUL.md — identity ("You are Hermes Agent...")
|
||||
2. Tool schemas, platform hints, guardrails
|
||||
|
||||
CONTEXT (cwd-dependent, changes between sessions)
|
||||
3. .hermes.md / HERMES.md (walks to git root)
|
||||
4. AGENTS.md (cwd only)
|
||||
5. CLAUDE.md (cwd only)
|
||||
6. .cursorrules (cwd only)
|
||||
(first match wins — only ONE loaded, ~20K char cap)
|
||||
|
||||
VOLATILE (per-session, not cached)
|
||||
7. MEMORY.md snapshot (memory_char_limit)
|
||||
8. USER.md snapshot (user_char_limit)
|
||||
9. External memory provider (optional, e.g. Hindsight)
|
||||
10. Date, model, provider, session ID
|
||||
```
|
||||
|
||||
## Alternative Context Injection Points
|
||||
|
||||
Beyond MEMORY.md/USER.md, additional context can be injected via:
|
||||
|
||||
- **SOUL.md** (`~/.hermes/SOUL.md`) — global identity/personality, always
|
||||
loaded, no char limit
|
||||
- **AGENTS.md** (in repo root) — project conventions, ~20K char cap,
|
||||
loaded when cwd is the repo
|
||||
- **CLAUDE.md / .cursorrules** — same as AGENTS.md, first-match-wins
|
||||
- **.hermes.md** — walks up to git root, highest priority among context files
|
||||
|
||||
## Live State vs Snapshot
|
||||
|
||||
| Aspect | Snapshot (System Prompt) | Live State (Tool Calls) |
|
||||
|--------|--------------------------|--------------------------|
|
||||
| When read | Once at session start | Every `memory()` call |
|
||||
| When written | Never (read-only) | Every `memory()` call → disk |
|
||||
| Prefix cache | Byte-stable for session | N/A (not in prompt) |
|
||||
| Changes visible | Next `/reset` or restart | Immediately in tool response |
|
||||
|
||||
## Key Insight
|
||||
|
||||
Memory writes via the `memory()` tool are **not visible in the current
|
||||
session's system prompt** — they persist to disk but the snapshot was
|
||||
already frozen. This is by design: mutating the system prompt mid-session
|
||||
would invalidate the prefix cache and multiply API costs.
|
||||
|
||||
## Source Files
|
||||
|
||||
- `tools/memory_tool.py` — `MemoryStore` class, file I/O, rendering
|
||||
- `agent/agent_init.py` lines 1199-1218 — initialization
|
||||
- `agent/system_prompt.py` lines 426-435 — injection into volatile tier
|
||||
- `agent/prompt_builder.py` lines 1921-1968 — context files (AGENTS.md etc.)
|
||||
- `agent/coding_context.py` — project detection, context file discovery
|
||||
Reference in New Issue
Block a user