perf(memory): add QMD search diagnostics and runtime cache#96655
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 26, 2026, 4:08 PM ET / 20:08 UTC. Summary PR surface: Source +934, Tests +969, Generated 0. Total +1903 across 15 files. Reproducibility: yes. at source/proof level: current main still routes QMD CLI/tool search through the implicated manager and debug-timer paths, and the PR supplies before/after CLI/tool logs. I did not run live QMD timing in this read-only review. Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Merge only after maintainer acceptance of the persisted QMD cache behavior and expanded debug surface, while keeping the broader QMD search strategy issue open. Do we have a high-confidence way to reproduce the issue? Yes, at source/proof level: current main still routes QMD CLI/tool search through the implicated manager and debug-timer paths, and the PR supplies before/after CLI/tool logs. I did not run live QMD timing in this read-only review. Is this the best way to solve the issue? Yes as a bounded first step, not as the full fix for the linked QMD overhead tracker. The implementation stays in memory-core, uses the existing SQLite plugin-state seam, and leaves broader grouped-search/concurrency decisions to the canonical issue. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 1089253ca97c. Label changesLabel justifications:
Evidence reviewedPR surface: Source +934, Tests +969, Generated 0. Total +1903 across 15 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
|
|
Step 1 to resolve #96561 |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
@clawsweeper re-review Resolved the reported merge conflict by rebasing onto current Also addressed the cache-key risk by adding a hashed QMD runtime spawn-environment fingerprint to the persisted validation/probe cache context, so PATH/XDG/QMD/HOME-relevant environment changes produce cache misses instead of waiting for TTL expiry. Added regression coverage for validation and probe cache misses when that fingerprint changes. Fresh validation: node scripts/run-vitest.mjs extensions/memory-core/src/memory/qmd-runtime-cache.test.ts extensions/memory-core/src/memory/qmd-manager.test.ts extensions/memory-core/src/memory/search-manager.test.ts extensions/memory-core/src/tools.test.ts extensions/memory-core/src/runtime-provider.test.ts src/plugin-sdk/memory-core-engine-runtime.test.ts
node scripts/check-sdk-package-extension-import-boundary.mjs
node scripts/check-src-extension-import-boundary.mjs
node --max-old-space-size=8192 --import tsx scripts/generate-plugin-sdk-api-baseline.ts --check
git diff --check
git diff --check origin/main...HEAD
git merge-tree --write-tree origin/main HEADResults: targeted Vitest passed, 2 shards / 6 files / 215 tests; both boundary checks passed; API baseline check passed; whitespace checks passed; merge simulation clean. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
I ran the same-machine env 2 comparison. Scope: isolated temp OpenClaw state, same synthetic corpus, same query, same QMD binary/device. Main results
After-branch debug also proves the cache behavior directly:
|
|
I ran 5 alternating before/after pairs in env 2. Order was: before1 -> after1 -> before2 -> after2 -> ... -> before5 -> after5 Each branch got 5 full harness runs. Each full run included 2 direct CLI-manager searches, 2 memory_search tool calls, 2 source CLI subprocess calls, and 1 forced missing-collection repair. All source CLI subprocesses exited 0 and returned 2 hits.
After-branch correctness checks from the same 5 runs:
|
What Problem This Solves
Refs #96561.
memory_searchandopenclaw memory searchcurrently have several seconds of wrapper-side latency above raw QMD search time. Before changing the query strategy further, maintainers need reliable attribution for manager acquisition, tool overhead, QMD collection validation, QMD capability probing, and search grouping.Baseline Metrics (Pre-Patch)
CLI Trace
A traced
openclaw memory searchinvocation with QMD showed this shape:Relevant config in that environment:
timeoutMs = 30000does not appear to cause the latency; it only raises the ceiling so searches do not hit a shorter timeout. The relevant behavior is that memory + sessions currently multiplies subprocess work.Tool Timing
The standard OpenClaw
memory_searchtool path was also timed separately and showed similar overhead above direct QMD:maxResults=1did not materially improve tool-call timing, and corpus-specific searches were still around 7s. That points away from result volume and toward fixed wrapper/search-path overhead.A later trace compared wall time against the tool result's own
debug.searchMsfield. From source,debug.searchMsstarts after manager acquisition and covers the measured search body plus tool-side filtering/decorating, so the gap points at work before or outside that measured search body:The stable ~4.8-5.0s outside
debug.searchMssuggests fixed pre-search overhead in the standard tool path.Why This Change Was Made
This is the diagnostics-first and near-term cache PR for the QMD wrapper latency issue. It intentionally does not redesign QMD search grouping yet.
Changes included:
qmd --versionwhen available, a hashed QMD runtime spawn-environment fingerprint, QMD index path, search mode, sources, and managed collection config.memory_searchcalls cannot overwrite or consume each other's debug state on a shared warm manager.supported: falsewhen a real combined collection-filter invocation is rejected.User Impact
QMD-backed memory searches should avoid repeated collection-list/show/help subprocess work across transient CLI/search-manager instances while preserving repair behavior when QMD reports stale or missing collections.
The debug payload now separates manager/tool/wrapper time from QMD search time so future latency fixes can be verified against real wall-clock attribution.
AI-assisted change; I reviewed the code, structured review output, and validation output before updating this draft PR.
Evidence
Latest validation after rebasing onto current
origin/mainat1cd6f81a46and adding the hashed QMD runtime environment cache key:Results:
origin/main: clean.Real Behavior Proof: QMD Cache And Repair
Redactions used below:
<PROOF_ROOT>,<WORKSPACE>,<STATE>,<HOME>,<QMD_BIN>, and<SNIPPET>. The proof used a synthetic temp workspace/state/home only, with syntheticMEMORY.mdandmemory/secondary.mdcontent containing the query tokenbasalt citrine qmd proof token.Repeated CLI-purpose QMD manager path, fresh cache then persisted cache hit:
Repeated
memory_searchtool path, fresh cache then persisted cache hit:Repeated
openclaw memory search --jsonsource-dev CLI timing against the same temp state also returned the two synthetic hits:Forced missing-collection repair after warming the cache:
Known scope note: this PR does not yet change QMD to one combined multi-collection candidate search or parallelize grouped source searches; it adds attribution and removes repeated validation/probe work first.