Skip to content

research(nightly): global-min-cut gated streaming memory admission - #955

Draft
ruvnet wants to merge 5 commits into
mainfrom
claude/focused-darwin-azj6te
Draft

research(nightly): global-min-cut gated streaming memory admission#955
ruvnet wants to merge 5 commits into
mainfrom
claude/focused-darwin-azj6te

Conversation

@ruvnet

@ruvnet ruvnet commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Nightly research contribution: a new crate, ruvector-memory-admission, implementing and benchmarking a global-min-cut gated write-time admission policy for streaming agent memory — the write-path dual of ruvector-namespace-merge's (ADR-299) read-time S-T max-flow namespace routing. Write-time admission has no natural source/sink (there's no query to define "relevant"), so this uses a terminal-free Stoer-Wagner global minimum cut instead.

Hypothesis

Given a stream of 4,000 synthetic agent-memory vectors (8 ground-truth clusters, 64 dims, 20% noisy boundary points, interleaved arrival order), does MincutGatedAdmission (global min-cut over existing centroids + the candidate point, gated on average crossing-edge weight) beat a fixed-cosine-threshold baseline at the same final cluster count (matched maintenance budget)? A secondary hypothesis asks whether a self-calibrating variant (AdaptiveMincutAdmission, Welford running mean/std) can replace the hand-tuned threshold.

Architecture

Three policies behind one AdmissionPolicy trait (decide read-only / commit mutating): NearestCentroidThreshold (baseline), MincutGatedAdmission (candidate A), AdaptiveMincutAdmission (candidate B). Self-contained Stoer-Wagner min-cut implementation (src/mincut.rs, zero external dependencies), correctness-checked against hand-solved and closed-form graphs.

Benchmark command & real results

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

