Back to all posts
EngineeringMay 12, 20269 min read

How Memanto Detects and Resolves Contradictory Memories

AI agents accumulate knowledge over time. That knowledge will eventually contradict itself. Memanto detects when new information conflicts with existing knowledge, surfaces the conflict, and provides structured tools to resolve it explicitly.

Hetkumar PatelSoftware Developer
How Memanto Detects and Resolves Contradictory Memories
CONFLICT RESOLUTION

AI agents accumulate knowledge over time. That knowledge will eventually contradict itself. A user says "we use Postgres" on Monday and "we migrated to MongoDB" on Thursday. Both statements were true when they were made, but only one is true now. If an agent silently overwrites the old memory, the history is lost. If it keeps both without flagging the conflict, it will eventually serve stale information with full confidence. Memanto treats this as a first-class problem.

Why Silent Overwrites Break Agent Memory

Most memory systems handle contradictions in one of two ways: last-write-wins (the new value replaces the old one) or append-only (both values coexist). Neither is sufficient for production agents.

Last-write-wins destroys provenance. If an agent overwrites "we use Postgres" with "we migrated to MongoDB," there is no record that Postgres was ever the answer. If the migration fails and the team rolls back, the agent has no history to fall back on.

Append-only creates a different failure mode. Both memories sit in the store with equal confidence. When the agent queries "what database do we use?", it retrieves both answers and has no signal to determine which one is current. This is what Memanto's documentation calls "constraint drift": unresolved contradictions accumulate over time and erode the coherence of the agent's world model.

Memanto's approach is different. Both memories are preserved. The system flags the conflict. A human or automated workflow resolves it explicitly. The old memory's provenance is retained, and the resolution is recorded.

How Conflict Detection Works

Conflict detection in Memanto is triggered by the daily summary pipeline. When you run memanto daily-summary, two things happen: a natural-language summary is generated from all session memories recorded that day, and a conflict report is generated by comparing new session memories against the agent's historical knowledge stored in Moorcheh.

