Quality-Weighted Merge with Conflict-Driven Decay
A Method for Forcing Convergence in Distributed Edge-Weight Graphs
Abstract
A method for resolving conflicting assertions in a distributed edge-weight graph, wherein each edge carries a quality score computed from reinforcement frequency, recency of activation, and historical conflict rate, and wherein the loser of a conflict is excluded from the shared namespace, forcing the graph toward consensus without central coordination. Stale edges (inactive past a namespace-specific threshold) undergo accelerated decay via a constant per-pass factor that avoids compounding explosion. The algorithm is local-first, stdlib-only, and operates over a committed JSON bundle that propagates through version control.
Background
Existing distributed knowledge graphs (Google Knowledge Graph, Wikidata, enterprise graph databases) rely on central curation or voting mechanisms to resolve conflicting assertions. These approaches fail in local-first, edge-compute scenarios:
- Last-write-wins (default Git merge): discards contributor quality signal, rewards recency over accuracy.
- MAX-merge (naive synaptic import): allows a single over-eager contributor to permanently distort shared recall.
- Consensus voting (Raft/Paxos): requires online coordination — unusable in disconnected, git-clone-and-fork workflows.
Our approach: each edge carries its own quality signal, and conflict resolution is purely local — no coordinator, no quorum, no round-trips. The loser of each conflict is excluded, so the system converges to the highest-quality assertions without any node having global authority.
Core Algorithm
1. Edge Quality Scoring
Each edge e in namespace ns is scored by a composite quality function:
score(e) = wr × reinforcement(e) + wt × recency(e) − wc × conflict_rate(e)
where:
reinforcement(e) = log1p(activation_count) / log1p(30)— saturates at ~1.0 after 30 activationsrecency(e) = exp(−0.693 × days_since_last_activation / 30.0)— 30-day half-lifeconflict_rate(e) = conflict_count / max(1, total_comparisons)— [0.0, 1.0]
Default weights: wr = 0.4, wt = 0.35, wc = 0.25. Theoretical maximum is 0.75 (achievable when activation_count ≥ 30 and edge was just activated). In practice, most edges score below 0.70.
| Score | Action |
|---|---|
| ≥ 0.70 | Auto-promote to shared namespace |
| [0.30, 0.70) | Retain as neutral (survives import, but doesn't win conflicts against ≥0.70 edges) |
| < 0.30 | Reject (excluded from shared) |
Peer review: Edges in the [0.30, 0.70) range are evaluated by PeerReviewGate (E3) — a secondary gating mechanism that can auto-promote, reject, or queue for operator review based on additional heuristics.
2. Conflict Resolution
When two bundles contain edges for the same (source, target) pair:
resolve(existing, incoming):
if |existing.score − incoming.score| < 0.05 AND max(existing.score, incoming.score) < 0.30:
return CONTEST → escalate to review
else:
winner = argmax(existing.score, incoming.score)
return winner → loser is dropped
3. Staleness Detection
Edges inactive past a namespace-specific threshold undergo accelerated decay:
| Namespace | Stale after | Decay factor per pass |
|---|---|---|
| shared | 30 days | 2(−5/30) ≈ 0.891 |
| branch:* | 14 days | 2(−5/14) ≈ 0.787 |
| personal | 60 days | 2(−5/60) ≈ 0.943 |
Decay is applied as a constant per-pass factor (not a cumulative formula):
decay_factor = 2(−fast_decay / half_life) = 2(−5/30) ≈ 0.891 per pass
After 30 daily passes: 0.891³⁰ = 2−5 = 1/32 — exactly 5× normal decay, no compounding explosion.
Example Walkthrough
Two contributors, Alice and Bob, publish bundles containing overlapping edges.
Alice's bundle
(source="auth/jwt.py", target="auth/handlers.py", weight=8.0, activation_count=40, conflicts=0, comparisons=1)
Score: 0.743
Bob's bundle
(source="auth/jwt.py", target="auth/handlers.py", weight=2.0, activation_count=3, conflicts=1, comparisons=2)
Score: 0.387
Difference: 0.743 − 0.387 = 0.356 (> 0.05, no contest)
Winner: Alice's edge (score 0.743)
Result: Bob's edge is excluded from the shared namespace
Properties
Convergence
Conflict resolution excludes the loser from the shared namespace — the winner survives, the loser is dropped. This forces the graph toward consensus: each conflict eliminates one conflicting assertion, monotonically reducing the set of competing edges.
Eventual Consistency
Bundle import is idempotent (tracked by content hash in meta.team_bundle_imported_hash). Given the same set of bundles, all replicas converge to the same state.
Complexity
- Scoring: O(|bundle|) — single pass
- Conflict detection: O(|A| + |B|) — dict-indexed
- Decay application: O(|stale|) — one UPDATE per stale edge
Reference Implementation
- Language: Python 3.10+ (stdlib-only)
- Repo: https://github.com/dfrostar/neuralmind
- Commit:
31aac0e(2026-07-22) - Files:
- neuralmind/contribution_scoring.py
- neuralmind/merge_semantics.py
- neuralmind/team_staleness.py
Prior Art Statement
To the best of our knowledge, the specific combination of: (1) per-edge composite quality scoring (reinforcement × recency − conflict penalty), (2) loser-exclusion conflict resolution, (3) constant per-pass staleness decay (avoiding compounding explosion), and (4) integration with git-committed bundle propagation — has not been previously published in the context of local-first code intelligence systems.
Related work includes Hebbian learning (Hebb, 1949), gossip protocols (Demers et al., 1987), federated learning (McMahan et al., 2017), and Wikidata (Vrandečić, 2013).