memnode
Sign InSign Up
Back to Articles

Belief Networks for Agents: Holding Contradictions Instead of Overwriting Them

Most agent memory resolves conflicts by overwriting or silent top-k ranking, so an agent asserts a claim its own memory contradicts. memnode models support and rebuttal edges, scores tension, and recalls disagreement instead of faking consensus.

memnode8 min read
agent memorymemnodecontradictionsbelief networkreasoningdesign notes

Give an agent a memory layer and the first hard problem is not storage. It is what to do when two things you stored disagree. A user tells your agent on Monday that the team deploys from the main branch. On Thursday a different teammate says deploys go out from a protected release branch and that pushing to main never ships anything. Both statements are real observations. Both were said with confidence. They cannot both be the current rule, but they might both be true at different times, in different repositories, or for different people. The question is what your memory does with the conflict.

Most memory systems do one of two things, and both lose information. The first is overwrite on conflict: last write wins, the Monday fact is gone, and the agent now believes the release rule with no trace that it ever thought otherwise. The second is quieter and arguably worse: the system keeps both records but recall just returns whichever chunk scored highest on similarity. The agent confidently asserts one convention while a directly contradicting memory sits in the same store, never surfaced. In both cases the agent sounds certain about something its own memory does not actually agree on.

This article is about the alternative memnode takes: instead of resolving every conflict by deletion or by silent ranking, it models the relationships between memories. Some memories support a claim, some rebut it, and a tension score flags where the memory graph is disagreeing with itself. Recall can then say the honest thing: the canonical view is X, but there is a standing rebuttal Y.

Why overwrite on conflict loses information you need

Overwrite assumes the newer statement is the truer one. Often it is. But the assumption fails in exactly the situations where memory matters most. The dissenting memory might be the correct one and the new write might be a mistake, a misremembering, or a deliberate poisoning attempt. The two statements might not actually be in conflict once you know their scope, in which case throwing one away destroys a distinction the agent will need later. And even when the new statement really does win, the fact that there was a disagreement is itself information. It tells you this is a contested area, that the rule changed recently, that an agent answering from this region of memory should hedge rather than assert.

A flat store cannot hold any of that. As the memnode whitepaper puts it, a vector database cannot represent that a claim is disputed; when two conflicting facts are stored, both are retrieved and the agent gets contradictory information with no guidance on which to trust, no mechanism to resolve the conflict, and often no way to even detect it. Overwrite avoids the contradictory-output problem by destroying one side. Silent top-k ranking avoids it by hiding one side. Neither models the disagreement, so neither can reason about it.

This is also where this piece picks up from the previous one in the series. In canonization we looked at the status of a single memory: how one claim earns its way from provisional to supported to canonical, and how the system decides what it believes about that one node. Belief networks are the layer above that. They are about the relationships across memories, the edges that say this observation backs that claim and this one argues against it. Canonization tells you the standing of a memory; the belief network tells you how memories stand in relation to each other, which is what lets the system know a claim is contested in the first place.

How support and rebuttal edges form

memnode is built as a graph, so the natural move is to make agreement and disagreement first-class edges rather than something inferred at query time. New observations land as raw episodic memory. When the consolidation engine clusters those episodes and distills a stable semantic claim, it does not just create the claim node. It wires each contributing episode to that claim with a typed edge. The model uses three edge types for this:

  • SUPPORTS. This episode or node backs a semantic claim. Several independent episodes all saying the same thing become several support edges, and the weight of that support is part of how a claim earns canonical status.
  • REBUTS. This episode or node contradicts a semantic claim. The Thursday release observation does not overwrite the Monday main claim; it attaches to it as a rebuttal.
  • CONTEXTUALIZES. This scopes or qualifies a claim without asserting it is true or false. It is the edge for I am not disagreeing, I am narrowing where this applies. This is the type that captures the these are different repositories case without forcing a winner.

The important design choice is that these edges are not derived on the fly during a query. They are stored structure, built and maintained by consolidation, so the graph carries an explicit record of what agrees with what. A claim node accumulates a support weight from its SUPPORTS edges and a rebuttal weight from its REBUTS edges. Those two numbers are the raw material for the next idea.

What a tension score is for

A tension score is a single measure of unresolved conflict on a claim, derived from the balance of its support and rebuttal. A claim with strong support and no live rebuttals has low tension; it is settled. A claim that is well supported but also carries a substantial standing rebuttal has high tension; it is contested. The exact formula, the weights, and the threshold where the system decides a claim has crossed from settled into disputed are tuned internals and not the point here. The point is what the score is for.

