chore: sync upstream/develop through v3.3.5#18
Merged
Conversation
release: v3.3.3 — sync develop → main for tag cut
Bumps every version source from 3.3.3 to 3.3.4: - pyproject.toml - mempalace/version.py (canonical) - .claude-plugin/plugin.json - .claude-plugin/marketplace.json - .codex-plugin/plugin.json - README.md badge Dates the CHANGELOG section and adds entries for the bug fixes that landed this cycle (MemPalace#1135, MemPalace#1191, MemPalace#1230, MemPalace#1231) plus expands the MemPalace#1194 entry to credit the lookup-side recovery path from MemPalace#1197. Pre-tag verification: - 1441 passed, 1 skipped (full suite minus benchmarks, all platforms) - ruff check + format clean - 44/44 in test_version_consistency + test_readme_claims (6-file sync) - JPH invariant: pyproject.toml + .claude-plugin/plugin.json both reference mempalace-mcp - Wheel build + fresh-venv install: mempalace --version reports 3.3.4, mempalace-mcp --help works (catches the v3.3.2-class regression)
Agent-Logs-Url: https://github.com/MemPalace/mempalace/sessions/01a1089d-da46-4dc8-85e8-d7e50763dd58 Co-authored-by: igorls <4753812+igorls@users.noreply.github.com>
The fix landed this cycle and is documented under 3.3.4. The 3.3.0 Bug Fixes block is shipped history and shouldn't grow new entries retroactively.
…entry The PR documenting the fix is MemPalace#1232; referencing it from inside its own changelog entry is circular.
…MemPalace#1288 Three fixes landed on develop after the initial release-prep cut and were brought in via the develop merge. Document them in the 3.3.4 Bug Fixes section so the release notes reflect what users will actually receive. - MemPalace#1287 - HNSW divergence floor scales with hnsw:sync_threshold (resolves a silent-fallback regression introduced by the interaction between MemPalace#1191 and MemPalace#1227 in this release) - MemPalace#1262 - ChromaBackend get_or_create_collection split, fixing the stop-hook SIGSEGV class on legacy palaces with mismatched stored metadata (MemPalace#1089) - MemPalace#1288 / MemPalace#1254 - repair --mode max-seq-id heuristic now decodes BLOB-typed embeddings.seq_id, restoring the un-poison path added in MemPalace#1135 for palaces where chromadb 1.5.x writes seq_ids natively
The release was originally cut on 2026-04-27 but did not tag that day. Three additional bug fixes have been folded in since then (MemPalace#1262, MemPalace#1287, MemPalace#1288) and the actual tag will happen on 2026-04-30. Update the header date to match.
…MCP server companion The same try/except split that MemPalace#1262 applied at the backend layer (ChromaBackend.get_collection) was needed at the parallel call site in mcp_server._get_collection(create=True), which carries the same metadata payload directly to chromadb's Python client. Both reopen paths in mempalace now bypass get_or_create_collection on existing collections, closing the SIGSEGV class for both tool_add_drawer and tool_diary_write (the Stop hook's path).
…prep chore(release): v3.3.4
Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 5 to 6. - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](actions/configure-pages@v5...v6) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nt (MemPalace#1315) After a bulk CLI mine, ChromaDB's HNSW segment metadata can be unflushed for ~30-60s. Wing-scoped MCP search hits "Internal error: Error finding id" during that window, and the existing inode/mtime cache invalidation isn't enough — tool_search routes via search_memories -> palace.get_collection -> _DEFAULT_BACKEND._client, which has its own per-palace cache. This wraps tool_search with a single retry that drops both the MCP-local cache and _DEFAULT_BACKEND._clients/_freshness for the palace, sleeps 2s, retries once, and tags successful retries with index_recovered=True. Does not address tool_check_duplicate or other index-touching tools, nor the underlying flush window — options 1-3 from MemPalace#1315 (auto-flush after mine, fail-fast detection, SQLite-only fallback) are still on the table for a complete fix. Refs MemPalace#1315
Substring checks in path/filename routing caused systemic misrouting in large monorepos — e.g., "views" ⊂ "interviews" sent every file under views/ to the interviews room. Switch to separator-bounded token matching (-, _, ., /) via a _name_matches helper, applied to priority 1 (path parts) and priority 2 (filename).
The Stop hook spawns mining subprocesses via subprocess.Popen and then returns. On Windows the parent stays blocked at session end because the child inherits stdout/stderr handles and the OS waits for them to release before the parent can exit — the user-visible symptom is the "running stop hooks... 3/3" spinner hanging for minutes (MemPalace#1268). Add _detached_popen_kwargs() helper that returns the right detach knobs per platform: - POSIX: start_new_session=True, stdin=DEVNULL, close_fds=True - Windows: creationflags=DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP| CREATE_BREAKAWAY_FROM_JOB, stdin=DEVNULL, close_fds=True Apply to all three fire-and-forget Popen sites in hooks_cli: _spawn_mine, _ingest_transcript, _desktop_toast. Leave _mine_sync's subprocess.run alone — that path is intentionally synchronous (the precompact hook must wait for the mine to finish). Note: the issue body references mempalace-stop.js, which does not exist in this repo (the plugin ships shell wrappers calling Python). The mechanism described — child holds parent open via inherited handles — is universal, so this fix targets the equivalent symptom in our Python hook path. Will follow up on the upstream JS file with the reporter.
When a `mempalace mine` collided with another writer (live mcp_server, another mine, anything taking mine_palace_lock), the operator saw a generic "another `mempalace mine` is already running" message and the CLI exited 0 — making the contention invisible to nohup or scripts checking $?. The reporter ran a `nohup mempalace mine ... & disown` and got a 200-byte log with only the auto-defaults warning, no clue that an MCP server was holding the store. palace.py: the lock file now records the holder's PID + first three argv tokens on acquire. A failed acquire reads the file and surfaces "palace <path> is held by PID N (mempalace mcp_server); wait for it to finish or stop the holder before retrying" in the MineAlreadyRunning message. Open mode changes from "w" to "a+" so the prior holder's identity survives long enough to be read. miner.mine() now lets MineAlreadyRunning propagate. cmd_mine catches it, prints the holder-aware message to stderr, and exits non-zero so shell wrappers detect the contention. Note: this is a behavior change for in-process callers that depended on miner.mine() silently swallowing MineAlreadyRunning. The silent swallow was the bug. Closes MemPalace#1264
Windows CI surfaced two bugs introduced by the holder-identity write: 1. msvcrt.locking(LK_NBLCK, 1) locks 1 byte at the *current* file position. Switching to "a+" mode put the position at end-of-file, so two contenders locked different bytes and silently both acquired (the test asserts saw [(ok, 1), (ok, 2)] instead of ok+busy). 2. With the byte-range lock active on Windows, the locked byte is read-blocked for other processes. A contender trying to read the holder identity from byte 0 would hit PermissionError. Switch to "r+" mode (after touch-create) and explicitly seek(0) before both lock and unlock. Then reserve byte 0 as a pure lock sentinel and write the holder identity from byte 1 onward. _read_lock_holder reads from byte 1+, so it never touches the locked byte. Also bound file growth across re-acquires: truncate to sentinel + len(ident) before writing so the file body stays the size of the current holder, never accumulating across runs. Linux fcntl.flock locks the whole file independent of byte position, so the seek(0) is harmless on POSIX. The shape works on both.
os.path.expanduser("~") reads HOME on POSIX but USERPROFILE on Windows;
the lock-body bound test was monkeypatching HOME only, so on
test-windows the lock file landed in the runner's real ~/.mempalace
and the tmp_path glob found nothing.
Patch USERPROFILE in addition to HOME, and read the body as bytes so
the byte-0 sentinel doesn't trip a UTF-8 decode warning. Assertion
shifts from line-count to size-bound (still detects unbounded growth
across re-acquires).
The v3.3.4 release prep landed on main but was never merged back into develop, leaving every version-bearing file one release behind. Bumps pyproject.toml, mempalace/version.py, both plugin manifests, the marketplace entry, the README badge, and the lockfile to 3.3.4 to match the tagged release.
End-user installs now lead with `uv tool install mempalace`, with `pip install mempalace` kept as a fallback. Dev/contributor docs lead with `uv sync --extra dev` and `uv run` for tests/benchmarks/lint, with the equivalent pip recipe kept inline. The shipped `/mempalace:init` skill instructions (mempalace/instructions/init.md) try `uv tool install` first when uv is on PATH, then fall back through the pip variants. Adds a .python-version pin at 3.12 because the lockfile's onnxruntime==1.24.3 only ships wheels for Python >=3.11; without the pin, `uv sync` on a host where uv prefers 3.10 fails with no source distribution available, which would make the documented command a footgun. pyproject's `requires-python = ">=3.9"` is unchanged — pip users on 3.9/3.10 are unaffected. Files updated: README.md, CONTRIBUTING.md, CLAUDE.md, the gemini-cli guide and example, the .claude-plugin / .codex-plugin READMEs, the mempalace SKILL, the openclaw SKILL, tools/save.md, the three benchmarks docs, and the corresponding website mirrors.
…h-windows fix(hooks): detach Popen children so hook exits cleanly on Windows (MemPalace#1268)
…older-diagnostics fix(mine): identify lock holder + exit non-zero on contention (MemPalace#1264)
- mempalace/instructions/init.md: only skip Step 4 when `mempalace --version` succeeds. `pip show` / `uv tool list` reporting an install is not enough -- if the package lives in an unactivated venv, Step 5 (`mempalace init ...`) fails with command-not-found. Treat that case as not-installed and re-install via Step 3 into a PATH-visible location. - .codex-plugin/README.md: switch the git-install recipe from `uv sync` to `uv tool install --editable .` so the bundled `plugin.json` (which invokes `mempalace-mcp` by bare name) can launch the MCP server. Plain `uv sync` only puts the script in `.venv/bin/`, which Codex won't find unless the venv is activated first.
…emPalace#1206) The hook PID guard used a single global ``~/.mempalace/hook_state/mine.pid`` file, which failed two ways: 1. ``_mine_already_running`` read-then-spawn was a TOCTOU race. Two near-simultaneous Stop hook fires both passed the existence/liveness check before either wrote — so both ended up calling ``_spawn_mine``. 2. ``_spawn_mine`` unconditionally overwrote the global PID file with the new child's PID. The first PID was lost, orphaning the first child. The user-visible result in MemPalace#1212 was two concurrent ``mempalace mine`` processes running against the same source, both driving HNSW inserts in parallel — exactly the corruption pattern the guard was meant to prevent. MemPalace#1206 reported the same shape from the perspective of the user (two mines hung on a 350MB folder). Replace the global file with per-target slots under ``~/.mempalace/hook_state/mine_pids/``, keyed by sha256 of the mine sub-arguments (everything after ``mine``). The slot is claimed via ``O_CREAT | O_EXCL`` so the claim is atomic — two simultaneous fires can never both pass. Stale slots (PID exists but is dead) are reclaimed transparently. Different targets (e.g. project mine vs transcript ingest, or two different MEMPAL_DIRs) get independent slots and run in parallel. The mine subprocess receives its slot path via ``MEMPALACE_MINE_PID_FILE`` env var; ``miner._cleanup_mine_pid_file`` reads that var on exit and removes the slot if it points at our PID, so orphaned slots from crashed mines don't accumulate. Also routes ``_ingest_transcript`` through ``_spawn_mine`` so the transcript ingest path now participates in the same dedup — repeated Stop fires for the same transcript no longer stack parallel mines. Closes MemPalace#1212 Closes MemPalace#1206
PEP 604 union syntax (Path | None) requires Python 3.10+. The project still supports 3.9 (per pyproject target-version and CI matrix), and this annotation lives in a function signature so it is evaluated at module load time — failing with "unsupported operand type(s) for |" on test-linux 3.9. The other ``int | None`` annotation in this file is inside a function body, where Python skips runtime evaluation of local annotations, so it does not trip 3.9.
…pid-guard fix(hooks): per-target PID guard with atomic claim (MemPalace#1212, MemPalace#1206)
…entity-1317 docs: clarify contributor git identity setup
fix(miner): use token-boundary matching in detect_room
…k subprocess state
… lock subprocess state
…try-on-hnsw-flush fix(mcp): retry tool_search once on Chroma "Error finding id" transient (MemPalace#1315)
test_palace_locks.py and test_chroma_collection_lock.py spawned child processes with the ``fork`` start method on POSIX. Under Python 3.13 this deadlocks reliably enough to hang the Linux 3.13 and macOS CI jobs indefinitely while Linux 3.9 / 3.11 / Windows complete normally. Root cause: by the time these tests run, the pytest parent process is multi-threaded — chromadb and onnxruntime both spawn background threads on import. ``fork`` snapshots the parent's address space into the child without those threads, so any lock another thread held at fork time stays locked in the child forever. Python 3.13 widened the window where Python's own internal threads can be holding locks (hence the new DeprecationWarning that fired ten times in our local 3.13 run). macOS hits a related but distinct issue: Apple's CoreFoundation explicitly forbids fork-without-exec; once anything in the parent has loaded a CF-using library (ONNX, anything via Objective-C bridges) a forked child will silently hang the moment it touches the same library. Switching to ``spawn`` re-imports modules in the child (~0.5s overhead per Process — measurable but bounded), which is the standard fix for both classes of bug. Lock-file semantics are unchanged: ``spawn`` inherits ``os.environ`` (including monkeypatched ``HOME``), which is all these tests need from the parent. Locally on Python 3.13: all 14 lock tests pass in 6.58s.
…sing-spawn fix(tests): use spawn instead of fork for lock-test subprocesses
Several tests opened sqlite3 connections without try/finally or context-manager cleanup, relying on a flat conn.close() after the work. Any assertion failure or exception between connect and close leaked the connection until GC, producing ``ResourceWarning: unclosed database`` in CI logs. On Python 3.13 / macOS the ResourceWarning isn't just noise: a leaked connection can hold a SQLite advisory lock long enough for later test setup to block on it, which appears to be the cause of recent intermittent CI hangs on those two runners. Wrap each affected ``conn = sqlite3.connect(...)`` block in ``contextlib.closing(...)`` so cleanup runs on the failure path too. Mirrors the try/finally pattern already used in production code (searcher.py, repair.py, backends/chroma.py). No behavior change — same operations, same assertions, just deterministic cleanup. All 162 affected tests pass locally.
…eanup chore(tests): wrap sqlite3 connections in contextlib.closing
Bumps version 3.3.4 → 3.3.5 across pyproject.toml, version.py, plugin manifests, README badge, and uv.lock. Flips CHANGELOG.md from ``[3.3.5] — unreleased`` to ``[3.3.5] — 2026-05-09`` and adds entries for the four PRs that landed after the bug-fix block was authored: - Bug Fixes: MemPalace#1396 (tool_search retry on transient HNSW flush) - Documentation: MemPalace#1385 (CONTRIBUTING git-identity guidance, closes MemPalace#1317) - Internal: MemPalace#1431 (test multiprocessing fork → spawn) - Internal: MemPalace#1430 (test sqlite connection lifecycle via contextlib.closing) The four open issues remaining on the v3.3.5 milestone (MemPalace#1266, MemPalace#1253, MemPalace#1092, MemPalace#1082) have been moved to v3.4 — they form the concurrent-writer / HNSW corruption cluster that needs deeper work than this cycle could absorb.
…etimes # Conflicts: # tests/test_palace_locks.py
…imes fix(kg): accept ISO datetimes for temporal inputs
The 3.3.4 release shipped 2026-05-01 (per GitHub release v3.3.4) but its CHANGELOG header was never flipped from ``unreleased`` to the release date. Backfill while we're already touching CHANGELOG for the 3.3.5 cut.
chore(release): 3.3.5
# Conflicts: # .claude-plugin/marketplace.json # .claude-plugin/plugin.json # .codex-plugin/plugin.json # CHANGELOG.md # README.md # mempalace/version.py # pyproject.toml # uv.lock
Copilot review on PR MemPalace#1434 caught that the existing 3.3.5 entry described the validator as it was authored under MemPalace#1167 — accepting ``YYYY``/``YYYY-MM``/``YYYY-MM-DD`` and rejecting ISO datetimes — but PR MemPalace#1417 (closes MemPalace#1374) merged into develop on 2026-05-10 and inverted that: ``sanitize_iso_temporal()`` now rejects partial dates and accepts canonical UTC datetimes (``YYYY-MM-DDTHH:MM:SSZ`` / ``+00:00``). ``sanitize_iso_date()`` is kept as a backwards-compat wrapper. Update the bullet to describe the *shipped* behavior, name both functions, list both accepted and rejected forms, and call out the 3.3.4 → 3.3.5 behavior change for partial-date inputs that now error. Reference both MemPalace#1167 (original) and MemPalace#1374/MemPalace#1417 (the expansion).
…k-to-develop chore(release): sync main back to develop after v3.3.5
Sync fork main with upstream/develop tip after MemPalace v3.3.5 release (2026-05-10). Brings in integrity/recovery/correctness fixes shipped in v3.3.5 — including our co-authored MemPalace#1377 (retry _get_collection once on transient failure) which extracted the surgical retry from MemPalace#1286. Notable upstream additions pulled in: - MemPalace#1310 — repair --mode from-sqlite for HNSW-corrupt palaces - MemPalace#1396 — tool_search retry on HNSW-flush transient - MemPalace#1214/MemPalace#1167/MemPalace#1417 — KG temporal validation (breaking: partial dates like "2026"/"2026-05" rejected) - MemPalace#1215 — atomic EntityRegistry.save() - MemPalace#1105/MemPalace#1160 — cross-process correctness on Windows + multi-tenant KG cache - MemPalace#1004 — detect_room token-boundary matching - MemPalace#1421 — gitignore-aware drawer prune - MemPalace#1107 — paginated closet_llm col.get - MemPalace#1415/MemPalace#1413/MemPalace#1412 — per-target PID guard atomic claim + Popen detach on Windows + mine-contention exit codes Conflict resolutions: - CLAUDE.md, README.md — kept fork (fork-only inventory + badges) - mempalace/version.py, pyproject.toml — took upstream v3.3.5 - tests/conftest.py — took upstream's _kg_by_path-aware cache reset (mcp_server no longer has _recovery_collection_cache); env scrubbing for PALACE_DAEMON_URL/STRICT/API_KEY preserved - mempalace/hooks_cli.py — kept daemon-strict short-circuit (rows 33/34) and project_wing semantics (row 5); adopted upstream's _spawn_mine wrapper (MemPalace#1415 per-target PID guard) - mempalace/miner.py — combined upstream's _name_matches token-bounded routing (MemPalace#1004) with fork's keyword-candidate list in Priority 2 - tests/test_miner.py — kept fork's expanded chunking-constants imports (row 17) Rows 33/34 daemon-strict gating verified intact in mcp_server.py (handle_request chokepoint) and cli.py (cmd_status / cmd_search / cmd_mine). Daemon-routed .claude-plugin/.mcp.json (row 30) untouched by upstream — no auto-merge regression. Test suite: 1828 passed, 1 skipped, 106 deselected (up from 1591 at 2026-05-07 sync — +237 tests from upstream's repair/PID-guard/sync additions). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR syncs the fork’s main branch with upstream develop through the MemPalace v3.3.5 release, bringing in multiple correctness/integrity fixes plus new functionality (notably gitignore-aware drawer pruning) and associated documentation/test updates.
Changes:
- Adds the new
mempalace synccapability end-to-end (coresync_palace, CLI command, MCP tool + docs) with extensive test coverage. - Strengthens multi-process correctness: per-target mine PID slots, improved lock-holder diagnostics, and safer multiprocessing test strategy (
spawn). - Updates KG temporal validation to a stricter ISO “date or canonical UTC datetime” model and adjusts MCP/knowledge-graph behavior + tests accordingly.
Reviewed changes
Copilot reviewed 51 out of 52 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
website/reference/mcp-tools.md |
Documents the new mempalace_sync MCP tool and updates tool count. |
website/reference/contributing.md |
Updates contributor workflow examples to prefer uv. |
website/reference/benchmarks.md |
Updates benchmark setup instructions to prefer uv. |
website/guide/getting-started.md |
Updates installation guidance to recommend uv tool install. |
website/guide/gemini-cli.md |
Updates Gemini CLI setup to use uv workflows. |
uv.lock |
Bumps locked editable package version to 3.3.5. |
tools/save.md |
Updates install instructions to recommend uv tool install. |
tests/test_sync.py |
Adds comprehensive tests for gitignore-aware sync/prune behavior and surfaces. |
tests/test_sources.py |
Improves sqlite connection cleanup in tests via closing(). |
tests/test_searcher.py |
Adds CLI rendering safety test for None documents. |
tests/test_repair.py |
Improves sqlite connection cleanup in tests via closing(). |
tests/test_palace_locks.py |
Switches lock tests to spawn and adds holder-identity regression coverage. |
tests/test_palace_graph_tunnels.py |
Adds coverage for shared wing normalization behavior. |
tests/test_miner.py |
Adds token-boundary routing tests and updates PID-slot cleanup tests. |
tests/test_mcp_server.py |
Adds retry-on-transient-search tests, KG datetime tests, and vector-disabled duplicate check test. |
tests/test_knowledge_graph.py |
Adds datetime compatibility + context manager/close cleanup tests. |
tests/test_hooks_cli.py |
Expands coverage for per-target PID guard and detached spawn behavior. |
tests/test_config.py |
Adds sanitize_iso_temporal test coverage and backward-compat wrapper assertions. |
tests/test_cli.py |
Adds CLI regression test ensuring lock contention exits non-zero with holder PID. |
tests/test_chroma_collection_lock.py |
Switches multiprocessing start method to spawn for reliability. |
tests/test_backends.py |
Improves sqlite connection cleanup in tests via closing(). |
tests/conftest.py |
Updates MCP cache reset fixture to avoid importing mcp_server and to clear _kg_by_path. |
README.md |
Updates version/upstream badges to 3.3.5. |
pyproject.toml |
Bumps project version to 3.3.5. |
mempalace/version.py |
Bumps runtime version constant to 3.3.5. |
mempalace/sync.py |
Introduces sync_palace implementation (gitignore-aware prune + reporting + closet purge). |
mempalace/palace.py |
Enhances per-palace lock with holder identity recording and improved diagnostics. |
mempalace/palace_graph.py |
Uses shared normalize_wing_name and trims empty/whitespace wings. |
mempalace/miner.py |
Adds token-boundary _name_matches routing and changes lock contention behavior to raise. |
mempalace/mcp_server.py |
Adds transient HNSW-flush retry, KG temporal validation update, and new tool_sync. |
mempalace/knowledge_graph.py |
Implements safe date/datetime temporal comparisons, validation, and context manager support. |
mempalace/instructions/init.md |
Updates install/run instructions to validate mempalace on PATH and prefer uv tool. |
mempalace/hooks_cli.py |
Implements per-target PID slots + detached Popen behavior for background mines. |
mempalace/entity_detector.py |
Updates output schema docstring to include topics. |
integrations/openclaw/SKILL.md |
Updates installation instructions to recommend uv tool install. |
examples/gemini_cli_setup.md |
Updates setup doc to recommend uv and use uv run. |
CONTRIBUTING.md |
Updates contributor guidance to prefer uv and adds git identity checks. |
CLAUDE.md |
Updates fork metadata/version sync notes. |
CHANGELOG.md |
Updates v3.3.5 section with upstream changes and internal/test notes. |
benchmarks/README.md |
Updates benchmark setup instructions to prefer uv. |
benchmarks/HYBRID_MODE.md |
Updates benchmark setup instructions to prefer uv. |
benchmarks/BENCHMARKS.md |
Updates benchmark setup instructions to prefer uv and uv run. |
.python-version |
Pins local dev Python version to 3.12. |
.github/workflows/deploy-docs.yml |
Updates GitHub Pages action version to actions/configure-pages@v6. |
.codex-plugin/README.md |
Updates plugin install docs to recommend uv tool install --editable. |
.codex-plugin/plugin.json |
Bumps plugin version to 3.3.5. |
.claude-plugin/skills/mempalace/SKILL.md |
Updates install instructions to recommend uv tool install. |
.claude-plugin/README.md |
Updates post-install wording to reflect uv/pip install flow. |
.claude-plugin/plugin.json |
Bumps plugin version to 3.3.5. |
.claude-plugin/marketplace.json |
Bumps marketplace version to 3.3.5. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| try: | ||
| ident = f"{os.getpid()} {' '.join(sys.argv[:3])}".strip() | ||
| lock_file.seek(_LOCK_SENTINEL_BYTES) | ||
| lock_file.truncate(_LOCK_SENTINEL_BYTES + len(ident.encode("utf-8"))) |
Comment on lines
+359
to
+365
| pid_file = _pid_file_for_cmd(cmd) | ||
| pid_file.parent.mkdir(parents=True, exist_ok=True) | ||
| try: | ||
| fd = os.open(str(pid_file), os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600) | ||
| os.close(fd) | ||
| return pid_file | ||
| except FileExistsError: |
| --- | ||
|
|
||
| ## [3.3.5] — unreleased | ||
| ## [3.3.5] — 2026-05-09 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sync fork
mainwithupstream/developtip after MemPalace v3.3.5 release (2026-05-10). Brings in integrity/recovery/correctness fixes — including our co-authored MemPalace#1377.What's pulled in from upstream
repair --mode from-sqlitefor HNSW-corrupt palacestool_searchretry on HNSW-flush transient (overlaps daemon-strict approach at different layer; complementary)"2026","2026-05") now rejectedEntityRegistry.save()(tempfile + fsync + replace)detect_roomtoken-boundary matchingcloset_llm col.get(does NOT coverminer.status()— row 16 stays fork-ahead)Conflict resolutions (8 files)
CLAUDE.md,README.mdmempalace/version.py,pyproject.tomltests/conftest.py_kg_by_path-aware cache reset (currentmcp_serverno longer has_recovery_collection_cache); env scrubbing forPALACE_DAEMON_URL/STRICT/API_KEYpreservedmempalace/hooks_cli.pyproject_wingsemantics (row 5); adopted upstream's_spawn_minewrapper (MemPalace#1415 per-target PID guard)mempalace/miner.py_name_matchestoken-bounded routing (MemPalace#1004) with fork's keyword-candidate list in Priority 2tests/test_miner.pyVerification
mcp_server.handle_requestandcli.cmd_{status,search,mine}— daemon routing intact.claude-plugin/.mcp.json(row 30 daemon-routed config) untouched by upstream — no auto-merge regressionscripts/check-docs.sh— clean (21 fork hashes resolve, 113 PR refs match, YAML→FORK_CHANGELOG.md parity)Test plan
python -m pytest tests/ -q→ 1828 passed, 1 skipped, 106 deselected (up from 1591 at 2026-05-07 sync — +237 tests)bash scripts/check-docs.sh→ cleandisks.jphe.in:8085daemon after merge🤖 Generated with Claude Code