Metadata-Version: 2.4
Name: limen-memory
Version: 1.2.6
Summary: Personal memory system with knowledge graph, novelty-gated learning, and context-influenced adaptation
License: MIT
Author: dlattka
Author-email: dennislattka@gmail.com
Requires-Python: >=3.11,<3.14
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Provides-Extra: dev
Provides-Extra: mcp
Provides-Extra: ollama
Provides-Extra: openai
Requires-Dist: bandit[toml] (>=1.7) ; extra == "dev"
Requires-Dist: click (>=8.0)
Requires-Dist: mcp[cli] (>=1.0,<2.0) ; extra == "mcp"
Requires-Dist: mypy (>=1.10) ; extra == "dev"
Requires-Dist: numpy (>=1.24)
Requires-Dist: ollama (>=0.3) ; extra == "ollama"
Requires-Dist: openai (>=1.0) ; extra == "openai"
Requires-Dist: pre-commit (>=3.7) ; extra == "dev"
Requires-Dist: pytest (>=7.0) ; extra == "dev"
Requires-Dist: pytest-asyncio (>=0.23) ; extra == "dev"
Requires-Dist: pytest-cov (>=4.0) ; extra == "dev"
Requires-Dist: pytest-xdist (>=3.0) ; extra == "dev"
Requires-Dist: pyyaml (>=6.0)
Requires-Dist: ruff (>=0.4) ; extra == "dev"
Requires-Dist: tox (>=4.0) ; extra == "dev"
Requires-Dist: types-pyyaml (>=6.0) ; extra == "dev"
Description-Content-Type: text/markdown

# Limen-memory

Personal memory system for Claude Code. Persistent memory with a unified knowledge graph, novelty-gated learning, and context-influenced adaptation.

Limen-memory observes how you work, identifies patterns, and adapts behavior over time — without being told to. It integrates with Claude Code through hooks (automatic session-boundary behavior) and an MCP server (on-demand tools during conversations).

## How It Works

Limen-memory runs a continuous learning loop:

1. **Session start** — A hook loads relevant context (session bridge, reflections, user facts, strategies, predictions) and injects it into the conversation.
2. **During conversation** — MCP tools let Claude record user facts (`limen_learn`), search memories (`limen_query`), load topic-specific context (`limen_context`), and more.
3. **Session end** — A hook analyzes the conversation transcript through the reflection pipeline: LLM-driven insight extraction, novelty filtering, embedding generation, knowledge graph connections, fact extraction, and strategy observations.
4. **Background maintenance** — A scheduler handles consolidation, aging, pruning, and backup on a priority-based schedule, triggered opportunistically at session boundaries.

Over time, limen-memory builds an increasingly accurate model of who you are and how to work with you.

## Installation

```bash
# Clone and install
git clone https://github.com/Taderich73/limen-memory.git
cd limen-memory
poetry install

# Initialize database, config, skill, hooks, and MCP server
limen-memory init
```

`limen-memory init` does the following:
- Creates the data directory (`~/.limen-memory/`) and SQLite database
- Writes default config at `~/.limen-memory/config.yaml`
- Installs the SKILL.md to `~/.claude/skills/limen-memory/`
- Copies hook scripts to `~/.claude/hooks/` and registers them in `~/.claude/settings.json`
- Registers the MCP server in `~/.claude/settings.json` under `mcpServers.limen-memory`

### Requirements

