Memory Vault

We built something that dreams.
Every morning at 4:17, while the haus sleeps, the vault does what a brain does overnight: it sorts the day’s raw observations, keeps what matters, and forgets the rest on purpose. Forgetting, here, is not a bug we tolerate — it is the feature we designed for. Somewhere during development we realized we’d shipped a system that remembers where you left your SSH keys, forgets trivial session data, and dreams at 4 AM. The horror movie writes itself.
The Memory Vault is Sanctum’s shared knowledge base, modeled on how human memory actually works. Three tiers of temporal memory — working, short-term, long-term — sit on top of a four-system backend stack, and a daily consolidation pass acts like sleep, distilling raw observations into lasting knowledge.
Memory Stack
Section titled “Memory Stack”Today’s stack is the local git vault, fronted by two access surfaces (a Rust REST service and a Python MCP server), plus the entity graph running on the VM. The doc once described a four-layer design that included a mem0.ai cloud tier; that integration was never wired up, and the privacy posture decided on 2026-05-16 (vault GitHub mirror archived, “the haus does not sync its thoughts to the cloud”) makes wiring it now an explicit policy violation. Honesty over aspiration.
| Layer | Role | Backend | Cost |
|---|---|---|---|
| Memory Vault | Git-native versioned source of truth, primary cross-agent semantic memory | Local-only git repo at ~/.sanctum/memory/ (GitHub mirror archived 2026-05-16 as part of the privacy scrub; the haus does not sync its thoughts to the cloud) |
Free |
sanctum-memory REST |
The read/write data plane over the vault git repo | Rust service on 127.0.0.1:42069, serving /health and /v1/* HTTP routes (search, read, write, recall, ingest, consolidate) |
Free |
memory_vault MCP |
Tool surface & Karpathy-style Second-Brain Wiki Compiler | Native Rust binary (sanctum-memory-vault) over stdio + CLI flags (--consolidate, --wiki-lint, --hub-caps), exposing 9 memory_* tools |
Free |
| Neo4j / Graphiti | Entity relationships & graph queries | Reached via SSH tunnel on local port 31416 (graph runs on the VM, not the host) | Free (self-hosted) |
Architecture
Section titled “Architecture”┌─────────────────────────────────────────────────────┐│ LAYER 1: WORKING MEMORY (per-session, ephemeral) ││ Agent's context window. Dies when session ends. │├─────────────────────────────────────────────────────┤│ LAYER 2: SHORT-TERM MEMORY (inbox/, days-weeks) ││ inbox/{agent}/ — raw observations, session notes ││ TTL: 7-30 days. Consolidated or discarded daily. │├─────────────────────────────────────────────────────┤│ LAYER 3: LONG-TERM MEMORY (consolidated, permanent)││ knowledge/{topic}/ — semantic facts (timeless) ││ events/YYYY/MM/ — significant episodes ││ procedures/ — how-to, runbooks ││ Neo4j/Graphiti — entity relationship graph │└─────────────────────────────────────────────────────┘Directory Structure
Section titled “Directory Structure”~/.sanctum/memory/├── inbox/ # Short-term, per-agent│ ├── claude-code/│ ├── gemini-cli/│ ├── openclaw/│ └── home-assistant/├── knowledge/ # Long-term semantic│ ├── devices/│ ├── network/│ ├── systems/│ ├── people/│ └── preferences/├── events/ # Long-term episodic│ └── 2026/03/├── procedures/ # Long-term procedural│ ├── troubleshooting/│ ├── maintenance/│ └── automation/├── archive/ # Expired, retained 90 days└── meta/ # Schema, consolidation logsNote Format
Section titled “Note Format”Every note has standardized YAML frontmatter. Opinions may vary on whether your haus needs a metadata schema for its thoughts. Opinions are wrong.
---type: semantic | episodic | procedural | observation | session_summarysource_agent: claude-code | gemini-cli | openclaw | user | systemcreated: 2026-03-20T17:00:00Zupdated: 2026-03-20T17:00:00Zlast_accessed: 2026-03-20T17:00:00Zaccess_count: 3importance: 0.85consolidation_status: raw | reviewed | consolidated | archivedttl_days: null # null = permanent, or integer dayssuperseded_by: null # path to newer versiontags: [network, infrastructure]related_entities: [mac-mini, ubuntu-vm]---
# Note Title
Content with [[wikilinks]] to related notes...Importance Scoring
Section titled “Importance Scoring”Every note has a computed importance score (0.0 to 1.0) that determines its TTL. The vault is, in essence, deciding what’s worth remembering. A power you’d think we’d reserve for sentient beings, but here we are.
| Importance | TTL | Notes |
|---|---|---|
| > 0.8 | Permanent | Core knowledge, user-stated facts |
| 0.5 - 0.8 | 90 days | Agent-observed patterns |
| 0.3 - 0.5 | 30 days | Single observations |
| < 0.3 | 7 days | Ephemeral session data |
Score formula: source_weight x recency x access_frequency x link_density
Notes accessed 5+ times are protected from expiry regardless of score. If the system keeps coming back to a memory, there’s probably a reason. Even if that reason is paranoia.
Consolidation & Karpathy Second-Brain Wiki Compiler
Section titled “Consolidation & Karpathy Second-Brain Wiki Compiler”The consolidation engine runs daily at 4:17 AM (LaunchAgent: com.sanctum.memory-consolidate) directly inside the Rust sanctum-memory-vault --consolidate binary (services/memory-vault-mcp/src/consolidate.rs). Inspired by Andrej Karpathy’s LLM Wiki second-brain architecture, it treats inbox/ and episodic streams as raw sources that are compiled into living, cross-linked canonical entity pages rather than merely shoveled into a growing folder of timestamped fragments.
- Scan inbox (both
inbox/<agent>/*.mdand top-levelinbox/*.mddrops) for notes older than 24 hours - Compile into canonical Wiki pages — match fragments against 13 canonical entity pages (
knowledge/{systems,network,devices,finance,people}/wiki-*.md), append structured dated synthesis entries with backlinks, and archive the raw fragment withsuperseded_bypointing to the canonical wiki page - Update Agent Knowledge Frontiers — maintain
agents/<agent>/knowledge-frontier.mdwith each agent’s latest domain contributions - Refresh Maps of Content — regenerate the canonical index tables in
MOC.mdandMOC-systems.md - Recompute importance scores and expire TTL-exceeded notes
- Enforce dynamic hub caps via
sanctum-memory-vault --hub-capsand bounded archive-eviction - Run Wiki Lint (
sanctum-memory-vault --wiki-lint) — verify zero broken[[wikilinks]], zero orphan knowledge pages, and zero uncompiled fragment clusters - Clean archive & SQLite artifacts — prune archived notes older than 90 days and stale
.vault.db.stale-*files, then writemeta/consolidation-log.md
Any agent can trigger consolidation or wiki linting manually via the memory_consolidate and memory_wiki_lint MCP tools.
Hard Caps
Section titled “Hard Caps”To prevent bloat, each layer has a dynamic maximum note count computed by sanctum-memory-vault --hub-caps (base + per_hub * active_hubs). Without limits, a system that remembers everything eventually remembers nothing useful — a problem familiar to anyone who’s ever hoarded browser tabs.
| Layer | Base Cap | Dynamic Hub Scaling (meta/caps.json) |
Action at Cap |
|---|---|---|---|
| Inbox | 300 | +7 per active hub (307 with 1 hub) | Wiki compilation + bounded archive-eviction |
| Knowledge | 1000 | +197 per active hub (1197 with 1 hub) | Wiki compilation + bounded archive-eviction |
| Events | 500 | Dynamic active window | Bounded archive-eviction |
| Procedures | 200 | Static runbook cap | Bounded archive-eviction |
Eviction sorts candidates by (importance ascending, created ascending) and skips anything with importance > 0.8 — permanent knowledge and canonical wiki-*.md pages (importance: 0.95) survive cap pressure. Archived notes are retained for 90 days via ARCHIVE_RETAIN_DAYS before deletion — eviction is reversible during that window.
MCP Tools (9 total)
Section titled “MCP Tools (9 total)”| Tool | Description |
|---|---|
memory_search |
Full-text search (SQLite FTS5) with tag and folder filters |
memory_read |
Read a note (auto-tracks access count and timestamp) |
memory_write |
Create/update with schema enforcement |
memory_delete |
Remove a note |
memory_list |
List notes by folder, tag, or type |
memory_links |
Traverse the wikilink graph |
memory_consolidate |
Run the native Rust consolidator + Second-Brain Wiki compiler (dry-run by default) |
memory_wiki_lint |
Audit the vault for broken [[wikilinks]], orphan knowledge pages, and uncompiled fragments |
memory_health |
Vault health metrics dashboard |
On Mem0 (historical aside)
Section titled “On Mem0 (historical aside)”Earlier versions of this doc described a mem0.ai cloud tier as the primary cross-agent memory layer, with a planned set of MEM0_* cloud tools and a “push to Mem0” step in nightly consolidation. None of that integration was ever wired up — there’s no mem0 client in the repo, no API key, and no mem0.ai traffic from the host.
When the privacy posture was decided on 2026-05-16 (vault GitHub mirror archived, “the haus does not sync its thoughts to the cloud”), Mem0-as-cloud-tier became incompatible with explicit policy. The architecture quietly converged on the local-only model documented above; the doc just hadn’t caught up. This section exists so anyone reading old commit messages or older drafts knows what happened: the cloud tier is not coming back absent a deliberate privacy-posture reversal.
Tool Integration
Section titled “Tool Integration”| Tool | Vault Access |
|---|---|
| Gemini CLI | memory_vault MCP over stdio (~/.gemini/settings.json) |
| Claude Code | Not currently wired — mcpServers is empty; reach the vault via the :42069 REST API or vault.sh until the MCP is added |
| OpenClaw agents | SSH skill (vault.sh) |
| Sanctum automations | :42069 REST API (/v1/write, /v1/search) — the old GitHub path died with the 2026-05-16 archive |
| Obsidian | File system (~/.sanctum/memory/) |
| Holocron | HausBrainPanel polls /vault/brain from Force Flow (:4077) every 5s; new-note particles fire in real time off an Electron IPC vault-event bridge, not a separate socket |
Known Gaps
Section titled “Known Gaps”After tonight’s reconciliation pass (2026-05-29), there are no open implementation gaps — the machinery does what this page says it does: short-term inbox + long-term knowledge/events/procedures, nightly consolidation with bounded archive-eviction, 90-day reversibility, the memory_* tool surface, the :42069 data plane.
One thing the caps table doesn’t show: the vault is currently over cap and grinding down. Events sits at roughly 8× its 500-note cap, and the nightly run evicts 100 events per cycle by design (MAX_EVICT_PER_RUN) rather than archiving thousands in one massacre. That’s the bounded-eviction design working, not a steady state — a system converging, not a system at rest.
The procedures layer was empty for months and is now seeded — 5 high-signal runbooks grounded in recent incidents live under procedures/{troubleshooting,maintenance,automation}/. The layer grows organically from there as incidents teach the haus new procedures worth remembering.
The only architectural decision left open is whether to ever re-introduce a cloud-sync tier (see On Mem0 above). That is a privacy-posture decision, not an engineering gap.
Anti-Bloat Rules
Section titled “Anti-Bloat Rules”- If derivable from code, logs, or sensors — don’t store it
- If the same fact is stated multiple ways — dedup into one
- If never accessed in 30 days and importance < 0.5 — archive
- Raw data goes to time-series DBs, not memory
- Every episodic memory needs context (who, what, when, why)
- Every semantic memory should be self-contained
A haus that remembered everything would remember nothing worth keeping. So the vault forgets, on schedule, the way you do — and every morning at 4:17 it still wakes up knowing where the SSH keys are. That is the whole trick. Your own brain has been running it, unpatched, your entire life.