v3.10.25

ruvnet/ruflov3.10.25May 30, 2026by ruvnet

AI Summary

This release introduces a reproducible BEIR benchmark harness and achieves top-2 ranking on the NFCorpus dataset with nDCG@10 = 0.352 using BGE-base-en-v1.5. It also fixes a critical environment bug where the embedding path could silently degrade to hash fallback due to a sharp/libvips issue on darwin-arm64, now bypassed through a direct BGE loading path.

Key Highlights

  • Achieved nDCG@10 = 0.352 on BEIR NFCorpus, ranking #2 out of 11 methods against public baselines
  • Fixed critical silent degradation bug where embedding path fell back to BM25 due to sharp/libvips issue on darwin-arm64
  • New direct BGE dense path bypassing problematic dependencies via @xenova/transformers
  • Created reproducible BEIR benchmark harness with on-disk embedding cache
  • Added support for bge-small (33M), bge-base (110M), and bge-large (335M) models

Breaking Changes

  • The `_realEmbedding: true` flag bug in neural-tools.ts is bypassed but not fixed - tracked separately

New Features

  • New src/memory/bge-embedder.ts - lazy-loaded singleton with CLS-token pooling and L2 normalization
  • New scripts/run-beir-nfcorpus.mjs - hybrid pipeline harness
  • New scripts/run-beir-bge.mjs - direct-dense BEIR runner with dataset auto-detect
  • New docs/benchmarks/BEIR-MATRIX.md - public benchmark tracking page

Full Release Notes

## ruflo 3.10.25 — reproducible BEIR NFCorpus benchmark, nDCG@10 0.352, top-2 against listed public baselines

We now have a reproducible BEIR benchmark harness, run JSONs, per-query metrics
(in 3.10.26), and a clean direct BGE dense path.

## First public result: BEIR NFCorpus

**nDCG@10 = 0.352** using **BGE-base-en-v1.5 (110M params)** via the direct
dense path (no fine-tuning, no hybrid BM25+dense fusion, no cross-encoder
reranker). Internal hybrid pipeline is isolated from this comparison so the
dense-vs-dense numbers stay honest.

| Rank | Method | Params | nDCG@10 |
|---:|---|---:|---:|
| 1 | BGE-large-v1.5 (listed) | 335M | 0.380 |
| **2** | **ruflo + BGE-base-en-v1.5 ← us** | **110M** | **0.352** |
| 3 | SPLADE++ | 110M | 0.347 |
| 4 | GTR-XL | 1.2B | 0.343 |
| 5 | DocT5query / Contriever | — | 0.328 |
| 7 | BM25 (Lucene) | — | 0.325 |
| 8 | TAS-B / GenQ | — | 0.319 |
| 10 | ColBERT | 110M | 0.305 |
| 11 | SBERT msmarco | 110M | 0.272 |

This is **top-2 on BEIR NFCorpus**, NOT "top-2 on BEIR." BEIR is an 18-dataset
suite; NFCorpus is one dataset. The broader BEIR average requires TREC-COVID,
FiQA, ArguAna, HotpotQA, NQ, etc. SciFact (2nd dataset) is queued.

## The more important part — the audit trail

We found and fixed a real environment bug where the embedding path could
silently degrade into hash fallback because of a `sharp`/`libvips` issue on
darwin-arm64. The neural store reported `_realEmbedding: true` because the
*import* succeeded — but per-call embeds threw and got swallowed by an inner
catch. The pure-BM25 path (with broken random cosine) was carrying the entire
"hybrid" signal undetected.

The new path bypasses that dependency by loading BGE directly through
`@xenova/transformers`'s `AutoTokenizer` + `AutoModel`. Text bi-encoders
don't need image preprocessing; `sharp` is a transitive dep that's never
needed for retrieval.

## What changed in code

1. **`src/memory/bge-embedder.ts`** — lazy-loaded singleton, supports
   bge-small (33M, 384-dim), bge-base (110M, 768-dim, default),
   bge-large (335M, 1024-dim). CLS-token pooling + L2 normalisation
   per BAAI spec.
2. **`scripts/run-beir-nfcorpus.mjs`** — hybrid-pipeline harness; with the
   embedder broken this collapses to pure-BM25 (measured 0.289 vs published
   BM25 0.325).
3. **`scripts/run-beir-bge.mjs`** — direct-dense BEIR runner, on-disk
   embedding cache, dataset auto-detect.
4. **`docs/benchmarks/BEIR-MATRIX.md`** — public benchmark tracking page
   (added in 3.10.26).

## Reproduce

```bash
git clone https://github.com/ruvnet/ruflo && cd ruflo
npm install && ( cd v3/@claude-flow/cli && npx tsc )

mkdir -p /tmp/beir-nfcorpus && cd /tmp/beir-nfcorpus
curl -sL -o nfcorpus.zip 'https://public.ukp.informatik.tu-darmstadt.de/thakur/BEIR/datasets/nfcorpus.zip'
unzip -q nfcorpus.zip

# BGE-base direct dense (one-time ~25min ingest + ~2min full eval)
node /path/to/v3/@claude-flow/cli/scripts/run-beir-bge.mjs
# → nDCG@10 0.352, rank 2/11 against listed baselines

# Cached subsequent runs (~2 min)
SKIP_INGEST=1 node /path/to/scripts/run-beir-bge.mjs
```

## Honest limits

- **One BEIR dataset measured.** SciFact in progress; broader BEIR average
  tracked.
- **Zero-shot, no fine-tuning.** NFCorpus has a 110K-pair train split that
  could fine-tune for an additional ~0.02-0.05 nDCG.
- **The 0.005 gap to SPLADE++ is small.** Paired bootstrap CI shipping
  in 3.10.26 will determine if it's statistically significant.
- **The `_realEmbedding: true` lie in `neural-tools.ts` is bypassed, not
  fixed.** BGE direct-API path is the workaround; the underlying flag bug
  is tracked.

## Install

```bash
npx ruflo@3.10.25    # latest / alpha / v3alpha all aligned
```

Full ADR: [v3/docs/adr/ADR-085-beir-public-benchmark.md](v3/docs/adr/ADR-085-beir-public-benchmark.md)