Its job is to make disagreement visible instead of letting it sit silently in storage. A flat store has no concept of a contested claim, so it cannot warn anyone. A tension score is the signal that says this region of memory does not agree with itself, do not answer from it as though it does. It feeds two parts of the system. It nudges recall scoring and the confidence reported on an answer, so an agent reading from a high-tension area is told its footing is shaky. And it gates the canonization lifecycle: a claim with unresolved high-weight rebuttals does not get promoted to canonical, and a previously canonical claim whose rebuttal pressure rises can drift back toward disputed. Tension is how an unresolved argument stays loud enough to change behavior rather than being quietly buried.

The design rule is the inversion of last write wins: a contradiction is not an error to clean up, it is a fact about the state of your knowledge that the memory layer should preserve and surface.

Disagreement-preserving recall

Storing the conflict is only half the value. The other half is answering with it. When an agent asks a question and the winning claim sits in a high-tension area, memnode does not flatten the answer into false consensus. The recall pipeline establishes a position before it writes an answer: it follows correction chains to the latest truth, computes the tension from the support and rebuttal weights around the candidates, and when tension is high it switches into a disagreement-preserving mode. Instead of a single confident sentence, the answer carries a dominant position, the competing interpretation, and a short account of why the dominant one currently wins.

Conceptually the response looks less like a lookup and more like a briefing:

recall("which branch do we deploy from?")

dominant_answer:        deploy from the protected "release" branch
competing_interpretation: an earlier statement said deploys go from "main"
why_dominant_wins:      more recent, and supported by the current
                        repo convention; the "main" claim has a
                        standing rebuttal and was not reconfirmed
tension_score:          high (claim is disputed, not settled)

That is a different contract with the calling agent. A flat store would have returned either the release rule alone, sounding settled, or the main rule alone if it happened to score higher, sounding equally settled and being wrong. Disagreement-preserving recall hands the agent enough to act carefully: use the dominant rule, but know it is contested, and maybe ask the user to confirm before doing something irreversible with it. The agent gets to inherit the memory layer's honesty instead of laundering uncertainty into confidence.

There is a further move for the case where neither side ever wins. When two competing claims both keep their support over time rather than one decaying, the consolidation engine can generate a dialectical synthesis candidate, a new claim that reconciles them by scoping, along the lines of deploys go from release in the production repository and from main in the internal tools repository. That synthesis is not trusted on creation. It enters as a fresh, unproven claim and has to earn canonical status through the same evidence-gated pipeline as anything else. The effect is that a long-running disagreement becomes productive structure, a better-scoped fact, rather than a permanent stalemate or a coin flip.

Why this is the relationships layer, not the status layer

It is worth being precise about the boundary with canonization, because the two are easy to conflate. Canonization is a property of a memory: a status label that says how much the system trusts this one node. A belief network is a property of the connections: it is the set of support and rebuttal edges that exist between memories, and the tension that emerges from their balance. You need both. Without status, every memory is equal and the system cannot tell a well-backed fact from a single guess. Without the relationship layer, status is computed in a vacuum, with no way to know a claim is contested, so canonization itself becomes a last-write heuristic in disguise.

The two layers feed each other. Support and rebuttal weights are direct inputs to whether a claim can be promoted, and a rising rebuttal weight is one of the signals that a canonical claim is drifting and should be re-examined. The belief network is what makes canonization more than a popularity contest, and canonization is what keeps the belief network from treating every passing disagreement as equally important.

What it buys you

For an agent builder the payoff is concrete. Your agent stops asserting one convention while its own memory holds the opposite. Contested areas announce themselves through tension rather than ambushing you in production. Disagreements that turn out to be scope differences get resolved into sharper facts instead of being decided by recency. And because the support and rebuttal structure is stored, you can inspect why a claim is contested, which ties directly into lineage and provenance: every edge in the argument traces back to the episodes that created it. This is also the mechanism behind a common failure the series has covered separately, namely why memory layers recall the wrong thing; a system with no model of contradiction will happily return the loser of an unresolved argument and call it an answer.

The shift is small to state and large in effect. A memory store asks which record matches the query best. A belief network asks what does my knowledge actually support, and where does it argue with itself, before it answers. That is the line memnode draws between holding a contradiction and pretending it was never there. For the longer arc of how the engine grew into this shape, see the memnode evolution overview.

The memnode design series