Skip to content

docs: documentation for LanceDB migration, embeddings, and multi-device sync - #642

Closed
dekoza wants to merge 15 commits into
MemPalace:developfrom
dekoza:docs/feat-sync-documentation
Closed

docs: documentation for LanceDB migration, embeddings, and multi-device sync#642
dekoza wants to merge 15 commits into
MemPalace:developfrom
dekoza:docs/feat-sync-documentation

Conversation

@dekoza

@dekoza dekoza commented Apr 11, 2026

Copy link
Copy Markdown

⚠️ Merge order

This PR depends on #575 and #641. It must be merged after #575.

This branch is based on feat/sync. If #575 is merged first, this PR will show only the documentation diff.


What this PR does

Complete documentation rewrite, updated for the LanceDB migration and multi-device sync features from feat/sync.

The docs from #641 were cherry-picked and updated for the new storage backend, pluggable embeddings, and sync layer.

New documentation

File Contents
README.md Updated: LanceDB as default backend, sync overview, new install extras
NOTICES.md Maintainer errata and fake-website warning
docs/getting-started.md Install with new deps, optional extras
docs/architecture.md LanceDB + ChromaDB dual backend, embedder architecture, sync architecture (hub-and-spoke, version vectors, conflict resolution)
docs/mining.md Mining guide
docs/searching.md Updated: ONNX embedder, LanceDB vector search
docs/mcp-server.md MCP tool reference
docs/knowledge-graph.md KG API reference
docs/hooks.md Auto-save hooks
docs/configuration.md New fields: backend, embedder, embedder_options, MEMPALACE_BACKEND env var
docs/cli-reference.md New commands: reindex, serve, sync. Updated: migrate (now ChromaDB→LanceDB)
docs/python-api.md New modules: db (backend abstraction), embeddings, sync, sync_client, sync_meta
docs/aaak.md AAAK dialect
docs/sync.md NEW — full sync guide: architecture, server setup, client usage, conflict resolution, security, Python API

