Skip to main content
Pages

Conflicts And Corrections

Standalone memory service for AI tools, with durable memory, evidence, team isolation, and MCP access.

Conflicts And Corrections

Dense-Mem preserves raw evidence and resolves stale authored state with audited Relationship lifecycle transitions. It asks for a client decision when the caller-owned identity, predicate, scope, time, or current-state behavior cannot be resolved safely. A profile cannot mutate another profile's Relationship, but the bounded system Conflict reviewer may close a losing team Relationship episode after an evidence-backed case resolution. Evidence bytes, observations, support links, and author attribution remain immutable.

This page is the single source of truth for conflict and correction interaction. Relationship lifecycle is in Relationship Model And Lifecycle, identity merge/split is in Entity Identity And Resolution, and orchestration is in Memory Write Pipeline.

Same-Owner Conflict Flow

%%{init: {"sequence": {"rightAngles": true}}}%%
sequenceDiagram
  actor User
  participant Host as AI client
  participant DM as Dense-Mem
  participant PG as PostgreSQL

  User->>Host: Production now deploys from release
  Host->>DM: remember(new evidence)
  DM->>PG: Preserve evidence, observation, verifier event, and conflict
  DM-->>Host: relationship_needs_review
  Host->>DM: trace_memory(related relationship_id)
  DM->>PG: Load current state and append-only history
  PG-->>DM: Existing/new evidence, decisions, and transitions
  DM-->>Host: Trace and explicit decision choices
  Host->>User: Ask the exact conflict question
  User-->>Host: Decision plus evidence
  Host->>DM: resolve_memory_placement(...)
  DM->>PG: Append decision and recompute affected current state

An unresolved same-owner conflicting observation is not an active edge. The owner's prior eligible Relationship stays current unless accepted evidence and deterministic predicate behavior permit supersession. A schema-valid, entailed cross-owner correction can become the caller's active edge and append a cross-reference to the other profile's record.

Why Review Is Required

CauseExampleSafe result
Entity ambiguitycontext now suggests a different person named Markidentity_needs_review; no guessed split or dependent edge
Unknown predicate“Dense-Mem dogfoods PostgreSQL” maps to no registered predicatepredicate_needs_review; preserve wording; create no Relationship
Scope ambiguity“uses PostgreSQL” may mean production or testspreserve observation and request scope
Current-state conflictproduction has competing deploys_from valuespreserve both histories and ask
Temporal ambiguitynew evidence may describe past rather than current staterequest validity context
Insufficient change evidenceweak evidence should not replace a supported current Relationshipretain candidate/pending_evidence without an active edge
Correction ambiguity“that is wrong” identifies no Relationshiprequest relationship_id or a disambiguating query
Cross-profile disagreementprofile B supplies stronger evidence against profile A's Relationshippreserve A, create B's eligible Relationship, append a challenge/correction cross-reference, and create/update the team Conflict case

Cross-Profile Corrections

Profiles A, B, and C may all read same-team knowledge. Each authors only the Relationships and observations created under its profile. Ordinary profile writes can change only caller-owned lifecycle state.

Assume profile A has two Relationships based on an identity that later appears to combine two people:

A: ent_mark -> works_on -> Dense-Mem
A: ent_mark -> works_on -> Billing

Profile B obtains distinguishing evidence. B creates its own Entity resolutions and Relationships through normal remember processing:

B: ent_mark_dense   -> works_on -> Dense-Mem
B: ent_mark_billing -> works_on -> Billing

In the same transaction, Dense-Mem appends corrects or challenges cross-references from B's new Relationships to A's related Relationships and opens or updates the durable team Conflict case. A's status, tier, supports, validity, and Entity resolutions do not change during B's placement.

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
  A1["A: Mark works_on Dense-Mem"] --> Set["Team conflict set"]
  A2["A: Mark works_on Billing"] --> Set
  B1["B: Mark-Dense works_on Dense-Mem"] --> Set
  B2["B: Mark-Billing works_on Billing"] --> Set
  B1 -->|"corrects"| A1
  B2 -->|"corrects"| A2
  Set --> Case["Team Conflict case"]
  Case --> C["Profile C recall"]
  C --> Ask["Show material alternatives<br/>and ask for evidence"]
  Ask --> CWrite["C remembers confirmation<br/>under profile C"]
  CWrite --> Nightly["Nightly reviewer resolves,<br/>overdues, or keeps open"]