- Python >=3.11, <3.14
- [Poetry](https://python-poetry.org/) >=2.0
- An embedding provider configured (OpenAI API key or Ollama running locally) for the reflection pipeline
- Claude Code CLI (for hook and MCP integration)

## Configuration

Limen-memory is configured via environment variables, `~/.limen-memory/config.yaml`, or constructor arguments (in that priority order).

| Variable | Description | Default |
|----------|-------------|---------|
| `LIMEN_EMBEDDING_PROVIDER` | Embedding provider (`openai` or `ollama`) | *(required for reflection)* |
| `LIMEN_EMBEDDING_API_KEY` | API key for OpenAI embeddings | *(required for openai provider)* |
| `LIMEN_DATA_DIR` | Data directory | `~/.limen-memory/` |
| `LIMEN_CLAUDE_MODEL` | Claude model for LLM operations | `sonnet` |
| `LIMEN_CLAUDE_TIMEOUT` | LLM timeout in seconds | `120` |

## Claude Code Integration

### MCP Server

The MCP server exposes limen-memory's memory system as native tools. Claude Code and Claude.ai can call these tools directly during conversations.

**13 tools:**

| Tool | Description |
|------|-------------|
| `limen_context` | Load tiered session context, optionally focused on a topic |
| `limen_learn` | Record a user fact (idempotent on category+key) |
| `limen_reflect` | Add a single reflection with novelty gating |
| `limen_query` | Hybrid search over reflections (semantic + keyword + recency + confidence + graph) |
| `limen_status` | System health check and database statistics |
| `limen_user_profile` | View user facts, optionally filtered by category |
| `limen_interaction_profile` | View behavioral model dimensions (-1.0 to 1.0 scale) |
| `limen_search_conversations` | Full-text search over conversation summaries |
| `limen_graph_inspect` | Inspect knowledge graph — global diagnostics or specific node edges |
| `limen_deprecate` | Soft-delete a reflection |
| `limen_consolidate` | Run LLM-driven memory consolidation (dedup, merge, validate) |
| `limen_scheduler_tick` | Execute one scheduler maintenance task |
| `limen_reflect_transcript` | Reflect on a full conversation transcript |

**4 read-only resources:** `limen://profile`, `limen://strategies`, `limen://predictions`, `limen://status`.

The MCP server is registered automatically by `limen-memory init` and can also be started manually:

```bash
limen-memory mcp                          # stdio transport (default)
limen-memory mcp --transport streamable-http --port 8000  # HTTP transport
```

### Hooks

Limen-memory uses Claude Code hooks so the memory loop runs without manual invocation:

**SessionStart hook** (`limen-memory-session-start.py`) — Fires on `startup` and `resume`. Calls `limen-memory context` and prints the output to stdout, which Claude Code injects as conversation context. Also spawns a background `scheduler-tick` for opportunistic maintenance.

**Stop hook** (`limen-memory-stop.py`) — Fires at session end. Skips trivial conversations (fewer than 10 transcript lines). Spawns `limen-memory reflect-transcript` as a background process with lock-file concurrency protection. Also spawns `scheduler-tick`.

Hooks are designed to never crash a session — all exceptions are caught and the process exits cleanly.

### Skill

The SKILL.md file (installed to `~/.claude/skills/limen-memory/`) teaches Claude when and how to use each MCP tool during conversations.

### Uninstalling

```bash
limen-memory uninstall          # or: limen-memory uninstall-hooks
```

Removes hook scripts from `~/.claude/hooks/`, hook entries from `~/.claude/settings.json`, and the MCP server entry from `~/.claude/settings.json`.

## CLI Reference

All commands support `--json` for machine-readable output.

### Core Commands

| Command | Description |
|---------|-------------|
| `limen-memory init` | Initialize database, config, skill, hooks, and MCP server |
| `limen-memory status` | Database stats and system health |
| `limen-memory query <topic>` | Search reflections (hybrid semantic + keyword scoring) |
| `limen-memory context <topic>` | Load tiered context with rule-engine processing |
| `limen-memory mcp` | Start the MCP server (stdio or streamable-http transport) |

### Learning & Reflection

| Command | Description |
|---------|-------------|
| `limen-memory learn -c CAT -k KEY -v VAL` | Record a user fact |
| `limen-memory add-reflection -s SECTION -c CONTENT` | Add a reflection with novelty filtering |
| `limen-memory reflect <session-file>` | Run full reflection pipeline on a conversation |
| `limen-memory reflect-transcript <path>` | Parse JSONL transcript and run reflection (used by hooks) |

### Querying

| Command | Description |
|---------|-------------|
| `limen-memory reflections` | List active reflections |
| `limen-memory user-profile` | Show user facts by category |
| `limen-memory interaction-profile` | Interaction profile dimensions (-1.0 to +1.0) |
| `limen-memory search <query>` | Full-text search over conversation summaries |
| `limen-memory graph-inspect` | Knowledge graph diagnostics |
| `limen-memory session-history` | Recent session contexts |
| `limen-memory run-rules <query>` | Run rule engine on a query |

### Maintenance

| Command | Description |
|---------|-------------|
| `limen-memory scheduler-tick` | Execute highest-priority overdue task |
| `limen-memory scheduler-status` | Show scheduler state and next-due tasks |
| `limen-memory consolidate` | Memory consolidation (dedup, merge, validate) |
| `limen-memory review-strategies` | Strategy review (promote, decay, merge) |
| `limen-memory cross-analyze` | Detect patterns across conversations |
| `limen-memory validate-predictions` | Check prediction edges against evidence |
| `limen-memory synthesize-profile` | Rebuild interaction profile from evidence |
| `limen-memory age` | Age stale reflections and edges |
| `limen-memory prune` | Deprecate orphaned graph relationships |
| `limen-memory backup` | Backup database (keeps last 5) |

### Data Management

| Command | Description |
|---------|-------------|
| `limen-memory deprecate <id>` | Soft-delete a reflection |
| `limen-memory create-edge --source ID --target ID --type T` | Create a knowledge graph edge |
| `limen-memory save-session --id ID --topic T` | Save a session context |
| `limen-memory uninstall` | Remove hooks and MCP server from Claude Code |

## Architecture

```
CLI (cli.py)     ──┐
                    ├──→ Services → Stores → SQLite (WAL mode)
MCP Server (mcp/)──┘        ↕
                       Rule Engine
```

Both CLI and MCP server share the same service layer via `service_factory.create_services()`.

**Data stores**: MemoryStore (reflections, facts, sessions), GraphStore (knowledge graph), EmbeddingStore (vectors), ConversationStore (FTS5 search), StrategyStore, ProfileStore.

**Services**: ReflectionService (full pipeline), ContextLoader (tiered retrieval with 6000-char budget), NoveltyFilter (embedding similarity gates with continuous temporal decay), ConsolidationService (LLM-driven dedup), Scheduler (background tasks), CrossAnalyzer, ProfileService, StrategyService.

**Rule engine**: Priority-based execution across 4 phases (PRE_RETRIEVAL → POST_RETRIEVAL → PRE_RESPONSE → POST_RESPONSE). Five rules: ContradictionDetection, HighConfidenceInjection, BehavioralDirective, PreferenceApplication, PredictionSurfacing.

### Key Design Patterns

- **Dual-write** — Every entity save registers a GraphNode in the knowledge graph
- **Novelty gating** — New reflections pass through embedding + LLM hybrid filtering
- **Soft deletes only** — Deprecation via `deprecated_at`, never hard deletion
- **Evidence accumulation** — Confidence grows with momentum-based updates (consistent evidence accelerates, oscillating stalls); decays via time-continuous exponential aging
- **Hybrid search** — Semantic (0.35) + keyword (0.20) + recency (0.20, exponential with 90-day half-life) + confidence (0.15) + graph connectivity (0.10)
- **Activity-pressure aging** — Reflections in active topic areas age faster; high-confidence reflections can begin aging when superseded

### Theoretical Foundation

The memory architecture is informed by computational neuroscience research on dual memory systems — the discovery that biological working memory and episodic memory solve the same problem through fundamentally different mechanisms. Limen implements this as a four-stage pipeline: fast approximate linking at write time, novelty-gated persistence, background LLM validation (consolidation), and relevance-gated retrieval that only surfaces knowledge when contextually relevant.

The decay, confidence, and forgetting mechanisms are inspired by the Titans paper ("Learning to Memorize at Test Time", arXiv:2501.00663). While the neural architecture (MAC/MAG/MAL) is specific to attention-based sequence models, the underlying update equations — surprise-as-gradient, momentum-based accumulation, and data-dependent forgetting — map onto limen-memory's novelty filtering, confidence evolution, and aging systems as continuous exponential functions replacing discrete step functions.

## Development

```bash
make dev          # Full dev environment (poetry + pre-commit hooks)
make test         # Run tests (tox -e py311)
make lint         # Lint (tox -e lint)
make mypy         # Type check (tox -e typecheck)
make typecheck    # Type check (alias for make mypy)
make format       # Auto-format (tox -e format)
make all          # All quality checks
make clean        # Remove build artifacts
tox -e coverage   # Tests with coverage (80% threshold)
tox -e bandit     # Security scan
```

Tests use in-memory SQLite. Shared fixtures in `tests/conftest.py` provide pre-built model instances and store instances. Test organization mirrors source structure, with `tests/test_mcp/` covering server lifecycle, tool handlers, and service factory.

## License

MIT

