Files
rUv 277c7bc03a dream(memory): #3168 wire embedding-cosine into SmartRetrieval's MMR step (evaluated, ACCEPT) (#3169)
* 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>
2026-09-05 11:57:23 -04:00
..
2026-01-04 23:50:45 +00:00
2026-01-04 23:50:45 +00:00
2026-01-05 16:42:40 +00:00
2026-02-08 17:11:18 +00:00
2026-01-05 17:28:09 +00:00
2026-02-08 03:36:33 +00:00
2026-02-08 03:37:26 +00:00
2026-02-08 03:36:39 +00:00
2026-02-08 03:38:14 +00:00
2026-01-05 17:28:09 +00:00