Skip to content

Why We Deleted Our AI Memory Conflict Detector

An embedding can tell you that two memories discuss similar things. It cannot tell you that they cannot both be true.

YantrikDB once blurred that distinction. We shipped a conflict detector that used similarity, shared entities, and changed words as evidence of possible contradiction. It looked plausible in demos. Real data showed that the model was wrong.

We deleted it.

The old similarity-based detector measured 0 of 16 precision. The current model compares structured, single-valued claims and preserves both records for review.

This is the failure report, the replacement, and the boundary we still do not claim to solve.

In April 2026, a Hacker News discussion pushed us to test the detector on a small running store instead of describing what the architecture was supposed to do.

The corpus contained 59 memories: repeated facts, distractors, and six seeded conflicts. Consolidation removed duplicate recall results and improved the top-result rate from 75% to 87.5%. Conflict detection found 0 of 6 seeded conflicts.

The reason was architectural. The detector ran over structured graph edges, while the normal memory write path stored text without creating those edges. The feature existed, but the default path did not feed it.

An early attempt to close that gap overcorrected. Similarity and shared-entity heuristics produced large review queues full of pairs that were related but not contradictory.

That result and the criticism are still public in the original Hacker News thread.

Four months later, we hand-labeled 16 open conflict flags from the production store. The old lexical path measured 0/16 precision on that set.

The failures fell into repeatable classes:

False-positive classWhat the old detector did
Shared person, different datesPaired unrelated project notes because both named the same person
Multi-valued relationsTreated “created project A” and “created project B” as mutually exclusive
Phantom subjectsLet headings and bare numbers anchor claims
Self-conflictsFlagged two values extracted from one progression record against itself

No threshold fixes these categories. A word-set difference is not a contradiction test, even when the two sentences are close in embedding space.

The replacement: conflict as a data constraint

Section titled “The replacement: conflict as a data constraint”

The current detector keys on structured claims:

(subject, relation) -> value

For example:

(Acme, headquartered_in) -> Boston
(Acme, headquartered_in) -> Denver

A pair becomes eligible for review only after passing structural gates.

  1. The relation must be single-valued. Distinct values for created, likes, or other multi-valued relations are just distinct facts.
  2. The subject must be admissible. Extraction debris cannot anchor a conflict. Deliberate relations created through the API remain eligible.
  3. The records must be distinct and active. One record cannot conflict with itself, and superseded history is not a live dispute.
  4. The values must differ after alias resolution. Two names for the same entity do not create a conflict.
  5. Time changes the classification. Overlapping validity windows can be a simultaneous conflict. Ordered windows are a succession candidate.

The scanner records a review item. It does not delete either memory or decide which value is true.

These statements can both be correct:

CT128 runs engine 0.14.1 [valid from day 1]
CT128 runs engine 0.15.0 [valid from day 30]

The current detector carries valid_from and valid_to qualifiers. Ordered open-ended starts are reported as possible succession with a newer-supersedes hint. Closed windows that actually overlap stay high-priority. An explicit supersession link resolves the pair and suppresses future flags.

Creation time is only a fallback hint when world-validity time is absent. The database does not pretend those timestamps mean the same thing.

The rewrite reconstructs the production failures as tests, alongside the positive path:

  • unrelated dated memories sharing an entity do not conflict;
  • multi-valued relations do not conflict pairwise;
  • phantom subjects cannot anchor a conflict;
  • one record cannot conflict with itself;
  • a functional relation with two active values creates one review item;
  • an explicit supersession link suppresses that item.

The six gates pass on YantrikDB 0.18.0. Read the detector and regression set, or run the focused tests:

Terminal window
cargo test -p yantrikdb class_
cargo test -p yantrikdb true_positive_

You can also exercise the actual Rust engine in the browser Memory Lab. It runs through WebAssembly with no server or API call.

This is conservative typed detection, not general natural-language inference.

“Alice is CEO” and “Bob is CEO” may describe a replacement, co-CEOs, two organizations, or an extraction mistake. The database cannot recover missing context from two loose sentences. A correct result depends on claim scope, relation cardinality, validity time, and evidence quality.

YantrikDB can make known constraints inspectable and deterministic. It cannot turn underspecified prose into certainty, and our public claims now say so.

That narrower promise is more useful than a broad detector nobody can trust.