fix(memory): fall back to wiki for missing all-corpus reads#100904
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 9:50 AM ET / 13:50 UTC. Summary PR surface: Source +39, Tests +37. Total +76 across 2 files. Reproducibility: yes. Current main is source-reproducible: Review metrics: none identified. Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Next step before merge
Security Review detailsBest possible solution: Merge this focused tool-boundary fix after exact-head checks remain green, keeping storage readers and supplement APIs unchanged. Do we have a high-confidence way to reproduce the issue? Yes. Current main is source-reproducible: Is this the best way to solve the issue? Yes. The patch fixes the tool-boundary success path that consumes the existing read contract, which is narrower than changing storage readers, supplement APIs, or corpus selection semantics. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against e35c7a3c95b2. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +39, Tests +37. Total +76 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
Land-ready maintainer validation for
Known proof gaps: none for this narrow memory-core result-routing change. |
|
Merged via squash.
|
…#100904) * Fix memory_get all supplement fallback * refactor(memory): use typed missing-read contract --------- Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…#100904) * Fix memory_get all supplement fallback * refactor(memory): use typed missing-read contract --------- Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Summary
memory_getwithcorpus=allso a valid empty memory miss can still read a registered wiki supplement.Origin / follow-up
corpus=allfallback handled thrown read failures, but not the successful empty miss result returned for missingmemory/*.mdfiles.corpus=wikireads.Root Cause
The root cause is a success-path contract mismatch in
executeMemoryReadResult. The memory host source of truth returns a missing but valid in-workspace memory file as{ text: "", path }, whileexecuteMemoryReadResulttreated every successful read as final by immediately returningjsonResult(result). That causedmemory_get corpus=allto stop before the wiki supplement lookup even though thecorpus=allcontract selected both memory and wiki sources.This fixes the root contract mismatch at the tool boundary that consumes memory read results. It recognizes only the real missing-file result shape: matching
path, emptytext, and nofrom/lines/truncation/error metadata. Forcorpus=all, that exact state now enters the existing supplement read path; existing file reads, partial empty excerpts, disabled results, andcorpus=memorybehavior still return the original memory result.A user asking for
corpus=allexpects the exact read to search both memory and wiki sources. Before this patch, a missing memory file could hide an available wiki entry even thoughcorpus=allselected both corpora.The patch does not change memory indexing, search ranking, provider routing, session visibility, file path validation,
corpus=memory, explicitcorpus=wiki, or normal successful reads. It only changes the empty-miss branch formemory_get corpus=all.The source-of-truth contract is
readMemoryFilereturning{ text: "", path }for missing valid memory files, whilebuildMemoryReadResultaddsfrom/linesmetadata for existing reads. The fix consumes that contract in memory-core rather than changing storage schema, validation, provider routing, or session-state ownership.Real behavior proof
memory_getwithcorpus=allshould return a wiki supplement when the memory backend returns a non-throwing empty miss for the requested valid memory path.Local OpenClaw worktree on the patched commit using the production
createMemoryGetToolimplementation, builtin memory backend, real filesystem workspace, and registered wiki supplement. The proof script confirmsmemory/entities/alpha.mddoes not exist on disk before calling the tool.node --import tsx "$EVIDENCE_DIR/proof-memory-get-empty-miss.mts"{ "backend": "builtin", "corpus": "all", "requestedPath": "memory/entities/alpha.md", "targetExistsBeforeRead": false, "resultDetails": { "corpus": "wiki", "path": "memory/entities/alpha.md", "title": "Alpha", "kind": "entity", "fromLine": 7, "lineCount": 2, "text": "Alpha wiki supplement served after a real empty memory miss." } }The exact
memory_getcall returned the wiki supplement details instead of{ text: "", path: "memory/entities/alpha.md" }while the requested memory file was absent from the real workspace.No hosted wiki process or remote agent session was used. The proof covers the local production tool boundary, builtin memory file reader, filesystem miss behavior, and supplement registry path.
Regression Test Plan
extensions/memory-core/src/tools.citations.test.tsA
memory_getrequest withcorpus=allreadsmemory/entities/alpha.md, the memory read returns the production missing-file shape{ text: "", path }, and a registered wiki supplement for the same path must be returned.The regression test locks the exact successful-empty-miss branch that used to bypass the supplement lookup, while existing
memory_get|corpus=alltests continue to cover the thrown-error fallback and neighboring corpus behavior.node scripts/run-vitest.mjs extensions/memory-core/src/tools.citations.test.ts -t "memory_get|corpus=all"The new regression test passes with the existing
corpus=allandmemory_getcoverage.The full
tools.citations.test.tsfile was not used as the final gate because an unrelated existing citation test timed out before this patch; the focusedmemory_get|corpus=allsubset passed after the fix.Merge risk
No merge-risk label should be needed.
merge-risk: session-statewas considered because this touches memory-core exact read behavior, but the change does not alter stored session data, session visibility, memory indexing, search ranking, provider routing, message delivery, auth, security boundaries, dependencies, or repository infrastructure.The new supplement lookup runs only when
requestedCorpus === "all"and the memory read result exactly matches a missing-file empty result. Results that includefrom/lines, truncation metadata, disabled/error fields, or any non-empty text continue to bypass this fallback.The branch adds the behavior that
corpus=allalready promises without broadeningcorpus=memory, explicitcorpus=wiki, or normal successful memory reads.Patch quality
Root cause fix.
High. The root cause is isolated to a single success-path early return, the patch is gated to one exact result shape, and both focused regression tests and production-tool proof pass.
No unrelated cleanup, docs changes, dependency changes, or generated artifacts are included. The helper's default
return falseis intentional: non-object values, arrays, and any read result that is not the exact missing-file contract must keep the previous direct-return behavior.