The conflict detection step sends a structured prompt to an LLM with two key inputs: the day's session memories (the new information) and the agent's full knowledge base (the historical context, retrieved via Moorcheh's semantic search). The LLM analyzes both and returns a JSON array of detected issues.

  • memanto daily-summary generates the summary and conflict report in one step
  • The conflict report is saved at ~/.memanto/conflicts/{agent_id}_{date}_conflicts.json
  • If conflicts are found, the CLI prints a warning: ! N conflict(s) detected

What the System Looks For

The detection prompt identifies four categories of issues:

CategoryWhat It Means
ContradictionNew information directly contradicts an existing fact. Example: old memory says "we use Postgres," new memory says "we migrated to MongoDB."
UpdateNew information is an improvement or revision of existing knowledge. Example: a market size estimate revised upward.
DuplicateNew memory is redundant with an existing one, no new information added.
ConflictA semantic disagreement between new and historical memories that does not fit neatly into the other categories.

Filtering Rules

The detection system applies specific filtering to avoid false positives. It only reports issues that involve at least one new memory from the day's sessions, it does not surface conflicts between two old historical memories. It filters out self-referencing conflicts where the old and new memory IDs are identical. Each detected conflict is enriched with timestamps and source metadata by fetching the original documents from Moorcheh, so the user can see when each memory was created and where it came from.

The Conflict Report Structure

Each entry in the conflict report contains the conflict type, a human-readable title, both memory IDs, both memory contents, a description of the issue, and the AI's recommended resolution. The recommendation field is the LLM's suggested resolution, one of keep_new, keep_old, merge, or remove_both. This is a suggestion, not an automatic action. The final decision is always made by the user.

FieldDescription
typeCategory: contradiction, update, duplicate, or conflict
titleHuman-readable summary of the issue
old_memory_id / new_memory_idIDs of both memories involved
old_content / new_contentFull content of both memories
descriptionExplanation of why the conflict was flagged
recommendationAI-suggested resolution action
old_created_at / new_created_atTimestamps showing when each memory was stored
old_source / new_sourceWhich tool or user created each memory
resolvedBoolean flag, false until explicitly resolved

Resolving Conflicts: The CLI

The memanto conflicts command loads the conflict report and walks through each unresolved entry one at a time. For each conflict, the CLI displays the conflict type and title, both memories side by side with their IDs, creation timestamps, and content, plus the AI recommendation.

  • memanto conflicts --list lists all unresolved conflicts without resolving
  • memanto conflicts walks through each conflict interactively
  • memanto conflicts --date 2026-05-08 resolves conflicts for a specific date

You then choose from five resolution actions:

ActionWhat Happens
Keep A (old)The old memory is retained. The new memory is deleted from the agent's namespace in Moorcheh.
Keep B (new)The new memory is retained. The old memory is deleted.
Keep bothBoth memories remain active. No deletions.
Remove bothBoth memories are deleted from the agent's namespace.
ManualBoth memories are deleted and replaced with a new memory you type in. The new memory is stored with provenance set to corrected and tagged with conflict-resolution.

After each resolution, the conflict is marked as resolved in the JSON report. Once all conflicts are resolved, Memanto automatically re-exports the agent's memory cache to keep the local MEMORY.md file in sync.

Resolving Conflicts: The REST API

For automated workflows or custom UIs, the same operations are available through the REST API. This makes it possible to build programmatic resolution pipelines or integrate conflict resolution into existing developer tooling.

List Unresolved Conflicts

  • Endpoint: GET /api/v2/agents/{agent_id}/conflicts?date=YYYY-MM-DD
  • Header: X-Session-Token: your_session_token
  • Response: JSON with agent_id, date, conflicts array, and count

Resolve a Conflict

  • Endpoint: POST /api/v2/agents/{agent_id}/conflicts/resolve
  • Body: { "date": "YYYY-MM-DD", "conflict_index": 0, "action": "keep_new" }
  • Actions: keep_old, keep_new, keep_both, remove_both, manual
  • Manual action requires manual_content and optionally manual_type in the body

End-to-End Example

Here is a practical walkthrough of contradiction detection and resolution using the CLI.

Step 1: Store an initial fact

  • memanto remember "The project uses PostgreSQL 16 for all persistent data" --type fact --confidence 0.9 --source claude_code --provenance explicit_statement

Step 2: A week later, store a contradictory fact

  • memanto remember "We migrated the primary database to MongoDB Atlas last week" --type fact --confidence 0.95 --source user --provenance explicit_statement

Step 3: Run the daily summary

Running memanto daily-summary triggers the conflict detection pipeline. The system compares the day's new memories against the full historical knowledge base and produces a conflict report. You will see output like: ! 1 conflict(s) detected. Run 'memanto conflicts' to resolve interactively.

Step 4: Resolve the conflict

Running memanto conflicts displays both memories side by side with their timestamps, sources, and the AI recommendation. You choose your preferred resolution action. For example, selecting "Keep B (new)" deletes the old PostgreSQL memory and keeps the MongoDB one.

Step 5: Verify

Running memanto recall "what database do we use" now returns only the MongoDB memory. The agent's knowledge is clean and unambiguous.

Scheduling Automated Conflict Detection

For teams running agents in production, manual daily summary generation is not practical. Memanto includes a scheduling system that automates the entire pipeline. When the schedule is enabled, the daily summary and conflict report are generated automatically. Detected conflicts still require resolution through either the CLI or the API.

  • memanto schedule enable enables daily automated summaries and conflict detection
  • memanto schedule status checks the current schedule configuration
  • memanto schedule disable turns off the schedule when needed

Best Practices

  • Do resolve conflicts explicitly. The documentation is clear: "Resolve conflicts explicitly when contradictions arise rather than deleting history." The conflict report preserves both sides and the resolution action, creating an audit trail.
  • Do use the `manual` action when neither memory is fully correct. If the old memory says "5.1 billion" and the new says "8.3 billion (revised upward)," the correct resolution might be a single memory that captures both the current figure and the revision history.
  • Do run conflict detection regularly. Unresolved contradictions accumulate. Each one individually might not cause a visible problem, but collectively they erode the reliability of the agent's recall.
  • Don't store the same fact repeatedly. Search with memanto recall before storing. Duplicate memories create unnecessary conflict detection noise.
  • Don't ignore the conflict report. Unresolved conflicts mean the agent may serve either version unpredictably depending on which scores higher in semantic search at query time.

Further Reading

▘ ▝End of article
CONTINUE READING