v3.6.0 — secure remote serving, temporal facts, and resilient recovery
This release makes MemPalace substantially easier to operate beyond a single local process while tightening the guarantees that protect long-lived palaces. A new secure-by-default mempalace serve path supports authenticated remote and team deployments with TLS and read-only enforcement; an opt-in Milvus backend adds embedded, self-hosted, and managed storage choices; and atomic knowledge-graph supersession gives changing facts precise temporal boundaries. Conversation chronology, mined-session graph derivation, project exclusions, and LaTeX coverage deepen ingestion, while startup, metadata, and recovery work make large palaces faster and safer. The MCP surface now comprises 36 tools.
Features
- Turnkey secure remote / team server.
mempalace serveexposes the full MCP surface over HTTP with secure defaults: non-loopback binds require a bearer token, generated tokens are stored with restrictive permissions and passed through the child environment rather than argv, native TLS 1.2+ is supported, and--read-onlyboth hides and refuses mutating tools. Docker Compose, systemd, and environment templates are included. (#1877, #1897, #1900) - Milvus storage backend. The new opt-in
milvusbackend supports Milvus Lite, self-hosted Milvus, and Zilliz Cloud, with COSINE vector search, native BM25 lexical search for new collections, namespace isolation, target-mismatch protection, and an optional dependency extra. (#1899) - Atomic knowledge-graph fact replacement.
supersede()/mempalace_kg_supersedecloses an open fact and opens its successor at one shared instant. Temporal queries use half-open intervals at timestamp precision while preserving whole-day semantics for date-only facts. (#1913) - Conversation chronology is preserved. Drawers retain transcript time as
authored_at, search results expose it, exact hybrid-score ties prefer recently authored content, and an idempotent dry-run-first backfill updates existing palaces without re-embedding.mempalace_list_drawersalso gainssince/beforebounds. (#1890, #1891) - Mined sessions populate the associative graph. A precision-biased structural extractor records code symbols, URLs, paths, and qualified identifiers as drawer entities; conversation mining derives hallways from them, exposed by the new
mempalace hallwaysCLI command. (#1894, #1895) - Per-project mining exclusions through
exclude_patternsinmempalace.yaml, without changing corrected--limitsemantics. (#1213, #1953) - LaTeX project coverage for
.texand.bibprose sources. (#1901) - Shared daemon write-routing policy provides one consistent policy seam for routing write-capable clients toward the local daemon. (#2027)
- Checkpoint author attribution now preserves the filing agent instead of hard-coding every checkpoint drawer as
checkpoint. (#2023, #2034)
Performance
- MCP initialization no longer waits for palace-wide integrity work. stdio answers
initializeimmediately while startup preflight runs in the background; concurrent tools join the same verdict instead of duplicating work. Large-palace startup SQLite probes are bounded, while repair preflights remain strict. (#1911, #1987) - Qdrant metadata counts use server-side facets instead of fetching and tallying every record; the embedding wrapper forwards facet and bulk-metadata capabilities correctly. (#1868, #1898)
- pgvector metadata-only fetches omit document payloads, reducing transfer and decoding work. (#1892)
Bug Fixes
- Chroma recovery distinguishes derived-index damage from data loss. Valid all-layer-0 HNSW segments are no longer quarantined repeatedly; isolated FTS5 corruption is rebuilt from intact content during repair and after mining; embedded NUL bytes are sanitized before reaching ChromaDB. (#1716, #1872, #1878, #1927, #1928)
- SQLite recovery is bounded, atomic, and honest. Integrity checks wait out transient writer contention; recovery archives use atomic rename;
repair --mode from-sqliterebuilds FTS5, vacuums, and requires a clean finalPRAGMA quick_check; cleanup failures return non-zero instead of printing false success. (#1945, #2015, #2017) - CLI search checks HNSW divergence before opening ChromaDB, routing damaged palaces directly to SQLite BM25 while leaving healthy and non-Chroma backends on their normal path. (#2016)
- Writer leases recover instead of stranding servers read-only. Refused writers retry and promote after a peer exits; status cannot acquire the writer lease; re-entrant holders are released across interruption;
checkpointanddelete_by_sourceare correctly classified as mutations. (#1923, #1930, #1934, #1960, #1970, #1971) - Status reports only checks that actually ran. Non-Chroma backends mark Chroma SQLite integrity as not applicable. (#1931, #1946)
- Conversation transcripts are treated as mutable. Appended or rewritten sessions are purged and re-filed by modification time, while Claude Code
tool-results/sidecars are excluded from scans. (#1957, #2010) - Explicit palace selection scopes derived graph state so mining hallways and tunnels remain beside the selected
--palace. (#2018) - Remote and local server hardening. Non-loopback HTTP requires a token unless explicitly overridden; provider probes cannot reuse ambient external keys before selection; hook transcript and file-copy/repair paths receive stricter validation; importing MCP no longer clobbers root logging; HTTP writes re-enter the palace lock safely; routine disconnects no longer emit tracebacks. (#1859, #1860, #1864, #1885, #2003, #2004)
- Mining and configuration correctness. Oversized files warn visibly, configured
~paths expand consistently, wing slugs handle special characters, and Windows background processes avoid console flashes. (#923, #1852, #1857, #1863, #1865) - Windows
.gitignorehandling uses UTF-8 explicitly, avoiding locale-dependent failures. (#1648) - L1 wake-up prefers the latest moments when importance ties. (#1630)
- Backend detection requires a SQLite magic header, preventing unrelated files from being mistaken for a palace. (#1893, #1896)
Documentation
- Added a storage-backend configuration reference, a remote/team-server deployment guide,
authored_atmigration guidance, and refreshed the OpenClaw integration for the full 36-tool MCP surface. (#1719, #1877, #1890, #1904, #1905)
Internal
- Expanded WAL crash-safety, idempotence, and redaction-path coverage; updated GitHub Actions and Ruff; repaired
uv.lockdrift for Ruff 0.15.20 and Python 3.9 dependency markers. (#1869)
A big thank-you to everyone who contributed to this release. Contributors and first-time contributors are credited below.
What's Changed
- fix: tighten local guards and file handling by @igorls in #1864
- test(wal): cover WAL crash-safety, idempotent setup, and redaction edge paths by @arnoldwender in #1869
- fix: spawn daemon with CREATE_NO_WINDOW to match hook miner (#1783) by @eldar702 in #1857
- fix(cli): add repair rebuild-index alias by @jsiu93 in #1670
- Fix/wing slug special chars by @tp9imka in #1852
- fix(hooks): hide conhost window on Windows in _mine_sync non-daemon path by @davidfi01 in #1863
- fix: expand tilde in palace_path when read from config file by @joesebastian6079 in #1865
- fix(chroma): stop quarantining valid all-layer-0 HNSW segments (#1716) by @igorls in #1872
- fix(repair): auto-heal isolated FTS5 inverted-index corruption (#1596) by @igorls in #1878
- fix(mcp): stop clobbering host app root logger at import (#1860) by @mvalentsev in #1885
- fix(layers): order L1 wake-up by recency (filed_at) so it surfaces the latest moments by @davidglidden in #1630
- fix(cli): force UTF-8 when reading/writing .gitignore in init by @ALaDingAhmad in #1648
- chore(deps): bump actions/checkout from 6 to 7 by @dependabot[bot] in #1882
- chore(deps): bump docker/setup-qemu-action from 3 to 4 by @dependabot[bot] in #1880
- chore(deps): bump docker/setup-buildx-action from 3 to 4 by @dependabot[bot] in #1881
- chore(deps-dev): bump ruff from 0.15.18 to 0.15.20 by @dependabot[bot] in #1883
- fix(backends): require SQLite magic header for chroma + sqlite_exact detect() (#1893) by @messelink in #1896
- fix(pgvector): skip document column for metadata-only fetches (#1840 follow-up) by @messelink in #1892
- feat(convo): preserve authored timestamp from transcripts by @JosefAschauer in #1890
- fix(palace): process-wide mine_palace_lock re-entrancy so the HTTP transport can write by @trongnguyenbinh in #1859
- feat(mcp): add since/before date filter to list_drawers (#1128) by @mvalentsev in #1891
- feat: optimize metadata counting using Qdrant server-side facets by @Prayaksh in #1868
- feat(graph): auto-populate the associative graph from mined sessions by @JosefAschauer in #1895
- docs(guide): Remote / Team Server deployment guide (#1877) by @igorls in #1897
- feat(serve): turnkey secure remote MCP server (#1877) by @igorls in #1900
- docs(config): add storage backends configuration reference by @igorls in #1904
- fix(docs): wide-table layout — stop clipping, fit backend table by @igorls in #1905
- feat: add LaTeX (.tex, .bib) to readable and prose extensions by @messelink in #1901
- docs(openclaw): catch up SKILL.md with 8 newer MCP tools by @raman325 in #1719
- fix: read-only mode misses checkpoint and delete_by_source in _MUTATING_TOOLS by @yusefhaddad in #1930
- fix(mine): log warning when files exceed MAX_FILE_SIZE (#923) by @mvalentsev in #924
- fix(backends): forward facet_counts + get_all_metadata in EmbeddingCollection by @messelink in #1898
- fix: skip startup SQLite integrity check on oversized palace (unblocks MCP handshake) by @trek-e in #1911
- fix: sanitize embedded NUL bytes before they reach ChromaDB by @jrzmurray in #1929
- fix: half-open as-of interval + supersede() to end KG boundary double-count by @ggettert in #1914
- [codex] fix status writer lease classification by @igorls in #1934
- fix(mcp): mark sqlite_integrity not-applicable on non-chroma backends (#1931) by @mvalentsev in #1946
- fix(convo_miner): treat transcripts as mutable, not immutable by @jrzmurray in #1957
- fix(mcp): self-heal writer lease instead of latching read-only for life by @Evgen197310 in #1960
- fix(repair): use os.rename for in-place archive, not shutil.move by @KeilerHirsch in #1945
- Add Milvus storage backend by @zc277584121 in #1899
- style(tests): fix ruff format check left red by #1960 by @Evgen197310 in #1965
- feat: add exclude_patterns config key to mempalace.yaml (rebase of #1213) by @jrzmurray in #1953
- fix(palace): pair the mine_palace_lock holder-set update with its release (#1970) by @mvalentsev in #1971
- fix(convo_miner): don't mine Claude Code tool-results/ dirs — raw tool dumps flood the palace by @KeilerHirsch in #2010
- fix(mcp): answer initialize immediately — run startup preflight in a background thread by @KeilerHirsch in #1987
- mine: auto-heal isolated FTS5 corruption instead of forcing manual repair by @jrzmurray in #1928
- fix(mcp): don't log a traceback when an HTTP client disconnects mid-response (#2003) by @mvalentsev in #2004
- fix(repair): wait out transient SQLite contention by @igorls in #2015
- fix(searcher): guard CLI divergence before Chroma open by @igorls in #2016
- fix(repair): require clean SQLite recovery finalization by @igorls in #2017
- fix: scope derived graph state to explicit palace by @igorls in #2018
- chore(release): 3.6.0 by @igorls in #2019
- chore: sync main hotfixes into develop before 3.6.0 by @igorls in #2022
- fix(mcp): preserve agent attribution in mempalace_checkpoint (#2023) by @mvalentsev in #2034
- feat(routing): add shared daemon write-routing policy by @fatkobra in #2027
- Release v3.6.0 — promote develop to main by @igorls in #2020
New Contributors
- @tp9imka made their first contribution in #1852
- @davidfi01 made their first contribution in #1863
- @joesebastian6079 made their first contribution in #1865
- @davidglidden made their first contribution in #1630
- @ALaDingAhmad made their first contribution in #1648
- @JosefAschauer made their first contribution in #1890
- @trongnguyenbinh made their first contribution in #1859
- @Prayaksh made their first contribution in #1868
- @raman325 made their first contribution in #1719
- @yusefhaddad made their first contribution in #1930
- @jrzmurray made their first contribution in #1929
- @Evgen197310 made their first contribution in #1960
- @KeilerHirsch made their first contribution in #1945
- @zc277584121 made their first contribution in #1899
Full Changelog: v3.5.0...v3.6.0