Skip to content

fix(memory): fall back to wiki for missing all-corpus reads#100904

Merged
vincentkoc merged 2 commits into
openclaw:mainfrom
mushuiyu886:fix/followup-77356
Jul 6, 2026
Merged

fix(memory): fall back to wiki for missing all-corpus reads#100904
vincentkoc merged 2 commits into
openclaw:mainfrom
mushuiyu886:fix/followup-77356

Conversation

@mushuiyu886

Copy link
Copy Markdown
Contributor

Summary

  • Fix memory_get with corpus=all so a valid empty memory miss can still read a registered wiki supplement.
  • Add regression coverage for the non-throwing miss shape returned by the real memory file reader.

Origin / follow-up

Root Cause

  • 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 }, while executeMemoryReadResult treated every successful read as final by immediately returning jsonResult(result). That caused memory_get corpus=all to stop before the wiki supplement lookup even though the corpus=all contract selected both memory and wiki sources.
  • Why this is root-cause fix:
    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, empty text, and no from/lines/truncation/error metadata. For corpus=all, that exact state now enters the existing supplement read path; existing file reads, partial empty excerpts, disabled results, and corpus=memory behavior still return the original memory result.
  • Why it matters / User impact:
    A user asking for corpus=all expects the exact read to search both memory and wiki sources. Before this patch, a missing memory file could hide an available wiki entry even though corpus=all selected both corpora.
  • What did NOT change:
    The patch does not change memory indexing, search ranking, provider routing, session visibility, file path validation, corpus=memory, explicit corpus=wiki, or normal successful reads. It only changes the empty-miss branch for memory_get corpus=all.
  • Architecture / source-of-truth check:
    The source-of-truth contract is readMemoryFile returning { text: "", path } for missing valid memory files, while buildMemoryReadResult adds from/lines metadata 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

  • Behavior or issue addressed:
    memory_get with corpus=all should return a wiki supplement when the memory backend returns a non-throwing empty miss for the requested valid memory path.
  • Real environment tested:
    Local OpenClaw worktree on the patched commit using the production createMemoryGetTool implementation, builtin memory backend, real filesystem workspace, and registered wiki supplement. The proof script confirms memory/entities/alpha.md does not exist on disk before calling the tool.
  • Exact steps or command run after this patch:
    node --import tsx "$EVIDENCE_DIR/proof-memory-get-empty-miss.mts"
  • Evidence after fix:
    {
      "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."
      }
    }
  • Observed result after fix:
    The exact memory_get call returned the wiki supplement details instead of { text: "", path: "memory/entities/alpha.md" } while the requested memory file was absent from the real workspace.
  • What was not tested:
    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

  • Target test file:
    extensions/memory-core/src/tools.citations.test.ts
  • Scenario locked in:
    A memory_get request with corpus=all reads memory/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.
  • Why this is the smallest reliable guardrail:
    The regression test locks the exact successful-empty-miss branch that used to bypass the supplement lookup, while existing memory_get|corpus=all tests continue to cover the thrown-error fallback and neighboring corpus behavior.
  • Exact steps or command run after this patch:
    node scripts/run-vitest.mjs extensions/memory-core/src/tools.citations.test.ts -t "memory_get|corpus=all"
  • Evidence after fix:
    Test Files  1 passed (1)
    Tests  10 passed | 11 skipped (21)
    
  • Observed result after fix:
    The new regression test passes with the existing corpus=all and memory_get coverage.
  • What was not tested:
    The full tools.citations.test.ts file was not used as the final gate because an unrelated existing citation test timed out before this patch; the focused memory_get|corpus=all subset passed after the fix.

Merge risk

  • Risk labels considered:
    No merge-risk label should be needed. merge-risk: session-state was 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.
  • Risk explanation:
    The new supplement lookup runs only when requestedCorpus === "all" and the memory read result exactly matches a missing-file empty result. Results that include from/lines, truncation metadata, disabled/error fields, or any non-empty text continue to bypass this fallback.
  • Why acceptable:
    The branch adds the behavior that corpus=all already promises without broadening corpus=memory, explicit corpus=wiki, or normal successful memory reads.

Patch quality

  • Fix classification:
    Root cause fix.
  • Maintainer-ready confidence:
    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.
  • Patch quality notes:
    No unrelated cleanup, docs changes, dependency changes, or generated artifacts are included. The helper's default return false is intentional: non-object values, arrays, and any read result that is not the exact missing-file contract must keep the previous direct-return behavior.

@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 9:50 AM ET / 13:50 UTC.

