Skip to main content

The stance

Most memory systems resolve contradictions silently: last write wins, or an LLM picks a winner. memloom’s position is that a contradiction between your memories is information, and deciding it is your call. When an incoming memory can’t be true at the same time as an existing one, memloom keeps both active and records a conflict for you to resolve. Nothing is auto-overwritten; nothing is lost while the conflict is pending.

How a conflict is detected

On every save (with dedup enabled), memloom:
  1. Short-circuits exact duplicates by content hash (no LLM involved).
  2. Finds up to 5 existing active memories with cosine similarity ≥ 0.5 to the incoming one.
  3. Asks the LLM to classify each candidate’s relation to the incoming memory:
The conflict record stores the incoming memory, every contradicting candidate, and the classifier’s stated reason, so when you look at it later you see why it was flagged.

Resolving

Pending conflicts show up in memloom conflicts, the viewer’s Conflicts tab, the GET /memory/conflicts endpoint, and the list_conflicts MCP tool (so an agent can say “you have a pending conflict about the staging database”). Four resolutions:

Auto-resolving with an LLM judge

memloom conflicts auto (POST /memory/conflicts/resolve-auto/stream) runs the same LLM over the pending queue a second time, now with context the dedup classifier never had. The classifier only ever compares two pieces of text in isolation; the auto-resolver also sees when each side was recorded and, for memories that came from import sessions, the transcript excerpt it was distilled from. Most import conflicts are a later session recording a state change (“we moved to railway”) against an older fact (“the deploy target is fly.io”), and with time and context in view that resolution is mechanical. The judge answers one of the same four actions, minus merge (there’s no reconciled text for an LLM to author on your behalf): It is told to prefer unsure over guessing: when recording times are close or the excerpts don’t show which side is current, the conflict stays in the queue untouched. Only a decisive verdict calls resolveConflict, so an auto-resolution lands in the same revertable history as a manual one, and revert undoes it exactly the same way.
This is the same one-shot judge that resolves some conflicts during import sessions itself (see Session distillation). conflicts auto is how you run it again over whatever is left, on demand, for conflicts from any source, not just import.

Everything is reversible

No resolution deletes anything. Losers go status = 'stale'; the relationships are recorded as edges (replaces, distinct) that can be deactivated. revert on a resolved conflict:
  • reactivates whatever was staled,
  • deactivates the edges the resolution created,
  • undoes any lineage re-parenting,
  • and puts the conflict back in the pending queue.
You can resolve a conflict, change your mind a week later, revert it, and resolve it the other way.
Conflict detection requires the LLM, so it’s off in offline mode (no OPENROUTER_API_KEY). Offline saves skip the belief pipeline entirely and always report added.