Profile C sees both material positions while the case is open. C may submit new evidence through normal remember; any confirmation C remembers belongs to C and may confirm B or challenge A. It does not directly edit either record.

If A later accepts the correction directly, A submits or adopts exact evidence through the normal verifier. A may then supersede A's old Relationships and create A's corrected Relationships. Separately, the system Conflict reviewer may supersede A's stale episode after the team case resolves. Adoption preserves B's evidence author, provenance, and source-group identity; it does not count the same evidence twice.

The canonical ownership and cross-reference fields are defined in Relationship Model And Lifecycle. Conflict grouping and preference ranking are defined in Vector Search And Ranking.

Stale team knowledge example

Assume A recorded an accurate business rule six months ago. The business changed the rule five months ago, but Dense-Mem learned about the change only when B later submitted exact evidence:

t0  A owns Relationship A1: production deploys_from main
t1  the business changes production to release
t2  B owns Relationship B1: production deploys_from release
    B1 corrects A1, with valid_from=t1 supported by B's evidence

At t2, B's placement creates B1, the corrects cross-reference, and an open team Conflict case. A1, A's evidence, support, tier, status, and validity remain unchanged during placement. The AI verifier does not decide that a conflict exists; server policy detects the incompatible single-current state after B's submitted evidence verifies.

While the case is open, C receives both material positions plus an explicit conflict question. C may submit new exact evidence through normal remember; any resulting Relationship belongs to C and is grouped with the matching or new position. A bare vote, profile count, or unsupported "B is right" assertion changes no disposition.

The nightly Conflict reviewer owns automatic resolution. If B's side becomes the unique winner under the deterministic policy, one PostgreSQL transaction marks the case resolved, sets A1 status=superseded, writes A1 valid_to to the resolved cutoff, appends Relationship and Conflict ledger events with actor=system_conflict_reviewer, and queues rebuildable search refresh. A's original evidence fragment and support remain traceable. Current recall at or after the cutoff returns B-side evidence in primary results[], includes a compact resolved conflict reference, and keeps A1 available through trace. Recall with valid_at before the cutoff may still return A's position. Recall with known_at before B's correction arrived reconstructs the older system view.

Durable Team Conflict Cases

An authored conflict set is still derived from Relationships, accepted cross-references, registered single-current behavior, identity history, scope, and time. When that set contains a material cross-profile Relationship disagreement, Dense-Mem also persists one team-scoped conflict case so review, deadlines, retries, and decisions survive process restarts.

ConflictCase
  conflict_id
  team_id
  kind
  status: open | overdue | resolved | dismissed
  version
  opened_at
  review_due_at
  next_review_at
  claim_token
  lease_expires_at
  review_attempts
  last_evaluated_at
  resolved_at
  effective_at
  effective_time_basis: evidence_time | recorded_fallback
  preferred_position_id
  policy_version

ConflictPosition
  position_id
  member Relationship IDs and versions
  owner profile IDs
  accepted evidence and source-group handles

ConflictEvent
  event_id
  prior and resulting case state
  actor profile when client-triggered or system worker when reviewer-triggered
  reason code, policy version, time basis, and referenced versions
  created_at

The case row is current materialized workflow state. Case events are append-only. Position membership never merges authored Relationships or counts copied evidence more than once. dismissed means fewer than two material positions remain after an owner retraction, source revision, or other normal lifecycle change; it is not a truth decision.

