fix(backend): expose pending MCP memory writes to readers - #12574
Conversation
7e14dea to
3273908
Compare
Failure-Class: new
3273908 to
5950835
Compare
|
Verified end to end — the root-cause diagnosis is correct and the fix is well scoped. Root cause confirmed: Per-file notes:
Independent verification on 5950835: backend unit tests ( Two points worth a maintainer's eye before merge (not blockers in my read):
Leaving those two points for human maintainer review; everything else checks out. Thanks for the careful failure-class write-up and the sabotage-based verification — an exemplary bug report and fix. by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with |
|
You're welcome.
Have a good day.
Suny
Get Outlook for iOS<https://aka.ms/o0ukef>
…________________________________
From: David Zhang ***@***.***>
Sent: Tuesday, 01 September 2026 23:41:30
To: BasedHardware/omi ***@***.***>
Cc: smn565s ***@***.***>; Author ***@***.***>
Subject: Re: [BasedHardware/omi] fix(backend): expose pending MCP memory writes to readers (PR #12574)
[https://avatars.githubusercontent.com/u/9387252?s=20&v=4]Git-on-my-level left a comment (BasedHardware/omi#12574)<#12574 (comment)>
Verified end to end — the root-cause diagnosis is correct and the fix is well scoped.
Root cause confirmed: MemoryService.read() defaults include_pending_processing=False, and both MCP list surfaces called it without the flag, while /v3/memories hard-codes include_pending_processing=True in all three of its read paths. Explicit create_memory submissions that enter the pending required-processing state were therefore invisible to MCP readers until delayed promotion — a silent read-after-write failure on exactly the surface the create response points to.
Per-file notes:
* backend/utils/mcp_memories.py — resolve_mcp_pending_visibility() is the right shape: pending rows have not completed sensitivity classification, so include_sensitive=false fails closed and drops them rather than treating unclassified as standard. Conservative direction, and it is the single seam both transports share.
* backend/routers/mcp.py — new include_pending_processing query param (default true, parsed through the existing parse_mcp_bool 400 path) and the McpCreatedMemory response model. The response change is strictly additive (id/created_at/updated_at/memory_tier/layer) and avoids exposing the internal uid a full MemoryDB serialization would carry; test_rest_create_response_serializes_identity_and_excludes_internal_uid pins that.
* backend/routers/mcp_sse.py — tool schema, description, and execute_tool wiring updated consistently, including documenting the include_sensitive=false interaction in the schema itself so agent callers see it.
* mcp/src/mcp_server_omi/server.py — GetMemories model, get_memories(), and call_tool dispatch forward the flag to the REST bridge; with the create response now carrying id, standalone clients get the same readback guarantee.
* backend/tests/unit/test_mcp_data_endpoints.py — good coverage: default-include, explicit opt-out, the sensitive-exclusion fail-closed path, a create→list read-after-write canary, and the response serialization contract.
* backend/tests/unit/test_mcp_memory_filters.py and mcp/tests/test_get_memories.py — pin the helper truth table and the standalone forwarding contract (model default, param forwarding, dispatch).
* docs/doc/developer/mcp/tools.mdx — accurate; matches the implemented defaults and the fail-closed interaction.
* .github/failure-classes/FC-accepted-write-hidden-by-reader-filter.json — matches the registry schema and the commit's Failure-Class: new declaration.
Independent verification on 5950835<5950835>: backend unit tests (test_mcp_data_endpoints.py, test_mcp_memory_adapter.py, test_mcp_memory_filters.py) — 99 passed; uv run --project mcp pytest mcp/tests/test_get_memories.py — 4 passed; make preflight with the PR body — all 27 checks pass, including the failure-class protocol and the INV-MEM-4/INV-MEM-1 citations.
Two points worth a maintainer's eye before merge (not blockers in my read):
1. The default flip means MCP get_memories now returns unclassified pending rows by default. That restores parity with /v3/memories and pre-rollout behavior, but it is a data-visibility default on a privacy-sensitive surface, so it deserves an explicit maintainer sign-off.
2. The REST create response model change is additive, but it is a public wire-format change; confirming no downstream consumer depends on the exact old field set would be prudent.
Leaving those two points for human maintainer review; everything else checks out. Thanks for the careful failure-class write-up and the sabotage-based verification — an exemplary bug report and fix.
________________________________
by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level<https://github.com/Git-on-my-level> and escalate with need human response.
—
Reply to this email directly, view it on GitHub<#12574?email_source=notifications&email_token=AHUE3V6WN3NBE7P4TYM456L5M6JGVA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNJQGM4TSMJXGU32M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-5503991757>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AHUE3V6BIVJNVDKYLXNXL2D5M6JGVAVCNFSNUABFKJSXA33TNF2G64TZHM3TONRRGIYTAMZUHNEXG43VMU5TKMZRG44TCOJWGI42C5QC>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Summary
create_memorysubmissions that are still in canonical required processing.true, and expose a processed-only opt-out.include_sensitive=false: pending submissions remain hidden until sensitivity classification completes.Root cause
The required-processing rollout changed explicit memory submissions from immediately processed long-term rows to short-term pending canonical rows.
/v3/memoriesincludes those rows, but both MCP list surfaces calledMemoryService.read()with itsinclude_pending_processing=Falsedefault.create_memorytherefore returned success and an ID that the same MCP client could not read until delayed promotion.Verification
backend/.venv/bin/python -m pytest backend/tests/unit/test_mcp_data_endpoints.py backend/tests/unit/test_mcp_memory_adapter.py backend/tests/unit/test_mcp_memory_filters.py -q- 99 passed.uv run --project mcp pytest mcp/tests/test_get_memories.py -q- 4 passed.origin/main11 passed / the same 2 errors (mcp/tests/test_server.pyrequests a missinguidfixture).test_created_pending_memory_is_immediately_readable_by_idfailed; restored fix: 1 passed.call_toolhandler to ignoreinclude_pending_processing=false; the handler-level test failed, then passed after restoring forwarding.PYTHON=.venv/bin/python bash scripts/run-unit-ci.sh --changed-files /tmp/omi-changed-files.txt- passed.PATH="$PWD/backend/.venv/bin:$PATH" scripts/pr-preflight --pr-body-file /tmp/omi-pr-body.md- 27 checks passed.Risk and rollback
The default restores pre-regression read-after-write behavior. Callers that only want processed memories can set
include_pending_processing=false. Callers that setinclude_sensitive=falsenever receive unclassified pending submissions. The REST create response adds the canonical ID and lifecycle fields while continuing to exclude internal user metadata. Rollback is limited to the MCP read projections, standalone forwarding, the safe create response model, their shared visibility policy, and the additive tool argument.Fixes #12569
Product invariants affected
Failure class (fixes)
Failure-Class: new
New class:
FC-accepted-write-hidden-by-reader-filterLine-Count-Exception: backend/routers/mcp_sse.py | 2024 -> 2054 | document and route pending-processing visibility through the hosted MCP memory reader