Review fixes (from Sage's review):
- Restore mtime check in file_already_mined (check_mtime=True for miner)
- Restore limit=10000 on MCP metadata fetches to prevent OOM on large palaces
- Apply _SAFE_NAME_RE regex in sanitize_name (was dead code)
- Drop raw_aaak metadata duplication in diary_write
- chmod 0o700 on WAL dir, 0o600 on WAL file
- Add check_same_thread=False on KnowledgeGraph SQLite connection
- Remove __del__ (unreliable) and dead PRAGMA foreign_keys=ON
Remove datetime.now() from drawer_id hash so same content + wing + room
always produces the same ID. This enables the idempotency check that
returns "already_exists" on duplicate writes.
The 30s TTL metadata cache returned stale data between test runs and
after write operations. Reverted to direct col.get() reads which match
the original behavior and pass all tests.
- _client → _client_cache to match conftest.py reset fixture
- _get_collection now uses _get_client() return value instead of stale ref
- Restore .pytest_cache and other dirs missing from palace.py SKIP_DIRS
Merged both the PR's benchmark suite additions (psutil dep, pytest
markers, --ignore=tests/benchmarks) and upstream's coverage changes
(pytest-cov, --cov-fail-under=30, coverage config) so both coexist.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
_patch_mcp_server had palace_path removed from its signature but the
assertion body still referenced it, causing NameError at runtime and
F821 from ruff.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CI was installing latest ruff (0.15.x) which has different formatting
rules than our local 0.4.x. Pin to ruff>=0.4.0,<0.5 for consistency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add tests for config, convo_miner, spellcheck, knowledge_graph
- Fix Windows PermissionError in test cleanup (chromadb file locks)
- Add UTF-8 encoding to split_mega_files, entity_registry, hooks_cli
- Fix mcp_server parse_known_args logging for unknown args
- Set coverage threshold to 85 in pyproject.toml and CI
- Reset all version files to 3.0.11
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MCP tool_add_drawer:
- Make drawer_id content-based: hash full content instead of
content[:100] + timestamp. Same content → same ID, eliminating
TOCTOU race conditions
- Switch from col.add() to col.upsert() so re-filing with updated
content updates the existing drawer
miner.add_drawer:
- Switch from collection.add() to collection.upsert() so re-mining
a modified file updates instead of silently failing
- Remove the try/except catching 'already exists' — upsert handles
this naturally
Findings: #11 (HIGH — add ignores updates), #6 (MEDIUM — TOCTOU),
#13 (MEDIUM — non-deterministic IDs)
Includes test infrastructure from PR #131.
92 tests pass.
Add/expand tests for normalize (39%→97%), searcher (39%→100%),
layers (28%→97%), split_mega_files (34%→72%).
Fix mcp_server.py parse_args→parse_known_args to prevent SystemExit
when imported during pytest (CI was crashing on all test jobs).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When --palace is not explicitly provided, fall back to KnowledgeGraph()
which uses DEFAULT_KG_PATH (~/.mempalace/knowledge_graph.sqlite3),
preserving backward compatibility for existing users.