Authored knowledgeTeam conflict disposition
A1 and B1 retain immutable author attributionthe case belongs to the team, not A or B
each Relationship keeps its own evidence/support ledgerresolution may close losing stale episodes through audited system transitions
neither author receives the other's evidence as supportequivalent evidence retains its original source-group identity
ordinary profiles cannot rewrite cross-profile validityeffective_at is the cutoff used for current-read disposition and losing-episode closure
trace returns every authorized position and eventprimary current recall omits resolved non-preferred support paths

A conflict case is created or changed only from committed, schema-valid state. Vector similarity alone cannot open one. The initial durable-case scope is a cross-profile Relationship disagreement established by a verified challenges/corrects reference or by incompatible, comparable current_cardinality=one positions. Identity ambiguity and same-owner placement review continue to use their existing review workflows.

Deterministic resolution policy

The counting unit is a current accepted independent source group. Profile count, Relationship row count, copied fragments, summaries, adoptions, and repeated source revisions are not votes.

Before review_due_at, one position qualifies only when it has at least four independent source groups and more than 75% of counted support for the material case. At or after review_due_at, one position qualifies when either:

  1. it is the unique position with an allowed authoritative source group; or
  2. it has at least two independent source groups and more than 50% of counted support.

In all cases, every counted support must be accepted, entailed, currently effective, and applicable to the conflict scope. A source group that currently supports incompatible positions counts toward neither side until its support is cleaned up.

Authoritative opposition normally blocks automatic replacement. A timed strong override is allowed only when the proposed winner has at least four independent source groups, more than 75% of counted support, and verifier-confirmed evidence that the replacement became effective after the losing authoritative position. recorded_fallback time cannot override authoritative opposition.

The cutoff is the evidence-supported effective time when the verifier confirms the extracted temporal bound. If no reliable bound exists and no authority override is needed, the reviewer may use the first contradictory placement time as recorded_fallback. Missing or conflicting time keeps the case open when the chosen threshold requires evidence time.

Resolution appends case events, appends Relationship transitions for losing episodes, updates their current status/valid_to, and queues rebuildable search refresh. It never edits raw evidence, observations, verification events, support links, or author attribution. One fragment may support unrelated current Relationships, so primary-result filtering operates on the relevant Relationship support path rather than globally hiding the fragment.

Responding from another profile

Any active same-team profile with write scope may respond with new evidence. The relevant Relationship proposal carries the recall-supplied conflict_id and expected case version. Dense-Mem validates the version and that the verified proposal materially belongs to the case before committing evidence or case state. A stale version fails without changing state so the host can recall the current alternatives and retry. The exact MCP field shape belongs in Technical Reference.

The same transaction that places the caller-owned Relationship and validated cross-reference opens or updates the case, membership, deadline/version, and search refresh intent. It does not resolve the case. There is no separate cross-profile resolve command; automatic resolution belongs to nightly review.

Nightly Conflict Review

The nightly job is the deterministic Conflict maintainer. It reviews known open or overdue cases, repairs membership, resolves qualifying cases, and closes stale Relationship episodes. It does not scan all old Relationships by age and it does not call a model.

For each case whose next_review_at is due, whether before or after review_due_at, the job:

  1. claims bounded team-local work with a durable lease
  2. reloads current Relationship versions, effective supports, source groups, cross-references, scope, and temporal bounds from PostgreSQL
  3. repairs stale position membership and recomputes the policy view
  4. resolves only when exactly one position meets the automatic floor for the current pre-TTL or post-TTL phase
  5. marks the case overdue, appends an escalation event, and schedules the next nightly check when no unique position qualifies
  6. dismisses a case only when committed lifecycle/source changes leave no material disagreement
  7. when resolving, locks and updates the losing Relationship rows, appends transition events, marks the case resolved, appends the Conflict event, and queues rebuildable search/read-model refresh work in one transaction

The review deadline comes from the versioned team policy. Reaching it is not evidence and does not force a winner; it only enables the lower automatic threshold. Duplicate evidence from the same source group does not extend the deadline. New independent support updates membership and may resolve on a later nightly run, but it does not move the original deadline. A later contradictory business change opens a new conflict episode instead of reopening a resolved case. Database/worker failure leaves the case due and unresolved. Multi-instance workers use durable daily run reservation plus team-local FOR UPDATE SKIP LOCKED claims, bounded retries, and lease recovery.

The job may update conflict workflow rows, losing Relationship status and valid_to, append Relationship transition events, and enqueue rebuildable search state. It may not edit or delete evidence, observations, verification events, RelationshipCrossReferences, support links, Relationship ownership, author attribution, Entity resolution, or source history. Operators inspect an overdue case or submit new evidence; they do not repair it with direct SQL. Defaults and bounded overrides belong in Configuration.

Inspect Before Deciding

Use the relationship_id from recall discovery paths or from a placement relationship_outcomes[] entry:

json
{
  "relationship_id": "r_deploy_branch",
  "include_evidence_content": true,
  "include_verification": true,
  "include_transitions": true,
  "max_depth": 1,
  "max_edges": 12
}

The client presents:

  • current subject, predicate, object, polarity, scope, and validity
  • tier, status, current-cardinality behavior, and source count
  • accepted evidence and material verification events
  • the new conflicting observation and its evidence verdict
  • exact identity, predicate, scope, or temporal ambiguity
  • the before/after impact of each allowed decision

An opaque “accept or reject?” prompt is insufficient.

Identity Review

The client may select only a server-supplied same-team candidate:

json
{
  "ingest_id": "ing_01J...",
  "placement_item_id": "item_identity_1",
  "action": "select_entity",
  "decision": {
    "mention_ref": "mark",
    "entity_id": "ent_mark_huang"
  },
  "evidence": [
    {
      "content": "I mean Mark Huang, the Dense-Mem maintainer.",
      "source_type": "manual",
      "authority": "authoritative",
      "source_group": "user-resolution:ing_01J..."
    }
  ],
  "idempotency_key": "identity-resolution-1"
}

confirm_new_entity requires evidence that distinguishes a new identity. The client never allocates the new ID.

A late same-name conflict may require a split. Dense-Mem first shows only the caller's observations and Relationships that may move. After confirmation, it creates the new Entity and reassigns only selected caller-owned immutable observation IDs. It never moves another profile's rows or every row based on display text.

Predicate Review

An unknown phrase remains on the observation with no predicate_key. Review may:

  • select an existing server-supplied registered predicate when meaning matches
  • reject the observation mapping
  • route a proposed registry change through a separately authorized, versioned vocabulary workflow

The verifier and ordinary review endpoint cannot add a predicate definition. A Hypothesis is not an unknown predicate; it is an isolated dream output using an already registered predicate. See Dreaming.

Relationship Review Actions

ActionMeaning
acceptappend authoritative client evidence for the pending observation, then rerun normal policy
rejectappend the rejection and preserve observation/history
correctappend replacement evidence and reprocess affected knowledge
forgetretract the caller-owned selected Relationship from active reads while retaining its ledger
acknowledgemark review consumption; change no semantic state

accept does not bypass verification or directly assign fact. Fact promotion uses the authority and independent-source rules in Relationship Model And Lifecycle.

These client actions mutate only a Relationship owned by the authenticated profile. To address another profile's Relationship, the caller submits new evidence through remember; deterministic post-verification identity and conflict policy derive the appropriate cross-reference and case update. The system Conflict reviewer is the only non-owner lifecycle writer for a cross-profile stale-state case. There is no cross-profile client accept, forget, supersede, merge, or split shortcut.

Correct With New Evidence

A correction appends evidence; it is not an in-place text edit.

