Skip to content

research: structural-time conflict resolution for concurrent multi-agent memory - #829

Draft
ruvnet wants to merge 3 commits into
mainfrom
claude/focused-darwin-1je9ll
Draft

research: structural-time conflict resolution for concurrent multi-agent memory#829
ruvnet wants to merge 3 commits into
mainfrom
claude/focused-darwin-1je9ll

Conversation

@ruvnet

@ruvnet ruvnet commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Hypothesis

Given 2000 genuinely concurrent (causally-unordered) synthetic memory-write conflicts across 6 agents, each write carrying a hidden ground-truth quality label never exposed to any policy, when conflicts are resolved by StructuralCoherenceMerge instead of LwwWallClock (400ms per-agent clock skew) or LwwVectorClock (agent-id tiebreak), then its correct-resolution rate should exceed both baselines by ≥10 percentage points, subject to zero causal-order violations on a 500-case causally-ordered control set and merge throughput within 5× of the wall-clock baseline.

Fixed in src/main.rs's doc comment before the benchmark was run; not modified afterwards.

Why

RuVector's prior agent-memory nightlies (temporal-coherence, agent-memory-compaction) both address a single agent managing its own memory. None address what happens when multiple agents write concurrently to the same shared memory key without a synchronized clock or a single sequencer — a gap directly relevant to RuVector's ruFlo/swarm/edge-fleet ambitions. This connects two existing-but-previously-unconnected primitives: emergent-time's StructuralProperTime clock and ruvector-agent-memory's coherence-scoring pattern.

Architecture

New crate crates/ruvector-structural-memory-merge (4 files, 936 lines, none over 500, one dependency — emergent-time, itself zero-dependency):

  • MemoryWrite / VectorClock — causal metadata per write.
  • Three MergePolicy impls: LwwWallClock (baseline), LwwVectorClock (variant A), StructuralCoherenceMerge (candidate — respects causal order exactly like variant A, but breaks concurrent-write ties by τ · (0.5 + 0.5·coherence) where τ is StructuralProperTime::tick).
  • Deterministic synthetic scenario generator with a leakage-free ground truth: a hidden alpha drives three independently-noised observable channels (structural snapshot, coherence context, skewed wall clock); no policy ever sees alpha or the resulting true_quality label.

Files changed

  • crates/ruvector-structural-memory-merge/{Cargo.toml,src/{lib,main,scenario,vclock}.rs} — new crate
  • Cargo.toml, Cargo.lock — workspace registration
  • docs/adr/ADR-305-structural-time-memory-merge.md
  • docs/research/nightly/2026-08-14-structural-time-memory-merge/{README,gist}.md

Benchmark command

cargo run --release -p ruvector-structural-memory-merge --bin structural-memory-merge-bench

x86-64 Linux 6.18.5-fc-v20, rustc 1.94.1, release profile, deterministic seed 0xA6E17.

Real benchmark results (realistic 400ms per-agent clock skew)

Policy Correct-resolution rate Mean quality regret Causal violations (of 500) Merges/sec
LwwWallClock 48.5% 0.1784 19 12,098,078
LwwVectorClock 50.6% 0.1716 0 12,153,589
StructuralCoherenceMerge 86.8% 0.0162 0 4,338,379

Wall-clock LWW's causal-order violations scale directly with skew: 0/500 at 0ms, 19/500 at 400ms, 171/500 at 2000ms. LwwVectorClock and StructuralCoherenceMerge have zero violations at every skew level tested, by construction. Full three-skew-level table in the ADR/README.

Honest caveat: both LWW baselines are content-blind by construction and sit at ≈50% (chance) on this two-way choice — the +36–38pp margin should be read as "content-aware beats content-blind under this noise model," not evidence of proximity to any information-theoretic ceiling. No ablation of τ-only vs. coherence-only was run this cycle (see ADR "Open Questions").

Acceptance result

- beats LwwWallClock by >=10pp: true (+38.3pp)
- beats LwwVectorClock by >=10pp: true (+36.2pp)
- zero causal-order violations (vclock & structural): true (vclock=0, structural=0)
- throughput within 5x of wall-clock baseline: true (4338379 vs 12098078 merges/sec)

VERDICT: ACCEPT

Darwin result

Not run as a generational search: npx ruvector harness darwin is not installed in this environment (verified — npm error: could not determine executable to run), and this cycle compared three fixed policies rather than a population to mutate. The natural Darwin extension (evolving StructuralMetric channel weights against correct-resolution-rate fitness) is documented as the concrete next experiment, not attempted here.

Flywheel result

No ruvector harness flywheel CLI is installed in this environment either (verified, same check). Evidence is instead retained directly in the ADR and nightly README: hypothesis, sources, rejected alternatives, measured results, and open questions, all attributable to the exact benchmark command and raw output reproduced verbatim in both documents.

Security review

Pure computation over caller-supplied data; no I/O, no network, no filesystem access, no unsafe code. Decision records are auditable (reason, tau_a, tau_b, causal_order) but not tamper-evident in this PoC — production hardening should route them through the existing ruvector-proof-gate / ruvector-retrieval-receipt witness-chain crates rather than reimplementing that here. The design assumes honest (non-Byzantine) agents; an agent that fabricates its own state snapshot to inflate τ is not defended against — flagged as a hard prerequisite before any untrusted-multi-tenant deployment (would need RVM-style attestation).

