Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ members = [
"crates/ruvector-cluster-rag",
# S-T mincut namespace routing for multi-namespace search (ADR-299)
"crates/ruvector-namespace-merge",
"crates/ruvector-memory-admission",
# Semantic query-result reuse for repeated agent-memory queries (ADR-301)
"crates/ruvector-query-cache",
# Reservoir-sampled adaptive product quantization under drift (ADR-302)
Expand Down
21 changes: 21 additions & 0 deletions crates/ruvector-memory-admission/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "ruvector-memory-admission"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
description = "Global min-cut gated write-time cluster admission for streaming agent memory in RuVector"
readme = "README.md"
keywords = ["vector-search", "agent-memory", "mincut", "streaming", "clustering"]
categories = ["algorithms", "data-structures"]

[[bin]]
name = "benchmark"
path = "src/bin/benchmark.rs"

[dependencies]

[lints.rust]
dead_code = "allow"
unused_variables = "allow"
39 changes: 39 additions & 0 deletions crates/ruvector-memory-admission/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ruvector-memory-admission

Global-min-cut gated write-time cluster admission for streaming agent memory.

`ruvector-namespace-merge` (ADR-299) uses S-T max-flow/min-cut to answer a
**read-time** question: given a query and a fixed namespace set, which
namespaces should be searched? This crate answers the dual **write-time**
question, which has no natural source/sink to fix the flow terminals on:
given a stream of incoming agent-memory vectors and a growing set of
clusters, should the next vector merge into an existing cluster, or does it
belong to a new one?

A fixed cosine-to-nearest-centroid threshold (the obvious baseline) only
looks at one edge. The **global** minimum cut (Stoer-Wagner, no source/sink)
of the (existing centroids + candidate point) similarity graph looks at the
whole structure: it finds the single weakest link in the graph and checks
whether the candidate sits on the weak side of it.

Three policies implement `AdmissionPolicy`:

1. `NearestCentroidThreshold` — baseline: merge into the nearest centroid if
cosine similarity clears a fixed threshold, else spawn a new cluster.
2. `MincutGatedAdmission` — candidate A: global min-cut over centroids +
candidate, gated on the cut's average crossing-edge weight against a
fixed `tau`.
3. `AdaptiveMincutAdmission` — candidate B: same mechanism, but `tau` is set
online from a running mean/std of previously observed cut weights
(Welford's algorithm) instead of a hand-tuned constant.

Run the benchmark:

```bash
cargo run --release -p ruvector-memory-admission --bin benchmark
```

See `docs/research/nightly/2026-09-02-mincut-streaming-memory-admission/README.md`
for the full hypothesis, methodology, and measured results, and
`docs/adr/ADR-344-mincut-gated-streaming-memory-admission.md` for the
architecture decision record.
Loading
Loading