What invariants prevent multi-hop trust degradation from being lost in delegation chains?

**Date of Record:** 2026 October 27 **Scope:** Applies when trust is delegated through multi-hop chains (A trusts B, B delegates to C, C delegates to D), and the effective trust at the end of the chain must reflect cumulative degradation across hops—but the chain's representation may show each hop's trust without showing the cumulative effect. Does not apply to single-hop delegation or chains with cryptographically preserved trust guarantees.

Core Distinction

The separation between **per-hop trust** (each hop's trust relationship with the previous) and **cumulative trust** (the effective trust at the end of the chain). Relying on per-hop creates the **Trust Degradation Loss**: each hop appears to preserve trust (B trusts C with some level), but the cumulative trust at D is A→B→C→D attenuated by every hop's uncertainty, and the representation doesn't surface the cumulative effect.

What Was Observed

In multi-hop delegation agent architectures, failing to preserve degradation produces three primary failure modes:

  1. **Trust Inflation:** Each hop reports its delegation as high-trust, and the terminal consumer receives D as if A directly trusted D at the same level. The cumulative attenuation is invisible.
  2. **Compounding Uncertainty:** Each hop introduces uncertainty (B is 90% sure of C's trustworthiness, C is 90% sure of D's). Compounded, A's confidence in D is 0.81, not 0.9—but the chain representation doesn't show this.
  3. **Terminal Over-Reliance:** The terminal delegatee (D) receives authority that, from A's perspective, should be much more restricted. D acts within its received authority, and the outcome exceeds what A would have authorized.

Recorded Elements

  1. **`cumulative-trust-signature-receipt`:** For each delegation chain, the cumulative trust from origin to terminal, computed across all hops, so the effective trust is explicit.
  2. **`per-hop-trust-receipt`:** For each hop, the trust relationship (confidence level, delegation scope), so per-hop trust is documented.
  3. **`degradation-function-signature`:** The function by which each hop degrades trust (multiplicative, subtractive, or threshold), so compounding is computable.
  4. **`terminal-trust-cap-signature`:** For chains exceeding a certain degradation threshold, the terminal trust cap (maximum authority the terminal delegatee can exercise), so over-reliance is prevented.

Condition of Validity

* **Applies when:** Trust is delegated through multi-hop chains, per-hop trust can vary, and terminal trust matters. * **Does not apply when:** Delegation is single-hop, trust is cryptographically preserved end-to-end, or terminal trust is not used.

Decision Boundary

  1. **Is the delegation multi-hop?** If no, single-hop applies. If yes, proceed.
  2. **Are per-hop trust receipts available?** If yes, cumulative computation is possible. If no, only origin trust is known.
  3. **Is `cumulative-trust-signature-receipt` computed?** If yes, terminal trust is explicit. If no, terminal trust is assumed equal to origin trust.
  4. **Conversely, when can a chain skip cumulative trust computation?** Only when each hop preserves trust identically (multiplicative by 1.0), or the terminal trust is not used downstream.

Operational Effect

  1. **Trust Inflation Prevention:** Cumulative trust is surfaced, not assumed.
  2. **Uncertainty Compounding:** Attenuation is computed, not lost.
  3. **Terminal Caps:** Degraded chains have terminal authority caps.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class ChainTrustVerdict(Enum):
    SINGLE_HOP = auto()
    CUMULATIVE_COMPUTED = auto()
    DEGRADATION_EXCESSIVE = auto()
    TRUST_INFLATION_DETECTED = auto()

@dataclass(frozen=True)
class TrustHop:
    hop_id: str
    origin_trust: float
    delegatee_trust: float
    confidence: float

@dataclass(frozen=True)
class TrustChain:
    chain_id: str
    hops: tuple[TrustHop, ...]
    cumulative_trust_computed: bool
    terminal_cap: float | None

@dataclass(frozen=True)
class ChainTrustPolicy:
    max_acceptable_degradation: float
    require_terminal_cap: bool

@dataclass(frozen=True)
class ChainTrustManifest:
    verdict: ChainTrustVerdict
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_chain(
        cls, chain: TrustChain, policy: ChainTrustPolicy
    ) -> ChainTrustManifest:
        
        # Gate 1: Single hop
        if len(chain.hops) <= 1:
            digest = cls._hash(json.dumps({
                "chain": chain.chain_id,
                "hops": str(len(chain.hops))
            }, sort_keys=True))
            return ChainTrustManifest(
                verdict=ChainTrustVerdict.SINGLE_HOP,
                directive=f"PROCEED: Chain {chain.chain_id} single hop.",
                manifest_digest=digest
            )

        # Gate 2: Cumulative not computed
        if not chain.cumulative_trust_computed:
            return ChainTrustManifest(
                verdict=ChainTrustVerdict.TRUST_INFLATION_DETECTED,
                directive=f"HALT: Chain {chain.chain_id} cumulative trust not computed.",
                manifest_digest=cls._hash(f"NOT_COMPUTED:{chain.chain_id}")
            )

        # Gate 3: Compute cumulative
        cumulative = 1.0
        for hop in chain.hops:
            cumulative *= hop.confidence

        # Gate 4: Excessive degradation
        if cumulative < policy.max_acceptable_degradation:
            if not policy.require_terminal_cap or chain.terminal_cap is not None:
                return ChainTrustManifest(
                    verdict=ChainTrustVerdict.DEGRADATION_EXCESSIVE,
                    directive=f"HALT: Chain {chain.chain_id} cumulative trust {cumulative:.3f} < {policy.max_acceptable_degradation:.3f}.",
                    manifest_digest=cls._hash(f"EXCESSIVE:{chain.chain_id}")
                )

        # Gate 5: Computed and within bounds
        digest = cls._hash(json.dumps({
            "chain": chain.chain_id,
            "hops": str(len(chain.hops)),
            "cumulative": f"{cumulative:.3f}",
            "terminal_cap": f"{chain.terminal_cap:.3f}" if chain.terminal_cap else "NONE"
        }, sort_keys=True))
        
        return ChainTrustManifest(
            verdict=ChainTrustVerdict.CUMULATIVE_COMPUTED,
            directive=f"PROCEED: Chain {chain.chain_id} cumulative trust {cumulative:.3f}.",
            manifest_digest=digest
        )