Main limitations

Synthetic (not real-trace) ground truth; no τ-vs-coherence ablation; no adversarial/Byzantine testing; no WASM build measured (only argued plausible from the zero-extra-dependency graph); not wired into ruvector-agent-memory, MCP, or ruFlo — this is an opt-in, standalone crate, not a production integration.

Production recommendation

Promote the crate as an experimental, non-default workspace addition (this PR). Do not default-enable StructuralCoherenceMerge inside ruvector-agent-memory yet. Production path documented in the ADR: ablation → real-trace validation → RVM Byzantine hardening → feature-flagged integration → route Decision records through ruvector-proof-gate.

Research document / ADR / gist

Verification

  • cargo build --release -p ruvector-structural-memory-merge — clean
  • cargo test --release -p ruvector-structural-memory-merge — 10/10 passed
  • cargo clippy --release -p ruvector-structural-memory-merge --all-targets — clean
  • cargo fmt -p ruvector-structural-memory-merge — applied

Generated by Claude Code

claude and others added 3 commits August 14, 2026 08:00
Introduce crates/ruvector-structural-memory-merge: a MergePolicy for
concurrent shared agent-memory writes that never overrides real causal
order (vector clock gated) but breaks ties among genuinely concurrent
writes using emergent-time's StructuralProperTime magnitude weighted by
context coherence, instead of wall-clock or vector-clock LWW.

Connects emergent-time (structural clock, previously only used inside
its own crate) with the ruvector-agent-memory coherence-scoring pattern,
for the first time addressing multi-writer (not single-agent) memory.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01AJBYzsXc1sMfqTyfYrUy8U
Records hypothesis, measured evidence (86.8% correct-resolution rate
vs ~50% for wall-clock/vector-clock LWW baselines, zero causal-order
violations, 2.8x throughput cost), acceptance verdict, alternatives
considered, and the honest caveats/open questions before any production
promotion.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01AJBYzsXc1sMfqTyfYrUy8U
…y merge

Full research record: hypothesis, architecture diagram, benchmark
methodology (leakage-free ground truth, causal-order control group),
raw measured results at three skew levels, competitor comparison,
practical and long-horizon applications, MCP/RVF/RVM/ruFlo integration
analysis, and a standalone technical gist.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01AJBYzsXc1sMfqTyfYrUy8U
@aurumflux20

Copy link
Copy Markdown

The leakage-free ground truth here is the part I'd steal — a hidden alpha driving three independently-noised observable channels, so no policy can accidentally see the label it's being scored against. Most conflict-resolution benchmarks I've read quietly leak the answer into one of the observables and then report a win.

One distinction that might be worth naming explicitly in the ADR, because it changes what "correct resolution" even means: all three policies here assume a concurrent conflict is resolvable. For shared memory that holds — two writes to a key, pick the better one, and τ · (0.5 + 0.5·coherence) is a defensible way to pick. The write that loses simply didn't happen.

That assumption inverts for irreversible side effects. Two agents concurrently deciding to scale a node pool, or settle a payment, or send a message: there is no merge. If you tie-break and let the "higher coherence" one proceed, you've still got a loser who may have already executed — and unlike a memory write, you can't un-execute it. Worse, both actions can be individually correct and still be catastrophic together (scale-up and scale-down on the same pool, both justified by what each agent read).

So for effects the correct resolution of a genuine concurrency is not picking a winner — it's refusing both and escalating, because concurrency itself is the signal that neither agent knew what the other was doing.

Concretely, the two cases want opposite policies at the same code point:

concurrent writes to shared memory  -> resolve (merge/rank; a loser costs you data quality)
concurrent irreversible effects     -> refuse  (a loser costs you money or an outage)

I've been building the effect-side version of this (effectfence, MIT) and it lands on the same VectorClock::concurrent() predicate you're using — but where your policy then ranks, mine aborts before the tool runs and returns which domain moved and to what sequence, so the caller re-reads instead of re-firing. Same primitive, opposite conclusion, because the cost of being wrong is asymmetric.

Two things from it that might be relevant to RuVector's swarm/edge-fleet direction:

  1. Read-set validation, not just write ordering. Vector clocks order the writes; they say nothing about whether the state an agent read to justify its write is still true. An agent that reasoned for 900ms on a value another agent has since changed produces a causally well-ordered write that is nonetheless based on a world that no longer exists. Validating the read-set at admission catches that class, and it's orthogonal to whichever merge policy wins your benchmark.

  2. Count the refusals, not just the resolutions. I added since-boot counters (admitted / replayed / refused_stale / refused_race) mostly for ops, and the surprising value was diagnostic: a spike in concurrent-refusals localises which agents are reasoning from stale views, which the aggregate correct-resolution rate averages away.

Genuinely curious whether the structural-time tick would outperform on the effects side too, where the question isn't "which write was better" but "should either of these run at all." If you ever want a second implementation to benchmark the causal-order control set against, happy to point mine at it — different conclusions, same primitives, and disagreement would be informative.

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.

3 participants