Summary
Adds a missing-read detector so memory_get with corpus=all can fall through to registered corpus supplements when the memory reader returns the successful empty miss shape, plus a regression test.

PR surface: Source +39, Tests +37. Total +76 across 2 files.

Reproducibility: yes. Current main is source-reproducible: executeMemoryReadResult returns successful memory reads immediately, while both memory readers return { text: "", path } for a validated missing file, so corpus=all never reaches supplement lookup on that path.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: vector/embedding metadata: extensions/memory-core/src/tools.citations.test.ts, vector/embedding metadata: extensions/memory-core/src/tools.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • No repair lane is needed; the open PR already contains the narrow code and test change and should proceed through normal maintainer review.

Security
Cleared: The diff is limited to memory-core TypeScript logic and a focused test, with no dependency, CI, secret, install, or publishing surface change.

Review details

Best 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: executeMemoryReadResult returns successful memory reads immediately, while both memory readers return { text: "", path } for a validated missing file, so corpus=all never reaches supplement lookup on that path.

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 changes

Label changes:

  • add P2: This is a normal-priority memory-core bug fix with limited blast radius in memory_get corpus=all fallback behavior.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix copied live output from a production createMemoryGetTool run against a real filesystem workspace with the target memory file absent and a registered wiki supplement returned.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix copied live output from a production createMemoryGetTool run against a real filesystem workspace with the target memory file absent and a registered wiki supplement returned.

Label justifications:

  • P2: This is a normal-priority memory-core bug fix with limited blast radius in memory_get corpus=all fallback behavior.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix copied live output from a production createMemoryGetTool run against a real filesystem workspace with the target memory file absent and a registered wiki supplement returned.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix copied live output from a production createMemoryGetTool run against a real filesystem workspace with the target memory file absent and a registered wiki supplement returned.
Evidence reviewed

PR surface:

Source +39, Tests +37. Total +76 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 40 1 +39
Tests 1 37 0 +37
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 77 1 +76

What I checked:

Likely related people:

  • vincentkoc: Current-main blame for the supplement read helper and executeMemoryReadResult points to Vincent Koc on commit fa70403403da, which currently carries this tool-boundary behavior. (role: recent area contributor; confidence: medium; commits: fa70403403da; files: extensions/memory-core/src/tools.ts)
  • hclsys: Merged PR fix(memory): prevent memory-hit starvation in corpus=all by capping per-corpus results (#77337) #77356, authored by hclsys, changed the same memory-core all-corpus supplement surface and tests for search behavior. (role: adjacent all-corpus contributor; confidence: medium; commits: 5add41c1506a, d5edeae6ee9d; files: extensions/memory-core/src/tools.ts, extensions/memory-core/src/tools.citations.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jul 6, 2026
@vincentkoc vincentkoc self-assigned this Jul 6, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Land-ready maintainer validation for dcf0ffbda023fe3bca174369fe3c7a4f9329099d:

  • Verified the real producer contract in packages/memory-host-sdk/src/host/read-file.ts: a missing valid file returns { text: "", path }, while existing empty ranges carry from/lines.
  • Simplified the runtime check to the typed MemoryReadResult contract and added a negative regression proving a past-EOF range does not fall back to wiki.
  • ../../node_modules/.bin/oxfmt --check extensions/memory-core/src/tools.ts extensions/memory-core/src/tools.citations.test.ts
  • ../../node_modules/.bin/oxlint extensions/memory-core/src/tools.ts extensions/memory-core/src/tools.citations.test.ts
  • git diff --check
  • git merge-tree --write-tree --messages HEAD origin/main
  • Fresh structured AutoReview: clean, no accepted/actionable findings.
  • Exact-head CI run 28797419795: passed, including QA Smoke CI, build artifacts, lint, type, guard, dependency, and Node test shards.
  • OPENCLAW_TESTBOX=1 scripts/pr prepare-run 100904: passed with exact PR/prep head dcf0ffbda023fe3bca174369fe3c7a4f9329099d.

Known proof gaps: none for this narrow memory-core result-routing change.

@vincentkoc vincentkoc changed the title Fix memory_get all supplement fallback fix(memory): fall back to wiki for missing all-corpus reads Jul 6, 2026
@vincentkoc
vincentkoc merged commit 9042e80 into openclaw:main Jul 6, 2026
94 checks passed
@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
…#100904)

* Fix memory_get all supplement fallback

* refactor(memory): use typed missing-read contract

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…#100904)

* Fix memory_get all supplement fallback

* refactor(memory): use typed missing-read contract

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: memory-core Extension: memory-core P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants