Are you the author? Sign in to claim
Hybrid adaptive memory system for Claude Code — Cheatsheet (positive patterns) + Immune (negative patterns)
A self-improving memory system that makes AI outputs better over time through two complementary memories:
v5.2 — Hybrid Search: Local embeddings (bi-encoder) + FTS4 keyword search, fused via Reciprocal Rank Fusion (RRF). Everything runs in-process via WASM — no server, no daemon, no API keys for search/dedup.
v5.2.2: retrieval contract fix —
domainsabsent or empty now means no filtering (previously defaulted to_global, hiding domain-tagged items from callers that pass no domains).
Provider-agnostic: Built around the Anthropic Messages API shape (originally for Claude Code), but compatible with any provider that exposes a Messages-API-compatible endpoint. Set
ANTHROPIC_BASE_URLto point at your provider (OpenRouter, Mistral, local llama.cpp, Ollama, vLLM, LM Studio, etc.) andANTHROPIC_DEFAULT_HAIKU_MODELto your provider's fast/cheap model. See Provider Configuration below.
| Component | Minimum | Notes |
|---|---|---|
| Node.js | 18+ | Tested on 20.x and 22.x. The installer refuses to run on older versions. |
| Disk | ~70 MB | Dependencies (~50 MB) + embedding model (~22 MB, downloaded on first use) |
| RAM | 256 MB free | Embedding model uses ~150 MB resident |
| API access | Any Anthropic-compatible endpoint | Only needed for the scan step (LLM). Search/dedup/dedup/strategy injection work fully offline. |
No GPU required. Embeddings run on CPU via WASM. The first run downloads the model (~22 MB); subsequent runs use the cache.
This repo ships the standalone CPU engine (default). MnemoClaw full installs also run an optional GPU daemon that reads the same memory files — pick per deployment, nothing else changes:
immune-adapter.js (this repo) | embed-daemon (mnemoclaw-docker) | |
|---|---|---|
| Embedding model | Xenova/all-MiniLM-L6-v2 (384 dims, ~22 MB) | nvidia/Nemotron-3-Embed-1B (2048 dims) |
| Reranker | none (RRF + heat composite) | BAAI/bge-reranker-v2-m3 cross-encoder |
| Hardware | CPU / WASM, no GPU, ~150 MB RAM | CUDA GPU (~8 GB VRAM) |
| Latency (583 items) | ~1-2 s | ~0.7-0.8 s warm (~5 s cold, fills cache) |
| Best for | installs clients "petit frère", mnemo-lite, offline, CI | full MnemoClaw / MnemoPi on the dev station |
Both engines read/write the same immune_memory.json / cheatsheet_memory.json
and follow the same retrieval contract (domains absent → no filtering, tier
hot/all/cold, RRF fusion, heat boost). Fixes are mirrored in both — keep them
in sync when you touch retrieval logic.
No API key needed for retrieval. Only the scan phase (where an LLM checks your output for known errors) calls a model. Everything else — embedding search, dedup, FTS4 keyword search, strategy injection, scoring, housekeeping — runs locally.
npm install -g @mnemoclaw/immune
immune init
That's it — immune init copies the skill into ~/.claude/skills/immune/, installs dependencies, and verifies the install. Re-run immune init after every npm update to upgrade in place (your memory is preserved).
No npm? Use Manual install below.
In Claude Code:
/immune Check this function for common pitfalls
/immune domain=fitness Vérifie ce programme
/immune domains=fitness,code Check this workout API
First invocation will trigger the embedding model download (~22 MB, one-time).
If you prefer git clone over npm, or want to hack on the source:
git clone https://github.com/Mnemoclaw/immune.git
cd immune
npm install
Then copy only the runtime files into your Claude Code skills directory:
mkdir -p ~/.claude/skills/immune
cp immune-adapter.js immune-inject.js sanitizer.js config.yaml skill.md package.json \
~/.claude/skills/immune/
cp -r agents ~/.claude/skills/immune/
cd ~/.claude/skills/immune/
npm install --omit=dev
node immune-adapter.js stats
Prefer a filtered copy over
cp -r *—cp -r *copiesnode_modules/, dev artifacts, and lockfiles alongside the files you actually need.
The immune scan (LLM-based detection) needs a model. The "haiku" alias in the code is a logical name — Claude Code resolves it through environment variables. Any provider works as long as it speaks the Messages API shape.
Anthropic (default):
export ANTHROPIC_API_KEY=sk-ant-...
# haiku alias already points to claude-haiku on first-party
OpenRouter:
export ANTHROPIC_BASE_URL=https://openrouter.ai/api/v1
export ANTHROPIC_API_KEY=sk-or-...
export ANTHROPIC_DEFAULT_HAIKU_MODEL=mistralai/ministral-8b # cheap fast tier
export ANTHROPIC_DEFAULT_SONNET_MODEL=anthropic/claude-sonnet # balanced tier
Local (Ollama, llama.cpp, LM Studio, vLLM):
export ANTHROPIC_BASE_URL=http://localhost:11434/v1 # Ollama example
export ANTHROPIC_API_KEY=local # any non-empty string
export ANTHROPIC_DEFAULT_HAIKU_MODEL=qwen2.5:7b
export ANTHROPIC_DEFAULT_SONNET_MODEL=qwen2.5:14b
GLM / Mistral / Together / Fireworks / Groq / DeepSeek — same pattern. The system keeps every vendor configurable.
Without these variables, the scan step will fail. Search, dedup, strategy injection, and scoring all keep working — they operate independently of any model.
[User Request]
--> Keyword domain detection (no LLM)
--> Hybrid search: local embeddings + FTS4 via Reciprocal Rank Fusion
--> Inject cheatsheet strategies (positive patterns) into prompt
--> Generate output (with strategy context)
--> Immune scan via cheap LLM (detect known + new errors)
--> Fix errors + learn new antibodies
--> Local embedding dedup (before adding new patterns)
--> Score (0-100, domain-normalized via Welford's algorithm)
--> Session log (for future context recall)
Xenova/all-MiniLM-L6-v2 (384 dims, ~22 MB, WASM) for semantic matchingKeeps context lean for optimal performance:
immune_memory.json / cheatsheet_memory.json) — Primary, portable, human-readableimmune.sqlite) — FTS4 full-text search + embedding cachehousekeep only archives patterns that are COLD + low-seen + old + non-criticalflush-pending runs check-duplicate before any write — duplicates reactivate the original instead of creating new entriesfreeze / unfreeze pauses aging clocks (e.g. during vacations) without losing historyInject relevant strategies into every Claude response automatically:
# Test the inject script manually
echo '{"prompt":"Write a Node.js API endpoint"}' | node ~/.claude/skills/immune/immune-inject.js
Add to ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "node /absolute/path/to/.claude/skills/immune/immune-inject.js",
"timeout": 10
}
]
}
]
}
}
The inject hook detects domains from your prompt via keyword matching and injects up to 5 HOT strategies as compact XML. Zero injection on unrelated prompts. ~50 ms overhead. No LLM call — entirely local.
immune/
immune-adapter.js # CLI adapter — all operations go through this
immune-inject.js # Pre-generation hook (local keyword detection)
sanitizer.js # Input sanitization (strips secrets before storage)
config.yaml # Full configuration
skill.md # Claude Code skill definition
agents/
immune-scan.md # Scan agent instructions
benchmark/
run-blind.js # Blind retrieval + generalization + learning benchmarks
run-learning.js # Standalone learning curve benchmark
sample-queries.json # Example benchmark queries (20 cases)
cases-learning-blind.json
BENCHMARKS.md # Published benchmark results
tools/viz/ # Optional D3 dashboard for inspecting your memory
README.md
immune-viz.js # Generates immune-viz.html from memory files
Files generated at runtime (gitignored): immune_memory.json, cheatsheet_memory.json, immune.sqlite, migration_state.json, archived_*.json, context/.
# Search (hybrid embeddings + FTS4 via RRF)
node immune-adapter.js search --query "docker crash loop" --type antibody
node immune-adapter.js get-context --query "fitness programme" --days 90
node immune-adapter.js check-duplicate --pattern "..." --type antibody
# Retrieval
node immune-adapter.js get-antibodies --domains '["code"]' --tier hot --limit 15
node immune-adapter.js get-strategies --domains '["code"]' --query "security" --limit 10
# Add / Update
node immune-adapter.js add-antibody --json '{"id":"AB-001","pattern":"...","severity":"critical","correction":"..."}'
node immune-adapter.js update-antibody --id AB-001 --increment_seen
# Bulk
node immune-adapter.js flush-pending --json '{"antibodies":[...],"strategies":[...]}'
node immune-adapter.js import --file export.immune.json
# Maintenance
node immune-adapter.js index # Rebuild FTS4 index
node immune-adapter.js stats # Show counts and migration state
node immune-adapter.js housekeep # Archive useless patterns
node immune-adapter.js integrity-check # SQLite integrity check
node immune-adapter.js freeze / unfreeze # Pause/resume aging clocks
# Testing
node immune-adapter.js similarity-test # Run dedup test suite
node immune-adapter.js retrieval-test # Run semantic retrieval tests
node immune-adapter.js embed --text "..." # Get raw embedding vector
Patterns are tagged with domains for targeted retrieval. Edit config.yaml:domain_keywords to add your own.
| Domain | Example Keywords |
|---|---|
code | function, docker, API, script, deployment |
fitness | muscu, exercice, programme, séance |
writing | article, SEO, blog, rédaction |
research | source, étude, analyse, hypothèse |
strategy | marché, compétiteur, ROI |
webdesign | CSS, HTML, responsive, UI |
travel | voyage, hôtel, billet, itinéraire |
_global | Cross-domain patterns |
See benchmark/BENCHMARKS.md for the full methodology. Headline results (blind test cases written by independent AI agents kept fully blind to the memory data):
| Benchmark | Score |
|---|---|
| Retrieval accuracy | 70 % (14/20) |
| Cross-domain generalization | 53 % (4 strong + 8 partial / 15) |
| Improvement after 1 learning pass | +74 pts (0 % → 74 %) |
| Housekeep safety | 0 pts lost |
Reproduce:
node benchmark/run-blind.js
node benchmark/run-learning.js --cases benchmark/cases-learning-blind.json
The retrieval benchmark reads from benchmark/sample-queries.json by default. Point IMMUNE_BENCH_QUERIES at your own file to evaluate against your own memory.
All tunable parameters live in config.yaml:
max_antibodies: 500, max_strategies: 300, max_sqlite_mb: 50)@xenova/transformers ^2.17.2 — Local embedding model (auto-cached on first use)sql.js ^1.14.1 — SQLite in WASM for FTS4 searchproper-lockfile ^4.1.2 — Concurrency safetyprotobufjs ^7.5.8 (override) — Forces patched version to silence npm audit warningsMIT — Jacques Chauvin. See LICENSE.
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases
Official GitHub integration for repos, issues, PRs, and CI/CD workflows