Skip to content

research(agent-memory): mincut-gated forgetting — rejected, with evidence (ADR-345) - #961

Merged
ruvnet merged 5 commits into
mainfrom
claude/focused-darwin-b983y6
Sep 5, 2026
Merged

research(agent-memory): mincut-gated forgetting — rejected, with evidence (ADR-345)#961
ruvnet merged 5 commits into
mainfrom
claude/focused-darwin-b983y6

Conversation

@ruvnet

@ruvnet ruvnet commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Summary

Nightly research run (2026-09-05, ADR-345): tests whether ruvector-mincut's existing RuVectorGraphAnalyzer can give ruvector-agent-memory's compaction a structural "don't evict the bridge memory" signal that the existing scalar CoherencePolicy cannot express.

Result: REJECT, with evidence. Two independent, measured failure modes:

  1. Performance: RuVectorGraphAnalyzer::partition() scales from ~77ms (n=50 vertices) to ~11.4s (n=400), and cost ~1,800–2,700x the scalar baseline even at a deliberately tiny 84-memory corpus (threshold was 100x).
  2. Non-determinism: on a hand-built graph with a provably unique weakest link, 30 repeated partition() calls on byte-identical input returned an empty/unusable result in 15/30 (50%) of calls.
  3. At the corpus size the performance wall forced (84 memories), the structural bonus made zero measurable difference to bridge-memory survival vs. baseline (+0.0pp gap; threshold was ≥15pp).

A separate, independent piece shipped as a working capability regardless: compact_witnessed + EvictionWitnessChain, which closes a real gap — ruvector-agent-memory witnesses memory admission and (via a sibling crate) retrieval, but had nothing witnessing deletion. This reuses the crate's existing ADR-134 witness-record machinery verbatim (one new action_kind tag) and passed its own acceptance test cleanly (20/20 tamper-detection trials).

What changed

  • crates/ruvector-agent-memory/src/graph_forget.rs (new, feature-gated behind mincut-forget, off by default): MincutGatedForgetting compaction policy (Soft/Hard variants).
  • crates/ruvector-agent-memory/src/witnessed_compaction.rs (new, always on): compact_witnessed + EvictionWitnessChain.
  • crates/ruvector-agent-memory/src/compaction.rs: factored CoherencePolicy's scoring into reusable weighted_importance().
  • crates/ruvector-agent-memory/src/ops.rs: added action_kind::LEDGER_COMPACT_EVICT = 0xA7.
  • crates/ruvector-agent-memory/examples/: mincut_gated_forgetting_bench.rs (the acceptance benchmark), mincut_scaling_probe.rs, mincut_determinism_probe.rs (the two feasibility/characterization probes referenced above — runnable, not one-off output).
  • docs/adr/ADR-345-mincut-gated-forgetting.md
  • docs/research/nightly/2026-09-05-mincut-gated-forgetting/README.md and gist.md

No existing behavior changes: CoherencePolicy/LruPolicy/LfuPolicy and compact() are untouched. graph_forget is opt-in and off by default.

