Conflicts
Conflicts are expected
In multi-agent systems, contradictions are not bugs. Two agents with different data, different perspectives, or different priors will produce conflicting findings. The question is not how to prevent this — it is how to detect it explicitly and give the agent the information it needs to decide what to do.
Akashik treats conflicts as first-class protocol events. In v0.2, reckon() surfaces them automatically.
How conflicts are detected in v0.2
Two committed entries conflict when all three conditions hold:
- They share the same
entry.topic(strict equality). - They share at least one other key in
entry. - The value at that key differs, and both values are primitive (
string,number,boolean, ornull).
Object-valued keys are not compared in v0.2. Each conflicting pair appears once in the conflicts array.
await field.write({
entry: { topic: 'market-size', cagr: '23%' },
intent: 'market size from three analyst reports covering 2023-2024',
agent: 'researcher',
})
await field.write({
entry: { topic: 'market-size', cagr: '14%' },
intent: 'revised projection after reviewing Q4 earnings directly',
agent: 'fact-checker',
})
const result = await field.reckon({ agent: 'writer', topic: 'market-size' })
console.log(result.conflicts)
// [{
// keys: ['cagr'],
// a: { entry: { topic: 'market-size', cagr: '23%' }, agent: 'researcher', ... },
// b: { entry: { topic: 'market-size', cagr: '14%' }, agent: 'fact-checker', ... }
// }]
The Conflict type
type Conflict = {
a: FieldEntry // one conflicting entry
b: FieldEntry // the other conflicting entry
keys: string[] // keys where values disagree, sorted alphabetically
}
a and b are not ordered by write time or precedence. The conflict is symmetric — the protocol surfaces the disagreement and leaves resolution to the caller.
Resolving conflicts in v0.2
MERGE (formal conflict resolution with configurable strategies) is a Level 2 operation, not in v0.2. Your code decides what to do:
Supersede the outdated entry — any agent can replace a committed entry with a newer one:
await field.supersede({
superseding_id: 'fact-checker-entry-id',
entry: { topic: 'market-size', cagr: '19%' },
intent: 'reconciled estimate: average of both sources weighted by evidence count',
agent: 'orchestrator',
})
Retract a wrong entry — the author can withdraw their own:
await field.retract({
id: 'researcher-entry-id',
intent: 'CAGR figure was from pre-2023 dataset — incorrect for current period',
agent: 'researcher',
})
Write a synthesis — publish a new entry that acknowledges and reconciles both:
await field.write({
entry: {
topic: 'market-size',
cagr: '19%',
note: 'consensus after reconciling two sources',
},
intent: 'synthesised estimate after reviewing both data sources and weighting by recency',
agent: 'orchestrator',
})
After any resolution, reckon() will no longer surface the original pair as a conflict (the superseded/retracted entries are excluded from scoring).
What's coming
In v0.3+, the MERGE operation will provide configurable resolution strategies: last-write-wins, confidence-weighted, authority-based, synthesis, and human escalation. These will be registered as Level 2 conformance requirements.
Next
- reckon() reference — full signature and conflict type definition
- retract() / supersede() — how to manage and update entries