What invariant-drift invariants must prevent trust signals from being laundered through agent endorsements?

**Date of Record:** 2026 October 27 **Scope:** Applies when agentic sessions endorse each other (explicitly via signed endorsements, implicitly via citation or referral), and endorsement chains can be exploited to launder trust—an untrusted agent builds up apparent trust by being endorsed by agents whose own trust depends on the untrusted agent, creating circular trust amplification. Does not apply to strictly rooted trust hierarchies (e.g., PKI with a single root) or systems with no endorsement mechanism.

Core Distinction

The separation between **endorsement presence** (the agent received endorsements) and **endorsement groundedness** (the endorsements ultimately derive from independent, trustworthy roots rather than circular endorsement). Relying on presence creates the **Trust Laundering Cycle**: Agent A endorses Agent B, B endorses A, and outside observers see two mutually-endorsing agents, interpreting this as mutual validation, when it is actually a closed loop of self-reinforcing trust that has no independent basis.

What Was Observed

In endorsement-based agent architectures, failing to detect laundering cycles produces three primary failure modes:

  1. **Sybil Trust Amplification:** A group of colluding agents endorse each other intensively, and outside agents interpret the mutual endorsements as evidence of trust, unaware that all endorsers are the same adversary group.
  2. **Circular Endorsement Laundering:** Agent A's trust score is X. It endorses B with X-weighted endorsement. B endorses C with (X+Y)-weighted endorsement. C endorses A with (X+Y+Z)-weighted endorsement. All three have inflated trust scores traced to the same origin.
  3. **Endorsement Churn Exploitation:** An attacker continuously creates new agents, endorses them from existing agents (either colluding or compromised), builds up their trust, uses them for one exploit, then abandons them and repeats the cycle.

Recorded Elements

  1. **`endorsement_root_attestation_receipt`:** For each endorsement, the cryptographic proof of the trust roots it ultimately derives from, distinguishing endorsements rooted in independent trust from those in cycles.
  2. **`endorsement_graph_cycle_signature`:** A cryptographic detection of cycles in the endorsement graph (A→B→A), flagging endorsements that close a loop rather than extend trust from a foundation.
  3. **`endorsement_decay_by_generation_receipt`:** The exact decay applied to endorsements based on graph depth from roots, so that endorsements far from roots carry less weight.
  4. **`endorsement_endorser_diversity_signature`:** The diversity of endorsers (distinct roots, distinct topologies), distinguishing well-corroborated endorsements from coordinated ones.

Condition of Validity

* **Applies when:** Agents endorse each other, endorsement chains can be circular, and outside agents act based on endorsement-derived trust. * **Does not apply when:** Trust is strictly rooted (e.g., single-rooted PKI), or outside agents independently verify every endorsement target without relying on endorsements.

Decision Boundary

  1. **Is the endorsement rooted in an independent trust authority?** If yes, the endorsement is grounded. If no, proceed to cycle detection.
  2. **Does the `endorsement_graph_cycle_signature` show the endorsement closes a cycle?** If yes, the endorsement is circular and must be discounted to zero.
  3. **Does the `endorsement_decay_by_generation_receipt` show the endorsement is far from roots?** If yes, its weight is already decayed, but the receiver must verify the remaining weight is meaningful.
  4. **Conversely, when can an endorsement carry full trust without root verification?** Only when the endorser itself has verifiable trust from a rooted authority (not just from its own endorsements), making the chain grounded at every hop.

Operational Effect

  1. **Laundering Cycle Detection:** Cycles in the endorsement graph are flagged, preventing mutual endorsement from inflating trust.
  2. **Sybil Resistance:** Endorsement decay and diversity metrics make mass-endorsement attacks less effective.
  3. **Grounded Trust:** Endorsements are weighted by their rootedness, ensuring apparent trust corresponds to actual trust.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class EndorsementVerdict(Enum):
    ROOTED_ENDORSEMENT = auto()
    CYCLE_DETECTED = auto()
    DECAYED_ENDORSEMENT = auto()
    INSUFFICIENT_DIVERSITY = auto()

@dataclass(frozen=True)
class Endorsement:
    endorser_id: str
    endorsee_id: str
    root_attestation: str | None
    closes_cycle: bool
    generation_from_root: int
    endorser_diversity_score: float

@dataclass(frozen=True)
class EndorsementPolicy:
    max_generation_from_root: int
    min_diversity_score: float

@dataclass(frozen=True)
class EndorsementManifest:
    verdict: EndorsementVerdict
    effective_weight: float
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_endorsement(
        cls, endorsement: Endorsement, policy: EndorsementPolicy
    ) -> EndorsementManifest:
        
        # Gate 1: Cycle
        if endorsement.closes_cycle:
            return EndorsementManifest(
                verdict=EndorsementVerdict.CYCLE_DETECTED,
                effective_weight=0.0,
                directive=f"HALT: Endorsement {endorsement.endorser_id} -> {endorsement.endorsee_id} closes cycle. Zero weight.",
                manifest_digest=cls._hash(f"CYCLE:{endorsement.endorser_id}:{endorsement.endorsee_id}")
            )

        # Gate 2: Root attestation
        if endorsement.root_attestation:
            digest = cls._hash(json.dumps({
                "endorser": endorsement.endorser_id,
                "endorsee": endorsement.endorsee_id,
                "root": endorsement.root_attestation,
                "generation": str(endorsement.generation_from_root)
            }, sort_keys=True))
            return EndorsementManifest(
                verdict=EndorsementVerdict.ROOTED_ENDORSEMENT,
                effective_weight=1.0,
                directive=f"PROCEED: Rooted endorsement, full weight.",
                manifest_digest=digest
            )

        # Gate 3: Generation decay
        if endorsement.generation_from_root > policy.max_generation_from_root:
            return EndorsementManifest(
                verdict=EndorsementVerdict.DECAYED_ENDORSEMENT,
                effective_weight=0.0,
                directive=f"HALT: Endorsement generation {endorsement.generation_from_root} > {policy.max_generation_from_root}.",
                manifest_digest=cls._hash(f"DECAYED:{endorsement.endorser_id}")
            )

        # Gate 4: Diversity
        if endorsement.endorser_diversity_score < policy.min_diversity_score:
            return EndorsementManifest(
                verdict=EndorsementVerdict.INSUFFICIENT_DIVERSITY,
                effective_weight=0.3,
                directive=f"WARN: Endorser diversity {endorsement.endorser_diversity_score:.2f} < {policy.min_diversity_score:.2f}. Reduced weight.",
                manifest_digest=cls._hash(f"LOW_DIVERSITY:{endorsement.endorser_id}")
            )

        # Gate 5: Decayed but acceptable
        decay = 1.0 / (1.0 + endorsement.generation_from_root * 0.5)
        digest = cls._hash(json.dumps({
            "endorser": endorsement.endorser_id,
            "endorsee": endorsement.endorsee_id,
            "generation": str(endorsement.generation_from_root),
            "diversity": f"{endorsement.endorser_diversity_score:.3f}",
            "weight": f"{decay:.3f}"
        }, sort_keys=True))
        
        return EndorsementManifest(
            verdict=EndorsementVerdict.DECAYED_ENDORSEMENT,
            effective_weight=decay,
            directive=f"PROCEED: Endorsement weight {decay:.2f} after {endorsement.generation_from_root} generations.",
            manifest_digest=digest
        )