At a matched 17-cluster budget (baseline threshold binary-searched to match candidate A's own cluster count):

Variant Clusters Purity Recall@10 Mean insert
NearestCentroidThreshold (calibrated) 17 0.8285 0.7840 0.01µs
MincutGatedAdmission 17 0.8735 (+4.50pp) 0.8623 (+7.83pp) 19.28µs
AdaptiveMincutAdmission 48 0.8615 0.6610 (−12.30pp) 37.14µs

An uncalibrated first run (hand-picked constants) exposed a real methodology bug: purity alone is gameable by over-fragmentation (3,289 clusters from 4,000 points scored 0.9988 "purity" with 0.06 recall). Fixed by comparing policies at a matched final cluster count instead of independently hand-picked thresholds. Both the original degenerate run and the calibration sweeps that replaced it are preserved verbatim as raw evidence in the nightly doc — nothing was quietly overwritten.

Acceptance result

  • Candidate A: ACCEPT — all 4 pre-registered criteria pass (purity gain ≥0pp, recall gain ≥2pp, latency ≤500µs, clusters ≤3×K_true).
  • Candidate B: REJECT — fails 2 of 3 criteria (self-calibrating threshold drifts to the safety-valve cap, losing 12.3pp recall). Documented as a genuine negative result, not silently dropped.
  • Overall: PARTIAL (per the run's own defined ACCEPT/REJECT/INCONCLUSIVE semantics) — a real positive result plus a real, evidence-backed negative result, both retained.

Darwin / MetaHarness / Flywheel tooling note

npx metaharness --help resolves to a project-scaffolding generator, not an in-repo evolution tool; npx ruvector harness doctor/darwin/flywheel does not resolve to an installed executable in this repository (verified before starting, not assumed). In their place, this run performed the equivalent bounded manual search by hand: one parameter (tau) swept across a documented range with a fixed fitness proxy, one promotion decision, one explicitly rejected and preserved variant.

Security review

No untrusted deserialization, no network/filesystem I/O beyond benchmark diagnostics, no secrets. max_clusters bounds this crate's own worst-case O(C³) cost; disclosed caller-side rate-limiting consideration if ever exposed to untrusted write volume. Full disclosure in the nightly doc's Security section.

Main limitations

Synthetic data only; single run per configuration (no variance characterization); no concurrent-writer, delete, or scale-beyond-4,000 testing. Candidate B's negative result is about one specific estimator design, not a claim that no self-calibrating threshold could work.

Production recommendation

Not wired into any production write path. Candidate A is a validated research result with a concrete production path (concurrent-writer support, delete/eviction interaction with ruvector-agent-memory, scale testing, cross-platform determinism check, then an opt-in feature-flagged integration) — none of which was attempted here.

Files changed

  • crates/ruvector-memory-admission/ — new crate: src/mincut.rs (Stoer-Wagner global min-cut), src/dataset.rs (synthetic streaming dataset), src/policy.rs (three admission policies), src/bin/benchmark.rs (matched-budget benchmark), tests/integration.rs, README.md. 20/20 tests pass; cargo clippy --all-targets clean.
  • Cargo.toml / Cargo.lock — register the new (zero-dependency) workspace member.
  • docs/research/nightly/2026-09-02-mincut-streaming-memory-admission/README.md — full nightly research report (hypothesis, methodology, SOTA survey, architecture, raw evidence, ecosystem analysis, applications, promotion decision).
  • docs/research/nightly/2026-09-02-mincut-streaming-memory-admission/gist.md — standalone public technical gist.
  • docs/adr/ADR-341-mincut-gated-streaming-memory-admission.md — architecture decision record.
  • docs/adr/INDEX.md — regenerated via node scripts/adr-index.mjs (CI-check passes).

Test plan

  • cargo test --release -p ruvector-memory-admission — 20/20 passing
  • cargo clippy --release -p ruvector-memory-admission --all-targets — clean
  • cargo fmt -p ruvector-memory-admission -- --check — clean
  • cargo run --release -p ruvector-memory-admission --bin benchmark — real output captured, preserved in the nightly doc
  • node scripts/adr-index.mjs --check — passes
  • Reviewer: confirm the matched-budget benchmark methodology (binary-searching the baseline threshold) is a fair comparison, not favoring the candidate

🤖 Generated with claude-flow

https://claude.ai/code/session_01MUQvcKaga5t9Q8XPZxByLv


Generated by Claude Code

claude and others added 5 commits September 2, 2026 07:36
…ission

Implements MincutGatedAdmission and AdaptiveMincutAdmission alongside a
NearestCentroidThreshold baseline behind a shared AdmissionPolicy trait.
Uses a self-contained Stoer-Wagner global min-cut (terminal-free, unlike
ruvector-namespace-merge's S-T max-flow) to gate write-time cluster
admission for streaming agent memory.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MUQvcKaga5t9Q8XPZxByLv
Covers no-lost-vectors across all three policies, bounded cluster count
under both mincut policies, decide() read-only invariance, and centroid
unit-norm preservation across merges.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MUQvcKaga5t9Q8XPZxByLv
Compares all three policies at the same final cluster count: binary-
searches the baseline threshold to match candidate A's natural cluster
count under a fixed tau, so purity/recall comparisons aren't skewed by
independently hand-picked operating points (an earlier unmatched run
showed purity alone is gameable by over-fragmentation).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MUQvcKaga5t9Q8XPZxByLv
Documents the matched-budget hypothesis, methodology, and measured
result (candidate A ACCEPT: +4.50pp purity, +7.83pp recall@10 at matched
17-cluster budget; candidate B self-calibration REJECT: drifts to the
safety-valve cap and loses 12.3pp recall). Preserves the original
uncalibrated run and threshold/tau sweeps as raw evidence.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MUQvcKaga5t9Q8XPZxByLv
Regenerated docs/adr/INDEX.md via node scripts/adr-index.mjs to register
ADR-341 and advance the allocation counter to 342.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MUQvcKaga5t9Q8XPZxByLv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants