How must an instance resolve ground truth conflicts between trusted authorities?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session relies on multiple trusted authorities (certificate authorities, identity providers, oracles, or canonical registries), and two or more authorities assert conflicting ground truth about the same fact, requiring the session to resolve the conflict or operate correctly despite it. Does not apply to single-authority setups or authorities with verified consistency.

Core Distinction

The separation between **authority trust** (each authority is individually trusted) and **authority agreement** (the authorities agree on the fact in question). Relying on trust creates the **Authority Conflict Paralysis**: both authorities are trusted, both are asserting contradictory facts, and the session can either arbitrarily pick one (losing information) or freeze (losing progress), neither of which uses the conflict itself as information.

What Was Observed

In multi-authority agent architectures, failing to resolve conflicts produces three primary failure modes:

  1. **Arbitrary Picking:** The session picks whichever authority responds first or is most convenient, and downstream behavior reflects the arbitrary choice. Other parties who picked differently diverge, and reconciliation is impossible because neither party was wrong.
  2. **Double Bookkeeping:** The session tracks both versions of the fact, but at decision time must pick one, and the picking is ad hoc rather than principled—causing the same fact to resolve differently in different decisions.
  3. **Escalation Overload:** Every conflict escalates to a human or external authority, and the volume of conflicts overwhelms the escalation path, causing operational stalls.

Recorded Elements

  1. **`authority-assertion-receipt`:** For each authority, the exact fact asserted, with cryptographic proof of the assertion, so conflicts are precisely characterized.
  2. **`authority-jurisdiction-signature`:** For each authority, its claimed scope of jurisdiction (which facts it claims to be authoritative about), so conflicts can be resolved by scope rather than by arbitrary selection.
  3. **`conflict-classification-receipt`:** The exact class of conflict (JURISDICTION_OVERLAP, STALE_ASSERTION, GENUINE_DISAGREEMENT, or ADVERSARIAL_ASSERTION), based on whether the authorities' scopes overlap, whether one is stale, or whether the disagreement is fundamental.
  4. **`resolution-precedence-signature`:** For each conflict class, the resolution rule (most-recent-wins, jurisdiction-wins, staleness-wins, or escalate), applied consistently.

Condition of Validity

* **Applies when:** Multiple trusted authorities exist, conflicts can occur, and downstream decisions depend on the fact's resolution. * **Does not apply when:** Single authority is used, authorities are verified consistent, or facts are strictly non-conflicting.

