Skip to main content
← Back to Blog
Memory Architecture6 min read

Edge Cases in Agentic Memory: Conflicting Facts and Stale Context

Two true statements about the same entity at different times are not a conflict, they are a version history. Resolution strategies and when each one is wrong.

"Marc works at Stripe" and "Marc works at Anthropic" are not in conflict. They are a version history with the timestamps stripped off. A memory system that resolves this pair by picking a winner has destroyed the only information that made the pair interpretable, and it did so at write time, before anyone knew which query would need it.

Almost every conflict-resolution bug in agentic memory traces back to this one modeling error: storing what is true instead of storing when it was true.

The four strategies and where each breaks

Every system converges on one of four rules. All four are correct sometimes and each has a specific, reproducible failure.

Recency-wins

Newest write replaces the old one. Cheap, deterministic, and the default in most implementations.

It fails on out-of-order arrival, which is common and not exotic. A user pastes an old email thread from 2023 to correct something you learned last month. The write timestamp is now; the fact is two years stale. Recency-wins takes it. The same failure appears in any multi-device setup where an offline client syncs late, and in any pipeline that backfills historical transcripts, which is exactly what happens the first time a user imports their conversation archive.

Confidence-wins

Attach a score to each assertion and keep the higher one.

This fails hard when the confidence is model-estimated, because LLM-reported confidence is poorly calibrated and the miscalibration is not random. Models are systematically more confident on fluent, canonical-sounding text than on hedged, precise text. So "Marc is the CTO" extracted from a marketing bio outscores "Marc stepped back from the CTO role in March and is now an individual contributor" extracted from a Slack message. The second is true and specific, which is exactly why it reads as less confident. Confidence-wins is defensible only when the score comes from something external, like source class or extraction method, and at that point you are doing trust weighting and should say so.

Ask-the-user

Correct, and it does not scale. It also has a subtle cost: interrupting to disambiguate teaches users that the memory layer is unreliable, and it puts a synchronous human round trip inside an agent loop that was supposed to be autonomous. Reserve it for facts with a high blast radius (identity, access, payment) and never trigger it from an offline consolidation job where there is no user to ask.

Keep-both-with-provenance

The only one that never loses information, and the only one that moves the problem rather than solving it. If you keep both, retrieval now has to decide which to surface, and if retrieval has no temporal model it will surface both, and the model will read two contradictory facts and pick one arbitrarily. Keeping both is necessary and insufficient.

Bitemporal storage is the actual fix

The reason all four strategies feel unsatisfying is that they are answering a question with one time axis when the domain has two. This is old, well-trodden ground in database modeling: Fowler's bitemporal history article and the broader temporal database literature both name the two axes explicitly.

Valid time is when the fact was true in the world. Transaction time is when your system learned it. Recency-wins collapses these into one axis, which is precisely why the pasted-old-email case breaks it.

CREATE TABLE facts (
  id              uuid PRIMARY KEY,
  entity_id       uuid NOT NULL,
  predicate       text NOT NULL,          -- 'employer'
  object          text NOT NULL,          -- 'Anthropic'

  valid_from      timestamptz NOT NULL,   -- true in the world from
  valid_to        timestamptz,            -- NULL = still true
  recorded_at     timestamptz NOT NULL DEFAULT now(),
  retracted_at    timestamptz,            -- NULL = we still believe it

  source_id       uuid NOT NULL,
  source_trust    smallint NOT NULL,      -- 0..100, externally assigned
  extraction      text NOT NULL           -- 'user_stated' | 'llm_inferred'
);

CREATE INDEX ON facts (entity_id, predicate, valid_from DESC);

Two queries fall out of this, and the fact that they are different queries is the whole payoff:

-- What is true now, per our current beliefs?
SELECT * FROM facts
WHERE entity_id = $1 AND predicate = 'employer'
  AND retracted_at IS NULL
  AND valid_from <= now()
  AND (valid_to IS NULL OR valid_to > now());

-- What did we believe on 2026-03-01 about January 2025?
SELECT * FROM facts
WHERE entity_id = $1 AND predicate = 'employer'
  AND recorded_at <= '2026-03-01'
  AND (retracted_at IS NULL OR retracted_at > '2026-03-01')
  AND valid_from <= '2025-01-15'
  AND (valid_to IS NULL OR valid_to > '2025-01-15');

The second query is what you need when a user says the assistant told them something wrong last month. Without transaction time you cannot reconstruct what the system believed then, which means you cannot debug a memory system at all. You are guessing.

The write rule becomes mechanical. A new assertion about the same (entity_id, predicate) whose valid interval overlaps an existing row closes that row by setting valid_to. It does not delete it. Supersession is an interval boundary, not a tombstone.

The cases that are still hard

Retraction versus supersession

These look identical in a naive schema and they are semantically opposite. Supersession: "Marc worked at Stripe until March, now Anthropic." The Stripe fact remains true of its interval forever. Retraction: "Marc never worked at Stripe, I confused him with someone else." The Stripe fact was never true of any interval.

This is why the schema needs both valid_to and retracted_at. Closing an interval and marking a belief as mistaken are different operations, and if you only have one column you will eventually answer "where did Marc work in February" with a fact you already know is fabricated. Retracted rows must stay queryable, because the retraction itself is information: an extraction path that produced a retracted fact is an extraction path with a measurable error rate.

Partial conflicts

"Marc is a senior engineer at Anthropic" versus "Marc leads the retrieval team at Anthropic." Same entity, overlapping claims, no contradiction. A conflict detector working on whole strings will flag these, and a resolver will discard one of two compatible facts.

The fix is decomposition. Store (entity, predicate, object) triples rather than sentences, and scope conflict detection to a single predicate. Two facts conflict only if they share entity and predicate, the predicate is single-valued, and their valid intervals overlap. That last qualifier matters: employer is single-valued for most people, speaks_languageis not, and a system that treats every predicate as single-valued will delete four of a user's five languages.

Trust asymmetry across sources

A user's explicit correction and a model's inference from an ambiguous transcript are not peers. Rank sources deterministically, before any timestamp comparison: direct user statement, then verified integration data, then user-provided documents, then model inference from conversation. A lower-trust source never silently overwrites a higher-trust one about the same predicate over an overlapping interval. It gets recorded with its own provenance and it loses at read time, which is recoverable, rather than at write time, which is not.

If your memory layer cannot answer "what did you believe last Tuesday," every conflict bug you hit will be unreproducible.

Unimatrix keeps superseded memories with their interval boundaries intact rather than overwriting, which is what makes cross-device late-arriving writes safe: an iPad syncing yesterday's conversation cannot clobber a fact recorded this morning. The tool-level surface for supersession is documented in the MCP reference.

Your AI remembers everything. Everywhere.

Unimatrix gives you a shared, durable memory layer across Claude Desktop, Cursor, ChatGPT, and Gemini. Setup in 2 minutes. Free and paid plans available.

Keep reading