(Note: this ADR was originally numbered 341, which collided with an existing ADR merged from another PR (#933) while this one was open. Renumbered to ADR-345 and rebased onto the current main in a follow-up commit on this branch.)

Benchmark command

cargo run --release -p ruvector-agent-memory \
  --example mincut_gated_forgetting_bench --features mincut-forget

Real benchmark results

Policy                           Bridge Surv.    Recall@10  Compaction (us)
----------------------------------------------------------------------------
CoherenceWeighted                       66.7%       100.0%               47
MincutGatedForgetting-Soft              66.7%       100.0%            86188
MincutGatedForgetting-Hard              66.7%       100.0%            85658

Tamper-detection trials (eviction witness chain)
  Detected 20/20 single-byte-flip tampers

Acceptance test
  Soft bridge-survival gap  (+0.0pp) >= 15pp : FAIL
  Hard bridge-survival gap  (+0.0pp) >= 15pp : FAIL
  Soft |recall delta| (0.00pp) <= 2pp                 : PASS
  Hard |recall delta| (0.00pp) <= 2pp                 : PASS
  Soft compaction slowdown  (1833.8x) <= 100x                : FAIL
  Hard compaction slowdown  (1822.5x) <= 100x                : FAIL
  Tamper detection (20/20)                          : PASS

=> REJECT: one or more mandatory acceptance thresholds failed (see above).

Full raw output, the scaling table (n=19..400), and the determinism-probe numbers are in the nightly README's "Benchmark Results" and "Failure modes" sections.

Acceptance result

REJECT (for production use as designed). graph_forget is retained, feature-gated and unpromoted, as a working reference implementation and as negative evidence so a future attempt doesn't rediscover the same two failure modes from scratch. witnessed_compaction is not gated by this rejection and ships as a usable capability today.

Darwin / Flywheel result

Neither tool exists in this repository: npx ruvector harness doctor --json fails (no such CLI), and no harness/darwin/flywheel subcommand exists anywhere in crates/ruvector-cli. npx metaharness --help resolves to a generic project-scaffolding tool unrelated to orchestrating research inside this repo. This capability-discovery result is recorded in the nightly README rather than assumed; the role-separation this process calls for (planner/researcher/engineer/critic) was performed serially in one session instead, with the design-probe → hypothesis-lock → run → analyze sequence documented in the README standing in for it.

Security review

No new cryptographic primitive. compact_witnessed reuses the crate's existing keyless-FNV-1a witness chain and its documented tamper-evidence scope unchanged (naive-edit detection, not adversary-resistant — see src/ops.rs's module docs). The mincut structural signal is advisory-only: a wrong or empty boundary set degrades to the already-reviewed CoherencePolicy behavior, never to an unsafe state.

Main limitations

  • The effectiveness benchmark ran at only one corpus size (84 memories) — the size the measured performance wall forced. Whether the "no measured benefit" result holds at a larger, faster-computed scale is untested.
  • The non-determinism reproduction uses one hand-built 19-vertex topology; its prevalence on larger, realistic clustered data is not independently isolated.
  • ruvector-mincut's lower-level APIs (DynamicMinCut, ClusterHierarchy), which might avoid the measured overhead, were not tried — flagged as the primary next-research direction.

Production recommendation

Do not use MincutGatedForgetting in production. Do use compact_witnessed for any existing compaction policy that needs an auditable eviction trail — it has no mincut dependency and is enabled by default. Next research: repeat this exact, unmodified benchmark against ruvector-mincut's lower-level API surface once/if its performance and non-determinism are addressed upstream.


🤖 Generated with claude-flow

https://claude.ai/code/session_01TKszxZVDnLu1fCH2BAwFi5

ruvnet commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

CI status: Tests (core-platform) failed on this PR's head commit (d0071c2), but the failure is not in code this PR touches.

The job log shows 623/624 tests passed; the sole failure is ruvector-replication::replica::tests::test_promotion timing out at the nextest per-test limit (600.008s):

TIMEOUT [ 600.008s] (624/624) ruvector-replication replica::tests::test_promotion

That test (crates/ruvector-replication/src/replica.rs) is a trivial, synchronous, no-I/O unit test (three in-memory ReplicaSet operations, no sleeps, no network) that this PR does not modify — this PR only touches crates/ruvector-agent-memory. A test with that shape does not organically take 10 minutes; this looks like CI-runner-level contention (e.g. a stuck/hung neighboring test in the same nextest binary, or resource starvation) rather than a regression introduced here.

Re-running the failed jobs once to confirm this is transient, per the drive-to-green flake policy.


Generated by Claude Code

claude and others added 5 commits September 5, 2026 13:44
Add graph_forget::MincutGatedForgetting (feature-gated: mincut-forget), a
CompactionPolicy that layers a ruvector-mincut boundary signal on top of
the existing CoherencePolicy scalar score, to test whether structural
"bridge" memories can be protected from eviction. Factor CoherencePolicy's
scoring into weighted_importance() for reuse.

Add witnessed_compaction::compact_witnessed + EvictionWitnessChain: an
always-on eviction path that emits a chained ADR-134 witness record per
evicted entry before mutating the store, closing the gap where admission
and retrieval are witnessed but deletion is not. Adds one action_kind
constant (LEDGER_COMPACT_EVICT = 0xA7).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TKszxZVDnLu1fCH2BAwFi5
- mincut_gated_forgetting_bench: the fixed, falsifiable acceptance test
  (baseline CoherencePolicy vs. MincutGatedForgetting Soft/Hard) with real
  timing, bridge-survival, recall, and witness tamper-detection measurement.
- mincut_scaling_probe: RuVectorGraphAnalyzer::partition() latency vs. graph
  size (50-11400ms across n=50..400).
- mincut_determinism_probe: reproduces partition() returning an
  empty/unusable result in ~50% of repeated calls on an identical graph.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TKszxZVDnLu1fCH2BAwFi5
Records the rejected hypothesis, measured evidence (performance and
non-determinism findings against ruvector-mincut's RuVectorGraphAnalyzer),
and the decision to keep the module feature-gated and unpromoted while
retaining the eviction-witness half as a default-on capability.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TKszxZVDnLu1fCH2BAwFi5
Full methodology, raw benchmark output, scaling/determinism evidence,
rejected alternatives, and next-research directions for the 2026-09-05
nightly run (ADR-341).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TKszxZVDnLu1fCH2BAwFi5
Also fixes the nightly README's ADR link, which pointed at ../../adr/
(docs/research/adr/, a non-existent path) instead of ../../../adr/.
The RNG seed 341 in examples/mincut_gated_forgetting_bench.rs is a
seed, not an ADR reference, and is left unchanged.

Co-Authored-By: RuFlo <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_019xHM4rAH4aaShb4DTr1n6s
@ruvnet
ruvnet force-pushed the claude/focused-darwin-b983y6 branch from d0071c2 to 99c7e98 Compare September 5, 2026 17:48
@ruvnet ruvnet changed the title research(agent-memory): mincut-gated forgetting — rejected, with evidence (ADR-341) research(agent-memory): mincut-gated forgetting — rejected, with evidence (ADR-345) Sep 5, 2026
@ruvnet
ruvnet marked this pull request as ready for review September 5, 2026 17:49
@ruvnet
ruvnet merged commit cae37fd into main Sep 5, 2026
62 of 63 checks passed
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