* fix(kernel): resolve relative dbPath to prevent split-brain dual-database writes UnifiedPersistenceManager and HybridMemoryBackend pass static relative path '.agentic-qe/memory.db' to UnifiedMemoryManager, which overrides the resolved absolute path in the constructor via spread. When CWD differs from project root (e.g. tests running from v3/), this creates a duplicate database at v3/.agentic-qe/memory.db, splitting dream/concept data from patterns/KV data. Fix: resolve any relative dbPath through findProjectRoot() in the constructor, ensuring all callers converge on the single project-root database. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * release(v3.6.8): fix MCP auto-init, experience persistence, DB isolation, and missing deps - Fleet auto-initializes on MCP server startup (no manual fleet_init needed) - ExperienceReplay unified to read from captured_experiences table - Data migrator writes to captured_experiences instead of removed experiences table - Added fast-json-patch and jose to root package.json (fixes #262) - Wrapped MinCut dispose saveSnapshot in try/catch for test resilience - Kernel initializes UnifiedPersistence with temp DB for in-memory backend - All 6 MCP handler test files use memoryBackend:'memory' and resetUnifiedPersistence() - domain-handlers and wrapped-domain-handlers use beforeAll to prevent OOM Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add RVF integration plan, ADRs, and benchmark script - RVF integration implementation plan and Six Hats analyses - Phase 0 gate report for RVF integration readiness - ADR-065: RVF integration hybrid architecture - ADR-066: RVF pattern store progressive HNSW - ADR-067: Agent memory branching with RVF copy-on-write - AQE baseline benchmark script Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(tests): restore fleet after dispose in wrapped-domain-handlers beforeAll tests The "not initialized" tests call disposeFleet() but with beforeAll the fleet is only initialized once. Subsequent tests failed because the fleet was never re-initialized. Add handleFleetInit() after each dispose-based test to restore state for later tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
41 KiB
RVF Integration Implementation Plan (ADR-065)
Revised 2026-02-15 after Phase 0 validation. See
rvf-phase0-gate-report.mdfor full findings.
Architecture: SQLite + @ruvector/core Bridge
Phase 0 Finding: @ruvector/rvf (RvfDatabase) SDK is not functional — @ruvector/rvf-node and @ruvector/rvf-wasm are published stubs with no binaries. Progressive HNSW exists in Rust but is not wired into the runtime query path.
What works today: @ruvector/core (VectorDb, CollectionManager) — native in-memory vector engine, 8-4000x faster search than current SQLite BLOB approach.
Revised Decision: Use @ruvector/core VectorDb as hot in-memory search layer. SQLite keeps all persistence (KV, Q-values, GOAP, pattern metadata) plus durable vector storage for promoted patterns. When @ruvector/rvf-node ships with binaries, swap the backend via feature flag.
Current State:
- Persistence:
better-sqlite3in.agentic-qe/memory.db(UnifiedMemoryManager singleton) - Vector search:
InMemoryHNSWIndex(~250 LOC pure JS HNSW in unified-memory.ts:841) - HNSW (PatternStore):
@ruvector/gnnv0.1.19 (N-API, differentiable search) - Learning:
@ruvector/sonav0.1.5 (pattern learning) - Attention:
@ruvector/attentionv0.1.3 (Flash Attention) - Pattern Store: in-memory cache + lazy HNSW, persisted to
qe_patternstable - Feature Flags:
RuVectorFeatureFlagsinv3/src/integrations/ruvector/feature-flags.ts
Target State (Bridge):
- SQLite: KV store, RL Q-values, GOAP tables, hypergraph, dream cycles, feedback loops, durable vector storage for promoted patterns
@ruvector/coreVectorDb: hot in-memory search layer replacingInMemoryHNSWIndex- CollectionManager: per-domain vector isolation (test-generation, defect-intelligence, etc.)
- Lazy persistence: only flush vectors to SQLite when patterns are promoted/valuable
- Feature-flagged:
useRuvectorCorecontrols JS HNSW vs native VectorDb routing
Future Target (when rvf-node ships):
- RVF file (
.agentic-qe/patterns.rvf): replaces SQLite vector BLOBs with persistent native format - Progressive HNSW, COW branching, witness chains — all deferred until SDK is functional
- Feature-flagged:
useRVFBackendcontrols VectorDb vs RVF file routing
Phase 0.5 -- Bridge Layer (Week 1-2)
Replaces original Phase 1. Uses
@ruvector/core(working today) instead of@ruvector/rvf(stub).
RVF-0.5.1: VectorBackend Interface
Description: Define a VectorBackend interface that abstracts vector storage, so the underlying engine can be swapped between JS HNSW, @ruvector/core, and eventually @ruvector/rvf without changing callers.
| Field | Value |
|---|---|
| File | v3/src/kernel/vector-backend.ts |
| Agent | coder |
| Dependencies | None |
| Parallel Group | P0-A |
| Success Criteria | Interface defined with store/search/delete/clear/size/flush methods; exported from kernel |
Interface:
export interface VectorBackend {
/** Store a vector with string ID */
store(id: string, vector: number[]): void;
/** Store a batch of vectors */
storeBatch(entries: Array<{ id: string; vector: number[] }>): void;
/** Search for k nearest neighbors. Returns results sorted by descending similarity. */
search(query: number[], k: number): Array<{ id: string; score: number }>;
/** Remove a vector by ID */
remove(id: string): void;
/** Clear all vectors */
clear(): void;
/** Number of vectors stored */
size(): number;
/** Get all vector IDs (for persistence sync) */
ids(): string[];
/** Dispose resources */
dispose(): void;
}
RVF-0.5.2: Wrap InMemoryHNSWIndex as JsHnswBackend
Description: Wrap the existing InMemoryHNSWIndex class (unified-memory.ts:841) as a VectorBackend implementation. This is the zero-risk baseline — same code, new interface.
| Field | Value |
|---|---|
| File | v3/src/kernel/vector-backend.ts |
| Agent | coder |
| Dependencies | RVF-0.5.1 |
| Parallel Group | P0-A |
| Success Criteria | JsHnswBackend wraps existing InMemoryHNSWIndex; passes all existing vector tests |
RVF-0.5.3: Create RuvectorCoreBackend
Description: Implement VectorBackend using @ruvector/core VectorDb. This is the native engine that provides the speed improvement.
| Field | Value |
|---|---|
| File | v3/src/kernel/vector-backend.ts |
| Agent | coder |
| Dependencies | RVF-0.5.1 |
| Parallel Group | P0-A (parallel with RVF-0.5.2) |
| Success Criteria | RuvectorCoreBackend wraps @ruvector/core VectorDb; insertBatch uses Float32Array; search uses { vector, k } API; passes same tests as JsHnswBackend |
Implementation notes:
@ruvector/coreVectorDb requiresFloat32Arrayfor vectors (notnumber[]). The backend handles conversion.@ruvector/coreuses{ id: string, vector: Float32Array }for insertBatch. The backend converts thenumber[]interface.- Search API is
db.search({ vector: Float32Array, k })— returns{ id, score }. - CollectionManager enables per-namespace isolation (future: per-domain collections).
RVF-0.5.4: Add useRuvectorCore Feature Flag
Description: Extend RuVectorFeatureFlags with useRuvectorCore: boolean, defaulting to false.
| Field | Value |
|---|---|
| File | v3/src/integrations/ruvector/feature-flags.ts |
| Agent | coder |
| Dependencies | None |
| Parallel Group | P0-A (parallel) |
| Success Criteria | getRuVectorFeatureFlags().useRuvectorCore === false by default; RUVECTOR_USE_CORE=true env var toggles it |
RVF-0.5.5: Wire VectorBackend into UnifiedMemoryManager
Description: Replace direct InMemoryHNSWIndex usage in UnifiedMemoryManager with the VectorBackend interface. Select backend based on feature flag.
| Field | Value |
|---|---|
| File | v3/src/kernel/unified-memory.ts |
| Agent | coder |
| Dependencies | RVF-0.5.2, RVF-0.5.3, RVF-0.5.4 |
| Parallel Group | P0-B |
| Success Criteria | UnifiedMemoryManager.vectorIndex replaced with VectorBackend; backend selected by feature flag; all existing tests pass with both backends |
Changes to unified-memory.ts:
- Replace
private vectorIndex: InMemoryHNSWIndexwithprivate vectorBackend: VectorBackend - In constructor/init: select
JsHnswBackend(default) orRuvectorCoreBackend(when flag on) vectorStore(): callsthis.vectorBackend.store()instead ofthis.vectorIndex.add()vectorSearch(): callsthis.vectorBackend.search()instead ofthis.vectorIndex.search()vectorDelete(): callsthis.vectorBackend.remove()instead ofthis.vectorIndex.remove()loadVectorIndex(): callsthis.vectorBackend.storeBatch()instead of loopingthis.vectorIndex.add()
RVF-0.5.6: Lazy Persistence (persist-when-valuable)
Description: Make SQLite vector writes conditional — only persist vectors for patterns that are promoted or meet a value threshold. Ephemeral vectors live only in the VectorBackend and are lost on restart.
| Field | Value |
|---|---|
| File | v3/src/kernel/unified-memory.ts |
| Agent | coder |
| Dependencies | RVF-0.5.5 |
| Parallel Group | P0-B |
| Success Criteria | vectorStore() with persist: false skips SQLite write; vectorStore() with persist: true writes to both; flush() persists all dirty vectors; shutdown triggers flush |
Changes:
vectorStore(id, embedding, namespace, metadata, options?: { persist?: boolean }):- Always writes to VectorBackend (fast, in-memory)
- Only writes SQLite BLOB if
persist !== false - Tracks unpersisted IDs in a
Set<string>(dirtyVectors)
vectorFlush(): persists all dirty vectors to SQLite in a single transaction- On shutdown (
close()): auto-flush dirty vectors vectorPromote(id): explicitly persist a previously-ephemeral vector
Who decides persistence?:
- PatternStore calls
vectorStore()withpersist: truefor promoted patterns (high confidence, frequently used) - PatternStore calls
vectorStore()withpersist: falsefor ephemeral/exploratory patterns shouldPromotePattern()(already exists inqe-patterns.ts) is the decision function
RVF-0.5.7: Unit Tests
Description: Tests for VectorBackend implementations and feature flag.
| Field | Value |
|---|---|
| Files | v3/tests/unit/kernel/vector-backend.test.ts, v3/tests/unit/integrations/ruvector/feature-flags-core.test.ts |
| Agent | tester |
| Dependencies | RVF-0.5.2, RVF-0.5.3, RVF-0.5.4 |
| Parallel Group | P0-C |
| Success Criteria | All tests pass; both backends pass identical test suite; lazy persistence tested |
Test cases:
store()+search()round-trip returns stored vector (both backends)search()returns results sorted by descending similarity (both backends)remove()makes vector unfindable (both backends)clear()empties the store (both backends)storeBatch()is equivalent to multiplestore()calls (both backends)vectorStore(persist: false)does NOT write to SQLitevectorStore(persist: true)DOES write to SQLitevectorFlush()persists all dirty vectorsvectorPromote()persists a previously-ephemeral vector- Feature flag toggles backend selection
RVF-0.5.8: Benchmark — JS HNSW vs @ruvector/core
Description: Comparative benchmark of both backends integrated in UnifiedMemoryManager.
| Field | Value |
|---|---|
| File | scripts/benchmark-vector-backends.ts |
| Agent | tester |
| Dependencies | RVF-0.5.5 |
| Parallel Group | P0-C (parallel with tests) |
| Success Criteria | Benchmark report comparing both backends on insert, search, memory, cold-start |
Scenarios (at 100, 500, 1000, 5000 vectors, dimension 384):
- Insert throughput (ops/s)
- Search latency p50/p95/p99
- Memory footprint
- Cold-start (load from SQLite into backend)
- Lazy persistence overhead (flush 1000 dirty vectors)
Phase 0.5 Parallel Execution Strategy
P0-A (parallel): RVF-0.5.1 (interface) | RVF-0.5.4 (feature flag)
|
v
RVF-0.5.2 (JS backend) | RVF-0.5.3 (Core backend)
| |
v v
P0-B (sequential): RVF-0.5.5 (wire into UnifiedMemory) → RVF-0.5.6 (lazy persist)
|
P0-C (parallel): RVF-0.5.7 (tests) | RVF-0.5.8 (benchmark)
Agent assignments:
| Task | Agent | Est. Hours |
|---|---|---|
| RVF-0.5.1 | coder | 1 |
| RVF-0.5.2 | coder | 2 |
| RVF-0.5.3 | coder | 3 |
| RVF-0.5.4 | coder | 1 |
| RVF-0.5.5 | coder | 4 |
| RVF-0.5.6 | coder | 3 |
| RVF-0.5.7 | tester | 4 |
| RVF-0.5.8 | tester | 2 |
| Phase 0.5 Total | 2 agents | 20 hours |
Phase 1 -- Full RVF Integration (GATED: requires @ruvector/rvf-node binaries)
Gate condition:
@ruvector/rvf-nodepublishes prebuilt N-API binaries AND progressive HNSW is wired into rvf-runtime query path. Check weekly:npm view @ruvector/rvf-node versionand testRvfDatabase.create().Until this gate is met, Phase 0.5 bridge is the production architecture. The tasks below are preserved from the original plan for when the gate opens.
RVF-1.1: Full RvfPatternStore Implementation
Description: Complete the RvfPatternStore with progressive HNSW support, reuse optimization (ADR-042), and token tracking.
| Field | Value |
|---|---|
| File | v3/src/learning/rvf-pattern-store.ts |
| Agent | coder |
| Dependencies | RVF-1.4 |
| Parallel Group | P2-A |
| Success Criteria | All IPatternStore methods implemented; search() uses RVF progressive HNSW (layer A for instant recall, B/C for precision); reuse optimization calculates canReuse, estimatedTokenSavings, reuseConfidence |
Implementation details:
store(): Validate pattern viavalidateQEPattern(), write metadata toqe_patterns, write embedding to RVF, index in local cachessearch(vector, opts): Query RVF fork*2candidates, hydrate metadata from SQLite, apply filters, calculate reuse info, return top-ksearch(text, opts): Text search on SQLiteqe_patternstable (name, description LIKE), then optionally use RVF for re-ranking if embeddings existrecordUsage(): Update SQLite metadata, update confidence/quality scorespromote(): Update tier in SQLite; no RVF change needed (vectors are tier-agnostic)cleanup(): Delete low-quality patterns from both SQLite and RVFgetStats(): Merge SQLite pattern counts with RVF status (totalVectors, fileSize)
RVF-2.2: Migration Utility (SQLite BLOBs to RVF)
Description: Create a migration utility that exports existing vector embeddings from SQLite qe_pattern_embeddings and vectors tables into the RVF store.
| Field | Value |
|---|---|
| File | v3/src/migrations/migrate-vectors-to-rvf.ts |
| Agent | coder |
| Dependencies | RVF-1.3 |
| Parallel Group | P2-A (parallel with RVF-2.1) |
| Success Criteria | Migration reads all rows from qe_pattern_embeddings and vectors; batch-ingests into RVF; reports count migrated, count failed, elapsed time; idempotent (skip if already migrated via epoch check) |
Migration steps:
- Open existing
memory.dbviaUnifiedMemoryManager - Create/open
.agentic-qe/patterns.rvfviaRvfBackend - Read all rows from
qe_pattern_embeddings(pattern_id, embedding BLOB, dimension) - Convert BLOBs to Float32Array, batch ingest into RVF with pattern_id as key
- Read all rows from
vectors(id, embedding BLOB, dimensions, namespace) - Batch ingest into RVF with
{namespace}:{id}as key - Record migration metadata in
kv_storenamespacervf-migrationwith epoch and counts - Log summary:
[RVF Migration] Migrated {n} pattern embeddings + {m} vectors in {t}ms
Safety:
- Does NOT delete SQLite data after migration. Both stores coexist.
- Idempotent: checks
kv_storeforrvf-migration:completedbefore running. - Can be invoked via CLI:
aqe migrate-vectors-to-rvf
RVF-2.3: Feature-Flagged Routing in PatternStore
Description: Modify the existing PatternStore class to route vector operations to either the existing SQLite/in-memory HNSW path or the new RvfPatternStore based on the useRVFBackend feature flag.
| Field | Value |
|---|---|
| File | v3/src/learning/pattern-store.ts |
| Agent | coder |
| Dependencies | RVF-2.1, RVF-1.2 |
| Parallel Group | P2-B |
| Success Criteria | When useRVFBackend=false, behavior identical to current; when useRVFBackend=true, vector operations delegate to RvfPatternStore; flag can be toggled at runtime without restart |
Changes to PatternStore:
- Add optional
rvfStore: RvfPatternStorefield, lazily initialized when flag is true store(): ifuseRVFBackendand pattern has embedding, delegate embedding storage torvfStoresearch(): ifuseRVFBackendand query is vector, delegate torvfStore.search()ensureHNSW(): skip HNSW init whenuseRVFBackendis true (RVF handles HNSW internally)dispose(): closervfStoreif active
RVF-2.4: WITNESS_SEG for Pattern Provenance
Description: When storing patterns via RVF, generate witness chain entries that record pattern origin, agent ID, domain, and creation context for tamper-evident audit trails.
| Field | Value |
|---|---|
| File | v3/src/integrations/ruvector/rvf-witness.ts |
| Agent | coder |
| Dependencies | RVF-1.3 |
| Parallel Group | P2-A (parallel with RVF-2.1, RVF-2.2) |
| Success Criteria | Each pattern store operation generates a witness entry; witness chain is verifiable via RvfDatabase API; witness entries include: pattern_id, agent_id, domain, operation (create/update/delete/promote), timestamp, content_hash |
Witness entry structure:
interface PatternWitnessEntry {
patternId: string;
agentId: string;
domain: string;
operation: 'create' | 'update' | 'delete' | 'promote' | 'migrate';
timestamp: number;
contentHash: string; // SHA-256 of pattern JSON
previousHash: string | null; // Chain link
metadata?: Record<string, unknown>;
}
RVF-2.5: Integration Tests
Description: Integration tests verifying SQLite and RVF data consistency, migration correctness, and feature flag routing.
| Field | Value |
|---|---|
| Files | v3/tests/integration/learning/rvf-pattern-store.test.ts, v3/tests/integration/migrations/migrate-vectors-to-rvf.test.ts |
| Agent | tester |
| Dependencies | RVF-2.1, RVF-2.2, RVF-2.3 |
| Parallel Group | P2-C |
| Success Criteria | All integration tests pass; pattern stored via RVF is retrievable; migrated vectors produce same search results; flag toggle mid-session works correctly |
Test scenarios:
- Store pattern with embedding via
RvfPatternStore, retrieve by ID, verify metadata + embedding - Search with vector query, verify results ranked by similarity
- Run migration on test DB with 100 patterns, verify all migrated to RVF
- Toggle
useRVFBackendfrom false to true mid-session, verify seamless transition - Store pattern with
useRVFBackend=true, switch tofalse, verify pattern still accessible (metadata in SQLite) - Witness chain: store 5 patterns, verify chain integrity (each entry links to previous)
- Regression: run existing PatternStore tests with
useRVFBackend=false, all pass unchanged
Phase 2 Parallel Execution Strategy
P2-A (parallel): RVF-2.1 (full impl) | RVF-2.2 (migration) | RVF-2.4 (witness)
| |
v v
P2-B: RVF-2.3 (flag routing) -- depends on RVF-2.1
|
v
P2-C: RVF-2.5 (integration tests) -- depends on all P2-A + P2-B
Agent assignments:
| Task | Agent | Est. Hours |
|---|---|---|
| RVF-2.1 | coder | 12 |
| RVF-2.2 | coder | 6 |
| RVF-2.3 | coder | 6 |
| RVF-2.4 | coder | 6 |
| RVF-2.5 | tester | 8 |
| Phase 2 Total | 3 agents | 38 hours |
Phase 2 -- Agent Memory Branching (GATED: requires Phase 1)
RVF-3.1: COW Branching for Swarm Agent Memory Isolation
Description: Integrate RvfDatabase.derive() with the swarm coordinator so each spawned agent gets a COW branch of the shared pattern store, enabling isolated memory that can be merged back.
| Field | Value |
|---|---|
| File | v3/src/integrations/ruvector/rvf-agent-memory.ts |
| Agent | coder |
| Dependencies | RVF-2.1 |
| Parallel Group | P3-A |
| Success Criteria | createAgentBranch(agentId) returns a COW child RvfBackend; writes to child do not affect parent; parent writes after derive are not visible in child; mergeBack(agentId) applies child patterns to parent |
Interface:
export interface RvfAgentMemoryManager {
/** Create a COW branch for an agent */
createBranch(agentId: string): Promise<RvfBackend>;
/** List active branches */
listBranches(): Array<{ agentId: string; fileId: string; depth: number; vectorCount: number }>;
/** Merge agent's patterns back to parent (with conflict resolution) */
mergeBranch(agentId: string, strategy?: MergeStrategy): Promise<MergeResult>;
/** Discard an agent's branch */
discardBranch(agentId: string): Promise<void>;
/** Close all branches */
closeAll(): Promise<void>;
}
type MergeStrategy = 'latest-wins' | 'highest-confidence' | 'union';
interface MergeResult {
merged: number;
conflicts: number;
skipped: number;
newPatterns: string[];
}
Implementation notes:
- Branch files stored at
.agentic-qe/branches/{agentId}.rvf - Branch metadata stored in SQLite
kv_storenamespacervf-branches mergeBranch()reads all vectors from child, queries parent for duplicates (cosine similarity > 0.99), merges new patterns, resolves conflicts per strategy- Cleanup: branches older than 24h without merge are auto-discarded
RVF-3.2: Swarm Coordinator Integration
Description: Wire RvfAgentMemoryManager into the swarm coordinator lifecycle so branches are created on agent spawn and optionally merged on agent completion.
| Field | Value |
|---|---|
| Files | v3/src/coordination/ (swarm coordinator files) |
| Agent | coder |
| Dependencies | RVF-3.1 |
| Parallel Group | P3-B |
| Success Criteria | Agent spawn creates RVF branch (when useRVFBackend=true); agent completion triggers merge-back; failed agents have branches discarded; branch lifecycle logged |
Integration points:
agentSpawn(): ifuseRVFBackendflag is true, callmemoryManager.createBranch(agentId)agentComplete(): callmemoryManager.mergeBranch(agentId, 'highest-confidence')agentFailed(): callmemoryManager.discardBranch(agentId)swarmShutdown(): callmemoryManager.closeAll()
RVF-3.3: Lineage Tracking
Description: Track pattern lineage across branches so merged patterns retain provenance: which agent discovered them, from which branch, at what lineage depth.
| Field | Value |
|---|---|
| File | v3/src/integrations/ruvector/rvf-lineage.ts |
| Agent | coder |
| Dependencies | RVF-3.1, RVF-2.4 (witness chain) |
| Parallel Group | P3-A (parallel with RVF-3.1) |
| Success Criteria | Merged patterns have lineage metadata: { originAgent, originBranch, branchDepth, mergedAt, mergeStrategy }; lineage queryable via PatternStore |
Lineage metadata added to qe_patterns:
ALTER TABLE qe_patterns ADD COLUMN lineage_json TEXT;
Lineage structure:
interface PatternLineage {
originAgent: string;
originBranchFileId: string;
branchDepth: number;
mergedAt: string; // ISO timestamp
mergeStrategy: MergeStrategy;
parentPatternId?: string; // If pattern was derived from existing
witnessEntryId?: string; // Link to witness chain
}
RVF-3.4: Concurrent Agent Memory Tests
Description: Stress tests for COW branching with 15 concurrent agents performing simultaneous reads, writes, and merges.
| Field | Value |
|---|---|
| File | v3/tests/integration/ruvector/rvf-concurrent-agents.test.ts |
| Agent | tester |
| Dependencies | RVF-3.1, RVF-3.2 |
| Parallel Group | P3-C |
| Success Criteria | 15 agents each write 100 patterns to their branch; all merges complete without data loss; parent store contains all merged patterns; no file corruption; total time < 30s |
Test scenarios:
- Parallel writes: 15 branches created, each writes 100 vectors. Verify no cross-branch contamination.
- Concurrent merge: 15 branches merge simultaneously. Verify all patterns present in parent.
- Read-during-write: Parent queried while branches are writing. Verify parent reads are consistent.
- Branch-after-branch: Agent A derives, writes, merges. Agent B derives (sees A's patterns), writes, merges. Verify lineage chain.
- Discard + re-branch: Agent creates branch, writes patterns, branch discarded. Agent re-branches. Verify clean state.
- Memory pressure: 15 branches with 1000 vectors each. Verify RSS stays under 500MB.
Phase 3 Parallel Execution Strategy
P3-A (parallel): RVF-3.1 (COW branching) | RVF-3.3 (lineage tracking)
|
v
P3-B: RVF-3.2 (swarm integration) -- depends on RVF-3.1
|
v
P3-C: RVF-3.4 (concurrent tests) -- depends on RVF-3.1, RVF-3.2
Agent assignments:
| Task | Agent | Est. Hours |
|---|---|---|
| RVF-3.1 | coder | 10 |
| RVF-3.2 | coder | 8 |
| RVF-3.3 | coder | 6 |
| RVF-3.4 | tester | 8 |
| Phase 3 Total | 3 agents | 32 hours |
Phase 3 -- Quality Attestation and Polish (GATED: requires Phase 2)
RVF-4.1: Signed Quality Report Generation
Description: Generate quality assessment reports as .rvf files containing coverage metrics, test results, and pattern confidence scores, with witness chains for tamper-evident attestation.
| Field | Value |
|---|---|
| File | v3/src/domains/quality-assessment/services/rvf-quality-report.ts |
| Agent | coder |
| Dependencies | RVF-2.4 (witness chain) |
| Parallel Group | P4-A |
| Success Criteria | generateQualityReport() produces a .rvf file with embedded metrics; witness chain verifiable; report includes coverage, test pass rate, pattern confidence distribution, agent performance |
Report structure (stored as RVF metadata segments):
QUALITY_METRICS_SEG: coverage percentages, test counts, pass ratesPATTERN_SUMMARY_SEG: pattern count by domain/tier, average confidenceAGENT_PERFORMANCE_SEG: per-agent success rates, latenciesWITNESS_SEG: chain of all quality events leading to this reportVEC_SEG: embedding vectors of high-confidence patterns (for cross-project transfer)
RVF-4.2: MCP Server Integration
Description: Wire @ruvector/rvf-mcp-server into the AQE MCP server so agents can natively access RVF operations (query, derive, witness verify) through MCP tools.
| Field | Value |
|---|---|
| Files | v3/src/mcp/tools/rvf-tools.ts, MCP server registration |
| Agent | coder |
| Dependencies | RVF-1.1, RVF-2.1 |
| Parallel Group | P4-A (parallel with RVF-4.1) |
| Success Criteria | MCP tools registered: rvf_query, rvf_store, rvf_derive, rvf_status, rvf_witness_verify; tools callable from agent prompts |
MCP tools:
| Tool | Description |
|---|---|
rvf_query |
Search RVF store by vector similarity |
rvf_store |
Store a vector with metadata |
rvf_derive |
Create a COW branch for an agent |
rvf_status |
Get RVF store status (vector count, file size, epoch) |
rvf_witness_verify |
Verify witness chain integrity |
rvf_quality_report |
Generate quality attestation report |
RVF-4.3: Performance Optimization
Description: Optimize RVF integration for production workloads based on Phase 1 benchmark results.
| Field | Value |
|---|---|
| Files | v3/src/integrations/ruvector/rvf-backend.ts, v3/src/learning/rvf-pattern-store.ts |
| Agent | coder |
| Dependencies | RVF-1.5 (benchmark results), RVF-2.1 |
| Parallel Group | P4-B |
| Success Criteria | Cold-start < 200ms for 50K vectors; query latency p99 < 5ms; batch ingest > 10K vectors/sec; memory < 200MB for 50K vectors |
Optimization areas:
- Batch operations: Group pattern stores into batches of 100 before calling
ingestBatch() - ID mapping cache: LRU cache for string-to-numeric ID mapping (avoid SQLite lookup on every query)
- Lazy compaction: Schedule
compact()during idle periods (post-cleanup timer in PatternStore) - Progressive HNSW tuning: Tune A/B/C layer parameters based on benchmark data
- Memory-mapped I/O: Ensure RVF file is memory-mapped for read-heavy workloads
RVF-4.4: Monitoring and Observability
Description: Extend RuVectorObservability to track RVF-specific metrics: store size, query latency, branch count, witness chain length.
| Field | Value |
|---|---|
| File | v3/src/integrations/ruvector/observability.ts (extend existing) |
| Agent | coder |
| Dependencies | RVF-2.1 |
| Parallel Group | P4-A |
| Success Criteria | getObservabilityReport() includes RVF section with: vectorCount, fileSize, queryLatencyP50/P95/P99, activeBranches, witnessChainLength, lastCompactionTime |
RVF-4.5: Documentation
Description: Create ADR-065 document and update existing docs to reflect hybrid architecture.
| Field | Value |
|---|---|
| Files | docs/adr/ADR-065-rvf-hybrid-architecture.md, docs/plans/rvf-integration-implementation-plan.md (this file, marked complete) |
| Agent | reviewer |
| Dependencies | All Phase 4 tasks |
| Parallel Group | P4-C |
| Success Criteria | ADR explains decision rationale, architecture diagram, rollback plan; CLAUDE.md updated with RVF references; README mentions RVF capability |
RVF-4.6: Final Regression and Acceptance Tests
Description: Full regression suite ensuring existing SQLite path works unchanged and new RVF path meets acceptance criteria.
| Field | Value |
|---|---|
| Files | v3/tests/integration/ruvector/rvf-acceptance.test.ts |
| Agent | tester |
| Dependencies | All Phase 4 implementation tasks |
| Parallel Group | P4-C |
| Success Criteria | All existing tests pass with useRVFBackend=false; acceptance tests pass with useRVFBackend=true; benchmark targets met |
Acceptance test matrix:
| Scenario | useRVFBackend=false | useRVFBackend=true |
|---|---|---|
| Pattern CRUD | PASS (existing) | PASS (new) |
| Vector search recall@10 > 90% | PASS | PASS |
| Pattern migration round-trip | N/A | PASS |
| COW branch create/merge | N/A | PASS |
| Witness chain verify | N/A | PASS |
| Quality report generation | N/A | PASS |
| MCP tool invocation | N/A | PASS |
| Cold-start < 500ms | PASS | PASS |
| 15 concurrent agents | N/A | PASS |
Phase 4 Parallel Execution Strategy
P4-A (parallel): RVF-4.1 (quality reports) | RVF-4.2 (MCP) | RVF-4.4 (observability)
| |
v v
P4-B: RVF-4.3 (performance optimization)
|
v
P4-C (parallel): RVF-4.5 (documentation) | RVF-4.6 (acceptance tests)
Agent assignments:
| Task | Agent | Est. Hours |
|---|---|---|
| RVF-4.1 | coder | 8 |
| RVF-4.2 | coder | 6 |
| RVF-4.3 | coder | 8 |
| RVF-4.4 | coder | 4 |
| RVF-4.5 | reviewer | 4 |
| RVF-4.6 | tester | 8 |
| Phase 4 Total | 4 agents | 38 hours |
Integration Plan
Phase 0.5 Bridge Architecture
.agentic-qe/
memory.db <-- SQLite (KV, Q-values, GOAP, hypergraph, pattern metadata,
durable vector BLOBs for promoted patterns)
In-memory (not persisted to disk):
@ruvector/core VectorDb <-- Hot search layer (all vectors, including ephemeral)
Data flow:
vectorStore(id, embedding, namespace, metadata, { persist }):- ALWAYS writes to
VectorBackend(in-memory, fast) - If
persist: true: also writes BLOB to SQLitevectorstable - If
persist: false: vector is ephemeral, lost on restart
- ALWAYS writes to
vectorSearch(query, k): queriesVectorBackenddirectly, no SQLite involvedvectorFlush(): batch-persists all dirty (unpersisted) vectors to SQLite- Cold start:
loadVectorIndex()reads promoted vectors from SQLite intoVectorBackend
Invariant: Pattern metadata is ALWAYS in SQLite. Vector embeddings are always in VectorBackend for search. SQLite BLOBs are the durable backup for vectors worth keeping.
Backend Selection
// In UnifiedMemoryManager constructor
private vectorBackend: VectorBackend = isRuvectorCoreEnabled()
? new RuvectorCoreBackend({ dimensions: 384, metric: 'cosine' })
: new JsHnswBackend();
// vectorStore — same code regardless of backend
async vectorStore(id, embedding, namespace, metadata, opts?: { persist?: boolean }) {
this.vectorBackend.store(id, embedding); // always fast
if (opts?.persist !== false) {
this.db.prepare('INSERT OR REPLACE INTO vectors ...').run(...); // durable
} else {
this.dirtyVectors.add(id); // track for potential later flush
}
}
// vectorSearch — delegates to backend, enriches with SQLite metadata
async vectorSearch(query, k, namespace?) {
const results = this.vectorBackend.search(query, k * 2);
// batch-fetch metadata from SQLite for result IDs
// filter by namespace, return top-k
}
Feature Flag Rollout Strategy
| Stage | Flag | Description |
|---|---|---|
| Stage 0 | useRuvectorCore=false |
JS HNSW backend (current behavior). Zero risk. |
| Stage 1 | useRuvectorCore=true in dev |
Enable @ruvector/core VectorDb. Run full test suite. |
| Stage 2 | useRuvectorCore=true in prod |
Enable in production. Monitor search latency improvement. |
| Stage 3 | Add lazy persistence | Enable persist: false for ephemeral patterns. |
| Rollback | useRuvectorCore=false |
Flip flag back. JS HNSW rebuilds from SQLite BLOBs. |
Future: Full RVF (when rvf-node ships)
| Stage | Flag | Description |
|---|---|---|
| Stage 4 | useRVFBackend=true |
Swap VectorBackend to RVF file backend. |
| Stage 5 | Enable COW branching | Agent memory isolation via RVF derive(). |
| Stage 6 | Enable witness chains | Tamper-evident audit trails. |
Dependency Management
{
"dependencies": {
"@ruvector/core": "^0.1.29",
"@ruvector/gnn": "^0.1.19",
"@ruvector/sona": "^0.1.5",
"@ruvector/attention": "^0.1.3"
},
"optionalDependencies": {
"@ruvector/rvf": "^0.1.4"
}
}
Compatibility notes:
@ruvector/coreVectorDb replacesInMemoryHNSWIndexinunified-memory.tsfor vector search when enabled@ruvector/gnncontinues for PatternStore HNSW (separate concern, different dimension/usage)@ruvector/rvfmoved to optionalDependencies until backend binaries ship- No conflicts between core/gnn/sona/attention — they serve different purposes
Verification Plan
Unit Tests (London School TDD)
All new modules get mock-first unit tests:
| Module | Test File | Mock Dependencies | Key Assertions |
|---|---|---|---|
rvf-backend.ts |
rvf-backend.test.ts |
RvfDatabase (mocked) |
create/open/store/query/derive/close lifecycle |
rvf-pattern-store.ts |
rvf-pattern-store.test.ts |
RvfBackend (mocked), MemoryBackend (mocked) |
IPatternStore contract fulfilled |
rvf-witness.ts |
rvf-witness.test.ts |
RvfBackend (mocked) |
Witness entries chained correctly |
rvf-agent-memory.ts |
rvf-agent-memory.test.ts |
RvfBackend (mocked) |
Branch create/merge/discard lifecycle |
rvf-lineage.ts |
rvf-lineage.test.ts |
SQLite (in-memory) | Lineage metadata persisted and queryable |
feature-flags.ts |
feature-flags-rvf.test.ts |
None | New flag behavior |
migrate-vectors-to-rvf.ts |
migrate-vectors.test.ts |
SQLite (in-memory), RvfBackend (mocked) |
Migration counts correct |
Integration Tests
| Test Suite | Description | Duration Target |
|---|---|---|
| SQLite-RVF consistency | Store via RVF, read metadata from SQLite, verify match | < 5s |
| Migration round-trip | Migrate, then search: results match pre-migration | < 10s |
| Feature flag toggle | Toggle mid-session, verify no data loss | < 5s |
| Branch create/merge | Create branch, write, merge, verify parent updated | < 10s |
| Witness chain verification | Store 10 patterns, verify chain integrity | < 5s |
| MCP tool invocation | Call each RVF MCP tool, verify response | < 10s |
Benchmark Suite
| Benchmark | Metric | Target | Method |
|---|---|---|---|
| Cold start (10K vectors) | Time to first query | < 500ms | Time from initialize() to first query() |
| Cold start (50K vectors) | Time to first query | < 2s | Same |
| Recall@10 (10K vectors) | Recall vs brute-force | > 90% | 1000 random queries, compare to exact NN |
| Query latency (10K) | p99 | < 5ms | 10K queries, measure per-query time |
| Insert throughput | vectors/sec | > 10K/sec | Batch insert 50K vectors, measure elapsed |
| Memory (10K vectors) | Peak RSS delta | < 50MB | process.memoryUsage() before/after |
| Memory (50K vectors) | Peak RSS delta | < 200MB | Same |
| COW branch create | Time to derive | < 10ms | Time derive() call |
| COW merge (1K patterns) | Time to merge | < 1s | Time mergeBranch() with 1000 new patterns |
Regression Tests
- All existing test suites run with
useRVFBackend=false: Zero regressions expected. - Critical path:
pattern-store.test.ts,hnsw-index.test.ts,unified-memory.test.tsmust pass unchanged. - CI integration: Add
RUVECTOR_USE_RVF_BACKEND=truematrix entry to CI pipeline.
COW Branching Stress Tests
| Scenario | Agents | Vectors/Agent | Duration Target |
|---|---|---|---|
| Parallel writes | 15 | 100 | < 10s |
| Concurrent merge | 15 | 100 | < 15s |
| Sequential merge chain | 15 (sequential) | 100 | < 30s |
| Memory pressure | 15 | 1000 | < 60s, RSS < 500MB |
Witness Chain Verification Tests
| Test | Description |
|---|---|
| Chain integrity | Hash chain from root to tip is valid |
| Tamper detection | Modify one entry, verify chain breaks |
| Cross-branch witness | Merged pattern's witness links to both branch and parent chains |
| Empty chain | New store has empty but valid witness chain |
Parallel Execution Strategy (All Phases)
Agent Roster
| Agent ID | Type | Specialization |
|---|---|---|
rvf-coder-1 |
coder | RVF backend, pattern store, migration |
rvf-coder-2 |
coder | Feature flags, swarm integration, MCP |
rvf-tester-1 |
tester | Unit tests, benchmarks |
rvf-tester-2 |
tester | Integration tests, stress tests |
rvf-reviewer-1 |
reviewer | Code review, documentation |
Phase-by-Phase Agent Allocation
Phase 1 (3 agents active)
rvf-coder-1: RVF-1.1 -> RVF-1.3 -> RVF-1.4
rvf-coder-2: RVF-1.2
rvf-tester-1: (wait for RVF-1.3) -> RVF-1.5, RVF-1.6
Phase 2 (3 agents active)
rvf-coder-1: RVF-2.1 -> RVF-2.3
rvf-coder-2: RVF-2.2, RVF-2.4
rvf-tester-1: (wait for P2-B) -> RVF-2.5
Phase 3 (3 agents active)
rvf-coder-1: RVF-3.1 -> RVF-3.2
rvf-coder-2: RVF-3.3
rvf-tester-2: (wait for RVF-3.2) -> RVF-3.4
Phase 4 (4 agents active)
rvf-coder-1: RVF-4.1 -> RVF-4.3
rvf-coder-2: RVF-4.2, RVF-4.4
rvf-tester-2: RVF-4.6
rvf-reviewer-1: RVF-4.5
Critical Path
RVF-1.1 -> RVF-1.3 -> RVF-1.4 -> RVF-2.1 -> RVF-2.3 -> RVF-3.1 -> RVF-3.2 -> RVF-4.3 -> RVF-4.6
Total critical path estimated duration: ~60 hours of sequential work spread across 8 weeks with parallelism reducing wall-clock time to ~4-5 weeks with 3-4 agents.
Risk Mitigation
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
@ruvector/core VectorDb API breaks between versions |
Low | Medium | Pin to ^0.1.29; VectorBackend interface isolates callers |
| @ruvector/core missing on platform (e.g., ARM64) | Low | Low | Feature flag defaults to JS HNSW; graceful fallback |
| In-memory vectors lost on crash (lazy persistence) | Medium | Medium | Promoted patterns always in SQLite; only ephemeral patterns lost |
@ruvector/rvf-node never ships binaries |
Medium | Low | Phase 0.5 bridge is production-viable indefinitely |
| Performance regression vs JS HNSW at small scale | Low | Low | At <100 vectors both are sub-millisecond; no user impact |
| Feature flag toggle mid-request | Low | Low | Flag checked at operation start, not mid-operation |
Rollback Plan
Phase 0.5 Rollback
- Set
RUVECTOR_USE_CORE=falsein environment - All operations revert to JS HNSW path (InMemoryHNSWIndex)
- SQLite vector BLOBs unchanged (always the source of truth for promoted patterns)
- No data loss: in-memory VectorDb is rebuilt from SQLite on next cold start
Future Phase 1+ Rollback
- Set
RUVECTOR_USE_RVF_BACKEND=false - Falls back to Phase 0.5 bridge (VectorDb or JS HNSW)
.rvffiles can be left in place or deleted- SQLite metadata always intact
Summary
| Phase | Status | Duration | Tasks | Key Deliverable |
|---|---|---|---|---|
| 0: Validate | DONE | 1 day | 2 | Phase 0 gate report, AQE baseline benchmark |
| 0.5: Bridge | READY | Week 1-2 | 8 | VectorBackend interface, @ruvector/core integration, lazy persistence |
| 1: Full RVF | GATED | Week 3-4 | 5 | RvfDatabase integration, migration, witness chains |
| 2: Branching | GATED | Week 5-6 | 4 | COW agent memory, swarm integration |
| 3: Polish | GATED | Week 7-8 | 6 | Quality reports, MCP tools, optimization |
Phase 0.5 effort: 20 hours across 8 tasks with 2 agents. Delivers immediate value. Full plan effort (if all gates pass): 134 hours across 29 tasks.
What Phase 0.5 Delivers NOW
- Native vector search via
@ruvector/core(8-4000x faster than JS HNSW) - Clean
VectorBackendinterface for future RVF swap - Lazy persistence (only persist valuable patterns to SQLite)
- Per-domain collection isolation via CollectionManager
- Zero risk: feature-flagged, falls back to existing JS HNSW
What Phases 1-3 Deliver LATER (when rvf-node ships)
- Persistent
.rvffile format (no cold-start rebuild) - Progressive 3-layer HNSW (instant partial results)
- COW branching for agent memory isolation
- Witness chains for tamper-evident audit trails
- Quality attestation as signed
.rvffiles