Release/v2.33.0 - #119
Conversation
Replace the personal Gmail and the retired marmsystems.com addresses with the business addresses, using support@marmemory.com where the contact is a support/reporting channel and ryanlyell@marmemory.com for authorship fields. - SECURITY.md, CONTRIBUTING.md: support@marmemory.com - pyproject.toml: fix the ryanlyell@marmmemory.com typo (doubled "m") that shipped in the 2.32.0 authors metadata; maintainers to support@ - __init__.py: __email__ to match the author field Also carries a pyproject description wording fix (indices -> indexing). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ff (v2.33.0) Recall falls back to keyword-only search when the embedding model cannot load or throws. That lane built its MATCH with strict AND, so a natural-language question matched nothing, the LIKE fallback then searched for the whole question as one substring and also matched nothing. If the model failed to load, recall returned empty for effectively every question. Measured on LoCoMo (1,977 questions, 5,882 memories, top-5) with the encoder disabled: any-hit 0.1% -> 55.4%, all-hit 0.1% -> 46.7%, ev-recall 0.1% -> 50.5%. Every category improved; adversarial went 0.0% -> 51.8%, since there was no precision to lose from a lane returning nothing. The full engine scores 62.5% on this corpus, so the degraded path now reaches ~89% of it. The change is one line: apply_temporal was already the lane discriminator, so the fallbacks take the wide builder and the exact lane keeps strict AND. No FTS_WIDEN_FALLBACK setting - a knob was used to run the arms and then removed, because narrow is broken rather than a tradeoff and FTS_QUERY_MODE=and already forces strict matching everywhere. - SEMANTIC_SEARCH_ENABLED (default 1): set to 0 to run as though fastembed were absent. Added because the degraded path could not be measured any other way; also lets a low-memory host skip the model. Surfaced in doctor. - FTS_LONE_HIT_SCORE now applies to the fallback lane. It shares a row fetcher with the exact lane and so always reported 1.0, which was right under strict AND and wrong under a wide OR. Exact lane still always uses 1.0. No change at the default. - Both dependency warnings in settings.py moved to stderr; stdout carries JSON-RPC on the STDIO transport. Tests: 5 new fallback-lane tests plus 2 for the lone-hit wiring, all verified to fail without their fix. test_exact_retrieval_lane.py passes unmodified as the widening regression guard. Suite: 872 passed, 2 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (6)**/*.{py,json,md,toml,yml,yaml,Dockerfile}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{md,py}📄 CodeRabbit inference engine (AGENTS.md)
Files:
marm-mcp-server/tests/**/*.py📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/tests/**⚙️ CodeRabbit configuration file
Files:
**/*.py⚙️ CodeRabbit configuration file
Files:
🪛 ast-grep (0.45.0)marm-mcp-server/tests/test_hybrid_search.py[error] 1349-1356: Command coming from incoming request (subprocess-from-request) 🔇 Additional comments (2)
📝 WalkthroughWalkthroughVersion 2.33.0 adds configurable semantic-search availability, broadens keyword fallback recall when embeddings are unavailable, applies fallback-specific lone-hit scoring, exposes doctor diagnostics, adds regression tests, and updates release metadata and documentation. ChangesSemantic fallback and diagnostics
Fallback recall and release
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 479899ca6e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| </details> | ||
|
|
||
| For memory behavior, transports, supported clients, compaction, and backup questions, see the [FAQ](https://github.com/Lyellr88/marm-memory/blob/MARM-main/docs/FAQ.md). | ||
| For memory behavior, transports, supported clients, compaction, and backup questions, see the [FAQ](docs/FAQ.md). |
There was a problem hiding this comment.
In the PyPI README variant, this relative URL resolves beneath marm-mcp-server/, but a repo-wide search finds no marm-mcp-server/docs/FAQ.md; the FAQ exists only at root docs/FAQ.md and in the packaged resources. Consequently, readers following this link from the source view—and potentially the PyPI-rendered description—reach a nonexistent page, so retain the absolute GitHub URL or use a target valid for the publication context.
AGENTS.md reference: AGENTS.md:L33-L36
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@marm-mcp-server/tests/test_hybrid_search.py`:
- Around line 1216-1255: Extend the semantic-disabled coverage beyond the
import-time flag by adding a fresh-process test that sets
SEMANTIC_SEARCH_ENABLED=0, instantiates MARMMemory, verifies encoder loading is
refused, and performs a normal write whose stored result has no embedding. Reuse
the existing subprocess setup and relevant MARMMemory symbols, while preserving
the current assertions for the enabled and disabled configuration values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1e19acf5-73de-4de1-9529-6a0b838b9c3f
📒 Files selected for processing (24)
CHANGELOG.mdCONTRIBUTING.mdREADME.mdSECURITY.mddocs/INSTALL-DOCKER.mddocs/INSTALL-LINUX.mddocs/INSTALL-PLATFORMS.mddocs/INSTALL-WINDOWS.mddocs/TECHNICAL-OVERVIEW.mdmarm-mcp-server/Dockerfilemarm-mcp-server/README.mdmarm-mcp-server/docker-compose.ymlmarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/config/settings.pymarm-mcp-server/marm_mcp_server/core/memory_recall.pymarm-mcp-server/marm_mcp_server/core/memory_scoring.pymarm-mcp-server/marm_mcp_server/core/memory_utils.pymarm-mcp-server/marm_mcp_server/resources/marm-docs/README.mdmarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/cli_output.pymarm-mcp-server/marm_mcp_server/services/runtime_status.pymarm-mcp-server/pyproject.tomlmarm-mcp-server/server.jsonmarm-mcp-server/tests/test_hybrid_search.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{py,json,md,toml,yml,yaml,Dockerfile}
📄 CodeRabbit inference engine (AGENTS.md)
Keep changes surgical: modify only what the task requires, match existing style, and preserve behavior during refactors.
Files:
SECURITY.mdCONTRIBUTING.mddocs/INSTALL-DOCKER.mdmarm-mcp-server/marm_mcp_server/services/cli_output.pydocs/INSTALL-WINDOWS.mdmarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/runtime_status.pydocs/TECHNICAL-OVERVIEW.mdREADME.mdmarm-mcp-server/docker-compose.ymlmarm-mcp-server/marm_mcp_server/core/memory_utils.pymarm-mcp-server/pyproject.tomlmarm-mcp-server/server.jsondocs/INSTALL-PLATFORMS.mddocs/INSTALL-LINUX.mdmarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/core/memory_scoring.pymarm-mcp-server/README.mdmarm-mcp-server/marm_mcp_server/config/settings.pyCHANGELOG.mdmarm-mcp-server/marm_mcp_server/resources/marm-docs/README.mdmarm-mcp-server/marm_mcp_server/core/memory_recall.pymarm-mcp-server/tests/test_hybrid_search.py
**/*.{md,py}
📄 CodeRabbit inference engine (AGENTS.md)
When adding or removing an MCP tool, update every full tool list and tool count in the README, protocol documentation, FAQ, and maintained
marm-docscopies; add tests covering both transports.
Files:
SECURITY.mdCONTRIBUTING.mddocs/INSTALL-DOCKER.mdmarm-mcp-server/marm_mcp_server/services/cli_output.pydocs/INSTALL-WINDOWS.mdmarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/runtime_status.pydocs/TECHNICAL-OVERVIEW.mdREADME.mdmarm-mcp-server/marm_mcp_server/core/memory_utils.pydocs/INSTALL-PLATFORMS.mddocs/INSTALL-LINUX.mdmarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/core/memory_scoring.pymarm-mcp-server/README.mdmarm-mcp-server/marm_mcp_server/config/settings.pyCHANGELOG.mdmarm-mcp-server/marm_mcp_server/resources/marm-docs/README.mdmarm-mcp-server/marm_mcp_server/core/memory_recall.pymarm-mcp-server/tests/test_hybrid_search.py
**/*
📄 CodeRabbit inference engine (AGENTS.md)
**/*: Never commit changes without an explicit user request.
Use semantic versioning: MAJOR for breaking changes, MINOR for new tools, parameters, or features, and PATCH for fixes and documentation updates.
Files:
SECURITY.mdCONTRIBUTING.mddocs/INSTALL-DOCKER.mdmarm-mcp-server/marm_mcp_server/services/cli_output.pymarm-mcp-server/Dockerfiledocs/INSTALL-WINDOWS.mdmarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/runtime_status.pydocs/TECHNICAL-OVERVIEW.mdREADME.mdmarm-mcp-server/docker-compose.ymlmarm-mcp-server/marm_mcp_server/core/memory_utils.pymarm-mcp-server/pyproject.tomlmarm-mcp-server/server.jsondocs/INSTALL-PLATFORMS.mddocs/INSTALL-LINUX.mdmarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/core/memory_scoring.pymarm-mcp-server/README.mdmarm-mcp-server/marm_mcp_server/config/settings.pyCHANGELOG.mdmarm-mcp-server/marm_mcp_server/resources/marm-docs/README.mdmarm-mcp-server/marm_mcp_server/core/memory_recall.pymarm-mcp-server/tests/test_hybrid_search.py
**/*.md
⚙️ CodeRabbit configuration file
**/*.md: Only flag documentation issues that are materially wrong, misleading for installation/release behavior, or inconsistent with live MCP behavior. Skip style, phrasing, formatting, and wording preferences.
Files:
SECURITY.mdCONTRIBUTING.mddocs/INSTALL-DOCKER.mddocs/INSTALL-WINDOWS.mddocs/TECHNICAL-OVERVIEW.mdREADME.mddocs/INSTALL-PLATFORMS.mddocs/INSTALL-LINUX.mdmarm-mcp-server/README.mdCHANGELOG.mdmarm-mcp-server/marm_mcp_server/resources/marm-docs/README.md
marm-mcp-server/marm_mcp_server/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
marm-mcp-server/marm_mcp_server/**/*.py: All memory writes must use the serialized asynchronous write queue; do not add bypass paths.
A semantic-store failure duringmarm_log_entrymust never fail the corresponding log write.
Keep the memory database and isolated concept-graph database on separate connection pools; never share connections between them.
Graph and concept failures must never break the seven core memory tools.
marm_smart_recallmust keep primary memory ranking authoritative; graph enrichment is bounded, read-only, fail-open, and must be trimmed before primary results when enforcing response limits.
Use one lazy-loadedjinaai/jina-embeddings-v2-small-enencoder with 512 dimensions, serialized behind a lock; writes must succeed if the encoder is unavailable.
Keep orchestration in its current owner file and extract modules only at real boundaries consistent with the existing endpoint split.
Comments must be minimal, explain only non-obvious reasons, and never narrate the next line.
Files:
marm-mcp-server/marm_mcp_server/services/cli_output.pymarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/runtime_status.pymarm-mcp-server/marm_mcp_server/core/memory_utils.pymarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/core/memory_scoring.pymarm-mcp-server/marm_mcp_server/config/settings.pymarm-mcp-server/marm_mcp_server/core/memory_recall.py
**/*.py
⚙️ CodeRabbit configuration file
**/*.py: Prioritize runtime correctness, async/concurrency safety, SQLite transaction safety, auth/rate-limit behavior, release-breaking packaging issues, and MCP protocol compatibility.
Files:
marm-mcp-server/marm_mcp_server/services/cli_output.pymarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/runtime_status.pymarm-mcp-server/marm_mcp_server/core/memory_utils.pymarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/core/memory_scoring.pymarm-mcp-server/marm_mcp_server/config/settings.pymarm-mcp-server/marm_mcp_server/core/memory_recall.pymarm-mcp-server/tests/test_hybrid_search.py
marm-mcp-server/{pyproject.toml,server.json,marm_mcp_server/__init__.py,marm_mcp_server/config/settings.py,marm_mcp_server/server.py,Dockerfile,docker-compose.yml}
📄 CodeRabbit inference engine (AGENTS.md)
When bumping the version, update every listed package, manifest, server, Docker, and configuration version occurrence, and audit with
python scripts/find-versions.py.
Files:
marm-mcp-server/Dockerfilemarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/docker-compose.ymlmarm-mcp-server/pyproject.tomlmarm-mcp-server/server.jsonmarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/config/settings.py
marm-mcp-server/marm_mcp_server/server.py
📄 CodeRabbit inference engine (AGENTS.md)
Keep HTTP MCP tools listed in
MCP_TOOL_OPERATIONS; tools absent from this whitelist must not be exposed over HTTP.
Files:
marm-mcp-server/marm_mcp_server/server.py
marm-mcp-server/{server.py,server_stdio.py,server.json}
📄 CodeRabbit inference engine (AGENTS.md)
When adding or removing an MCP tool, update the endpoint implementation, HTTP route and whitelist, STDIO registration/wrapper, and
server.jsontools array.
Files:
marm-mcp-server/server.json
marm-mcp-server/tests/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
marm-mcp-server/tests/**/*.py: Run tests withpytestfrommarm-mcp-server/; tests should exercise real FastAPI endpoints and real SQLite, using mocks only when they preserve at least 95% fidelity and provide meaningful speedup.
Every new MARM Console API route must have at least one happy-path FastAPI response-contract test with the MCP adapter stubbed.
Do not write existence-check or coded-to-pass tests; prefer deep tests exercising real paths over broad shallow coverage.
Usepytest.mark.skiponly for genuinely unavailable dependencies, never merely to avoid implementation effort.
Files:
marm-mcp-server/tests/test_hybrid_search.py
**/tests/**
⚙️ CodeRabbit configuration file
**/tests/**: Focus on tests that are flaky, non-isolated, incorrectly asserting behavior, or missing coverage for a changed high-risk path. Skip minor naming, comments, and layout preferences.
Files:
marm-mcp-server/tests/test_hybrid_search.py
🪛 ast-grep (0.45.0)
marm-mcp-server/tests/test_hybrid_search.py
[error] 1225-1236: Command coming from incoming request
Context: subprocess.run(
[
sys.executable,
"-c",
"from marm_mcp_server.config.settings import SEMANTIC_SEARCH_AVAILABLE as v;"
"print(repr(v))",
],
capture_output=True,
text=True,
env=env,
cwd=str(pathlib.Path(file).resolve().parent.parent),
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
🔇 Additional comments (24)
CHANGELOG.md (1)
5-25: LGTM!CONTRIBUTING.md (1)
9-9: LGTM!SECURITY.md (1)
7-7: LGTM!docs/INSTALL-DOCKER.md (1)
5-5: LGTM!docs/INSTALL-LINUX.md (1)
5-5: LGTM!Also applies to: 323-323
docs/INSTALL-PLATFORMS.md (1)
1-1: LGTM!docs/INSTALL-WINDOWS.md (1)
5-5: LGTM!Also applies to: 297-297
docs/TECHNICAL-OVERVIEW.md (1)
3-3: LGTM!marm-mcp-server/Dockerfile (1)
76-76: LGTM!marm-mcp-server/docker-compose.yml (1)
8-8: LGTM!Also applies to: 21-21
marm-mcp-server/marm_mcp_server/__init__.py (1)
17-22: LGTM!marm-mcp-server/marm_mcp_server/server.py (1)
8-8: LGTM!marm-mcp-server/pyproject.toml (1)
7-16: LGTM!marm-mcp-server/server.json (1)
6-6: LGTM!Also applies to: 20-25
marm-mcp-server/marm_mcp_server/config/settings.py (1)
80-104: LGTM!Also applies to: 182-182, 347-351
marm-mcp-server/marm_mcp_server/services/runtime_status.py (1)
26-26: LGTM!Also applies to: 232-232
marm-mcp-server/marm_mcp_server/services/cli_output.py (1)
95-96: LGTM!README.md (1)
8-8: LGTM!Also applies to: 988-988
marm-mcp-server/README.md (1)
10-10: LGTM!Also applies to: 133-134, 990-990, 1129-1129
marm-mcp-server/marm_mcp_server/resources/marm-docs/README.md (1)
1-1: LGTM!Also applies to: 22-23, 107-108, 958-958, 1095-1096
marm-mcp-server/marm_mcp_server/core/memory_recall.py (1)
12-12: LGTM!Also applies to: 352-394
marm-mcp-server/marm_mcp_server/core/memory_utils.py (1)
139-142: LGTM!marm-mcp-server/marm_mcp_server/core/memory_scoring.py (1)
200-201: LGTM!Also applies to: 234-240
marm-mcp-server/tests/test_hybrid_search.py (1)
1126-1214: LGTM!Also applies to: 1258-1306
The existing test only proved the flag reached settings.py. The release claims more than that: no model load, and no embeddings written. Both are decided by an import-time constant read inside MARMMemory, so neither was covered. Adds a fresh-process test that sets the switch, instantiates MARMMemory, asserts _load_encoder_lazily() refuses and no encoder object is built, performs a normal store_memory, then reads the row back and asserts its embedding is NULL. Verified additive rather than duplicate: with the SEMANTIC_SEARCH_AVAILABLE guard deleted from _load_encoder_lazily, only this new test fails while the existing config-value test still passes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
postcss <=8.5.17 auto-loads the .map file named by a sourceMappingURL comment and can be walked out of the intended directory, disclosing arbitrary .map files (Dependabot #11, high). The console pinned 8.5.16. postcss is transitive via vite, so there is no dependency line to bump. Adds a pnpm override alongside the existing esbuild one, in pnpm-workspace.yaml where this workspace already keeps them. Resolves postcss 8.5.16 -> 8.5.24, pulling nanoid 3.3.15 -> 3.3.16 as its own dependency. A range rather than a pin, so a later resolution cannot drop back below the fix. Practical exposure was low: postcss runs at build time over CSS authored in this repo, and nothing at runtime or in the published MCP server touches it. Verified: installed tree resolves to postcss@8.5.24, pnpm typecheck clean, and pnpm build succeeds with CSS emitted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
v2.33.0 - Keyword-Only Recall Works When the Embedding Model Is Unavailable
MARM falls back to keyword-only search when the embedding model cannot load or throws mid-recall. That fallback was unusable: it required every word of the query to appear in a single memory, so natural-language questions matched nothing and recall came back empty. This release makes the fallback actually work.
FTS_QUERY_MODE=andstill forces strict matching everywhere for anyone who wants it.SEMANTIC_SEARCH_ENABLED(default1). Set it to0to run as though fastembed were not installed: no model load, no embeddings written, keyword-only recall. It exists because the degraded path could not be measured any other way, and it also lets a low-memory host skip loading the model.marm-memory doctorreports when it is off.FTS_LONE_HIT_SCOREnow applies to the fallback lane. That lane shares a row fetcher with the exact-lookup lane, so it always reported1.0correct under strict all-terms matching, wrong once the lane matched on a broad query, where a single match can mean one memory happened to share one word. The exact lane still always uses1.0. No change at the default.settings.pyprinted to stdout, which can corrupt JSON-RPC on the STDIO transport. Both now use stderr.Behavior is unchanged for anyone whose embedding model loads normally, and there is no migration, schema change, or re-embed.
Validation
Suite: 872 passed, 2 skipped.
tests/test_exact_retrieval_lane.pypasses unmodified, which is the guard that the widening did not leak into the exact lane. The 7 new tests were each re-run with their fix removed to confirm they fail one initially passed for the wrong reason, because recency decay between two successive recalls satisfied the assertion by about 4e-11 rather than by the setting under test.Summary by CodeRabbit
SEMANTIC_SEARCH_ENABLEDto disable embedding/semantic behavior and force keyword matching only.marm-memory initruntime setup commands, including a Claude integration option.