mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-09-14 14:01:28 +08:00
277c7bc03a
* dream(memory): wire embedding-cosine into SmartRetrieval's MMR step (evaluated, ACCEPT) smart-retrieval.ts's MMR diversity re-ranking used token-Jaccard text overlap as its "similarity to already-selected" term, even though memory-initializer.ts's searchEntries() already computes real ONNX-embedding cosine similarity for the primary relevance score and discards it before returning. 2025-2026 production practice (LangChain's reference maximal_marginal_relevance, Qdrant's native Mmr query shipped Sept 2025, Weaviate's MMR reranker shipped in 1.37) universally uses embedding-cosine for this term; token overlap misses low-token-overlap paraphrases embeddings correctly flag as near-duplicates. Threads the embedding through: searchEntries()'s two live compute sites (RaBitQ rerank, brute-force SQL) now return it instead of discarding it; the two CLI/MCP bridge mappers (memory-tools.ts, commands/memory.ts) pass it through; SearchCandidate gains an optional `embedding` field; mmrRerank uses cosine when both candidates have one, falling back to token-Jaccard otherwise (existing callers/tests without embeddings are unaffected). controller-registry.ts's separate toCands()/applyMMR path had the same gap for a different reason (embedding available on r.entry.embedding but never copied) — fixed the same way. Evaluated via deterministic Vitest, zero LLM calls, $0 cost. New discriminating test: a low-token-overlap paraphrase (near-1.0 cosine to the seed) vs. a genuinely different topic (near-0 cosine). Baseline (git stash-isolated): picks the paraphrase second (Jaccard can't tell "low overlap because paraphrase" from "low overlap because unrelated"). Candidate: correctly picks the different topic second. Full @claude-flow/memory suite: 460/461 passing identically with/without the candidate (1 pre-existing chmod-based environmental failure, same class documented since 2026-08-15). tsc --noEmit: zero new errors (verified @claude-flow/cli's 455 pre-existing errors, from unbuilt workspace packages, are identical with and without this diff). Darwin: skipped, scope mismatch (correctness/similarity-metric fix with a discriminating unit test, not a continuous parameter with a gold-labeled corpus). Co-Authored-By: RuFlo <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01Qho5K4p5ACBt4yzCWjkBGe * dream(memory): address review remediation — split CI, real benchmark, hardening Response to ruvnet's REJECT review on #3169: 1. Split — dream-cycle-backlog-guard.yml moved out to #3205; this branch now carries only the MMR fix, rebased onto main (which already includes the merged #3203 CI fix). 2. Real benchmark (new src/mmr-benchmark.test.ts): 18-doc/6-topic labeled corpus (1 canonical + 2 low-token-overlap paraphrases per topic), run through the actual smartSearch/mmrRerank code, swept across mmrLambda in {0.3, 0.5, 0.7, 0.9} rather than one favorable value. Honest finding: at diversity-heavy lambda, candidate's recall/nDCG drop sharply vs. baseline, because cosine correctly suppresses same-topic near-duplicates that Jaccard fails to detect at all (and so "accidentally" keeps full recall). At smart-retrieval.ts's own default (lambda=0.7), recall@6/nDCG@6 are identical to baseline (1.000/0.777 both) while topic-diversity improves 0.472->0.667 and ground-truth duplicate-rate drops 0.289->0.200. Reports latency (sub-ms both paths at this corpus size) and a memory-overhead estimate. 3. Malformed/dimension-mismatch: found and fixed a real bug while writing these cases. A NaN/Infinity-poisoned embedding component reached cosineSimilarity unguarded; the poisoned NaN score meant `mmr > bestMmr` was never true (NaN comparisons are always false in JS), which could silently break MMR's selection loop and under-fill results below the requested limit. Added isWellFormedEmbedding() so malformed/empty embeddings fall back to token-Jaccard, same as absent/mismatched ones. 3 new cases (NaN/Infinity, empty array, explicit dimension-mismatch) plus a test mirroring the two real CLI/MCP output whitelists (memory-tools.ts:559-569, commands/memory.ts:633-639) to assert `embedding` cannot appear in either shape. 4. Determinism: new test runs the same input through smartSearch 5 times concurrently, asserts byte-identical result ordering every time, including a genuine same-embedding tie. Full @claude-flow/memory suite: 465/466 (1 pre-existing, unrelated environmental failure). tsc --noEmit: zero errors. Co-Authored-By: RuFlo <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01Qho5K4p5ACBt4yzCWjkBGe --------- Co-authored-by: Claude <noreply@anthropic.com>