Contextual Differentiation Memory Service — a local-first, forgetting-driven memory daemon for Claude Code CLI
Project description
CDMS — Contextual Differentiation Memory Service
An AI that grows a personality by forgetting.
CDMS is a local-first, forgetting-driven memory daemon for AI agents. Most memory systems accumulate everything. CDMS does the opposite: it captures each turn, scores it for salience, lets noise decay away, and consolidates survivors during idle periods into a compact personality. Two instances fed different histories develop measurably different recall patterns.
Runs entirely on your machine (0 GPU, single SQLite file). Integrates with Claude Code via lifecycle hooks and an MCP server.
Quickstart
# 1. Install
pip install cdms
# 2. Initialize
cdms init --scope user
# 3. Verify
cdms doctor
# 4. Restart Claude Code and approve the 'cdms-memory' MCP server
That's it. CDMS captures your sessions and builds memory automatically.
Check that it's working:
cdms stats # see what's been captured
cdms retrieve "build" # query memory
cdms history # recent timeline
Project-scoped memory:
cdms init --scope project # per-repo store instead of global
Uninstall anytime:
cdms uninstall --scope user --purge
What CDMS Does
Most AI agents treat memory as a bucket: add everything, query everything. That works for personalization, but it doesn't create a personality — it creates a database with your name on it.
CDMS applies a cheap "is this worth keeping?" rule to everything an AI does, lets the rest decay, and consolidates the survivors into a compact sense of self. Feed two CDMS instances the same conversations but with different forgetting policies, and they develop measurably different recall patterns. The differences are what make them distinct.
Observed so far: seeded with ~10k real coding-session turns across three projects, CDMS grew three distinct personalities with zero overlap in their defining traits.
Why CDMS?
Other memory systems accumulate. CDMS discriminates.
| CDMS | Mem0 | Zep / Graphiti | Letta | |
|---|---|---|---|---|
| Core approach | Forgetting-driven | ADD-only accumulation | Temporal knowledge graph | Context window management |
| Creates distinct personalities? | Yes — two instances diverge | No — remembers facts about users | No — tracks entity relationships | Partially — LLM-written persona |
| Runs fully local | Yes (sqlite-vec, 0 GPU) | Partial (needs cloud LLM) | No (Neo4j + cloud LLM) | Partial (DB + vector store + LLM) |
| Forgetting | Salience-gated power-law decay | Premium feature gate | Temporal invalidation only | Summarization |
| Security model | Provenance + trust boundary | API key scoping | None | Tool permissions |
- Want exhaustive recall of everything? Use Mem0.
- Want a temporal knowledge graph? Use Zep.
- Want a full agent OS? Use Letta.
- Want a lightweight daemon that develops a personality through forgetting, running entirely local? Use CDMS.
Architecture
Claude Code CLI
┌───────────────────────┴───────────────────────┐
│ lifecycle hooks (deterministic capture) │ MCP stdio (model-driven)
▼ ▼
SessionStart PostToolUse PreCompact/SessionEnd store · retrieve · history
(inject ctx) (spool turn) (drain + consolidate) list_paths · create_link
│ │ │ │
└──────────────┴──────┬───────┴────────────────────────┘
▼
┌──────────────────────┐
│ CDMS service │ single `cdms` binary
│ ┌────────────────┐ │
│ │ write path │ │ surprisal-gated S0
│ │ read path │ │ hybrid recall + accessibility
│ │ sleep/dream │ │ evict · compete · renorm · gist
│ └────────────────┘ │
└──────────┬───────────┘
▼
SQLite (WAL) + sqlite-vec (cosine KNN) + FTS5 (BM25) · CPU ONNX embedder
~/.local_memory/cdms-a/memory.db (fastembed, 0 VRAM)
Three-tier memory model
L1 mem_episodic raw turn-by-turn logs high decay (hippocampal trace)
│
│ ── "sleep" consolidation ──►
▼
L2 mem_gist PersonaTree relational tuples slow decay (cortical gist)
│
L3 mem_scars pinned crisis-remediation rules no decay (engineering pin)
Core cognitive formulas
Write-time salience (S0):
S0 = G_goal · (S_surprise + C_contingency + W_self-ref + A_affect)
Decay-driven accessibility:
A(m,t) = S0 · (1 + t/τ)^(-β) · min(α^c, Cap)
Power-law forgetting with retrieval reinforcement, capped. 29-day half-life.
Sleep consolidation (runs at rest boundaries):
- Scar elevation — negative crises pinned to L3
- Temporal eviction — decayed episodes dropped
- Hierarchical competition — session/epoch softmax
- Conserved-budget renorm — zero-sum downscaling (SHY-style)
- Mechanical tuple extraction — geometry + lexicon only; LLM never authors identity
What We've Found
CDMS is a research project as much as a tool. Headline results:
-
Differentiation is real. Three real projects (~10k turns) → three distinct psyches, zero trait overlap, stable across 6 consolidation windows. Decay is activity-based — a project you don't touch doesn't lose its personality.
-
Memory steers recall, not disposition. Injected memory reliably steers recall on every model of a 5-model panel. But two opposite temperaments produce overlapping choices — disposition appears to live in the model's weights, not in retrievable context.
-
Enriched phenotype works. Gist exemplars + flashbulb floor raised behavioral adherence 1.67→3.67 and rule-citation 9×, for bounded preamble cost.
Full research with methodology and caveats: docs/.
Claude Code Integration
CDMS hooks into Claude Code two ways:
1. Lifecycle hooks (registered in .claude/settings.json):
| Hook | Action |
|---|---|
SessionStart |
Injects guardrails + PersonaTree as read-only context |
UserPromptSubmit |
Spools user intent |
PostToolUse |
Spools tool trajectory + outcome (~100ms) |
PreCompact |
Drains spool + ingests before compaction |
SessionEnd |
Drains, ingests, runs full consolidation |
2. MCP stdio server (5 tools): store, retrieve, history, list_paths, create_link.
CLI Reference
cdms init initialize store + optionally wire into Claude Code
cdms serve run the MCP stdio server
cdms hook <Event> handle a lifecycle hook (reads JSON on stdin)
cdms consolidate drain queue + run sleep/dream pass
cdms drain ingest spooled events without consolidating
cdms retrieve <q> [-k] query memory from terminal
cdms history [-n] recent episodic timeline
cdms paths show PersonaTree paths
cdms stats store statistics
cdms doctor verify environment + warm embedder
cdms install/uninstall wire/unwire into Claude Code
cdms forget ... delete by --project / --session / --id
cdms ingest ... manually ingest a turn (testing)
Configuration
All parameters in cdms/config.py, overridable via CDMS_* env vars or $CDMS_HOME/config.json.
| Variable | Default | Meaning |
|---|---|---|
CDMS_HOME |
~/.local_memory/cdms-a |
Data directory |
CDMS_EMBED_MODEL |
BAAI/bge-small-en-v1.5 |
CPU ONNX embedding model |
CDMS_DECAY_HALFLIFE_DAYS |
29 |
Forgetting-curve half-life |
CDMS_SALIENCE_BUDGET |
1000 |
Conserved global salience K |
CDMS_RETENTION_FLOOR |
0.10 |
Eviction threshold |
CDMS_CRISIS_THRESHOLD |
3.0 |
S0 bar for scar elevation |
CDMS_RECALL_EXEMPLARS |
true |
Attach e.g. quotes to gists |
CDMS_ENFORCE_PROVENANCE |
true |
Block untrusted content from identity |
Full reference: docs/PARAMETER_BASIS.md.
Privacy, Durability & Hardening
10 adversarial red-team cycles. Key guarantees:
- Right-to-forget —
cdms forgetdeletes across all tiers, scrubs spool,secure_delete - Secret redaction — credentials scrubbed before persistence
- Trust boundary — untrusted content can never poison identity layer
- Crash-safe — WAL + cross-process lock + orphan reclaim + corrupt-DB quarantine
- Embedder integrity — vector-space identity pinned, refused on mismatch
- Operator-only observability — audit UI on localhost, model never sees disposition
Full report: docs/REDTEAM_FINDINGS.md.
Development
git clone https://github.com/Chance6706/contextual_differentiation_memory_service.git
cd contextual_differentiation_memory_service
uv pip install -e ".[dev]"
CDMS_EMBED_BACKEND=hash uv run pytest -q # 229 tests, fully offline
The cognitive core (salience.py) is pure stdlib, fully unit-tested. Tests use a deterministic hash embedder for offline runs.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cdms-0.1.0.tar.gz.
File metadata
- Download URL: cdms-0.1.0.tar.gz
- Upload date:
- Size: 26.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75924e07a7c35a46f48fe2f642164fb4d76c444e547f47be8bc86ca0c4007c7f
|
|
| MD5 |
cbfb9674ec747b971f295801e62965bc
|
|
| BLAKE2b-256 |
592c13a9c23d8600485980d3cbe5dfaa3c5054f517e2fb2d7c3637220a6f5521
|
File details
Details for the file cdms-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cdms-0.1.0-py3-none-any.whl
- Upload date:
- Size: 146.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5930b1b53627b722ccef54e35c80146e64da335417f634cfc3657ad835a7a2e
|
|
| MD5 |
cba1960abda24f868affff84b49bbd85
|
|
| BLAKE2b-256 |
748a9fba0358b89ad6f335f49a00db23505cab490d8d78799915676b29c11454
|