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
docs: add Status column + prune superseded rows from "Still ahead"
Every remaining row in "Still ahead of upstream" now carries a status
so the reader can tell at a glance whether each change is being
upstreamed, pending a PR, or deliberately fork-local.
Dropped:
- "Guard ChromaDB 1.5.x metadata-mismatch segfault" — this row was
overstated. The memory file for today's debugging notes that the
try-get/except-create pattern is defensive code that never
reproduced a specific crash (the actual crashes traced to HNSW
drift). Leaving it in "Still ahead" implied an upstream-candidate
fix, which it isn't. Code stays in place as defensive, but the
README no longer claims it as a fork-ahead feature.
Moved to Superseded:
- "Stale HNSW mtime detection + mempalace_reconnect" — upstream took
a different approach in MemPalace#757. Our broader inode+mtime detection
and the mempalace_reconnect MCP tool remain as fork-local
convenience; they're just not "ahead of upstream" anymore.
Statuses now populated:
- Linked PR number for the 7 changes with active upstream PRs
(MemPalace#659, MemPalace#660, MemPalace#661, MemPalace#673 with APPROVED note, MemPalace#999, MemPalace#1000, MemPalace#1005).
- "PR pending" for 3 items that are good candidates but unfiled:
epsilon mtime comparison, max_distance parameter, tool output
mining.
- "fork-only" for 2 items we keep intentionally without pitching
upstream: .blob_seq_ids_migrated marker (narrow), bulk_check_mined
(complementary to upstream's MemPalace#784 file-locking).
Legend sentence added above the table explains the three status
values. 42 README-claim tests pass.
|**Reliability**| Stale HNSW mtime detection + `mempalace_reconnect` MCP tool |`mcp_server.py`|
123
-
|**Reliability**|Guard ChromaDB 1.5.x metadata-mismatch segfault — `try get → fallback create` instead of `get_or_create_collection(metadata=…)`|`backends/chroma.py`, `mcp_server.py`|
124
-
|**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 |`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) |`backends/chroma.py`|
126
-
|**Reliability**|`meta or {}` None-metadata guards across 8 read-path loops — ChromaDB's `query()`/`get()` return `None` entries for drawers with no stored metadata, which crashed `searcher.py` (CLI + API + closet-boost), `miner.status()`, and 4 MCP handlers (`tool_status`, `tool_list_wings`, `tool_list_rooms`, `tool_get_taxonomy`) with `AttributeError` mid-tally |`searcher.py`, `miner.py`, `mcp_server.py`|
127
-
|**Performance**|`bulk_check_mined()` — paginated pre-fetch for concurrent mining |`palace.py`, `miner.py`|
128
-
|**Performance**| Graph cache — 60s TTL, invalidated on writes |`palace_graph.py`|
|**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) |`searcher.py`|
132
-
|**Hooks**| Silent save mode — direct Python API, deterministic, zero data loss |`hooks_cli.py`|
133
-
|**Hooks**| Tool output mining — per-tool formatting strategies in `normalize.py`|`normalize.py`|
Status legend: a PR number means there's an open upstream PR for the change; **PR pending** means the fork has the change but no PR has been filed yet; **fork-only** means the fork keeps it intentionally but isn't pitching it upstream.
120
+
121
+
|Area|Change | Status | Files|
122
+
|---|---|---|---|
123
+
|**Reliability**|Epsilon mtime comparison (`abs() < 0.01` vs `==`) prevents re-mining | PR pending (verify vs current `develop` first) |`palace.py`, `miner.py`|
124
+
|**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`|
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
+
|**Reliability**|`meta or {}` None-metadata guards across 8 read-path loops — ChromaDB's `query()`/`get()` return `None` entries for drawers with no stored metadata, which crashed `searcher.py` (CLI + API + closet-boost), `miner.status()`, and 4 MCP handlers (`tool_status`, `tool_list_wings`, `tool_list_rooms`, `tool_get_taxonomy`) with `AttributeError` mid-tally |[#999](https://github.com/milla-jovovich/mempalace/pull/999)|`searcher.py`, `miner.py`, `mcp_server.py`|
127
+
|**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
+
|**Performance**| Graph cache — 60s TTL, invalidated on writes |[#661](https://github.com/milla-jovovich/mempalace/pull/661)|`palace_graph.py`|
|**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`|
132
+
|**Hooks**| Silent save mode — direct Python API, deterministic, zero data loss |[#673](https://github.com/milla-jovovich/mempalace/pull/673) · APPROVED externally 2026-04-12 |`hooks_cli.py`|
- Batch ChromaDB writes — upstream has file-level locking for concurrent agents via [#784](https://github.com/milla-jovovich/mempalace/pull/784)
157
157
- Inline transcript mining in hooks — upstream uses `mempalace mine` in background
158
+
- Stale HNSW mtime detection — upstream took a different approach in [#757](https://github.com/milla-jovovich/mempalace/pull/757); fork's broader inode+mtime detection and `mempalace_reconnect` MCP tool stay as fork-local convenience
0 commit comments