Memory Merge
When two agent instances resolve to the same canonical entity, their memories merge automatically. Knowledge from the web agent and the Slack bot unify into a single memory store. The next time either instance resolves itself, it gets the complete picture.
This is the same behavior as customer entity merges. When "John Doe" in CRM merges with "Jonathan Doe" in billing, the merged entity gets both records' data. When "support-agent" on web merges with "support-bot" on Slack, the merged agent gets both instances' memories.
Before resolution
Two agent instances operate independently. Each has its own memory entries linked to its own agent entity:
Web agent (entity: agt_001) Slack bot (entity: agt_002)
Memory: Memory:
- "Customer prefers email contact" - "Resolved 847 tickets this week"
- "Escalation SLA is 4 hours" - "Common issue: billing page 404"
- "VIP list updated March 10" - "Team uses #support-escalation channel"The web agent does not know about the 404 issue. The Slack bot does not know about the VIP list. Each instance is working with a partial view.
After resolution
The resolution engine matches the two instances (via shared root authority, similar names, overlapping capabilities). They merge into a single canonical agent entity:
Unified agent (entity: agt_001)
Memory:
- "Customer prefers email contact" (from: web agent)
- "Escalation SLA is 4 hours" (from: web agent)
- "VIP list updated March 10" (from: web agent)
- "Resolved 847 tickets this week" (from: Slack bot)
- "Common issue: billing page 404" (from: Slack bot)
- "Team uses #support-escalation channel" (from: Slack bot)Five memory entries become accessible to every instance. No data migration. No explicit sync. The merge happened in the identity graph, and memory follows the entity.
How it works
Memory entries are linked to canonical entities via linked_entities. When two entities merge:
- The losing entity (
agt_002) is absorbed into the winning entity (agt_001) - All identity links from
agt_002are re-pointed toagt_001 - Memory entries linked to
agt_002are now retrievable viaagt_001 - The merge is logged as an
entity.mergedevent in the audit trail
Step 3 is the key. Memory entries are not copied or moved - they are linked to entities. When the entity mapping changes, the memory follows.
Retrieving merged memory
After the merge, any instance can retrieve the full memory by resolving itself:
POST /v1/resolve/realtime
Content-Type: application/json
X-API-Key: kn_live_...
{
"source_name": "slack",
"external_id": "support-bot-slack",
"data": {
"agent_name": "support-bot",
"agent_did": "did:agent:f7a8b9c0..."
},
"include_memory": true
}Response:
{
"entity_id": "agt_001",
"canonical_data": {
"agent_name": "support-agent",
"capabilities": ["resolve", "memorize", "search"],
"platforms": ["web", "slack"]
},
"is_new": false,
"confidence": 0.90,
"memory": [
{
"id": "mem_101",
"entry_type": "pattern",
"title": "Customer prefers email contact",
"author": "support-agent",
"platform": "web",
"created_at": "2026-03-10T08:00:00Z"
},
{
"id": "mem_102",
"entry_type": "knowledge",
"title": "Escalation SLA is 4 hours",
"author": "support-agent",
"platform": "web",
"created_at": "2026-03-10T09:00:00Z"
},
{
"id": "mem_201",
"entry_type": "pattern",
"title": "Resolved 847 tickets this week",
"author": "support-bot",
"platform": "slack",
"created_at": "2026-03-12T14:00:00Z"
},
{
"id": "mem_202",
"entry_type": "investigation",
"title": "Common issue: billing page 404",
"author": "support-bot",
"platform": "slack",
"created_at": "2026-03-13T10:30:00Z"
},
{
"id": "mem_203",
"entry_type": "knowledge",
"title": "Team uses #support-escalation channel",
"author": "support-bot",
"platform": "slack",
"created_at": "2026-03-13T11:00:00Z"
},
{
"id": "mem_103",
"entry_type": "knowledge",
"title": "VIP list updated March 10",
"author": "support-agent",
"platform": "web",
"created_at": "2026-03-14T08:00:00Z"
}
]
}The Slack bot now sees the web agent's VIP list. The web agent now sees the Slack bot's billing page issue. Six memory entries, ordered by creation time, with full provenance showing which platform and which instance created each one.
Using MCP tools
Agents on MCP can retrieve merged memory with a single tool call:
{
"tool": "resolve_with_memory",
"arguments": {
"source_name": "self",
"external_id": "current",
"data": {
"agent_did": "did:agent:f7a8b9c0..."
}
}
}Or recall memory directly by entity ID:
{
"tool": "recall",
"arguments": {
"entity_id": "agt_001"
}
}Both return the full merged memory set.
Searching across merged memory
Full-text search spans all memories from all merged instances:
{
"tool": "search_memory",
"arguments": {
"query": "billing 404",
"entry_type": "investigation"
}
}This finds the Slack bot's memory entry even when called by the web agent - because after resolution, they share the same entity and therefore the same memory index.
What merges, what does not
| Data | Merges? | Details |
|---|---|---|
| Memory entries | Yes | All entries from both instances are accessible via the merged entity |
| Delegations | No | Delegations are bound to specific DIDs, not canonical entities |
| API keys | No | Each instance keeps its own API key |
| Instance status | No | Each instance has its own online/idle/offline status |
| Reputation metrics | Yes | Resolution accuracy, decision quality, and volume consolidate |
| Intent declarations | Yes | Active intents from both instances are visible |
| Task assignments | Yes | Tasks assigned to either instance appear in the merged view |
Delegations do not merge because they are cryptographically bound to a specific DID. If instance A has a delegation granting [resolve, merge] and instance B has a delegation granting [resolve, search], each instance retains its own delegation chain after the entity merge. The permissions are not combined.
Conflict resolution
When merged memories contradict each other, the memory system does not automatically resolve the conflict. Both entries persist:
Web agent: "Customer prefers email contact"
Slack bot: "Customer prefers Slack DMs"Both entries are returned in recall results. The consuming agent (or a human reviewer) decides which is authoritative. You can mark the outdated entry as superseded:
{
"tool": "memorize",
"arguments": {
"entity_id": "agt_001",
"entry_type": "decision",
"slug": "contact-preference-resolved",
"title": "Customer prefers Slack DMs (confirmed)",
"content": "Updated after cross-platform merge. Email preference was from March 10, Slack preference from March 13. Customer confirmed Slack preference."
}
}Then update the old entry's status:
PUT /v1/memory/mem_101
Content-Type: application/json
{
"status": "superseded"
}Cascade through the entity graph
Memory merge does not stop at agent entities. If the merged agent has memories linked to customer entities, those memories are now attributable to the unified agent identity. The customer entity's memory view shows entries from "support-agent" (the canonical name) regardless of which platform instance created them.
This means the four-agent pipeline described in Agent Memory works even when the agents are deployed across platforms. Agent 1 on web qualifies a lead. Agent 2 on Slack enriches the same contact. After agent resolution, both agents' memories are linked to the same agent entity, and the customer entity's memory reflects contributions from the unified agent.
