A cross-session memory system for Claude Code. Claude Code has no persistent memory — every conversation starts from zero. PMS changes that through 4 Hooks + 1 MCP search service + 1 indexer, giving Claude Code:
- Identity continuity — auto-loads your profile, writing style, and preferences every session
- Experience accumulation — captures lessons learned from conversations, persists them across sessions
- Knowledge retrieval — search both conversation history and structured knowledge via a unified interface
- Tiered traceability — trace from summaries back to original conversation transcripts
Every Claude memory framework on GitHub does the same thing: store memories, search memories. Index conversation history, structured storage, vector search — everyone has it. But they all stop there. Nobody asks the next question: remembered it, then what?
Most frameworks treat memory as passive — it sits there waiting to be searched. Even when found, it's just text stuffed into context. Whether the agent actually uses it is up to chance.
PMS differs not in the bottom layer (indexing and search — everyone can do that), but in the top layer: how to turn memory into actual agent behavior change.
- Lessons you've written don't just sit in a file — they're written into
CLAUDE.mdas behavioral instructions the agent must follow - Your preferences aren't passively retrieved — they're auto-injected every session start, so the agent knows who you are from the first message
- What references to check and what SOPs to follow in a workflow aren't left to the agent's discretion — the system force-loads them
┌─────────────────────────────────────────────────────┐
│ Memory Consumption Layer │
│ │
│ Three-layer progressive loading │
│ Experience → behavioral instruction pipeline │
│ Workflow-driven active memory consumption │
│ │
├─────────────────────────────────────────────────────┤
│ Memory Infrastructure Layer │
│ │
│ Index Claude Code conversation history │
│ Structured storage + unified search │
│ Session summaries with transcript traceability │
│ │
└─────────────────────────────────────────────────────┘
The infrastructure layer doesn't reinvent the wheel. Claude Code already stores complete conversation transcripts at ~/.claude/projects/ (JSONL format with sessionId, timestamp, full messages). PMS indexes this existing data, combines it with its own structured memory (lessons, preferences, style), and provides unified search across both sources.
Indexer — Scans and chunks both knowledge files and conversation history into SQLite:
| Source | Path Format | Content |
|---|---|---|
| Knowledge base | _me/lessons.md, Growth/strategy.md, etc. |
Structured knowledge |
| Session summaries | .claude/memory/sessions/*.md |
Distilled session highlights |
| Conversation history | cc://{projectDir}/{session}.jsonl |
Raw conversation transcripts |
Indexing is incremental (mtime-based), only processing changed files.
Search engine — Hybrid search with score = 0.7 * vector_score + 0.3 * fts_score:
- FTS5 for English, CJK bigram + LIKE for Chinese
- PMS structured memory weighted 1.2x over raw conversation history
- Zero-result fallback: bigram miss → single-character search (0.5x weight)
- Optional vector search via OpenAI embeddings (degrades gracefully to FTS-only)
MCP tools — Three tools exposed via stdio:
| Tool | Purpose | Example |
|---|---|---|
memory_search |
Fuzzy search across knowledge + history | memory_search("product design lessons") |
memory_search_context |
Search within a specific file | memory_search_context(source="cc://...", query="...") |
memory_get |
Read files or formatted conversations | memory_get(path="cc://project/session.jsonl") |
Tiered retrieval — From summary to source in three steps:
User: "What did I work on yesterday?"
│
▼ memory_search("yesterday")
│
├── Hit: session summary .claude/memory/sessions/20260306-1430.md
│ with transcript_ref: cc://project/abc.jsonl
│
▼ Need more detail?
│
├── memory_search_context(source="cc://...", query="...")
│ → chunk-level results within that conversation
│
└── memory_get(path="cc://...", from=5, lines=10)
→ formatted original conversation transcript
This is where PMS actually differs. The consumption layer has three mechanisms:
1. Three-layer progressive context loading
Layer 0 (auto, every session) Layer 1 (on task identification) Layer 2 (on workflow entry)
───────────────────────────── ────────────────────────────────── ────────────────────────────
Profile, writing style, Domain-specific CLAUDE.md Project context,
preferences, experience index + content-index.md workflow SOPs,
reference materials
- Layer 0: SessionStart Hook injects identity (≤15,000 chars) — the agent knows you from message one
- Layer 1: CLAUDE.md instructions force the agent to load domain knowledge after identifying your task
- Layer 2: Workflow-specific context loaded when entering a defined workflow (e.g., writing a PRD)
2. Experience → behavioral instruction pipeline
Lessons don't just get stored — they get enforced:
Conversation produces insight
→ on-stop Hook detects signal (6 pattern types: correction, insight, error, cognitive shift, method discovery, anti-pattern)
→ session-end Hook extracts + deduplicates
→ pending-learnings.json (staged)
→ next session: user confirms
→ written to lessons.md or domain CLAUDE.md as mandatory instructions
→ agent must follow them in future sessions
3. Workflow-driven active consumption
In defined workflows (e.g., writing a PRD), the system doesn't wait for the agent to "remember" — it force-loads relevant experience:
- Before writing a PRD → load PRD experience rules + six-question pre-thinking framework
- Before growth strategy → load growth domain knowledge + reference materials
- Before processing new material → load target domain's content-index
PMS hooks into four moments of the Claude Code session lifecycle:
Session start Every user message After every AI reply Session end
│ │ │ │
▼ ▼ ▼ ▼
session-start.py user-prompt.py on-stop.py session-end.py
(inject identity) (prevent drift + (capture learning (generate summary +
match experience) signals) extract lessons)
| Hook | Trigger | Key Functions |
|---|---|---|
| session-start | Session begins | Load profile/style/preferences, scan for new files, inject pending learnings |
| user-prompt | Every user message | Re-inject format rules (drift prevention), keyword-match relevant lessons |
| on-stop | Every AI reply | Scan output for learning signals (6 types), track file changes, heartbeat review every 7 rounds |
| session-end | Session ends | Generate structured summary with transcript_ref, extract pending learnings, trigger index sync |
git clone https://github.com/citrolabs/local-personal-memory-system.git
cd local-personal-memory-system
python3 scripts/auto-install.py --name "Your Name"Runs: environment detection → profile setup → template installation → Hook installation → domain setup → Memory Server build → bootstrap analysis → post-install tests.
In Claude Code:
"Please read INSTALL.md and help me install this system"
python3 scripts/init-wizard.pypython3 scripts/install.py --name "Your Name" --domains "Product,Growth"
cd <install-dir>/.claude/memory-server && npm install && npm run buildyour-memory-dir/
├── CLAUDE.md # Agent instructions (system file)
├── config.json # System configuration
├── _me/ # Personal profile (user data — preserved on upgrade)
│ ├── profile.md # Who you are (name, role, stage, projects)
│ ├── writing-style.md # How you write (tone, patterns, banned expressions)
│ ├── preferences.md # How you work (tools, communication style)
│ ├── lessons.md # What you've learned (cross-project experience)
│ ├── workflows.md # How you operate (SOPs)
│ └── response-format.md # How you want responses formatted
│
├── Product/ # Domain workspaces (optional, role-based)
│ ├── PRD/
│ │ ├── CLAUDE.md # Domain-specific experience rules
│ │ ├── content-index.md # Reference material index
│ └── projects/
├── Growth/
│ └── projects/
├── Competitors/
│ └── projects/
├── [8 more domains...]
│
└── .claude/
├── hooks/ # 4 Hook scripts + shared libraries
├── memory/
│ ├── sessions/ # Session summaries (last 30)
│ ├── index.sqlite # FTS5 + optional vector index
│ └── pending-learnings.json # Staged experience awaiting confirmation
└── memory-server/ # MCP search service (TypeScript)
Domains installed based on your role — only what's relevant to you.
files(path, mtime_ms) -- File-level change tracking
chunks(id, path, line_start, line_end, text) -- Text chunks
chunks_fts(text) -- FTS5 full-text index
vec_chunks(chunk_id, embedding) -- Vector index (optional)
session_refs(summary_path, transcript_ref) -- Summary → transcript mapping| Principle | Implementation |
|---|---|
| Fail-open | All Hooks wrapped in try-catch — errors never block conversations |
| Incremental | Indexer uses mtime detection, only processes changed files |
| Layered loading | Layer 0 auto-injects identity; Layer 1/2 load on demand — no token waste |
| Dual-path degradation | Summaries: structured block preferred, regex fallback; Search: vector preferred, FTS5 fallback |
| Pointers, not copies | Session summaries reference transcripts via transcript_ref, never duplicate full text |
| User/system separation | _me/ and projects/ are user data — upgrades never overwrite them |
- Claude Code CLI
- Python 3.8+
- Node.js 18+ (for memory-server)
- Optional: OpenAI API Key (enables vector search)
python3 scripts/verify-installation.py /path/to/install-dirSupports --fix for auto-repair and --json for machine-readable output.
# Python tests
pytest tests/ -v
# TypeScript tests
cd core/memory-server && npm test
# End-to-end
bash tests/test_e2e.shPMS's memory consumption layer can be fully integrated into OpenClaw — identity files + Skill + Plugin (4 automated hooks). The complete integration gives your OpenClaw agent:
- Identity continuity — knows who you are from the first message of every session
- Search-first behavior — searches accumulated lessons before answering substantive questions
- Automatic experience capture — 6 types of learning signals detected and crystallized into behavioral rules
- Drift prevention — style rules re-injected every message, heartbeat reviews every 7 rounds
- Session summarization — structured summaries generated automatically at session end
# 1. Install PMS
git clone https://github.com/citrolabs/local-personal-memory-system.git
cd local-personal-memory-system
python3 scripts/auto-install.py --name "Your Name"
# 2. Copy identity templates to your OpenClaw project
cp integrations/openclaw/templates/MEMORY.md /path/to/your/project/
cp -r integrations/openclaw/templates/_me/ /path/to/your/project/memory/
# 3. Install Skill + Plugin
cp integrations/openclaw/skill/SKILL.md /path/to/openclaw/skills/personal-memory-consumption/SKILL.md
python3 integrations/openclaw/plugin/setup.py --pms-home /path/to/your/pms-installFull guide: docs/integration-openclaw.md | Design rationale: docs/philosophy.md
- INSTALL.md — AI Agent installation guide
- VERIFY.md — Post-install verification checklist
- docs/architecture.md — System internals
- docs/customization.md — Extension guide
- docs/upgrade.md — Upgrade procedures
- docs/philosophy.md — Why Memory Stored ≠ Memory Used
- docs/integration-openclaw.md — OpenClaw integration guide