Conversation
ADR-345 (nightly 2026-09-05) rejected mincut-gated agent-memory compaction partly on an unresolved finding: RuVectorGraphAnalyzer:: partition() is non-deterministic across calls on an identical graph (~50% empty-result rate) and very slow on one-shot queries, because it routes through MinCutWrapper's bounded-range dynamic instance ladder (built to amortize incremental updates, not "rebuild the graph, ask once" call sites) over a DynamicGraph whose DashMap-backed edge storage has no fixed iteration order. Add ruvector_mincut::static_cut::stoer_wagner_min_cut: a from-scratch, deterministic O(V^3) global min-cut (edges sorted by canonical endpoint+id before use, so results depend only on graph structure). Wire it into RuVectorGraphAnalyzer as partition_static()/min_cut_static(), and into ruvector-agent-memory's MincutGatedForgetting as a new MincutEngine::Static (soft_static()/hard_static() constructors) alongside the original MincutEngine::Dynamic path. Both crates' full test suites pass unchanged (520 + 68 tests, 0 failures). Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01EcgBy87uGS4Xtros5zVPDd
… path Documents the 2026-09-08 nightly follow-up to ADR-345: root cause, hypothesis, methodology, and full measured evidence (main benchmark, extended scaling probe, extended determinism probe) for the new deterministic static min-cut path. Verdict is split: the static_cut primitive is promoted (correct, deterministic, 65x-8421x faster than the dynamic engine depending on topology); the compaction-policy application is rejected again (bridge-survival gap flat at +0.0pp on both engines; static engine still 43.8x/46.9x over the pre-registered 10x speed bar versus the scalar baseline, despite being 65-74x faster than the rejected dynamic engine on the same corpus). Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01EcgBy87uGS4Xtros5zVPDd
|
CI status: every check passed except This is not caused by this PR's diff (two small crates, I'm not spending this PR's one allowed CI re-run on it, since the failure reproduces identically and unconditionally on Generated by Claude Code |
ruvnet
left a comment
There was a problem hiding this comment.
Dream cycle exact-head review.
Frozen hypothesis: the deterministic static Stoer-Wagner primitive returns complete, repeatable partitions and materially outperforms the current dynamic path while preserving native/WASM/workspace compatibility.
Evidence supports the primitive but not the full gate. The reported 19-vertex comparison is 0.099 ms versus 835 ms (about 8,421x), with zero empty static partitions versus 66% empty dynamic outputs. On the 84-memory corpus, static is reported 64.7x-73.6x faster than dynamic, but remains 43.8x-46.9x slower than the baseline and produces no bridge-rate gain; the PR correctly records that compaction hypothesis as rejected. Native, WASM-dedup, regression, supply-chain, formatting, and clippy workflows passed.
Required Workspace CI run 34200670407 was cancelled. The benchmark is also single-host/small-graph evidence, so cross-target compatibility and representative scaling remain unproven. Re-run Workspace CI and preserve deterministic cut/value parity on a frozen multi-size corpus before promotion.
INCONCLUSIVE
Addresses the 2026-09-09 PR review's INCONCLUSIVE verdict: the prior determinism evidence covered only a single 19-vertex fixture, leaving "representative scaling" unproven. Adds a fixed, non-random ring-graph corpus at five sizes (10-250 vertices), each independently rebuilt (fresh DynamicGraph, fresh DashMap hash seeds) 5 times, asserting the full StaticCutResult (cut value and both partition sides) is byte-identical across every rebuild at every size — a permanent regression/promotion gate, not a throwaway probe. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01EcgBy87uGS4Xtros5zVPDd
|
Addressed both points from the dream-cycle review:
On the "single-host/small-graph" point: agreed this run's evidence doesn't establish cross-target (WASM/other-arch) parity or behavior past 800 vertices — the ADR and nightly README already flag both as open/untested rather than claimed. Happy to scope a follow-up (WASM build of Generated by Claude Code |
|
Re-run result: Two independent runs on two different commits hitting the exact same wall-clock limit at the exact same point in dependency compilation confirms this is a fixed CI job/workflow timeout that this one shard's compile time is right up against — a repo-wide Frozen multi-size corpus parity test: landed in Given the CI item is now well-evidenced as a pre-existing infra limitation rather than a merge blocker this PR can fix, and the requested scaling/parity evidence is in place, this PR should be ready for another look whenever convenient. Generated by Claude Code |
Summary
Nightly research follow-up to ADR-345 (2026-09-05,
mincut-gated-forgetting), which rejected an agent-memory compaction policy partly on an unresolved finding:RuVectorGraphAnalyzer::partition()is non-deterministic across calls on an identical graph (~50% empty-result rate) and very slow for one-shot queries.This PR root-causes that finding and fixes it:
RuVectorGraphAnalyzer::partition()delegates toMinCutWrapper, a bounded-range dynamic instance ladder (arXiv:2512.13105) built to amortize incremental edge updates on one long-lived graph. Every actual call site in the workspace instead rebuilds a fresh graph and asks once — paying full bootstrap cost with nothing amortized.DynamicGraphstores edges inDashMaps with an independently-randomized hash seed per instance, sograph.edges()iteration order (and the wrapper's internal tie-breaking) differs across structurally-identical graphs — explaining the non-determinism without any intentional randomness anywhere in the chain.What's added:
ruvector_mincut::static_cut::stoer_wagner_min_cut— a from-scratch, deterministic O(V³) global min-cut (classical Stoer-Wagner), over edges sorted by canonical endpoint+id before any use, so results depend only on graph structure, never hash-map iteration order.RuVectorGraphAnalyzer::partition_static()/min_cut_static(), alongside (not replacing) the existing dynamicpartition()/min_cut().ruvector-agent-memory'sMincutGatedForgettinggainsMincutEngine::{Dynamic, Static}andsoft_static()/hard_static()constructors.Files changed
crates/ruvector-mincut/src/static_cut.rs(new) — algorithm + 6 unit testscrates/ruvector-mincut/src/{lib.rs,integration/mod.rs}— wiring + 2 new testscrates/ruvector-agent-memory/src/{graph_forget.rs,lib.rs}—MincutEngine, static constructors, 3 new testscrates/ruvector-agent-memory/examples/{mincut_gated_forgetting_bench,mincut_scaling_probe,mincut_determinism_probe}.rs— extended with Static-engine measurementsdocs/adr/ADR-346-static-mincut-fast-path.md(new)docs/research/nightly/2026-09-08-static-mincut-forgetting/{README.md,gist.md}(new)docs/adr/INDEX.md— regenerated vianode scripts/adr-index.mjsBenchmark command
Real benchmark results (this run; full tables in the nightly README)
Determinism (ADR-345's original 19-vertex fixture, 50 trials each):
partition())partition_static())Speedup: 8,421x on this fixture.
Main benchmark (84-memory bridge corpus, 50% compaction):
Static is 73.6x/64.7x faster than Dynamic on this corpus. Tamper detection: 20/20 (unchanged).
Acceptance result
Split verdict, per the hypothesis fixed before this run:
static_cutprimitive: ACCEPT / promoted. Correct (validated against known min-cut properties), deterministic, 65x–8,421x faster than the dynamic engine depending on topology. Shipped as new publicruvector-mincutAPI.MincutGatedForgetting-Static compaction application: REJECT (again, same disposition as its Dynamic-engine sibling). Two of three pre-registered thresholds still fail:A falsified hypothesis with strong retained evidence is a successful nightly run per the process's own definition — this one is stronger than its predecessor because it rules out "maybe it was just this one buggy engine call" as an explanation for the flat effectiveness result.
Darwin result
Not run.
npx metaharness --helpresolved (v0.4.16) but exposes template-scaffolding/scoring subcommands only;npx ruvector harness doctor/darwin/flywheel --jsonwas not resolvable in this environment ("could not determine executable to run"). No Darwin evolutionary search was available as an invokable CLI; the two variants compared (Dynamic-reproduction, Static-candidate) were defined and benchmarked directly, with the ADR-345 parent retained unchanged asMincutEngine::Dynamic. Full capability-discovery table in the nightly README.Flywheel result
No
ruvector harness flywheel/avoCLI was resolvable in this environment (see above), so no automated evidence-verification/witness-signing pipeline was invoked. All raw benchmark/test output is captured verbatim in the nightly README and this PR description; both crates' full test suites were run and their pass/fail counts recorded as the closest available substitute for automated replay verification.Security review
No new attack surface:
static_cutis a pure, deterministic,#[deny(unsafe_code)]-covered algorithm over data already resident inDynamicGraph; no I/O, no new external dependency, no update/mutation API. Full section in ADR-346.Test results
cargo test -p ruvector-mincut --release: 520 passed, 0 failed, 5 ignored (full pre-existing suite, unrelated modules included; newstatic_cutmodule: 6/6 pass, newintegrationtests: 2/2 pass).cargo test -p ruvector-agent-memory --release --features mincut-forget,proof-gate: 68 passed, 0 failed across all binaries (new static-engine tests: 3/3 pass).cargo build --release(both crates): clean.cargo clippy --release(both crates): no new warnings (only pre-existing, unrelated ones).cargo fmt: applied.node scripts/adr-index.mjs --check: OK, 377 ADR files, no duplicates.Main limitations
Production recommendation
Merge
static_cutas a general-purpose, low-risk, purely additive primitive — any one-shot min-cut query in the workspace (includingruvector-mincut's ownCommunityDetector/GraphPartitioner, still on the slow/non-deterministic path, flagged as a natural follow-up) can adopt it directly. Keep the compaction-policy application experimental and off by default (mincut-forgetfeature, unchanged), pending either a cheaper structural signal (articulation points) or a larger-corpus re-test now that the latency blocker is substantially weaker.Documentation
docs/research/nightly/2026-09-08-static-mincut-forgetting/README.mddocs/adr/ADR-346-static-mincut-fast-path.mddocs/research/nightly/2026-09-08-static-mincut-forgetting/gist.md🤖 Generated with claude-flow
https://claude.ai/code/session_01EcgBy87uGS4Xtros5zVPDd
Generated by Claude Code