Complete reference for all memory systems in VibeCLI and VibeUI — from the simple auto-recording file to the full cognitive engine with verbatim drawers, cross-project tunnels, and recall benchmarking.
For system architecture details, see
memory-architecture.md— includes detailed ASCII diagrams of the five memory stores, Context Assembler pipeline, storage security model, and Recap/Resume architecture.
Overview — Three Memory Layers
VibeCody provides three distinct memory systems that complement each other:
| System | Where it lives | Best for |
|---|---|---|
Auto-recording (memory.md) |
~/.vibecli/memory.md |
Simple per-session learnings, no extra setup |
| OpenMemory (cognitive store) | ~/.local/share/vibecli/openmemory/ |
Structured, searchable, long-term memories |
| Verbatim Drawers (MemPalace) | Same store, drawers.json |
Lossless raw-text recall, highest fidelity |
All three feed into the agent context automatically — you never have to manually pass memory to a prompt.
1 — Auto-Recording (memory.md)
The simplest layer. After an agent session with at least N tool-use steps, VibeCLI summarises what it learned and appends it to ~/.vibecli/memory.md. The file is injected verbatim into every future system prompt.
Configuration
# ~/.vibecli/config.toml
[memory]
auto_record = true # Enable automatic session recording
min_session_steps = 3 # Minimum tool-use steps before a session is recorded
How it works
- You run
vibecliand complete a coding task. - The agent makes 3+ tool calls (edit, bash, search, …).
- At session end, a summary like the following is appended:
## 2026-04-12 — Session: payment-service refactor
- Moved database connection pooling to a lazy-static OnceLock.
- All integration tests pass; unit tests for PaymentRepo were added.
- User prefers short commit messages with a verb prefix (fix:, feat:, chore:).
- Next session, the entire file loads into the system prompt before the first message.
Manual management
# View current memory file
cat ~/.vibecli/memory.md
# Clear memory (keeps the file, empties it)
echo "" > ~/.vibecli/memory.md
# Edit manually — add or remove anything
$EDITOR ~/.vibecli/memory.md
Tip: Keep
memory.mdunder ~2 000 tokens. Large files slow down each request because the whole file is re-sent every turn. Use OpenMemory for long-lived or large knowledge sets.
2 — OpenMemory Cognitive Engine
OpenMemory is a bio-inspired, five-sector cognitive memory engine. It stores memories as vector-embedded nodes, links them into an associative graph, decays them over time unless reinforced, and retrieves them with a composite score that weighs similarity, salience, recency, graph position, and sector match.
The Five Cognitive Sectors
| Sector | Purpose | Decay rate | Example |
|---|---|---|---|
| Episodic | Events and interactions | Fast | “Fixed a race condition in payment service, 2026-04-12” |
| Semantic | Facts and knowledge | Slow | “User prefers Rust over Go for backend work” |
| Procedural | Workflows and how-tos | Moderate | “Deploy: cargo build –release → docker push → kubectl apply” |
| Emotional | Sentiment and preferences | Fast | “User was frustrated by flaky CI timeouts” |
| Reflective | Auto-generated meta patterns | Slow | “User frequently debugs async issues on Tokio runtimes” |
Classification is automatic — the engine reads content and picks the best-fit sector.
Composite Retrieval Score
Every memory is ranked by five weighted factors:
score = 0.45 × semantic_similarity
+ 0.20 × salience
+ 0.15 × recency
+ 0.10 × waypoint_graph_score
+ 0.10 × sector_match_bonus
Storage paths
| Surface | Path |
|---|---|
| VibeCLI | ~/.local/share/vibecli/openmemory/ |
| VibeUI | ~/.local/share/vibeui/openmemory/ |
| Project-scoped | <workspace>/.vibecli/openmemory/ |
Each store contains: memories.json, waypoints.json, facts.json, drawers.json.
Configuration
# ~/.vibecli/config.toml
[openmemory]
enabled = true
auto_inject = true # Inject context into every agent turn
max_context_tokens = 1200 # Hard cap on injected context
decay_enabled = true # Run salience decay each session
consolidate_on_exit = false # Run sleep-cycle consolidation when REPL exits
encryption = false # AES-256-GCM at rest (see /openmemory encrypt)
VibeCLI REPL commands
All memory commands are under the /openmemory prefix. Run /openmemory with no arguments to show a summary of all available commands and live statistics.
Core memory operations
/openmemory add <content>
Store a memory. The engine auto-classifies the sector and builds TF-IDF embeddings.
/openmemory add "User prefers snake_case for Rust identifiers"
/openmemory add "Refactored auth middleware to remove JWT storage in cookies — compliance requirement"
/openmemory add "Always run cargo clippy --all-targets before committing"
/openmemory query <text>
/openmemory search <text>
Semantic search. Returns up to 10 results ranked by composite score.
/openmemory query "deployment workflow"
/openmemory query "what does the user prefer for error handling?"
/openmemory list
List all memories with sector labels, salience, and tag cloud.
/openmemory stats
Show count by sector, storage size, encryption status, association graph density.
/openmemory health
Full health dashboard: diversity index, at-risk counts, staleness percentages, decay schedule.
/openmemory at-risk
List memories whose salience is near the purge threshold (≤ 0.15). Pin them to save or let them decay.
/openmemory dedup [threshold]
Remove near-duplicate memories. Default cosine threshold: 0.92. Prefer the higher-salience copy.
/openmemory dedup # use default 0.92
/openmemory dedup 0.85 # broader dedup
Knowledge graph (temporal facts)
Facts are explicit subject-predicate-object triples with validity windows. Adding a new fact for the same subject+predicate automatically closes the previous one.
/openmemory fact <subject> <predicate> <object>
/openmemory fact user prefers_language Rust
/openmemory fact deploy uses_tool "docker + kubectl"
/openmemory fact payment_service last_debugged "2026-04-12 race condition"
/openmemory facts
Browse all active and closed facts. Closed facts show [CLOSED yyyy-mm-dd] and the superseding fact ID.
Memory lifecycle
/openmemory decay
Manually trigger the exponential decay cycle. Memories not accessed since last decay lose salience. Pinned memories are exempt.
/openmemory consolidate
Run the sleep-cycle consolidation pass:
- Merges near-duplicate memories (cosine ≥ 0.92).
- Reinforces frequently accessed memories.
- Generates a new Reflective memory summarising patterns.
/openmemory reflect
Immediately generate a one-off Reflective summary of current memory contents.
/openmemory summary
Show the user memory profile: top sectors, most-accessed memories, dominant tags, inferred preferences.
Import / Export / Migration
/openmemory export
Export all memories as a markdown file to stdout (redirectable to a file).
/openmemory export > my-memories.md
/openmemory import <file>
/openmemory import [mem0|zep|openmemory|auto] <file>
Import from a JSON file. The auto format detector recognises mem0, Zep, and native OpenMemory exports. Duplicates are skipped via FNV-1a hash comparison.
/openmemory import mem0 exported-memories.json
/openmemory import auto ~/backup/memories-2026-04-01.json
Document ingestion
/openmemory ingest <file>
Chunk a document into 400-character overlapping segments and store each chunk as a Semantic memory. Use this for long documents like architecture specs, runbooks, or design docs.
/openmemory ingest docs/architecture.md
/openmemory ingest ~/runbooks/incident-response.txt
Encryption
/openmemory encrypt
Enable AES-256-GCM encryption at rest. All existing memories are re-encrypted in place. The key is stored at ~/.local/share/vibecli/openmemory/.key (mode 0600). To use a passphrase instead:
VIBECLI_MEMORY_KEY="$(pass show vibecli/memory)" vibecli
4-Layer Context Retrieval
When the agent runs, OpenMemory assembles context in four layers — from cheapest to richest:
| Layer | Name | Behaviour |
|---|---|---|
| L0 | Identity | Always included. Fixed user profile header (≤ 100 tokens). |
| L1 | Essential story | Always included. Top memories by salience across all sectors (≤ 700 tokens). |
| L2 | Scoped semantic | Query-dependent. Wing/Room-filtered semantic search, top-8 matches. |
| L3 | Deep fallback + verbatim drawers | Triggered only when L2 returns < 3 matches. Full search + verbatim raw chunks. |
/openmemory context [query]
/openmemory layered [query]
Preview the exact context block the agent would receive for a given query.
/openmemory context "what is our deploy process?"
/openmemory layered "async rust patterns"
Output format:
<open-memory>
<!-- L1: Essential Story (salience ≥ 0.60) -->
User prefers Rust for backend. Deploy uses Docker + kubectl.
<!-- L2: Scoped (query: deploy process) -->
[Procedural, 0.91] cargo build --release → docker push → kubectl apply
[Episodic, 0.72] Debugged deploy pipeline timeout 2026-03-28
<!-- L3: Verbatim chunks (3 raw drawer hits) -->
[chunk:runbook-2026-04.txt] Step 4: run smoke tests before promoting to prod ...
</open-memory>
3 — Verbatim Drawers (MemPalace Technique)
Verbatim drawers store raw text in 800-character chunks with 100-character overlap — no summarisation, no information loss. They achieve 96.6% Recall@5 on LongMemEval benchmarks compared to ~74% for purely cognitive stores. Use drawers for any text where exact wording matters: runbooks, specs, commit messages, error logs, transcripts.
Wing / Room spatial scoping
Drawers are organised by Wing (project namespace) and Room (memory sector). Before running a vector search, the engine filters by Wing+Room, dramatically reducing search space on large stores:
Wing: "payment-service" → project namespace
Room: "procedural" → sector within the project
This maps directly to VibeCLI’s concept of a project-scoped store.
Commands
/openmemory chunk <text>
/openmemory chunk file:<path>
Ingest text as verbatim 800-char chunks. Exact duplicates (FNV-1a hash) are silently dropped. Near-duplicates (cosine ≥ 0.85) within a 20-item sliding window are also skipped.
/openmemory chunk "The incident on 2026-04-01 was caused by a missing index on payments.amount..."
/openmemory chunk file:docs/architecture.md
/openmemory chunk file:~/runbooks/deploy-runbook.txt
/openmemory drawers
Show drawer store statistics: total chunks, Wing distribution, Room distribution, dedup hit rate.
/openmemory tunnel <src-memory-id> <dst-memory-id> [weight]
Create a cross-project waypoint (Tunnel) between two memories. Tunnels are bidirectional and survive across store reloads. Weight defaults to 0.8.
/openmemory tunnel mem_a3f8c1d2 mem_b7e4f091 0.9
/openmemory auto-tunnel [threshold]
Automatically detect semantically similar memories across the default store and the current project-scoped store, and create Tunnel waypoints for pairs above the similarity threshold (default: 0.75).
/openmemory auto-tunnel
/openmemory auto-tunnel 0.80
LongMemEval Benchmark
Measure the recall quality of your current memory store across both cognitive and verbatim layers:
/openmemory benchmark [k]
Runs 20 built-in probe cases across all 5 sectors, reports Recall@K for cognitive (L2), verbatim (L3), and combined layers.
/openmemory benchmark # k=5 (default)
/openmemory benchmark 10 # k=10
Example output:
LongMemEval Benchmark Results (k=5)
Total memories: 47 Verbatim drawers: 132 Probe cases: 20
Recall@5 — Cognitive (L2): 78.0% ████████████████████████░░░░░░
Recall@5 — Verbatim (L3): 90.0% ██████████████████████████████
Recall@5 — Combined: 96.0% ████████████████████████████████
Per-case breakdown:
episodic What was the last project I worked on? ✓ cognitive ✓ verbatim
semantic What programming languages do I know? ✓ cognitive ✓ verbatim
procedural How do I run the test suite? ✓ cognitive ✓ verbatim
preference What coding style does the user prefer? ✗ cognitive ✓ verbatim
...
VibeUI — Memory Panels
The VibeUI desktop app exposes memory through four dedicated panels.
OpenMemory Panel
The primary memory management UI. Access via the AI sidebar → OpenMemory tab.
| Tab | Contents |
|---|---|
| Overview | Memory counts, sector distribution bar chart, 4-column stats (memories / waypoints / facts / drawers) |
| Memories | Paginated list with sector filter, salience bar, pin/unpin/delete actions |
| Query | Natural language semantic search with scored result cards |
| Facts | Temporal knowledge graph — active and closed facts with validity windows |
| Graph | D3 force-directed graph of memory associations and waypoints |
| Drawers | Verbatim drawer stats by Wing/Room, 4-layer context preview, LongMemEval benchmark runner |
| Settings | Encryption toggle, decay rate sliders, import/export, clear all |
Drawers tab — Benchmark Runner
The Drawers tab includes a live benchmark panel:
- Set k (recall depth, 1–20).
- Click Run.
- Three recall-percentage gauges appear instantly: Cognitive, Verbatim, Combined.
- Scroll down for the per-case hit/miss table — green ✓ for a hit, grey ✗ for a miss.
ChatMemoryPanel
Visible inside the Chat panel as a collapsible sidebar. Shows facts extracted from the current conversation in real time: pin facts to the long-term store, edit wording, or delete before they’re persisted.
SessionMemoryPanel
In the Session panel header. Tracks memory health for the current session: token budget consumed by context injection, staleness warnings, and a sparkline of salience over time.
MemoryPanel
A standalone rules-and-facts editor. Add, edit, or delete persistent user rules (always use tracing:: not println!, always run clippy before commit, etc.). Rules are injected into every agent system prompt ahead of memory context.
Agent Context Integration
All three memory systems feed into agent context automatically. You can tune the injection behaviour per-session:
VibeCLI flags
# Disable memory injection for this session
vibecli --no-memory
# Use a specific project store (project-scoped Wing)
vibecli --memory-scope ./payment-service
# Show what context would be injected without running
vibecli --dry-run-memory "what is our testing strategy?"
In the REPL
/openmemory context <your question>
Preview exactly what the agent will see before you ask.
Quick-Reference Cheat Sheet
# ── Core ──────────────────────────────────────────────────────────────
/openmemory add <text> Store a memory (auto-classifies sector)
/openmemory query <text> Semantic search
/openmemory list List all memories
/openmemory stats Counts, storage, encryption status
/openmemory health Full health dashboard
/openmemory at-risk Memories near purge threshold
/openmemory dedup [thresh] Remove near-duplicate memories
# ── Knowledge Graph ───────────────────────────────────────────────────
/openmemory fact <s> <p> <o> Add temporal fact (closes previous)
/openmemory facts Browse active + closed facts
# ── Lifecycle ─────────────────────────────────────────────────────────
/openmemory decay Run salience decay manually
/openmemory consolidate Sleep-cycle consolidation
/openmemory reflect One-off reflective summary
/openmemory summary User memory profile
# ── Import / Export ───────────────────────────────────────────────────
/openmemory export Dump as markdown
/openmemory import [fmt] <file> Import from mem0 / Zep / native JSON
/openmemory ingest <file> Chunk & store document (cognitive)
/openmemory encrypt Enable AES-256-GCM encryption
# ── 4-Layer Context ───────────────────────────────────────────────────
/openmemory context [query] Preview agent context (L1+L2+L3)
/openmemory layered [query] Same as context
# ── MemPalace (Verbatim Drawers) ──────────────────────────────────────
/openmemory chunk <text|file:path> Verbatim 800-char ingest
/openmemory drawers Drawer stats (Wing/Room distribution)
/openmemory tunnel <id1> <id2> [w] Cross-project waypoint
/openmemory auto-tunnel [thresh] Auto-detect and create tunnels
# ── Benchmark ─────────────────────────────────────────────────────────
/openmemory benchmark [k] LongMemEval recall@K
Operations
Where memory lives on disk
| Layer | Path |
|---|---|
| Auto-recording | ~/.vibecli/memory.md |
| OpenMemory store | ~/.local/share/vibecli/openmemory/ (Linux) / ~/Library/Application Support/vibecli/openmemory/ (macOS) / %APPDATA%\vibecli\openmemory\ (Windows) |
| Verbatim drawers | nested under the OpenMemory store directory |
| Encryption passphrase | ~/.vibecli/profile_settings.db (encrypted ProfileStore — never plaintext) |
The OpenMemory directory contains JSON serializations of memories, facts, lineage edges, and the embedding index. It’s safe to commit to a private backup, but do not commit the ProfileStore — that file is machine-bound by design.
Readiness signal — /health.memory
The daemon’s /health endpoint exposes a canonical memory readiness block. Use this from monitoring dashboards, scripts, or feature gates instead of probing each panel:
curl http://127.0.0.1:7878/health | jq '.memory'
{
"enabled": true,
"store_path": "/Users/me/Library/Application Support/vibecli/openmemory",
"total_memories": 1247,
"drawer_count": 38,
"encryption_enabled": true
}
A feature that depends on “memory has data” should check memory.enabled && memory.total_memories > N rather than calling /memory/list directly.
Backup and restore
The OpenMemory store is plain JSON files — copy them anywhere:
# Backup
tar czf vibecli-memory-$(date +%F).tar.gz "$HOME/Library/Application Support/vibecli/openmemory"
# Restore (overwrites existing memories)
tar xzf vibecli-memory-2026-05-01.tar.gz -C "$HOME/Library/Application Support/vibecli/"
If the store is encrypted, you’ll also need the passphrase. The passphrase lives in the encrypted ProfileStore; back it up via:
vibecli list-keys # confirm openmemory_passphrase is set
# Re-set the same passphrase on a new machine:
vibecli set-key openmemory_passphrase '<your-passphrase>'
Migration between machines
# On the old machine:
curl http://127.0.0.1:7878/memory/export > memories.md # human-readable
curl http://127.0.0.1:7878/memory/list > memories.json # full snapshot
# On the new machine — re-set the encryption passphrase first if any:
vibecli set-key openmemory_passphrase '<your-passphrase>'
# Then import:
curl -X POST http://127.0.0.1:7878/memory/import \
-H 'content-type: application/json' \
-d "{\"format\":\"openmemory\",\"content\":$(cat memories.json | jq -Rs .)}"
Export formats supported
The /memory/import route accepts four formats. Use format: "auto" to detect:
- openmemory — VibeCody’s native JSON. Round-trip safe; preserves salience, pin state, encryption flags.
- mem0 — popular open-source memory format. Lossy — sector classification re-runs on import.
- zep — temporal-knowledge-graph format. Imports as facts.
- markdown — paste any markdown; each
##heading becomes a memory.
Troubleshooting
“Memories I added aren’t surfacing in agent context”
The 4-layer retrieval combines L1 (working set), L2 (recent + reinforced), L3 (semantic recall), L4 (episodic). For a memory to surface in L3, it needs:
- A non-zero similarity score to the query (run
/openmemory query <text>to verify) - Effective salience above the recall threshold (default 0.1 — see
[memory.recall]config)
If the memory isn’t in the query results: check the sector. Memories in procedural and semantic rank higher for technical questions; episodic ranks higher for “what did we do last week?”.
If the memory IS in query results but not in agent context: check the layer caps — L3 defaults to 5 memories. Increase max_l3 in [memory.context] config.
“Layered context returns empty even with memories present”
Check /health.memory.enabled. If false, the store didn’t load — see permissions on the store directory.
curl -s http://127.0.0.1:7878/health | jq '.memory'
If enabled: true but total_memories: 0, you’re looking at the wrong store. The store path is shown in store_path — check that it matches what your agent is reading.
“LongMemEval recall@K is lower than expected”
Recall@K depends on the embedding backend, the corpus size, and the salience distribution. Common causes:
- Cold cache — the first query after restart loads the index from disk. Run a few queries first, then benchmark.
- TurboQuant compression artifacts — high compression ratios (>10×) can degrade recall by 1-3 percentage points. Fall back to
embedding_backend: "f32"in config if accuracy matters more than RAM. - Insufficient training memories — recall@K below 0.6 with <50 memories is normal; the index needs density to discriminate.
“Encryption was enabled but reads return garbage”
The passphrase changed since the store was last written. Recover by:
- Re-set the original passphrase:
vibecli set-key openmemory_passphrase '<original>' - Restart the daemon so
load_memory_store()re-applies the passphrase. - If the original passphrase is genuinely lost: the store is unrecoverable. Restore from backup, or delete the openmemory directory to start fresh.
“Permission denied on the store directory”
The daemon couldn’t write to ~/.local/share/vibecli/openmemory/ (Linux) or the equivalent on your platform. Fix:
# Linux
chmod -R u+rw "$HOME/.local/share/vibecli"
# macOS
chmod -R u+rw "$HOME/Library/Application Support/vibecli"
If you’re running the daemon under a different user (e.g. a systemd service), make sure the data directory is writable by that user.
“Disk full”
Run /openmemory decay to purge low-salience memories. If that’s not enough, export and re-import with a more aggressive salience threshold:
curl http://127.0.0.1:7878/memory/export > backup.md
rm -rf "$HOME/Library/Application Support/vibecli/openmemory"
# Re-import only the salient bits manually from backup.md.
FAQ
How long do memories persist?
Indefinitely, until you delete them or the salience-decay loop reclaims them. Decay runs once a day by default and only purges memories with effective_salience < 0.05 that haven’t been reinforced in 30+ days. Pinned memories are exempt.
Can I delete a specific memory?
Yes — via the OpenMemory panel’s per-row Delete button, or /openmemory delete <id> in the REPL, or POST /memory/delete with { "id": "..." }. Deletion is immediate and irreversible.
What’s the encryption overhead? The current implementation uses XOR-based stream encryption (lightweight, ~5% throughput overhead). AES-256-GCM is on the roadmap — when it lands, expect ~10-15% throughput overhead and no measurable recall impact.
Is memory available on mobile / watch?
No — by design. Memory authoring is a desktop / CLI workflow. Mobile and watch clients consume generated artifacts (recaps, sessions) but don’t surface the memory store directly. The HTTP routes at /memory/* are available to any client that wants them, including IDE plugins and the Agent SDK.
How do I share memories across teammates?
The store is single-user by design. To share, export specific memories as markdown and check them into your repo as docs/team-memory.md. The auto-recording layer reads any *.md file in the workspace at agent-context build time.
Will my memories sync across devices? Not automatically. The store is local-only (Zero-Config First — no cloud dependency). To sync manually, use the export/import flow above with a private file-share (Dropbox, iCloud, etc.) or a private git repo.
What happens if the JSON store gets corrupted?
On load failure, load_memory_store() falls back to a fresh empty store rather than crashing the daemon. You’ll see enabled: true, total_memories: 0 in /health even though you previously had memories. Restore from backup, or accept the loss and move on.
Cross-client scope
| Client | Memory access |
|---|---|
| VibeUI (desktop, Tauri) | Full UI: OpenMemoryPanel, ChatMemoryPanel, SessionMemoryPanel, MemoryProjectionsPanel, MemoryPanel |
| VibeCLI | Full REPL: /openmemory * commands |
| VibeMobile | None by current design |
| VibeWatch (watchOS / Wear OS) | None by current design |
| VS Code / JetBrains / Neovim plugins | HTTP via /memory/* routes (not surfaced in plugin UIs today) |
| Agent SDK | HTTP via /memory/* routes |
If you need a memory UI on a client where it’s currently absent, file an issue — the daemon-side API is stable and complete; only the client-side surface is missing.
See Also
- Demo 48: OpenMemory Cognitive Engine — Basic walkthrough
- Demo 61: Verbatim Drawers & MemPalace — Lossless chunk ingestion and cross-project tunnels
- Demo 62: Memory Benchmarking — LongMemEval recall@K in CLI and VibeUI
- Configuration Reference —
[memory]and[openmemory]config tables - API Reference — Tauri commands for frontend integration