Repository navigation
ruvector 0.3.6: full CRUD for vectors, RVF and hook memories - #1305
Merged
Merged
Conversation
…P, library)
Fixes a correctness bug in VectorDB.insert: re-inserting an existing id left
the old node in the native HNSW index, so search returned the id twice (once
with its stale vector); duplicate ids within one insertBatch did the same.
insert/insertBatch are now true upserts (last entry wins), at ~12 µs per
existing-id check and none for loads into an empty store. The root cause is
in the native core; this is the wrapper-level fix.
Library: VectorDB#update (never creates, optional metadata merge) and
VectorDB#deleteMany ({deleted, missing}).
CLI: `get`, `update`, `delete` for vector stores; `rvf delete`; hook memory
`memory-get`, `memory-list`, `memory-update` (re-embedded through the same
embedder and ADR-210 provenance gate as remember) and `forget`. recall now
returns memory ids.
MCP: vectordb_create/insert/get/update/delete/search/stats (paths confined to
the project, always explicit, never the ./ruvector.db default),
hooks_memory_get/list/update and hooks_forget. The readonly profile gains only
the two memory reads. RVF tools now validate entries, ids, vectors and k, and
always close the store (rvf_open leaked it; rvf_delete accepted only numbers
while the store takes string ids).
Memories get stable ids: new ids are collision-free (mem_<ms> collided within
a millisecond), legacy id-less entries get deterministic ids so the CLI and
MCP server agree, and the MCP engine's recall set is kept in step with edits
and deletes, including ones made by another process.
Input validation shared by CLI and MCP (bin/record-validate.js): ids (length,
control characters), finite vectors of the store's dimension, metadata as a
plain object with no __proto__/constructor/prototype keys at any depth and
bounded size/depth, batch and k caps.
Tests: tests/crud.test.mjs (9 e2e tests, 7 fail on 0.3.5). Benchmark:
scripts/bench/crud-bench.mjs.
Co-Authored-By: claude-flow <ruv@ruv.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
npx ruvectornow has create/read/update/delete on every data surface: vector stores, RVF stores and hook memories, through the CLI, the MCP server and the library.create,insertget,search,statsupdatedeletevectordb_create,vectordb_insertvectordb_get,vectordb_search,vectordb_statsvectordb_updatevectordb_deleteinsert,insertBatch(now true upserts)get,searchupdatedelete,deleteManycreate,ingest(upsert)query,statusingestreplaces an idrvf delete/rvf_deleterememberrecall(now with ids),memory-get,memory-listmemory-updateforgethooks_rememberhooks_recall,hooks_memory_get,hooks_memory_listhooks_memory_updatehooks_forgetThe native VectorDB has no enumerate API, so there is no vector
list;getby id is the read.Bug fixed: duplicate search results after re-inserting an id
Re-inserting an existing id left the old node in the native HNSW index, so
searchreturned that id twice, once with its stale vector. Duplicate ids within oneinsertBatchdid the same.insertandinsertBatchare now true upserts (the last entry wins). The root cause is in the native core; this is a wrapper-level fix that avoids a multi-platform native republish.Memory ids
mem_<ms>) could collide within one millisecond.Security
bin/record-validate.js, used by both the CLI and MCP:__proto__/constructor/prototypekeys at any depth; ≤64 KB, ≤8 levelsvectordb_*paths are confined to the project (RUVECTOR_MCP_ROOTSto widen) and are always explicit, so the./ruvector.dbdefault can never be created from MCP.remember, so an edit cannot create a mixed store.readonlyMCP profile gains onlyhooks_memory_getandhooks_memory_list. All new write tools stay hidden and can't be called.rvf_ingest,rvf_queryandrvf_deletenow validate their input.rvf_openno longer leaks the store handle.rvf_deleteaccepts string ids; it previously accepted only numbers, while the store uses string ids.Tests
tests/crud.test.mjs: 9 end-to-end tests covering the library, CLI subprocesses and MCP over stdio, including rejection cases. 7 of them fail on 0.3.5; the other two are a unit test of the new id module and the readonly-profile check, which have nothing to compare against on 0.3.5. Locally,npm testpasses andnode --test tests/*.test.mjspasses 61/61.Benchmark
scripts/bench/crud-bench.mjs(not shipped). Run: 10k × 384-dim, native, Linux x64. Values are p50 / p95.get(~12 µs) per id, under 0.5% of an insert, and is skipped entirely when loading into an empty store.🤖 Generated with claude-flow