ruvector/.gitignore
rUv afcaf07669
feat(rvf): ANN search across COW branches (dual-graph merge) (#618)
* feat(rvf): ANN search across COW branches (dual-graph merge)

Stack on feat/queryable-cow-branches (PR #617).  That PR added branch(),
CowEngine, MembershipFilter, and parent_path — but the HNSW/ANN paths were
disabled for COW children (fell back to O(N) exact scan of child's own slab
only, missing parent vectors entirely).

This commit adds sub-linear ANN across the full parent ∪ child-edits view:

Design — dual-graph query + merge (LSM-ANN pattern):
1. Child arm  : query child's own HNSW (exact scan when child < 1 024 vectors)
2. Parent arm : lazily open parent store read-only, cache in parent_store
   Mutex<Option<Box<RvfStore>>>; query parent's HNSW (built once, no rebuild
   per branch)
3. Over-fetch  : k' = k × 4 from each arm to absorb tombstones / overrides
4. Merge       : child distances override parent for same ID; IDs removed from
   membership_filter (tombstoned via child delete) are excluded; re-rank by
   distance; return top-k
5. Chained COW : parent.query() walks parent's own HNSW; lineage works
   transitively

Key changes to rvf-runtime/src/store.rs:
- Add parent_store: Mutex<Option<Box<RvfStore>>> field (all constructors)
- Fix query_routed early-return: COW children with 0 child-side vectors
  must not bail before parent read-through
- New cow_ann_eligible() guard
- New query_via_index_cow() — the dual-graph merge (replaces O(N) fallback)
- New cow_exact_parent_scan() — exact parent read-through for the exact path;
  makes query_exact the correct ground-truth for recall comparison
- Update query_exact to call cow_exact_parent_scan for COW children
- Update delete() to tombstone parent IDs from membership_filter so
  child-side deletion of inherited parent vectors is correctly reflected

New integration tests (cow_ann_recall.rs, 4 tests):
- cow_ann_recall_vs_exact    : 1 200-vector base, branch, add/override/delete;
  ANN recall@10 vs exact ground truth — measured 1.0000 (>= 0.95 contract)
- cow_ann_override_correctness: child override returns child distance, not
  parent's stale entry
- cow_ann_tombstone_absent   : tombstoned ID absent from ANN and exact results
- cow_branch_size_independence: child file (162 bytes) stays << parent
  (163 803 bytes) after queries — no HNSW rebuild in child file

Approximation: dual-graph merge is slightly approximate (sub-linear in parent
size, not exact). Measured recall@10 = 1.00 at ef_search=300 on 1 200-vector
L2/32-dim dataset with C=4 over-fetch. force_exact=true always provides
ground truth via cow_exact_parent_scan.

Cost: 2 HNSW queries (child + parent), flat in parent size. Parent HNSW built
once on first COW query then cached. Child HNSW only when child has >= 1 024
vectors. RaBitQ-across-COW deferred (exact fallback used until then).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_019rVRYrRDKyxYK18kuVrDSf

* fix(diskann): make search_returns_self_as_nearest non-flaky

The test used max_degree=16 / beam=16 on a 128-node graph whose initial
topology comes from thread_rng() (VamanaGraph::init_random_graph).  With
small M and a random graph, point 5 can end up outside the 16-candidate
window reachable from the medoid in some seedings — causing an intermittent
CI failure unrelated to the caller's changes.

Fix: bump max_degree to 32 and build_beam to 64 (matching production
defaults) so the graph is dense enough to guarantee connectivity on 128
nodes; use n = v.len() as the search beam so the test validates the
"self is retrievable" property exhaustively rather than testing ANN
efficiency (which is covered by other tests).

Fixes pre-existing flaky failure observed in Tests (vector-index) CI job.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_019rVRYrRDKyxYK18kuVrDSf

---------

Co-authored-by: ruvnet <ruvnet@gmail.com>
2026-06-28 14:50:17 -04:00

165 lines
3.7 KiB
Text

# macOS
.DS_Store
# Generated by Cargo
# will have compiled files and executables
debug
target
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
# Generated by cargo mutants
# Contains mutation testing data
**/mutants.out*/
# RustRover
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Node.js
**/node_modules/
package-lock.json
!npm/package-lock.json
# UI build artifacts
ui/**/build/
ui/**/.svelte-kit/
ui/**/adapter-node/
# napi-rs build artifacts
*.node
index.js
index.d.ts
# @ruvector/sona ships committed JS bindings: CI's napi CLI version drifts
# (v3 emits no v2-style loader), which published an empty 0.1.6 (#516)
!npm/packages/sona/index.js
!npm/packages/sona/index.d.ts
# Environment variables and secrets
.env
**/.env
**/.env.local
**/.env.*.local
*.key
*.pem
credentials.json
# Removed Windows wrapper files per user request
hive-mind-prompt-*.txt
# Removed Windows wrapper files per user request
hive-mind-prompt-*.txt
examples/scipix/test_images/
.fastembed_cache/
# Apify actor storage datasets
examples/apify/*/storage/
# Claude Flow generated files
.claude/settings.local.json
.mcp.json
mcp.json
claude-flow.config.json
.swarm/
.hive-mind/
.claude-flow/
memory/
coordination/
memory/claude-flow-data.json
memory/sessions/*
!memory/sessions/README.md
memory/agents/*
!memory/agents/README.md
coordination/memory_bank/*
coordination/subtasks/*
coordination/orchestration/*
*.db
*.db-journal
*.db-wal
*.sqlite
*.sqlite-journal
*.sqlite-wal
claude-flow
# Removed Windows wrapper files per user request
hive-mind-prompt-*.txt
# Agent worktree directories (runtime-only, per-agent isolation)
.claude/worktrees/
# Native intelligence database (binary)
.claude/intelligence/data/intelligence.db
# Intelligence data files (generated, not tracked)
.claude/intelligence/data/*.json
# RuVector intelligence data
.ruvector/
.claude/statusline.sh
# Benchmark generated files
logs/
data/
# PhotonLayer MNIST cache (public dataset, fetched at bench time, never committed)
crates/photonlayer-bench/data/
# Large model files
*.gguf
test_models/*.gguf
# Compiled server binaries (built for Cloud Run deploy)
/mcp-brain-server
crates/mcp-brain-server/mcp-brain-server
# Backup files
*.bak
# Large model checkpoint files (use weights.bin for runtime)
model*/*.pt
model*/*.onnx
model*/*.onnx.data
# Build dist artifacts for examples
examples/*/dist/
# Unrelated report SVGs
*_report.svg
*_sky_map.svg
# Training data
training-data*.jsonl
# Extracted code artifacts
claude-code-extracted/
examples/open-claude-code/
examples/real-eeg-analysis/data/*.edf
examples/real-eeg-multi-seizure/data/*.edf
agentdb.rvf
agentdb.rvf.lock
.kalshi
bench_data/
# Hailo Dataflow Compiler droppings — `hailo` CLI writes these into
# whatever cwd it's invoked from, even with --output-dir set. Always
# transient so any tree they land in should ignore them.
acceleras.log
hailo_sdk.client.log
# Iter 228 — per-crate Cargo.lock files for the hailo workspace members
# (post iter-219 workspace rejoin). The parent workspace's Cargo.lock
# is canonical; cargo regenerates these locally as a side effect of
# `cargo fmt --manifest-path` etc., but they should never be committed.
crates/ruvector-hailo/Cargo.lock
crates/ruvector-hailo-cluster/Cargo.lock
crates/hailort-sys/Cargo.lock
crates/ruvector-mmwave/Cargo.lock
node_modules