Decision Boundary

  1. **Do multiple trusted authorities exist for the same fact?** If no, single-authority applies. If yes, proceed.
  2. **Do they agree?** If yes, the fact is resolved. If no, conflict exists.
  3. **Is `authority-jurisdiction-signature` non-overlapping (each authority's scope is distinct)?** If yes, use the jurisdictionally appropriate authority. If no, proceed to conflict classification.
  4. **Conversely, when can the session resolve a conflict without proceeding to classification?** Only when one authority has explicitly superseded the other (via revocation, deprecation, or update), or when the fact is verified to be outside both authorities' claimed scope.

Operational Effect

  1. **Arbitrary Picking Prevention:** Authority selection is principled based on jurisdiction, staleness, or explicit precedence.
  2. **Double Bookkeeping Integrity:** Conflicts are tracked with clear resolution rules.
  3. **Escalation Discipline:** Only GENUINE_DISAGREEMENT or ADVERSARIAL_ASSERTION conflicts escalate.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class ConflictVerdict(Enum):
    SINGLE_AUTHORITY = auto()
    AUTHORITIES_AGREE = auto()
    JURISDICTION_RESOLVED = auto()
    STALENESS_RESOLVED = auto()
    UNRESOLVABLE_CONFLICT = auto()

@dataclass(frozen=True)
class AuthorityAssertion:
    authority_id: str
    fact_hash: str
    assertion_epoch: float
    jurisdiction_scope: frozenset[str]
    is_current: bool

@dataclass(frozen=True)
class FactConflict:
    fact_id: str
    assertions: tuple[AuthorityAssertion, ...]
    conflict_class: str  # "JURISDICTION_OVERLAP" | "STALE_ASSERTION" | "GENUINE_DISAGREEMENT" | "ADVERSARIAL_ASSERTION"

@dataclass(frozen=True)
class ConflictPolicy:
    require_escalation_for_genuine: bool

@dataclass(frozen=True)
class ConflictManifest:
    verdict: ConflictVerdict
    resolved_fact_hash: str | None
    directive: str
    manifest_digest: str

class GroundTruthConflictGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_conflict(
        cls, conflict: FactConflict, policy: ConflictPolicy
    ) -> ConflictManifest:
        
        # Gate 1: Single authority
        if len(conflict.assertions) <= 1:
            digest = cls._hash(json.dumps({
                "fact": conflict.fact_id,
                "authorities": str(len(conflict.assertions))
            }, sort_keys=True))
            return ConflictManifest(
                verdict=ConflictVerdict.SINGLE_AUTHORITY,
                resolved_fact_hash=conflict.assertions[0].fact_hash if conflict.assertions else None,
                directive=f"PROCEED: Single authority for {conflict.fact_id}.",
                manifest_digest=digest
            )

        # Gate 2: Agreement
        fact_hashes = {a.fact_hash for a in conflict.assertions}
        if len(fact_hashes) == 1:
            digest = cls._hash(json.dumps({
                "fact": conflict.fact_id,
                "fact_hash": next(iter(fact_hashes))
            }, sort_keys=True))
            return ConflictManifest(
                verdict=ConflictVerdict.AUTHORITIES_AGREE,
                resolved_fact_hash=next(iter(fact_hashes)),
                directive=f"PROCEED: Authorities agree on {conflict.fact_id}.",
                manifest_digest=digest
            )

        # Gate 3: Staleness
        if conflict.conflict_class == "STALE_ASSERTION":
            current = [a for a in conflict.assertions if a.is_current]
            if len(current) == 1:
                return ConflictManifest(
                    verdict=ConflictVerdict.STALENESS_RESOLVED,
                    resolved_fact_hash=current[0].fact_hash,
                    directive=f"PROCEED: Resolved by staleness, use current assertion from {current[0].authority_id}.",
                    manifest_digest=cls._hash(f"STALE:{conflict.fact_id}")
                )

        # Gate 4: Jurisdiction
        if conflict.conflict_class == "JURISDICTION_OVERLAP":
            # If jurisdictions are actually non-overlapping, pick the appropriate one
            scopes = [a.jurisdiction_scope for a in conflict.assertions]
            all_distinct = all(not (scopes[i] & scopes[j]) for i in range(len(scopes)) for j in range(i+1, len(scopes)))
            if all_distinct:
                return ConflictManifest(
                    verdict=ConflictVerdict.JURISDICTION_RESOLVED,
                    resolved_fact_hash=None,
                    directive=f"PROCEED: Use jurisdictionally appropriate authority for {conflict.fact_id}.",
                    manifest_digest=cls._hash(f"JURISDICTION:{conflict.fact_id}")
                )

        # Gate 5: Unresolvable
        if policy.require_escalation_for_genuine:
            return ConflictManifest(
                verdict=ConflictVerdict.UNRESOLVABLE_CONFLICT,
                resolved_fact_hash=None,
                directive=f"ESCALATE: Conflict class {conflict.conflict_class} for {conflict.fact_id} requires human resolution.",
                manifest_digest=cls._hash(f"UNRESOLVABLE:{conflict.fact_id}")
            )

        return ConflictManifest(
            verdict=ConflictVerdict.UNRESOLVABLE_CONFLICT,
            resolved_fact_hash=None,
            directive=f"FLAG: Conflict {conflict.fact_id} cannot be resolved.",
            manifest_digest=cls._hash(f"UNRESOLVED:{conflict.fact_id}")
        )