fix: SONA zero-vector bug, RVF wasm persistence, metadata safety, doc gaps (#708)

- #706: apply_micro_lora/apply_base_lora seeded their output buffer with
  zeros in napi.rs, napi_simple.rs, and wasm.rs, but the Rust LoRA forward
  pass has residual semantics (adds delta into the buffer). Cold queries
  collapsed to the zero vector, and post-feedback queries returned only
  the delta instead of input+delta. Fixed by seeding with a clone of the
  input in all three binding layers. Added regression tests.

- #705: WasmBackend had no byte-level persistence. The underlying
  rvf_store_export/rvf_store_open C-ABI functions already existed —
  wired them into WasmBackend.exportBytes()/openBytes() and
  RvfDatabase.exportBytes()/openBytes(), verified against the real
  compiled .wasm binary.

- #704: NodeBackend.ingestBatch() silently dropped RvfIngestEntry.metadata
  instead of forwarding it, and query() filter serialization omitted the
  native parser's required valueType. Since a full field-name-to-id
  design for metadata durability is a larger follow-up, applied the
  issue's own suggested interim fix: ingest now throws
  MetadataNotSupported instead of silently losing data. Filter
  serialization now infers and includes valueType.

- #707: docs/api/NODEJS_API.md and docs/guides/ADVANCED_FEATURES.md
  advertised HybridSearch/FilteredSearch/MMRSearch/ConformalPredictor as
  Node exports; none are bound by crates/ruvector-node. Corrected with
  explicit "not yet shipped" notes pointing at the tracking issue.

README corrections for #705/#707 (WasmRvfStore, HybridSearch docs) are
staged separately — a repo hook requires a visual design-grade ritual for
any README change that this session cannot complete (no browser/screenshot
access), so they'll follow once that's resolved.
This commit is contained in:
rUv 2026-07-17 13:34:16 -04:00 committed by GitHub
parent dc00c44253
commit fe11269ed1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 846 additions and 43 deletions

View file

@ -607,10 +607,21 @@ interface QuantizationConfig {
## Advanced Features
### HybridSearch
> **Not yet available in the `ruvector` Node package.** `HybridSearch`,
> `FilteredSearch`, and `MMRSearch` below exist in the Rust core
> (`ruvector-core::advanced_features`) but are **not bound or exported** by
> `crates/ruvector-node` / the published `ruvector` npm package — see
> [#707](https://github.com/ruvnet/RuVector/issues/707). Importing any of
> these names from `ruvector` in Node.js currently returns `undefined`.
> If you need hybrid/keyword search from JavaScript today, use AgentDB's
> `HybridSearch` / `KeywordIndex` (`ruvnet/agentdb`) instead. The snippets
> below describe the intended shape of a future Node binding, not a
> currently shipped API.
### HybridSearch (Rust-only; not exported to Node)
```javascript
const { HybridSearch } = require('ruvector');
const { HybridSearch } = require('ruvector'); // NOT YET SHIPPED — see #707
const hybrid = new HybridSearch(db, {
vectorWeight: 0.7,
@ -626,10 +637,10 @@ const results = await hybrid.search(
);
```
### FilteredSearch
### FilteredSearch (Rust-only; not exported to Node)
```javascript
const { FilteredSearch } = require('ruvector');
const { FilteredSearch } = require('ruvector'); // NOT YET SHIPPED — see #707
const filtered = new FilteredSearch(db, 'preFilter');
@ -641,10 +652,10 @@ const results = await filtered.search(queryVector, 10, {
});
```
### MMRSearch
### MMRSearch (Rust-only; not exported to Node)
```javascript
const { MMRSearch } = require('ruvector');
const { MMRSearch } = require('ruvector'); // NOT YET SHIPPED — see #707
const mmr = new MMRSearch(db, {
lambda: 0.5,