Implements 23 tasks across 4 phases per docs/implementation/ruvector-integration-plan.md: Phase 1 — Foundation (make what we have faster): - Native HNSW backend via @ruvector/router (150x search speedup, ADR-081) - Metadata filtering layer with composable AND/OR/NOT/FIELD expressions - Temporal tensor compression (Int8Array quantization, 4x memory reduction) - Deterministic golden-ratio dithering for cross-platform reproducibility - 15 feature flags (all default false) with CLI profiles Phase 2 — Intelligence (make agents smarter): - Neural TinyDancer router with REINFORCE policy gradient (ADR-082) - SONA three-loop enhancement (MicroLoRA 0.18μs/adapt via WASM) - Cross-domain transfer learning with Thompson Sampling (ADR-084) - Regret tracking with log-log regression growth classification Phase 3 — Safety (make agents trustworthy): - Sheaf-gated test validation via prime-radiant CohomologyEngine - Coherence-gated agent actions (3-filter pipeline, ADR-083) - Witness chain audit trail with SHA-256 hash linking - HNSW health monitoring with spectral analysis Phase 4 — Differentiation (make AQE unique): - Cognitive container export/import (RVF v2) - DAG attention scheduler for dependency-aware test ordering - CNN visual regression with spatial pooling embeddings - Behavior tree orchestration (Sequence/Selector/Parallel) - Reasoning QEC with majority-vote consensus - Browser QE dashboard scaffolding Also: remove obsolete v2-to-v3-migration test (source already removed), add ADR-081 through ADR-085, research docs, benchmarks, and integration test suites for all 4 phases. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
14 KiB
ADR-081: Native HNSW Integration via NAPI (ruvector-router-ffi)
| Field | Value |
|---|---|
| Decision ID | ADR-081 |
| Status | Proposed |
| Date | 2026-03-15 |
| Author | Architecture Team |
| Review Cadence | 6 months |
WH(Y) Decision Statement
In the context of AQE v3's vector search subsystem, which currently operates three fragmented HNSW implementations (ADR-071) -- a pure TypeScript HNSW, a RuvectorFlatIndex wrapping @ruvector/gnn, and a QEGNNEmbeddingIndex -- all running in JavaScript with cold-start index rebuilds from SQLite BLOBs,
facing a measured 150x-12,500x performance gap between AQE's JavaScript-based HNSW and the native Rust ruvector-router-ffi implementation (which achieves <0.5ms p50 at 1M vectors via SIMD-accelerated HNSW with AVX2/NEON/SIMD128), cold-start rebuild latency that grows linearly with the 150K+ pattern count, and the inability to leverage hardware-specific acceleration (AVX2, ARM NEON) from JavaScript,
we decided for adopting ruvector-router-ffi as the primary vector search engine via its NAPI-RS Node.js bindings, replacing all three existing JavaScript HNSW implementations with a single native backend, while maintaining a pure-JavaScript fallback (the existing TypeScript HNSW) for environments where native binaries are unavailable (CI containers, restricted platforms, WASM-only deployments),
and neglected (a) continuing with JavaScript-only HNSW (rejected: 150x+ performance gap is a measurable bottleneck at 150K+ patterns and will worsen as the knowledge base grows), (b) using RVF INDEX_SEG exclusively without the router-ffi layer (rejected: INDEX_SEG provides persistence but router-ffi provides the query-time SIMD acceleration; both are needed), (c) adopting an external vector database like Qdrant or Chroma (rejected: adds service dependency, does not integrate with ruvector ecosystem, and breaks the embedded deployment model),
to achieve sub-millisecond vector search at the current 150K+ scale with headroom to 1M+ patterns, elimination of cold-start index rebuilds via persistent HNSW state, unified vector search quality across all subsystems (patterns, QE memory, learning pipeline), and hardware-accelerated distance computation via platform-specific SIMD,
accepting that this introduces a native binary dependency (NAPI-RS compiled for linux-x64, darwin-arm64, win32-x64) that increases install complexity, requires maintaining a JavaScript fallback for unsupported platforms, and creates a tighter coupling to the ruvector ecosystem for a core capability.
Context
AQE v3's pattern retrieval performance is bounded by its JavaScript HNSW implementations. The Six Thinking Hats analysis (2026-03-15) identified a 150x-12,500x speed gap between AQE's current vector search and ruvector-router-ffi's native Rust implementation. At the current 150K+ pattern scale, this gap manifests as:
-
Query latency: JavaScript HNSW delivers 10-50ms per query at 10K vectors. ruvector-router-ffi delivers <0.5ms at 1M vectors -- a 20-100x improvement on queries alone.
-
Cold-start rebuild: Every process restart triggers a full HNSW index reconstruction from SQLite BLOBs. At 150K patterns with 384-dimensional embeddings, this takes multiple seconds. ruvector-router-ffi persists index state natively, eliminating rebuild entirely.
-
SIMD acceleration: JavaScript cannot access AVX2 (256-bit), ARM NEON (128-bit), or WASM SIMD128 instructions. ruvector-router-ffi auto-detects the best available SIMD backend at runtime, achieving 4-8x speedup on distance computations compared to scalar operations.
ADR-071 already decided to unify the three HNSW implementations behind a single HnswIndexProvider interface backed by RVF INDEX_SEG. This ADR specifies the concrete runtime engine (ruvector-router-ffi via NAPI) that powers that interface, and defines the fallback strategy for environments where native binaries are unavailable.
Benchmark Data (from research)
| Operation | JS HNSW (current) | ruvector-router-ffi (NAPI) | Speedup |
|---|---|---|---|
| 10-NN query (10K vectors) | 10-50ms | <0.1ms | 100-500x |
| 10-NN query (100K vectors) | 50-200ms | <0.3ms | 167-667x |
| 10-NN query (1M vectors) | N/A (OOM) | <0.5ms | N/A |
| Index construction (10K) | 2-5s | <100ms | 20-50x |
| Cold-start rebuild (150K) | 5-15s | 0ms (persistent) | Infinite |
Options Considered
Option 1: ruvector-router-ffi via NAPI-RS with JS Fallback (Selected)
Use ruvector-router-ffi's pre-built NAPI-RS bindings (@ruvector/router-node) as the primary vector search engine. Detect native binary availability at startup. If available, use native; if not, fall back to the existing TypeScript HNSW implementation with a startup warning.
Pros:
- Sub-millisecond queries at 1M+ scale via SIMD-accelerated HNSW
- Persistent index state eliminates cold-start rebuild
- Auto-detection of best SIMD backend (AVX2, NEON, SIMD128, scalar)
- Graceful degradation to JavaScript when native is unavailable
- Single codebase via HnswIndexProvider interface (ADR-071)
- Integrates with RVF INDEX_SEG for persistence (ADR-066)
Cons:
- Pre-built binaries needed for each target platform (linux-x64, darwin-arm64, win32-x64)
- Native dependency increases npm install size (~5-15MB per platform)
- Two code paths (native + JS fallback) during transition period
- Native binary version must stay synchronized with @ruvector/rvf version
Option 2: JavaScript-Only HNSW with Optimization (Rejected)
Optimize the existing TypeScript HNSW with WebAssembly-compiled distance functions and lazy loading.
Why rejected: Even with WASM distance functions, JavaScript HNSW cannot match native SIMD throughput. The V8 JIT cannot generate AVX2 vector instructions from JavaScript. Lazy loading does not solve the fundamental O(n) cold-start problem. The performance ceiling for JavaScript HNSW is approximately 10x current speed, still 15-1,250x slower than native.
Option 3: RVF INDEX_SEG Only (Without router-ffi) (Rejected)
Use RVF's INDEX_SEG for persistence and its built-in query capabilities without the router-ffi layer.
Why rejected: INDEX_SEG provides persistent storage of HNSW graph structure and progressive 3-layer loading, but query execution still requires a runtime engine. ruvector-router-ffi provides the SIMD-accelerated query engine that operates on INDEX_SEG data. The two are complementary: INDEX_SEG for persistence, router-ffi for query-time acceleration.
Option 4: External Vector Database (Rejected)
Adopt Qdrant, Chroma, or Milvus as the vector search backend.
Why rejected: Introduces an external service dependency (separate process, network latency, deployment complexity). Breaks AQE's embedded single-process deployment model. Does not integrate with ruvector's SONA learning pipeline, attention mechanisms, or coherence gating. Network round-trip latency (1-10ms) negates much of the native speed advantage.
Implementation
Native Detection and Fallback Strategy
// src/vectors/native-hnsw-provider.ts
interface NativeHnswProviderConfig {
/** Path to .rvf file for persistent index storage */
rvfPath: string;
/** Embedding dimensions (default: 384) */
dimensions: number;
/** Whether to allow JS fallback if native is unavailable */
allowJsFallback: boolean;
/** HNSW configuration */
hnsw: {
m: number; // Default: 32
efConstruction: number; // Default: 200
efSearch: number; // Default: 100
};
}
class NativeHnswProvider implements HnswIndexProvider {
private backend: 'native' | 'js-fallback';
static async create(config: NativeHnswProviderConfig): Promise<NativeHnswProvider> {
try {
// Attempt to load native NAPI binding
const native = require('@ruvector/router-node');
await native.initialize({ simd: 'auto' });
return new NativeHnswProvider(native, 'native', config);
} catch (error) {
if (!config.allowJsFallback) {
throw new Error(
'Native HNSW binary not available and JS fallback disabled. ' +
'Install @ruvector/router-node or set allowJsFallback: true.'
);
}
console.warn(
'[AQE] Native HNSW unavailable, using JS fallback. ' +
'Install @ruvector/router-node for 150x+ faster vector search.'
);
return new NativeHnswProvider(null, 'js-fallback', config);
}
}
}
SIMD Backend Selection
ruvector-router-ffi auto-detects the best available SIMD instruction set at startup:
| Platform | SIMD Backend | Distance Throughput |
|---|---|---|
| x86_64 (modern) | AVX2 (256-bit) | ~2B ops/sec |
| x86_64 (older) | SSE4.2 (128-bit) | ~1B ops/sec |
| Apple Silicon | NEON (128-bit) | ~1.5B ops/sec |
| WASM | SIMD128 | ~500M ops/sec |
| Any (fallback) | Scalar | ~200M ops/sec |
Integration with HnswIndexProvider (ADR-071)
The native provider implements the same HnswIndexProvider interface defined in ADR-071, maintaining named indexes:
class NativeHnswProvider implements HnswIndexProvider {
async getIndex(name: string, config?: IndexConfig): Promise<HnswIndex> {
if (this.backend === 'native') {
return new NativeHnswIndex(this.native, name, config);
}
return new TypeScriptHnswIndex(name, config); // JS fallback
}
async getLayerStatus(name: string): Promise<LayerStatus> {
if (this.backend === 'native') {
// Native provides progressive layer status from INDEX_SEG
return this.native.getLayerStatus(name);
}
// JS fallback has a single layer (always fully loaded)
return { layerA: { ready: true, recall: 1.0, latencyMs: 10 },
layerB: { ready: true, recall: 1.0, latencyMs: 10 },
layerC: { ready: true, recall: 1.0, latencyMs: 10 } };
}
}
Migration Path
- Week 1: Add @ruvector/router-node as an optional dependency. Implement NativeHnswProvider with fallback.
- Week 2: Wire NativeHnswProvider behind
useNativeHnswfeature flag (default: false). Shadow mode: run both native and JS, compare results. - Week 3: Validate recall parity (top-10 results match >98% between native and JS). Benchmark latency improvement.
- Week 4: Enable native by default for new installations. Existing installations opt-in via feature flag.
- Week 6: Remove feature flag. Native is default. JS remains as automatic fallback.
Observability
interface HnswMetrics {
backend: 'native' | 'js-fallback';
simdBackend: 'avx2' | 'neon' | 'sse42' | 'simd128' | 'scalar';
queryLatencyP50Ms: number;
queryLatencyP99Ms: number;
indexSizeVectors: number;
coldStartMs: number; // 0 for native (persistent index)
fallbackCount: number; // Times native was unavailable
}
Dependencies
| Relationship | ADR ID | Title | Notes |
|---|---|---|---|
| Implements | ADR-071 | HNSW Implementation Unification | Provides the concrete native backend for the unified HnswIndexProvider |
| Depends On | ADR-066 | RVF-backed Pattern Store with Progressive HNSW | Uses INDEX_SEG for persistent index storage |
| Depends On | ADR-065 | RVF Integration Strategy -- Hybrid Architecture | Native HNSW operates within the hybrid persistence architecture |
| Extends | ADR-050 | RuVector Neural Backbone | Replaces JS HNSW wrappers with native ruvector engine |
| Relates To | ADR-060 | Semantic Anti-Drift | Anti-drift embedding computation benefits from native speed |
| Relates To | ADR-038 | Memory Unification | Unified memory HNSW migrates to native backend |
| Part Of | MADR-001 | V3 Implementation Initiative | RVF integration -- Phase 1 Foundation |
References
| Ref ID | Title | Type | Location |
|---|---|---|---|
| RES-001 | RuVector Core & Infrastructure Research | Research Report | docs/research/ruvector-core-infrastructure.md |
| RES-002 | RuVector Router, SONA & Utilities Research | Research Report | docs/research/ruvector-routing-sona-utilities.md |
| RES-003 | Six Thinking Hats Analysis | Analysis | docs/research/six-thinking-hats-aqe-ruvector-analysis.md |
| EXT-001 | ruvector-router-ffi | npm Package | @ruvector/router-node NAPI-RS bindings |
| EXT-002 | ruvector-core HNSW | Technical Spec | ruvector-core HNSW documentation |
Governance
| Review Board | Date | Outcome | Next Review |
|---|---|---|---|
| Architecture Team | 2026-03-15 | Proposed | 2026-09-15 |
Status History
| Status | Date | Notes |
|---|---|---|
| Proposed | 2026-03-15 | Initial creation from Six Thinking Hats analysis Phase 1 recommendation. Specifies ruvector-router-ffi via NAPI as the native HNSW engine for ADR-071's unified HnswIndexProvider. |
Definition of Done Checklist
Before requesting approval, verify:
Core (ECADR)
- E - Evidence: Benchmark validates >100x speedup over JS HNSW at 150K vectors
- C - Criteria: 4 options compared (native NAPI, JS-only, INDEX_SEG-only, external DB)
- A - Agreement: Relevant stakeholders consulted
- D - Documentation: WH(Y) statement complete, ADR published
- R - Review: Review cadence set, owner assigned
Extended
- Dp - Dependencies: ADR-071, ADR-066, ADR-065, ADR-050 relationships documented
- Rf - References: Research reports linked, benchmark data cited
- M - Master: Linked to MADR-001 V3 Implementation Initiative