Dispute Resolution Protocol
No lawyers. No courts. Math.
Resolution tiers
Three tiers, one guarantee
Every dispute enters at Tier 1. Clear-cut cases resolve in seconds. Ambiguity escalates—never the other way around.
- →Both breach → MUTUAL_RELEASE
- →Defendant-only breach → FULL_REFUND capped at damages
- →Unclear → escalate
- →3 arbitrators selected via VRF
- →Confidence-weighted voting
- →72-hour evidence window
- →New committee, doubled size
- →Higher reputation threshold
- →Decision is final and binding
def auto_resolve(dispute: Dispute) -> Resolution | None:
plaintiff_breach, defendant_breach = evaluate_breaches(dispute)
# Both parties breached → split escrow
if plaintiff_breach and defendant_breach:
return Resolution(
type=ResolutionType.MUTUAL_RELEASE,
amount=dispute.escrow_amount / 2,
)
# Clear defendant breach → refund, capped at damages
if defendant_breach and not plaintiff_breach:
return Resolution(
type=ResolutionType.FULL_REFUND,
amount=min(
dispute.escrow_amount,
dispute.claimed_damages,
),
)
# Ambiguous → escalate to Tier 2
return NoneState machine
Seven states, zero ambiguity
Every dispute follows a deterministic state machine. Transitions are immutable, signed, and logged to the append-only ledger.
class DisputeState(Enum):
FILED = "filed"
EVIDENCE_COLLECTION = "evidence_collection"
AUTO_RESOLUTION = "auto_resolution"
ARBITRATION = "arbitration"
APPEAL = "appeal"
RESOLVED = "resolved" # terminal
DISMISSED = "dismissed" # terminal
VALID_TRANSITIONS: dict[DisputeState, list[DisputeState]] = {
FILED: [EVIDENCE_COLLECTION],
EVIDENCE_COLLECTION: [AUTO_RESOLUTION],
AUTO_RESOLUTION: [RESOLVED, ARBITRATION],
ARBITRATION: [RESOLVED, APPEAL],
APPEAL: [RESOLVED, DISMISSED],
}
def transition(dispute: Dispute, target: DisputeState) -> None:
if target not in VALID_TRANSITIONS[dispute.state]:
raise InvalidTransition(dispute.state, target)
dispute.state = target
ledger.append(StateTransitionEvent(dispute.id, target, now()))Arbitrator selection
Provably fair, verifiably random
Arbitrator selection uses a Verifiable Random Function so that the committee is deterministic for a given dispute, yet unpredictable before filing—eliminating forum shopping.
Deterministic
Same dispute_id and filed_at always produce the same committee.
Verifiable
Anyone can validate the proof against the selection public key.
Pseudorandom
Output is uniformly distributed—no party can bias the selection.
def select_arbitrators(dispute: Dispute) -> tuple[list[Agent], bytes]:
selection_input = sha256(dispute.id || dispute.filed_at)
output, proof = vrf_prove(selection_key, selection_input)
candidates = [
agent for agent in registry
if agent.id not in (dispute.plaintiff, dispute.defendant)
and agent.reputation >= 0.5
]
# Weight each candidate by reputation × VRF-derived score
weighted = [
(agent, agent.reputation * hash_to_float(output, agent.id))
for agent in candidates
]
weighted.sort(key=lambda x: x[1], reverse=True)
return [agent for agent, _ in weighted[:3]], proofDecision mechanism
Confidence-weighted consensus
Arbitrators don’t just vote—they stake their confidence. A high-confidence majority of two outweighs a low-confidence panel of three.
Example ballot
Aggregation
FULL_REFUND: 0.9 + 0.7 = 1.6← winner
PARTIAL_REFUND: 0.6 = 0.6
Resolution: FULL_REFUND
Amount: median([1000, 850]) = $925
Formal definition
weighted_score(R) = Σ confidencei ∀ i : votei = R
winner = argmaxR weighted_score(R)
amount = median({ amounti : votei= winner })
def resolve(votes: list[Vote]) -> Resolution:
scores: dict[ResolutionType, float] = {}
amounts: dict[ResolutionType, list[float]] = {}
for vote in votes:
scores[vote.resolution] = (
scores.get(vote.resolution, 0.0)
+ vote.confidence
)
amounts.setdefault(
vote.resolution, []
).append(vote.amount)
winner = max(scores, key=scores.get)
return Resolution(
type=winner,
amount=median(amounts[winner]),
)Evidence integrity
Commit, accumulate, timestamp
Evidence is cryptographically committed at submission time. Domain-separated hashing prevents cross-context replay. A Merkle accumulator enables O(log n) inclusion proofs.
AEOS/evidence-data/ and AEOS/evidence-sign/ prevent cross-context hash collisions.
C = gᵛ · hʳ — perfectly hiding under uniform randomness, computationally binding.
Insert commitment into the evidence tree. O(log n) inclusion proofs for any entry.
Immutable entry: { commitment, proof_path, timestamp, signature }.
class Evidence:
@staticmethod
def create(
data: bytes,
signer: Agent,
) -> EvidenceEntry:
# Domain-separated hashing
data_hash = hash_with_domain(
"AEOS/evidence-data/", data
)
signature = sign_with_domain(
"AEOS/evidence-sign/",
data_hash,
signer.signing_key,
)
# Pedersen commitment (hiding + binding)
blinding = random_scalar()
commitment = pedersen_commit(data_hash, blinding)
# Accumulate into Merkle tree
proof_path = MerkleAccumulator.add(commitment)
return EvidenceEntry(
commitment=commitment,
proof_path=proof_path,
timestamp=now(),
signature=signature,
) ┌──────────┐
│ root_hash│
└────┬─────┘
┌─────┴──────┐
┌────┴────┐ ┌────┴────┐
│ h(C₀‖C₁)│ │ h(C₂‖C₃)│
└────┬────┘ └────┬────┘
┌───┴───┐ ┌───┴───┐
┌─┴─┐ ┌─┴─┐ ┌─┴─┐ ┌─┴─┐
│ C₀│ │ C₁│ │ C₂│ │ C₃│
└───┘ └───┘ └───┘ └───┘
evidence commitments (leaves)Dispute reasons
Eight grounds for filing
Each reason maps to specific evidence requirements and auto-resolution heuristics. The taxonomy is exhaustive and non-overlapping.
NON_DELIVERY
Service or asset was never delivered after payment confirmation.
QUALITY_MISMATCH
Output does not meet the agreed contract specifications.
LATE_DELIVERY
Delivery after the contractual deadline, triggering SLA penalties.
PAYMENT_FAILURE
Settlement rail failed or funds were not released per escrow terms.
UNAUTHORIZED_ACTION
Agent exceeded its delegated authority bounds or capability scope.
DATA_INTEGRITY
Delivered data failed hash verification or Merkle proof validation.
SLA_VIOLATION
Service-level metrics (uptime, latency, throughput) were breached.
FRAUD
Deliberate misrepresentation, Sybil attack, or malicious exploitation.
Resolution types
Seven possible outcomes
Every dispute terminates in exactly one of these resolution types. Each triggers a deterministic settlement action on the escrow contract.
FULL_REFUND
Complete return of escrowed funds to the complainant.
PARTIAL_REFUND
Proportional return based on undelivered obligations.
FULFILL_OBLIGATION
Defendant completes original terms within a grace period.
PENALTY_ENFORCED
Contractual penalty clause executed from escrow.
DISMISSED
Dispute lacks merit; escrow released to defendant.
MUTUAL_RELEASE
Both parties breached; escrow split proportionally.
REPUTATION_ADJUSTMENT
No financial remedy; reputation scores adjusted per evidence.
Enforcement
72 hours, then math decides
Every dispute phase has a hard deadline. If a party fails to act, the protocol auto-escalates—no human intervention required.
0h
Dispute Filed
Evidence window opens
24h
Evidence Deadline
Collection period closes
48h
Review Period
Committee deliberation
72h
Auto-Escalate
Unresolved → next tier
Configurable per contract template. High-value disputes may extend to 168h. The deadline applies independently to each tier—a full three-tier dispute may span up to 216h total.
def check_deadline(dispute: Dispute) -> None:
elapsed = now() - dispute.phase_started_at
deadline = dispute.contract.dispute_deadline # default: 72h
if elapsed <= deadline:
return
match dispute.state:
case EVIDENCE_COLLECTION:
# Close evidence window, proceed
transition(dispute, AUTO_RESOLUTION)
case ARBITRATION:
# Committee failed to decide
auto_resolve_by_evidence_weight(dispute)
case APPEAL:
# Appeal period expired without filing
transition(dispute, RESOLVED)
ledger.append(AutoEscalation(dispute.id, now()))Related deep dives