GET /v1/contradictions.
200 application/json
What it is
Contradiction, a pair of beliefs from one subject’s own content that cannot both be current (in practice, a place where they changed their mind and the older position is still sitting in the graph). Exo does not resolve these. It finds them and hands them to you with both sides intact, because which side is right is a judgement about the subject’s intent, not about the text. An assistant that knows a user once committed to usage-based pricing and later argued for seats can say so. An assistant that silently retrieved whichever chunk scored higher cannot.Where it comes from
Contradictions are mined from the subject’s stored content during the background cognition cycle, not computed per request. Two kinds are detected. A retraction is a statement that walks back an earlier one, found through the language the subject used to walk it back. A reversal is a swap of one concept for another in the same role, for example one datastore replacing another as the chosen option.Fields
How tension is derived
tension is computed when you read, not stored, so the same conflict can come back with different numbers on different routes. That is deliberate: on a retrieval the number also reflects whether the conflict touches the answer you just asked for.
Retractions score above reversals because an explicit walk-back is stronger evidence of a changed mind than a substituted concept.
The two shapes, and which one you are holding
This is the trap on this object. The array on a retrieval is not theContradiction schema above.
id you can store. The retrieval array returns the mining shape in snake_case, with no id and no status, plus node_id so you can drill into the source and in_active_subgraph so you know whether the conflict actually touched this answer. For a reversal it also carries from_concept and to_concept.
Use the retrieval array to warn in the moment. Use the list route when you need something you can reference later.
How to use it
Surface the conflict alongside the answer instead of picking a side.POST /v1/graph/nodes/{node_id}/supersede. That records the newer belief as the successor and transfers authority away from the older one, which is how Exo represents a resolved conflict. See Belief and supersession.
Details worth knowing
Why every contradiction says open
Why every contradiction says open
Because the v1 store has no resolution lifecycle.
status is a fixed open on every row, so it carries no information today. It exists so a later release can report a resolved conflict without a breaking change. Do not build a filter on it, and do not show it as a state the user can toggle.Why the array on a retrieval can be empty
Why the array on a retrieval can be empty
Three ordinary reasons. The subject has no mined contradictions yet, because the background cycle has not run over their content. The query did not activate any node that carries one. Or you sent
includeContradictions: false. An empty array is not an error and does not mean the graph is consistent.How many come back at once
How many come back at once
The retrieval selector caps what it attaches: at most one per node, at most three per subkind, and at most eight in total. It prefers conflicts on nodes that are in the answer, then fills from recent rows. The list route paginates normally instead, so use it when you want the full set.
Whether a contradiction survives forgetting
Whether a contradiction survives forgetting
It drops out. The selector reads live content, so tombstoning a node with
DELETE /v1/graph/nodes/{node_id} removes the conflicts that rest on it from the next read. Restoring the node within the undelete window brings them back, because nothing about the conflict was stored separately.Limits
statusis alwaysopen. There is no route that resolves a contradiction directly; you resolve one by superseding a side.- Contradictions are mined from a subject’s own content. Exo does not compare one subject against another, so it will not tell you that two people on a team disagree.
- The array on
POST /v1/retrieveis typed as an open object in the contract, so a generated client hands you an untyped map. The field list above is what the route emits today. - Detection is language-driven. A belief someone changed without ever writing down the change is not detectable, and will not appear.
Next
Belief and supersession
How to close a conflict by recording what replaced what.
List contradictions
The route that returns the stable form, with pagination.