Parse --palace before initialising module-level singletons so that
both ChromaDB and KnowledgeGraph use the correct palace directory.
When --palace is provided the user is requesting an isolated palace;
KG must co-locate with ChromaDB under that path, not fall back to the
global default (~/.mempalace/knowledge_graph.sqlite3).
- Run ruff format on all benchmark files (fixes CI lint job)
- Fix check_regression() substring ambiguity: ordered keyword matching
so "latency_improvement_pct" is correctly classified as higher-is-better
- Update stale comments in conftest.py referencing wrong fixture
- Add pytest addopts to skip benchmark/slow/stress markers by default
- Introduced README.md for plugin overview and installation instructions.
- Added hooks configuration in hooks.json for auto-save and pre-compact functionality.
- Implemented stop and pre-compact hooks in bash scripts for memory management.
- Created marketplace.json and plugin.json for plugin metadata and versioning.
- Developed skills and instructions for help, init, mine, search, and status functionalities.
- Added CLI commands for executing hooks and displaying skill instructions.
- Implemented hooks_cli.py for handling hook logic and JSON input/output.
- Enhanced instruction files for user guidance on setup and usage.
- Updated .gitignore to exclude additional files.
- Created GitHub Actions workflow for syncing plugin version on push.
ChromaDB 0.6.x bundles a Posthog telemetry client whose capture()
signature is incompatible with the installed posthog library, producing
noisy "Failed to send telemetry event" stderr warnings on every
operation. Silence by raising the logger threshold to CRITICAL.
ONNX Runtime's CoreML execution provider segfaults during vector
queries on macOS ARM64 (issue #74). Auto-set ORT_DISABLE_COREML=1
on Apple Silicon to force CPU execution, while respecting any
user-provided override via os.environ.setdefault().
Made-with: Cursor
Concentrates all drawers into a single wing+room to isolate the
embedding model's retrieval limit independent of palace filtering.
Confirms recall degrades to ~0.4-0.5 at 5K drawers per room even
with wing+room filters applied — the spatial structure helps by
keeping buckets small, but can't fix the underlying embedding ceiling.
Benchmark mempalace at configurable scale (1K–100K drawers) to find
real-world performance limits. Tests cover MCP tool OOM thresholds,
ChromaDB query degradation, search recall@k, mining throughput,
knowledge graph concurrency, memory leak detection, palace boost
quantification, and Layer1 unbounded fetch behavior.
- tests/benchmarks/ with 8 test modules + data generator + report system
- Deterministic data factory with planted needles for recall measurement
- JSON report output with regression detection (--bench-report flag)
- CI benchmark job on PRs at small scale
- psutil added as dev dependency for RSS tracking
The MCP server previously created a new PersistentClient on every tool
call via _get_collection(). This incurs HNSW index loading overhead
on each request.
Cache the client and collection at module level. The cache resets
naturally on process restart (MCP runs as a subprocess).
Also adds a _reset_mcp_cache fixture to conftest.py for test isolation.
Includes test infrastructure from PR #131.
92 tests pass.
process_file() now returns (drawer_count, room) instead of just
drawer_count. The mine summary uses the returned room directly
instead of re-calling detect_room with empty content, which
produced wrong stats when routing relied on content keywords.
The save hook uses SESSION_ID in file paths (state_dir/).
A crafted session_id value like '../../etc/cron.d/evil' could write
state files outside the intended directory.
Strip everything except [a-zA-Z0-9_-] from SESSION_ID, defaulting
to 'unknown' if empty after sanitization.
Finding: #4 (HIGH — path traversal via SESSION_ID)
Includes test infrastructure from PR #131.
92 tests pass.
- Tighten chromadb dependency from >=0.4.0,<1 to >=0.5.0,<0.7
(the collection API changed significantly across majors; this
pins to the tested range)
- Add optional 'spellcheck' extras for the undeclared autocorrect
dependency used in spellcheck.py
- Add PEP 561 py.typed marker for type checker support
Findings: #10 (HIGH — chromadb range too wide), #30 (LOW — undeclared
autocorrect), #32 (LOW — missing py.typed)
Includes test infrastructure from PR #131.
92 tests pass.
- Enable WAL journal mode in _conn() for better concurrent read
performance and reduced SQLITE_BUSY risk
- Add LIMIT 100 to entity-filtered timeline query (was unbounded,
while global timeline already had LIMIT 100)
Findings: #8 (HIGH — no WAL mode), #22 (LOW — inconsistent limits)
Includes test infrastructure from PR #131.
92 tests pass.
- Remove palace_path from _no_palace() error response (prevents
leaking filesystem paths to the LLM)
- Replace str(e) with generic 'Internal tool error' in MCP dispatch
catch block (full error is still logged server-side via stderr)
- Replace sys.exit(1) with return in searcher.search() CLI function
(prevents process termination if called from library context)
- Remove unused sys import from searcher.py
Findings: #12 (HIGH), #5 (MEDIUM), #15 (LOW)
Includes test infrastructure from PR #131.
92 tests pass.
Prevents OOM when the palace grows large. The following unbounded
metadata fetches now have a safety cap:
- tool_status: col.get(include=['metadatas'], limit=10000)
- tool_list_wings: same
- tool_list_rooms: same (including wing-filtered variant)
- tool_get_taxonomy: same
- Layer1.generate: col.get(include=['documents','metadatas'], limit=10000)
Layer2 already had a limit parameter — no change needed.
Finding: #3 (CRITICAL — unbounded data fetching causes OOM)
Includes test infrastructure from PR #131.
92 tests pass.
- Replace len(text)//3 token heuristic with word-based estimate (~1.3 tokens/word)
- Old heuristic inflated compression ratios by ~3-5x
- Update docstrings: "compression" → "lossy summarization"
- Update module docstring to clarify AAAK is NOT lossless
- compression_stats() now returns honest field names and a note
- CLI output labels ratios as lossy
Fixes#43