Files
mempalace/mempalace
lcatlett 8472d553a3 fix(hooks): treat absent ~/.mempalace as auto-save off
When the user removes ~/.mempalace/ (a strong "do not auto-capture"
signal), the next hook fire would silently recreate the entire dir
hierarchy and ingest existing transcripts:

1. _log() at hooks_cli.py:148 unconditionally calls
   STATE_DIR.mkdir(parents=True, exist_ok=True), so the act of
   writing the hook log line recreated ~/.mempalace/hook_state/
2. With no config file present, hook_stop_auto_save and
   hook_precompact_auto_save defaulted to True (no override to read)
3. The full save path then ran, materializing palace/, wal/,
   knowledge_graph.sqlite3, and N drawers from existing transcripts
   in ~/.claude/projects/*.jsonl

All four entry points (hook_stop, hook_precompact, hook_session_start,
and _log itself) now check a new PALACE_ROOT = Path.home() / ".mempalace"
constant first and short-circuit (returning {} on stdout, never logging)
when the dir is absent. The user-removable directory is now a kill-switch.

Five unit tests in tests/test_hooks_cli.py cover: hook_stop /
hook_precompact / hook_session_start do not create the dir when absent;
_log() does not create it when absent; existing dir proceeds normally
(regression).

Caught in the wild on a downstream fork: ~146 drawers materialized in
under a second after a deliberate `rm -rf ~/.mempalace/`, into a planning
session that was explicitly not meant to be captured.
2026-05-02 20:33:58 -04:00
..
2026-04-13 18:25:01 -07:00
2026-04-13 18:25:01 -07:00
2026-04-13 18:25:01 -07:00
2026-04-23 16:44:22 -07:00

mempalace/ — Core Package

The Python package that powers MemPalace. All modules, all logic.

Modules

Module What it does
cli.py CLI entry point — routes to mine, search, init, compress, wake-up
config.py Configuration loading — ~/.mempalace/config.json, env vars, defaults
normalize.py Converts 5 chat formats (Claude Code JSONL, Claude.ai JSON, ChatGPT JSON, Slack JSON, plain text) to standard transcript format
miner.py Project file ingest — scans directories, chunks by paragraph, stores to ChromaDB
convo_miner.py Conversation ingest — chunks by exchange pair (Q+A), detects rooms from content
searcher.py Semantic search via ChromaDB vectors — filters by wing/room, returns verbatim + scores
layers.py 4-layer memory stack: L0 (identity), L1 (critical facts), L2 (room recall), L3 (deep search)
dialect.py AAAK compression — entity codes, emotion markers, 30x lossless ratio
knowledge_graph.py Temporal entity-relationship graph — SQLite, time-filtered queries, fact invalidation
palace_graph.py Room-based navigation graph — BFS traversal, tunnel detection across wings
mcp_server.py MCP server — 19 tools, AAAK auto-teach, Palace Protocol, agent diary
onboarding.py Guided first-run setup — asks about people/projects, generates AAAK bootstrap + wing config
entity_registry.py Entity code registry — maps names to AAAK codes, handles ambiguous names
entity_detector.py Auto-detect people and projects from file content
general_extractor.py Classifies text into 5 memory types (decision, preference, milestone, problem, emotional)
room_detector_local.py Maps folders to room names using 70+ patterns — no API
spellcheck.py Name-aware spellcheck — won't "correct" proper nouns in your entity registry
split_mega_files.py Splits concatenated transcript files into per-session files

Architecture

User → CLI → miner/convo_miner → ChromaDB (palace)
                                     ↕
                              knowledge_graph (SQLite)
                                     ↕
User → MCP Server → searcher → results
                  → kg_query → entity facts
                  → diary    → agent journal

The palace (ChromaDB) stores verbatim content. The knowledge graph (SQLite) stores structured relationships. The MCP server exposes both to any AI tool.