json
{
  "ingest_id": "ing_01J...",
  "placement_item_id": "item_relationship_1",
  "action": "correct",
  "evidence": [
    {
      "content": "The user confirmed that production now deploys from release.",
      "source_type": "manual",
      "authority": "authoritative",
      "source_group": "user-resolution:ing_01J..."
    }
  ],
  "proposal": {
    "entities": [
      {
        "ref": "production",
        "name": "production",
        "entity_kind": "environment",
        "identity_context": {
          "system": "Dense-Mem"
        }
      },
      {
        "ref": "release",
        "name": "release",
        "entity_kind": "git_branch",
        "identity_context": {
          "repository": "Dense-Mem"
        }
      }
    ],
    "relationships": [
      {
        "proposal_id": "production_deploys_from_release",
        "subject_ref": "production",
        "predicate": "deploys_from",
        "object_ref": "release",
        "polarity": "+",
        "modality": "statement",
        "evidence": [
          {
            "evidence_index": 0,
            "start": 0,
            "end": 60
          }
        ]
      }
    ]
  },
  "idempotency_key": "deployment-correction-1"
}

The replacement enters the same extraction, one-call verifier, deterministic lifecycle, and PostgreSQL transaction as every remember. Prior evidence and transitions remain traceable.

This action corrects the caller's Relationship; it does not declare a shared source globally obsolete. A source owner that can prove stable lineage instead uses source_key, source_revision, and previous_source_revision, optionally with its own supersedes_fragment_ids. Source activation occurs at intake, makes the prior revision ineffective for every profile that adopted it, and recomputes affected tiers from remaining effective support. The caller cannot mix a profile-local correction with unowned source-fragment retirement.

Same-Owner Before And After

Before decisionAfter an accepted correction
supported prior Relationship stays currentprior record is superseded or retracted only when registry behavior and evidence permit
new conflict is held and has no active edgeeligible replacement is exposed as one SemanticEdge
prior evidence and decisions are append-onlyboth old and new provenance remain traceable
vector search may still represent the prior versionsource/full-text/adjacency reads change at commit; version-matched embedding job updates vector search

For a cross-profile correction, the target record does not enter the right-hand column during placement. The caller creates a separately owned Relationship and cross-reference; the team Conflict case preserves both positions until the nightly reviewer resolves or escalates the case.

Forget And Retraction

forget removes a caller-owned Relationship from current graph-shaped reads without deleting its semantic nodes or historical ledger. Same-team visibility does not authorize forgetting another profile's record.

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
  Before["Relationship status=active<br/>SemanticEdge visible"] --> Decision["Authorized forget decision"]
  Decision --> Append["Append retraction event<br/>and audit"]
  Append --> Current["Set current status=retracted"]
  Current --> After["SemanticEdge no longer returned"]
  After --> Nodes["Entity / Value nodes remain"]
  After --> Trace["Evidence, verification,<br/>support and transitions remain"]

Because SemanticEdge is a PostgreSQL read rule, the edge disappears from normal reads in the same transaction that records the retraction. There is no second graph copy to delete.

This is logical forgetting. A privacy-erasure request is a separate authorized workflow that may redact payload content while retaining minimal tombstones, audit proof, and referential integrity required by policy. Clients must not emulate either operation with direct SQL deletion.

Deterministic Current-State Decisions

Predicate registry fields relationship_kind and current_cardinality guide whether accepted knowledge coexists or may supersede a prior current value owned by the same profile. They are not model decisions and never authorize cross-profile ordinary writes. Cross-profile stale-state closure is limited to the nightly Conflict reviewer and the deterministic case policy above.

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart TD
  Accepted["Accepted new Relationship"] --> Kind{"state or event?"}
  Kind -- event --> Coexist["Keep both occurrences"]
  Kind -- state --> Cardinality{"current cardinality"}
  Cardinality -- many --> Coexist
  Cardinality -- one --> Scope{"Same subject, predicate,<br/>scope and comparable time?"}
  Scope -- No --> Coexist
  Scope -- Yes --> Evidence{"Evidence safely establishes<br/>replacement?"}
  Evidence -- No --> Review["Hold conflict for review"]
  Evidence -- Yes --> Supersede["Append supersession;<br/>change current state atomically"]

Canonical behavior belongs in Relationship Model And Lifecycle; this page owns how the client sees and resolves uncertainty.

Risks And Mitigations

