Claims and entities
How Vault models facts, entity keys, and claim lifecycle.
Claims
A claim is one structured fact Vault stores:
| Field | Role |
|---|---|
entity | Subject key, e.g. user.diet, user.timezone |
text | Human-readable fact |
type | semantic (stable truth) or episodic (event/context) |
sourceAgent | Which agent wrote it |
conversationId | Provenance |
status | active, superseded, or disputed |
supersedes | ID of prior claim this replaced (audit) |
Entity keys
Entities group facts about one subject. Agents must agree on the same entity string before Vault compares them. Compatible facts on that subject can both stay active. Only a contradicts label starts recency or authority.
user.diet → diet preferences
user.timezone → IANA / regional timezone
user.schedule.* → wildcard patterns in authority configEntities are not a hardcoded enum. The extraction LLM picks a dotted-path string guided by the prompt (user.diet, user.timezone, etc.). Any non-empty string is accepted.
Entity resolution
After extraction and before classification, resolveEntity() aligns the extracted label with existing active claims when fact text is semantically similar. This fixes LLM drift (user.abc vs user.timezone) so cross-agent conflict can trigger.
| Similarity score | Behavior |
|---|---|
≥ 0.85 (entityMatchThreshold) | Auto-align to incumbent claim's entity |
| 0.70 – 0.85 | Optional LLM disambiguation (entityResolutionUseLlm) |
< 0.70 (entityDisambiguationThreshold) | Keep extracted entity |
Search is global across all active claims (no sourceAgent filter). Disable entirely with entityMatchThreshold: 0 or a custom resolveEntity hook.
On UPDATE, the stored entity is preserved from the target claim — extractor labels cannot rename via merge.
Entity registry (optional)
For production apps that need a canonical taxonomy, enable the entities table with useEntityRegistry: true:
import { Memory, seedEntities, EXAMPLE_ENTITY_SEED } from "vault-memory";
await seedEntities(db, EXAMPLE_ENTITY_SEED);
const memory = new Memory("my-agent", {
db,
apiKey: process.env.OPENAI_API_KEY,
useEntityRegistry: true,
entityRegistryAutoRegister: true, // default — register valid new: keys on first use
});When enabled:
- The extraction prompt includes known keys from the registry
- The LLM must pick an existing key or use
new:user.<domain>for new subjects ensureEntityInRegistry()validates keys againstentityKeyPattern(default:user.<dotted.path>)
See Configuration for all entity-related options.
Claim status
| Status | Searchable | Meaning |
|---|---|---|
active | Yes | Current canonical memory |
superseded | No | Replaced; kept for audit |
disputed | No | Challenger parked when authority ties |
If two agents extract different entities for the same fact (user.timezone vs user.location), no cross-agent conflict runs. Tune extraction and entity resolution to keep keys aligned.