Skip to content

Tensions & contradictions

A tension is a pair of engrams asserting incompatible things: one says “deploys go through Caddy,” the other says “deploys go through nginx.” Memory that contradicts itself is worse than no memory — the agent picks one at random and sounds confident either way. PLUR treats contradictions as first-class records with a lifecycle, not silent data corruption.

plur tensions --scan (CLI) or plur_tensions with scan: true (MCP) runs the contradiction scan:

  1. Pre-filter. Candidate pairs are built cheaply through three stages: scope partition (no scope overlap → skip), domain filter (domain hierarchies don’t touch → skip), and subject overlap (subject noun phrases don’t intersect → skip). Survivors are ranked by shared-token overlap, so the likeliest contradictions are judged first under the pair cap.
  2. LLM judge. Each surviving pair is judged for genuine contradiction (default: confidence ≥ 0.7, max 50 pairs per scan). Scan mode requires an LLM — OPENAI_API_KEY or OPENROUTER_API_KEY, or an explicit endpoint.
  3. Persist. New detections become tension records (T-YYYY-MMDD-NNN). Already-recorded pairs are never re-judged.

The judge is date-aware: both statements’ recorded dates go into the prompt, because “the deploy was green on Monday” and “the deploy was red on Friday” is an event log, not a contradiction. Snapshot-domain pairs and engrams whose validity window has closed are gated out before judging.

When knowledge legitimately changes, say so: plur_learn with supersedes: ["ENG-..."] (CLI: plur learn --supersedes). Supersedes-linked pairs are skipped by tension scans in both directions — an intentional update is a replacement, not a conflict. Reserve tensions for the case where you didn’t know the store disagreed with itself.

Shipped in 0.11.0. Every detection starts as detected and moves through explicit review:

ActionEffect
confirmMarks the tension as a real conflict, pending resolution.
dismissFalse positive — the pair is suppressed from all future scans.
resolve + --winner <engram-id>The winner is kept; the losing engram is retired.
Terminal window
plur tensions # list unresolved records
plur tensions --scan # detect new ones
plur tensions resolve T-2026-0703-001 --winner ENG-2026-0630-004

Unresolved tensions follow the engrams they touch: when injection selects an engram that is party to an unresolved tension, the inject result carries a warning. Contradicted context is flagged, never silently injected — the agent can hedge or ask instead of confidently asserting one side.

  • MCP: plur_tensions (list / scan / confirm / dismiss / resolve), plur_tensions_purge (clear legacy unvalidated conflict edges left by old importers).
  • CLI: plur tensions --scan and lifecycle subcommands, plus plur audit — which checks a runtime’s working memory (e.g. Claude Code auto-memory files) against the engram store and flags conflicts there too.

Next: Activation & decay →