RiskConcrete failure modeMitigation
Wrong review targeta decision for one conflict applies to anotherrequire ingest/item/Relationship IDs, idempotency key, and echo an impact summary
Accept bypasses policya client click writes an active fact directlyappend evidence and route through strict verification and deterministic lifecycle
Correction erases historyold evidence is edited to match new truthimmutable fragments plus append-only observations, decisions, support, and transitions
Homonym split corrupts historyfinance-team Mark causes all Mark edges to moveclient-confirmed impact preview and caller-owned observation-ID-level reassignment
Unknown predicate expands vocabularyverifier invents dogfoods as a durable keyregistry allowlist and separate authorized vocabulary workflow
Wrong supersessiona many-valued predicate is treated as single-currentexplicit current_cardinality, scope/time comparison, and before/after preview
Forget becomes data lossdeleting an edge also removes source and audit historytransactional retraction status; nodes and append-only ledger remain
Stale vector confuses reviewvector search surfaces meaning from before correctionsource-version checks, exact trace by ID, and explicit search freshness
Cross-profile correction becomes immediate mutationB's placement marks A's Relationship superseded before reviewplacement can write only B's Relationship, cross-reference, and open/update case; non-owner supersession is allowed only in the nightly reviewer transaction
Majority becomes truthseveral profiles copy one weak source and outvote stronger evidencepreserve source groups, deduplicate common origins, and rank evidence rather than author count alone
Correction impersonates source revisiona profile-local correct request invalidates evidence adopted by other ownersreserve team-wide invalidation for the immutable source owner and exact prior-revision contract
Deadline becomes truthan unresolved case automatically chooses B after seven daysTTL only switches thresholds; require one unique temporally applicable position above the applicable evidence floor, otherwise mark overdue and escalate
Reviewer closes the wrong episodeB's branch change supersedes an unrelated A Relationship sharing textlock case membership by Relationship ID/version, revalidate scope/predicate/cardinality/time, and update case plus losing Relationships in one transaction
Historical recall uses today's winnera query for six months ago returns only Bevaluate both valid_at and known_at against conflict events and effective time
Fragment-wide suppression hides valid factsA's fragment supports another still-current Relationshipfilter only query-relevant support paths and retain the immutable fragment/search document
Stale C response attaches to the wrong case versionC confirms an alternative after the case was reopened or regroupedrequire conflict_id plus expected version and reject stale context before commit

Acceptance Invariants

  1. conflict preserves old and new evidence
  2. unresolved identity or predicate creates no active dependent edge
  3. every decision records actor, provenance, time, target IDs, and idempotency
  4. correction never mutates verbatim evidence
  5. accept, reject, correct, split, and forget write through normal PostgreSQL policy—not a graph side channel
  6. a late split moves only explicitly selected caller-owned observations
  7. prior current state changes only in the same transaction as its transition
  8. forget removes the SemanticEdge but retains Entity/Value nodes and all ledger history
  9. trace reconstructs conflict, decision, and supersession/retraction lineage
  10. a profile cannot accept, forget, supersede, merge, split, or change support for another profile's knowledge
  11. cross-profile corrections remain independently authored and link both Relationships without hiding either from authorized trace
  12. adopting cross-profile evidence preserves its original provenance and does not create a second independent source group
  13. normal correction changes only caller-owned Relationship state, while an owned source revision may invalidate its evidence team-wide through system recomputation
  14. a material cross-profile disagreement has one durable team case with append-only events and versioned position membership
  15. a resolved case removes only non-preferred current support paths from primary recall and keeps every authored Relationship available to trace
  16. valid_at before the change and known_at before the correction reconstruct the corresponding historical view
  17. another writer's response creates that writer's evidence-backed Relationship and cannot act as a bare vote
  18. placement creates or updates Conflict cases but does not resolve them
  19. nightly review is the only automatic Conflict resolver and model-free
  20. deadline expiry without one qualifying position produces overdue, not an invented winner
  21. the nightly job may close losing Relationship episodes with audited status=superseded and valid_to updates, but cannot mutate raw evidence, support links, ownership, author attribution, Entity resolution, or source history