Skip to main content

Overview

Extraction echoes whatever spelling the text used, so a graph accumulates Postgres and PostgreSQL, Claude Code and claude-code, as separate entities. Recall anchors a query to at most 10 entities, so every duplicate spends a slot naming something another slot already names.

Lexical, not semantic

Rules find the pairs. A model only ever confirms one, and never proposes one.

Asks when unsure

One rule folds without asking. Everything else becomes a question in the Conflicts tab.

Reversible

A merge record stores every edge that moved, so revert restores the original row exactly.

What a fold does

One entity becomes the canonical and the other moves into it:
  • Every mention and relationship repoints to the canonical.
  • The absorbed spelling becomes an alias, keeping the original id and vector.
  • A merge record stores which edges moved and which were deactivated.
Nothing is deleted. The alias is also what extraction looks up on the next mention, so a new memory saying Opus 4.8 lands on the canonical instead of minting the row again.

How pairs are judged

Entities are bucketed by their words and key prefix, so only plausible pairs are compared. Each pair gets one verdict.
The identical-key rule casefolds and drops non-alphanumerics, so ClaudeCode collapses too. Two escapes send it to review instead: keys under 3 characters (C# collides with C), and punctuation-prefixed names (.next is a directory, Next is a framework).People are exempt from the two-word requirement, since a human’s name is written at several lengths: Ada pairs with Ada Lovelace. Both sides must be typed person, and it still only asks, because John against John Smith and John Doe is a real question.

Running it

Idempotent and safe to re-run. The queue caps at 50 pending questions so entity folds cannot bury memory conflicts. deferred is there so “nothing queued” never hides “there was more to ask”.

Reviewing the questions

Uncertain folds land in the Conflicts queue, in the same place and with the same reversibility as a contradiction between two memories.
On an entity, keep_both means “settled, do not ask again”. The resolver also writes it when a question became moot, so the decision log is not purely a record of human judgement.

Reverting

Restores the absorbed entity with its original id, type, vector and creation time, repoints exactly the edges the merge moved, and removes the alias. The original id matters because deactivated edges still point at it.
Deleting an entity that an unreverted fold points at is refused. The alias carries the absorbed entity’s id and vector, so deleting the canonical would make the fold permanent. Revert first, then delete.

Asking who is connected to what

The target can be an id, a name, or a folded-away spelling. Two kinds of connection come back separately and are never blended into one score:
  • Stated relationships are typed edges extraction asserted, with direction and confidence.
  • Co-mention is entities named by the same sources, with a count. Weaker, so it never outranks a stated link.
In the viewer this is the traverse panel on the Graph tab. Agents use related_entities.

What it will not do

A nickname sharing no letters with the name, Bob against Robert, is never proposed. That is not a lexical judgement. You can still declare it yourself with POST /memory/entities/{id}/merge, which records the same reversible merge.