You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+12-9Lines changed: 12 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@
8
8
9
9
---
10
10
11
-
Fork of [MemPalace v3.3.1](https://github.com/milla-jovovich/mempalace/releases/tag/v3.3.1), tracking `upstream/develop`. Running in production since 2026-04-09 — currently 152,682 drawers across 68 rooms in 22 wings, 8 open PRs upstream (#999 merged 2026-04-18). See upstream README for full feature docs.
11
+
Fork of [MemPalace v3.3.1](https://github.com/milla-jovovich/mempalace/releases/tag/v3.3.1), tracking `upstream/develop`. Running in production since 2026-04-09 — currently 152,682 drawers across 68 rooms in 22 wings, 8 open PRs upstream (#999 merged 2026-04-18; #681/#1000/#1023 merged 2026-04-19). See upstream README for full feature docs.
12
12
13
13
What this fork adds that you won't get from upstream yet: a **deterministic silent-save hook architecture** (zero data loss, `systemMessage` notification), **ChromaDB 1.5.x hardening** (`quarantine_stale_hnsw` drift recovery, segfault-trigger guards, 8-site `None`-metadata safety), and **search that never silently misses** (`search_memories` returns warnings + sqlite BM25 top-up + `available_in_scope` so callers can see what they aren't getting). Full list below.
14
14
@@ -122,17 +122,15 @@ Status legend: a PR number means there's an open upstream PR for the change; **P
122
122
|---|---|---|---|
123
123
|**Reliability**| Skip `_fix_blob_seq_ids` sqlite open after first successful migration via `.blob_seq_ids_migrated` marker — opening sqlite3 against a live ChromaDB 1.5.x file corrupts the next PersistentClient | fork-only (narrow chromadb 1.5.x debugging path) |`backends/chroma.py`|
124
124
|**Reliability**|`_get_client()` tries `get_collection` before `create_collection` — `get_or_create_collection` segfaults ChromaDB 1.5.x when the existing collection's metadata differs from the call-site metadata | fork-only |`backends/chroma.py`|
125
-
|**Reliability**|`quarantine_stale_hnsw()` helper — renames HNSW segments whose `data_level0.bin` is 1h+ older than `chroma.sqlite3`, sidesteps read-path SIGSEGV from dangling neighbor pointers (same failure mode as neo-cortex-mcp#2) |[#1000](https://github.com/milla-jovovich/mempalace/pull/1000) · closes #823|`backends/chroma.py`|
126
125
|**Reliability**|`quarantine_stale_hnsw()` should also validate `index_metadata.pickle` integrity — a process killed mid-write leaves a corrupt file with zero mtime drift, so the 1h threshold doesn't fire and the next palace open segfaults. Fix: attempt to deserialize the file in the quarantine check and quarantine on failure regardless of mtime. | PR pending |`backends/chroma.py`|
127
126
|**Performance**|`bulk_check_mined()` — paginated pre-fetch for concurrent mining | fork-only (complementary to upstream's file-locking in [#784](https://github.com/milla-jovovich/mempalace/pull/784)) |`palace.py`, `miner.py`|
128
127
|**Performance**| Graph cache — 60s TTL, invalidated on writes |[#661](https://github.com/milla-jovovich/mempalace/pull/661)|`palace_graph.py`|
|**Performance**|`miner.status()` paginates `col.get()` in 10 K-drawer batches — upstream's single `col.get(limit=total)` hits SQLite's max-variable limit on palaces with many thousands of drawers |PR pending|`miner.py`|
129
+
|**Performance**|`miner.status()` paginates `col.get()` in 10 K-drawer batches — upstream's single `col.get(limit=total)` hits SQLite's max-variable limit on palaces with many thousands of drawers |[#1036](https://github.com/milla-jovovich/mempalace/pull/1036) · closes #802, #1015|`miner.py`|
131
130
|**Config**| Configurable chunking parameters — `chunk_size` (default 800 chars), `chunk_overlap` (100), `min_chunk_size` (50) written to `config.json` and exposed via `MempalaceConfig` properties |[#1024](https://github.com/milla-jovovich/mempalace/pull/1024)|`config.py`, `miner.py`|
132
131
|**Search**| Warnings + sqlite BM25 top-up when vector underdelivers — `search_memories` returns `warnings: [...]` and `available_in_scope: N` so callers see why recall was partial; fallback hits tagged `matched_via: "sqlite_bm25_fallback"`. The palace never silently returns fewer results than the scope contains (sibling of #951, addresses read-side of #823) |[#1005](https://github.com/milla-jovovich/mempalace/pull/1005)|`searcher.py`|
133
132
|**Hooks**| Silent save mode — direct Python API, deterministic, zero data loss; extracts 2–3 topic words from recent messages for the diary title; optional desktop toast via `notify-send`|[#673](https://github.com/milla-jovovich/mempalace/pull/673) · APPROVED externally 2026-04-12 |`hooks_cli.py`|
134
133
|**Hooks**|`mempal_save_hook.sh` auto-detects Python — checks `MEMPAL_PYTHON` env var, then repo venv at `../../venv/bin/python3`, then system `python3`; no hardcoded path required. Same pattern applied to `.claude-plugin/` stop and precompact hooks. | fork-only |`hooks/mempal_save_hook.sh`, `.claude-plugin/hooks/mempal-stop-hook.sh`, `.claude-plugin/hooks/mempal-precompact-hook.sh`|
135
-
|**Hooks**| PID file guard prevents stacking mine processes — `_ingest_transcript` and `_maybe_auto_ingest` both check `hook_state/mine.pid` via `os.kill(pid, 0)` before spawning; without this, every hook fire (every 15 messages) launched a new `mempalace mine` that piled onto previous ones still running (observed: 4 concurrent mines at ~770% CPU) |[#1023](https://github.com/milla-jovovich/mempalace/pull/1023)|`hooks_cli.py`|
136
134
|**Hooks**| Honor silent_save when `stop_hook_active:true` — Claude Code 2.1.114 sets the flag on every plugin-dispatched Stop fire after the first, and the legacy block-mode loop guard was suppressing every subsequent auto-save (silent, no log entry, marker stuck). Fixed to only skip on the flag in block mode |[#1021](https://github.com/milla-jovovich/mempalace/pull/1021)|`hooks_cli.py`|
137
135
|**Hooks**| Write hook JSON to real stdout via `sys.modules` lookup — `mempalace.mcp_server` redirects stdout→stderr at import to protect MCP stdio from ChromaDB C-level noise; `_output()` checks `sys.modules` for an already-loaded `mcp_server` and reuses its `_REAL_STDOUT_FD`, otherwise writes directly to fd 1. Avoids triggering the redirect as a side effect. |[#1021](https://github.com/milla-jovovich/mempalace/pull/1021)|`hooks_cli.py`|
138
136
|**Features**| Diary wing routing — derive project wing from transcript path; `tool_diary_write` and `tool_diary_read` accept an optional `wing` parameter |[#659](https://github.com/milla-jovovich/mempalace/pull/659)|`hooks_cli.py`, `mcp_server.py`|
@@ -142,6 +140,9 @@ Status legend: a PR number means there's an open upstream PR for the change; **P
142
140
### Merged upstream (post-v3.3.1)
143
141
144
142
-`None`-metadata guards across 8 read-path loops — `searcher.py` (CLI + API + closet-boost), `miner.status()`, and 4 MCP handlers ([#999](https://github.com/milla-jovovich/mempalace/pull/999), merged 2026-04-18)
- PID file guard prevents stacking `mempalace mine` processes on every hook fire ([#1023](https://github.com/milla-jovovich/mempalace/pull/1023), merged 2026-04-19). Includes the cross-platform PID-check fix: `os.kill(pid, 0)` on Windows *terminates* the target via `TerminateProcess` instead of acting as an existence probe — replaced with `ctypes``OpenProcess`/`GetExitCodeProcess`.
145
+
- Unicode checkmark replaced with ASCII `+` for Windows encoding ([#681](https://github.com/milla-jovovich/mempalace/pull/681), closes #535, merged 2026-04-19)
145
146
146
147
### Merged upstream (in v3.3.0)
147
148
@@ -270,14 +271,16 @@ Tools and patterns we're evaluating for the two open problems above. Not competi
0 commit comments