Key changes from baseline docs (#641)

Storage backend:

  • All ChromaDB references updated to LanceDB (or backend-agnostic language)
  • db.py abstraction layer documented (LanceCollection / ChromaCollection)
  • Backend auto-detection explained
  • Migration path from ChromaDB documented

Embeddings:

  • Three backends: ONNX (default, no torch), sentence-transformers ([gpu]), Ollama
  • Config fields: embedder, embedder_options
  • mempalace reindex command for switching models

Sync:

  • New docs/sync.md covering hub-and-spoke model, version vectors, sequence numbers, conflict resolution (LWW + node_id tiebreak)
  • CLI commands: mempalace serve, mempalace sync
  • Python API: SyncEngine, SyncClient, NodeIdentity
  • Sync metadata fields: node_id, seq, updated_at

Dependencies:

  • Core: lancedb, onnxruntime, tokenizers, pyyaml
  • Optional: [chroma], [gpu], [server]

All cross-references verified — zero broken links.

dekoza added 15 commits April 11, 2026 21:35
Database abstraction (Phase 1):
- New db.py with LanceCollection/ChromaCollection sharing identical API
- New embeddings.py with SentenceTransformerEmbedder (default)
- palace.py now delegates to db.open_collection() with auto-detection
- All consumers (searcher, layers, mcp_server, miner, palace_graph)
  updated to use palace.get_collection() instead of direct chromadb
- Added 'mempalace migrate' for ChromaDB -> LanceDB migration
- LanceDB is new default; ChromaDB moved to optional [chroma] extra
- Dependencies: lancedb>=0.14, sentence-transformers>=2.2.0

Pluggable vectorizers (Phase 2):
- OllamaEmbedder for GPU server usage via HTTP
- Model aliases: bge-small, bge-base, e5-base, nomic, ollama
- 'mempalace reindex' to re-embed with different model
- 'mempalace embedders' to list available models
- embedding_model tracked in every record's metadata
- Config via ~/.mempalace/config.json embedder/embedder_options

Tests: 552 passed, 0 failed (18 new embedding tests)
knowledge_graph.py rewritten with dual backend:
- LanceDB (default): kg_entities + kg_triples tables in palace dir
- SQLite (legacy): preserved for existing .sqlite3 paths
- All operations (add_entity, add_triple, invalidate, query_entity,
  query_relationship, timeline, stats, seed_from_entity_facts) work
  on both backends with identical API

MCP server updated:
- KnowledgeGraph now uses palace_path instead of separate sqlite file
- One data directory, one format, one sync unit

UPGRADE.md updated with Phase 5 how-to and migration notes.
PLAN.md Phase 5 marked done.

Tests: 588 passed (28 KG tests all pass on LanceDB backend)
New benchmark runner (benchmarks/longmemeval_v4.py):
- Runs LongMemEval against multiple backends in one invocation
- Modes: chroma-default, lance-default, lance-bge-small, lance-bge-base,
  lance-nomic, and custom embedder
- Produces side-by-side comparison table with R@5, R@10, NDCG, ms/query
- Per-type breakdown across question categories
- Presets: 'all' (3 modes), 'quick' (2), 'embedders' (4)

Results on full 500 questions:
  ChromaDB + MiniLM (v3.x):  R@5=0.966  R@10=0.982  NDCG@5=0.888  1165ms/q
  LanceDB  + MiniLM (v4.0):  R@5=0.966  R@10=0.982  NDCG@5=0.888   638ms/q
  LanceDB  + BGE-small:      R@5=0.962  R@10=0.978  NDCG@5=0.895  2624ms/q

Key findings:
- Zero retrieval regression: LanceDB matches ChromaDB exactly
- 1.8x faster queries (638ms vs 1165ms) with cosine distance
- BGE-small trades tiny R@5 drop for better NDCG (ranking quality)

Docs:
- benchmarks/BENCHMARKS_V4.md — full results + reproduction steps
- UPGRADE.md updated with benchmark section + how-to
- PLAN.md Phase 6 marked done — all 6 phases complete

Tests: 588 passed
Added v4.0 Backend Comparison section at top of BENCHMARKS.md:
- LanceDB+MiniLM: R@5=0.966, identical to ChromaDB, 1.8x faster (638ms vs 1165ms)
- LanceDB+BGE-small: R@5=0.962, higher NDCG (0.895 vs 0.888)
- Per-type breakdown showing BGE-small tradeoffs
- Reproduction commands for longmemeval_v4.py

Updated existing sections:
- Score progression table: added LanceDB and BGE-small rows
- Comparison table: added v4 LanceDB entry alongside v3 ChromaDB
- Tradeoffs table: added v4 column (sync, pluggable embedders, query speed)
- Results files table: added results_v4_comparison.json

Tests: 588 passed
- Add OnnxEmbedder as default (onnxruntime+tokenizers, no torch)
- Move sentence-transformers to [gpu] optional extra
- Strip all sync code from db.py, cli.py, config.py, UPGRADE.md
- Apply ruff lint fixes from f21ba0a to migration-branch files
- Remove unused chromadb import from conftest.py
- Regenerate uv.lock for migration-only dependencies

config.py:
  mempalace/config.py
…sync from benchmark

- Add _check_dimension() to LanceCollection.__init__: raises RuntimeError
  if existing table vector dimension doesn't match the active embedder
- Replace invalid port 99999 with RFC discard port 9 in Ollama test
- Remove sync_meta import and sync_identity from benchmark script
These fields are used by the sync layer for indexed queries instead of
full table scans. Adding them to FILTER_COLUMNS and SCHEMA_COLUMNS now
avoids a schema migration later.

Records without sync metadata get defaults (node_id='', seq=0).
- UPGRADE.md: fix default dep table (onnxruntime+tokenizers, not sentence-transformers)
- db.py: catch ImportError in _open_chroma with actionable message
- db.py: upgrade merge_insert fallback log to warning
- db.py: add $in/$nin support to _chroma_where_to_sql
- searcher.py: distinguish empty palace vs missing palace vs missing chromadb
- cli.py: same distinction in cmd_compress
- knowledge_graph.py: use count_rows(filter=) instead of len(get(limit=100k))
- knowledge_graph.py: remove limit=100 from _lance_timeline queries
- palace.py: get_collection reads MempalaceConfig().backend before auto-detect
Phase 3: Sync metadata injection on all writes (node_id, seq, updated_at)
Phase 4: Sync engine with version vector protocol, HTTP server/client

- mempalace/sync_meta.py: NodeIdentity, atomic sequence counter
- mempalace/sync.py: SyncEngine, VersionVector, ChangeSet, conflict resolution
- mempalace/sync_server.py: FastAPI sync server (push/pull/status endpoints)
- mempalace/sync_client.py: HTTP sync client
- CLI: 'mempalace serve' and 'mempalace sync' commands
- db.py: sync metadata injection in LanceCollection.upsert, _raw bypass
- config.py: node_id property
- pyproject.toml: [server] optional extra (fastapi, uvicorn, httpx)
- UPGRADE.md: sync architecture, setup, and usage docs
- Tests for sync metadata, engine, and server
- get_changes_since: export records from ALL nodes, not just local node.
  Fixes hub-and-spoke where hub must relay client A's records to client B.
- _remote_wins: parse timestamps as timezone-aware datetimes instead of
  string comparison. Correctly handles mixed Z/+00:00/+05:00 offsets.
- apply_changes: split records with/without embeddings into separate upsert
  calls to preserve provided vectors instead of dropping the entire batch.
- sync_meta: replace Unix-only fcntl with cross-platform locking
  (fcntl on Unix, msvcrt on Windows).
- db.py: add dimension mismatch guard from Branch 1.
- Update test_bidirectional_sync assertion for correct multi-node export.
update() no longer writes to disk — callers use save() explicitly or
rely on update_from_records() which already batches.  Eliminates up to
N file writes per apply_changes() on an N-record changeset.
get_changes_since() now builds a WHERE clause against the top-level
node_id and seq columns (added in feat/lancedb-migration) instead of
scanning all records into Python.

Query for remote_vv={'a': 5, 'b': 3}:
  (node_id='a' AND seq>5) OR (node_id='b' AND seq>3)
  OR (node_id NOT IN ('a','b') AND seq>0)
- sync_meta: seek to offset 0 before msvcrt lock/unlock, lock 4096 bytes
  instead of 1 (msvcrt operates relative to file position, unlike fcntl)
- sync_server: detect ChromaDB palace and error with migrate guidance
  instead of failing on _raw=True at runtime
- cli cmd_sync: same ChromaDB guard
- cli cmd_serve: default bind to 127.0.0.1 instead of 0.0.0.0
- UPGRADE.md: clarify sync replicates drawers only, KG is node-local
Cherry-picks the documentation rewrite from fix/documentation and updates
all docs to reflect the feat/sync branch changes:

Storage backend:
- LanceDB is now the default backend (ChromaDB is legacy)
- Database abstraction layer (db.py) with unified Collection interface
- Backend auto-detection from palace directory contents
- Migration path from ChromaDB to LanceDB

Embeddings:
- Pluggable embedding backends: ONNX (default), sentence-transformers, Ollama
- ONNX all-MiniLM-L6-v2 runs without torch (~87 MB model, cached)
- GPU support via [gpu] extra, Ollama offloading via [server] extra
- Reindex command for switching embedding models

Multi-device sync:
- New docs/sync.md covering hub-and-spoke architecture
- Version vectors, sequence numbers, conflict resolution
- Server setup (mempalace serve) and client usage (mempalace sync)
- Python API for SyncEngine, SyncClient, NodeIdentity

New CLI commands documented:
- mempalace reindex (re-embed with different model)
- mempalace serve (start sync server)
- mempalace sync (sync with remote server)

Updated across all docs:
- ChromaDB references → LanceDB (or backend-agnostic)
- New config fields: backend, embedder, embedder_options
- New env var: MEMPALACE_BACKEND
- Sync metadata fields: node_id, seq, updated_at
- New dependencies: lancedb, onnxruntime, tokenizers
- Optional extras: [chroma], [gpu], [server]
@dekoza
dekoza requested a review from milla-jovovich as a code owner April 11, 2026 20:30
Copilot AI review requested due to automatic review settings April 11, 2026 20:30
@dekoza
dekoza requested a review from bensig as a code owner April 11, 2026 20:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces MemPalace v4 documentation and code updates to support the LanceDB default backend, pluggable embedding backends, and a new multi-device sync layer (client/server + version vectors), alongside broad test suite updates and new benchmarks.

Changes:

  • Add LanceDB/ChromaDB abstraction (db.py) and embedder backends (ONNX default, sentence-transformers, Ollama), plus CLI commands (migrate, reindex, embedders).
  • Add sync metadata (node_id, seq, updated_at), sync engine, HTTP sync server, and sync client + CLI wiring.
  • Add/refresh v4 docs and LongMemEval v4 benchmark scripts/results; update tests to use the new abstractions.

Reviewed changes

Copilot reviewed 51 out of 54 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
UPGRADE.md New v4 upgrade changelog/how-to guide.
PLAN.md New v4 phased implementation plan/status doc.
NOTICES.md New safety/errata notices (fake sites warning).
pyproject.toml Switch core deps to LanceDB/ONNX/tokenizers + add optional extras.
mempalace/db.py New backend abstraction (LanceDB default, ChromaDB legacy).
mempalace/embeddings.py New pluggable embedders + model alias/factory.
mempalace/sync_meta.py New node identity + atomic seq + metadata injector.
mempalace/sync.py New sync engine (version vectors, conflict resolution).
mempalace/sync_server.py New FastAPI sync server endpoints.
mempalace/sync_client.py New HTTP sync client.
mempalace/cli.py Add reindex/embedders/serve/sync/migrate and repair updates.
mempalace/config.py Add backend/embedder/node_id config properties.
mempalace/palace.py Centralize get_collection() via open_collection().
mempalace/searcher.py Route search via get_collection() and handle empty palaces.
mempalace/miner.py Remove direct ChromaDB usage; use get_collection().
mempalace/layers.py Replace direct ChromaDB usage with get_collection() calls.
mempalace/mcp_server.py Switch collection access + KG initialization to palace-based KG.
mempalace/palace_graph.py Replace direct ChromaDB client usage with get_collection().
mempalace/normalize.py Minor formatting change in file-size error message.
mempalace/split_mega_files.py Minor formatting change in printed size limit message.
mempalace/init.py Quiet dependency loggers (sentence-transformers, chromadb telemetry).
docs/getting-started.md New getting started guide updated for v4 deps/extras.
docs/architecture.md New architecture doc (currently out of sync with v4 storage reality).
docs/configuration.md New configuration doc (currently missing v4 backend/embedder fields).
docs/mining.md New mining guide (still contains backend-specific wording).
docs/searching.md New searching guide (still contains backend-specific wording).
docs/cli-reference.md New CLI reference including new commands.
docs/python-api.md New Python API overview including db/embeddings/sync modules.
docs/mcp-server.md New MCP server reference and tool docs.
docs/knowledge-graph.md New KG reference (currently describes SQLite-only storage).
docs/hooks.md New hooks guide.
docs/aaak.md New AAAK dialect doc (has backend-specific storage wording).
docs/sync.md New sync guide (documents a --dry-run flag not implemented).
tests/conftest.py Update fixtures to use get_collection() + upsert.
tests/test_embeddings.py New tests for embedder backends and metadata tracking.
tests/test_sync_meta.py New tests for node identity, seq counter, and metadata injection.
tests/test_searcher.py Update mocks/patching to new collection getter + empty-palace behavior.
tests/test_layers.py Update layer tests to patch _get_palace_collection.
tests/test_miner.py Update miner tests to use new collection helper.
tests/test_convo_miner.py Update convo miner tests to use new collection helper.
tests/test_cli.py Update CLI tests to patch get_collection() instead of chromadb module.
tests/test_mcp_server.py Update MCP server tests for new collection/KG behavior.
tests/test_palace_graph.py Remove chromadb import-time patching; import module directly.
tests/test_knowledge_graph.py Adjust WAL-mode test to explicitly test SQLite backend.
tests/test_knowledge_graph_extra.py Update fixture to use palace_path-based KG.
tests/benchmarks/test_layers_bench.py Minor assertion formatting change.
benchmarks/longmemeval_v4.py New v4 LongMemEval benchmark runner (Lance vs Chroma modes).
benchmarks/results_v4_comparison.json New committed v4 benchmark results.
benchmarks/BENCHMARKS_V4.md New v4 benchmark summary doc.
benchmarks/BENCHMARKS.md Add v4 comparison section and update summary tables.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mempalace/palace.py
Comment on lines +48 to +59
if backend is None:
from .config import MempalaceConfig
configured = MempalaceConfig().backend
if configured:
backend = configured

return open_collection(
palace_path=palace_path,
collection_name=collection_name,
backend=backend,
embedder=embedder,
)

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_collection() always overrides backend with MempalaceConfig().backend. Since MempalaceConfig.backend currently defaults to 'lance', this prevents auto-detection and will try to open LanceDB even for existing ChromaDB palaces (breaking the stated “auto-detection” behavior and potentially creating LanceDB data alongside chroma.sqlite3). Consider only honoring an explicitly configured backend (env var / config key), and otherwise pass backend=None so open_collection() can call detect_backend().

Copilot uses AI. Check for mistakes.
Comment thread mempalace/config.py
Comment on lines +158 to +162
"""Storage backend: 'lance' (default) or 'chroma' (legacy)."""
env_val = os.environ.get("MEMPALACE_BACKEND")
if env_val:
return env_val
return self._file_config.get("backend", DEFAULT_BACKEND)

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backend currently defaults to DEFAULT_BACKEND ('lance') even when the user has not set any backend in env/config. This makes it impossible for callers to distinguish “explicitly configured” from “use auto-detection”, and (via palace.get_collection) breaks opening legacy ChromaDB palaces automatically. Consider returning None when not explicitly configured, and letting detect_backend() decide; detect_backend() already defaults to LanceDB for new palaces.

Suggested change
"""Storage backend: 'lance' (default) or 'chroma' (legacy)."""
env_val = os.environ.get("MEMPALACE_BACKEND")
if env_val:
return env_val
return self._file_config.get("backend", DEFAULT_BACKEND)
"""Explicitly configured storage backend, or None if unset."""
env_val = os.environ.get("MEMPALACE_BACKEND")
if env_val:
return env_val
return self._file_config.get("backend")

Copilot uses AI. Check for mistakes.
Comment thread docs/sync.md
Comment on lines +98 to +105
### Dry run

```bash
mempalace sync --server http://homeserver:7433 --dry-run
```

Shows what would be synced without making changes.

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs describe a mempalace sync --dry-run option, but the CLI parser for sync does not define --dry-run and cmd_sync doesn’t implement it. Either add the flag + behavior or remove this section to avoid misleading users.

Suggested change
### Dry run
```bash
mempalace sync --server http://homeserver:7433 --dry-run
```
Shows what would be synced without making changes.

Copilot uses AI. Check for mistakes.
Comment thread docs/cli-reference.md
| `--server URL` | Server URL (required, e.g. `http://homeserver:7433`) |
| `--auto` | Repeat sync every `--interval` seconds |
| `--interval N` | Seconds between syncs when `--auto` is set (default: 300) |
| `--dry-run` | Show what would be synced without syncing |

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mempalace sync is documented as supporting --dry-run, but the implementation in mempalace/cli.py doesn’t define this flag for the sync subcommand. Please align the CLI reference with the actual CLI (either implement --dry-run or remove it here).

Suggested change
| `--dry-run` | Show what would be synced without syncing |

Copilot uses AI. Check for mistakes.
Comment thread docs/architecture.md
Comment on lines +5 to +16
MemPalace has two storage backends:

- **ChromaDB** (vector store) — stores verbatim text chunks (drawers) with metadata, supports semantic search via embeddings.
- **SQLite** (knowledge graph) — stores entity-relationship triples with temporal validity windows.

Both are local files. No network access, no external services.

```
User → CLI / MCP Server → ChromaDB (palace)
SQLite (knowledge graph)
```

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This architecture doc still describes ChromaDB + SQLite as the storage backends and shows a ChromaDB/SQLite data flow diagram. That conflicts with the v4 changes in this PR (LanceDB default backend, knowledge graph moved into LanceDB tables by default). Please update this overview to match the current storage architecture.

Copilot uses AI. Check for mistakes.
Comment thread docs/configuration.md
Comment on lines +31 to +49
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `palace_path` | string | `~/.mempalace/palace` | ChromaDB storage directory |
| `collection_name` | string | `mempalace_drawers` | ChromaDB collection name |
| `topic_wings` | list | see above | Default topic wing names |
| `hall_keywords` | dict | see above | Keywords that map content to halls |
| `people_map` | dict | `{}` | Name variant mappings (alternative to `people_map.json`) |

## Environment variables

Environment variables take precedence over config file values.

| Variable | Overrides | Description |
|----------|-----------|-------------|
| `MEMPALACE_PALACE_PATH` | `palace_path` | Path to the palace directory |
| `MEMPAL_PALACE_PATH` | `palace_path` | Alias for `MEMPALACE_PALACE_PATH` |
| `MEMPALACE_BACKEND` | `backend` | Storage backend: `lance` or `chroma` |
| `MEMPAL_DIR` | (hooks only) | Directory for auto-ingest during hook saves |

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The config reference still labels palace_path/collection_name as “ChromaDB” fields and doesn’t document the new v4 fields (backend, embedder, embedder_options, MEMPALACE_BACKEND). Please update the fields table and examples so they reflect the current configuration surface and defaults.

Copilot uses AI. Check for mistakes.
Comment thread mempalace/sync.py
Comment on lines +198 to +210
def get_changes_since(self, remote_vv: dict[str, int]) -> ChangeSet:
"""Get all records that the remote hasn't seen.

Uses indexed node_id/seq columns for efficient filtering.
Essential for hub-and-spoke: the hub relays records from any node.
"""
our_node = self._identity.node_id
where = self._build_changes_filter(remote_vv)

records = self._col.get(
where=where, limit=100_000, include=["documents", "metadatas"],
)

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SyncEngine.get_changes_since() hard-codes limit=100_000 for the get() call. If a node has more than 100k unseen records (first sync, or long offline period), the changeset will silently truncate and the version vector will still advance based on the truncated batch, risking permanent data loss. Consider paginating until exhaustion (or returning a continuation token) and only advancing the version vector for records actually sent/applied.

Copilot uses AI. Check for mistakes.
Comment thread mempalace/sync_server.py
Comment on lines +72 to +109
@app.get("/health")
def health():
return {"status": "ok", "service": "mempalace-sync"}

@app.get("/sync/status")
def sync_status():
engine = _get_engine()
col = engine._col
return {
"node_id": engine._identity.node_id,
"version_vector": engine.version_vector,
"total_drawers": col.count(),
}

@app.post("/sync/push")
async def sync_push(request: Request): # noqa: F811
body = await request.json()
engine = _get_engine()
cs = ChangeSet(
source_node=body.get("source_node", ""),
records=[SyncRecord.from_dict(r) for r in body.get("records", [])],
)
result = engine.apply_changes(cs)
return {
"accepted": result.accepted,
"rejected_conflicts": result.rejected_conflicts,
"errors": result.errors,
}

@app.post("/sync/pull")
async def sync_pull(request: Request): # noqa: F811
body = await request.json()
engine = _get_engine()
cs = engine.get_changes_since(body.get("version_vector", {}))
return {
"source_node": cs.source_node,
"records": [r.to_dict() for r in cs.records],
}

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sync server exposes push/pull endpoints without any authentication or authorization. Since mempalace serve can be bound to 0.0.0.0, anyone who can reach the port can read/write the full palace contents. Consider adding an optional shared-secret/API-key check (e.g., Authorization: Bearer ...), and/or strongly enforcing localhost-only binding unless explicitly overridden.

Copilot uses AI. Check for mistakes.
Comment thread pyproject.toml
Comment on lines 44 to +47
spellcheck = ["autocorrect>=2.0"]
chroma = ["chromadb>=0.5.0,<0.7"] # Legacy backend — install for migration
gpu = ["sentence-transformers>=2.2.0"] # Local GPU/CPU embeddings via torch
server = ["fastapi>=0.100", "uvicorn>=0.20", "httpx>=0.24"] # Sync server

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

httpx is listed in the [server] extra, but the sync implementation uses urllib.request (and there are no httpx imports in the codebase). Consider removing httpx from optional deps to keep the extra minimal, or switching SyncClient to httpx to justify the dependency (async support, timeouts, retries, TLS config).

Copilot uses AI. Check for mistakes.
Comment thread docs/aaak.md
mempalace compress --config entities.json # with entity config
```

Compressed drawers are stored in a separate `mempalace_compressed` ChromaDB collection. The raw originals are preserved.

Copilot AI Apr 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section says compressed drawers are stored in a “ChromaDB collection”. In v4 the storage backend is LanceDB by default (and compress uses get_collection()), so this should be updated to be backend-agnostic (or explicitly describe how it behaves on LanceDB vs legacy ChromaDB).

Suggested change
Compressed drawers are stored in a separate `mempalace_compressed` ChromaDB collection. The raw originals are preserved.
Compressed drawers are stored in a separate `mempalace_compressed` collection using the configured storage backend (LanceDB by default in v4; legacy setups may use ChromaDB). The raw originals are preserved.

Copilot uses AI. Check for mistakes.
@bensig
bensig changed the base branch from main to develop April 11, 2026 22:21
@bensig
bensig requested a review from igorls as a code owner April 11, 2026 22:21
@igorls

igorls commented Apr 14, 2026

Copy link
Copy Markdown
Member

Thanks a lot for this. We will migrate to a plugin based storage system for the next major release. Please re-open this once that infrastructure lands.

@igorls igorls closed this Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants