How must an instance handle reference delegation when the origin cannot be directly contacted?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session receives a reference (URI, capability descriptor, or peer identity) whose origin is unreachable or inaccessible, and the reference must be resolved via delegation (intermediaries, cached copies, or alternative resolution paths) instead of direct origin contact. Does not apply to cases where origin is reachable or references are content-addressed (no resolution needed).

Core Distinction

The separation between **delegated resolution** (the reference is resolved via an intermediary) and **original resolution** (the reference is resolved via the origin). Relying on delegated resolution creates the **Delegation Trust Gap**: the intermediary may return a different resource than the origin would have, either maliciously (attacker-controlled intermediary) or accidentally (stale cache, misconfigured mirror). The receiver has no direct way to verify that the delegated resolution matches the origin's intent.

What Was Observed

In networks with unreachable origins, failing to handle delegated resolution produces three primary failure modes:

  1. **Intermediary Substitution:** An intermediary returns a resource that looks like the origin's resource but is controlled by an attacker. The receiver has no way to distinguish this from legitimate delegation.
  2. **Stale Cache Return:** An intermediary returns a cached version of the resource from a time when the origin's content was different. The receiver gets the old content as if it were current.
  3. **Delegation Chain Confusion:** Multiple intermediaries are involved, each may or may not be trustworthy, and the receiver cannot verify which intermediaries actually handled the resolution.

Recorded Elements

  1. **`delegation_chain_receipt`:** The cryptographic chain of intermediaries that handled the resolution, each signed by the intermediary, allowing the receiver to see the full delegation path.
  2. **`intermediary_trust_attestation_receipt`:** For each intermediary, a cryptographic attestation of its trustworthiness (authorized by the origin, verified by a trusted third party), so the receiver can weight trust by intermediary.
  3. **`origin_signature_on_resource_receipt`:** If the resource is signed by the origin, the cryptographic proof that the resource matches what the origin signed, regardless of which intermediary delivered it.
  4. **`delegation_freshness_receipt`:** The exact epoch at which the delegated resolution was performed, so the receiver can detect stale cached versions.

Condition of Validity

* **Applies when:** The reference's origin is unreachable, delegation is required, and downstream decisions depend on resolution accuracy. * **Does not apply when:** The origin is reachable, references are content-addressed (no resolution needed), or delegation is prohibited and only origin resolution is acceptable.

Decision Boundary

  1. **Is the origin reachable?** If yes, resolve directly. If no, proceed to delegation.
  2. **Is the `delegation_chain_receipt` present and complete?** If no, the receiver cannot see the delegation path. Reject or treat as unverified.
  3. **Do all intermediaries have `intermediary_trust_attestation_receipts`?** If no, some intermediaries are untrusted. Weight accordingly or reject.
  4. **Conversely, when can a receiver accept a delegated resource without origin signature?** Only when all intermediaries are verified to be authorized by the origin, and the delegation chain is short (≤2 hops), and the resource is verified by content hash against a known-good value.

Operational Effect

  1. **Intermediary Substitution Detection:** Origin signatures on resources prevent substitution even via untrusted intermediaries.
  2. **Stale Cache Awareness:** Delegation freshness reveals stale cached content.
  3. **Delegation Chain Transparency:** The full delegation path is visible, allowing trust decisions at each hop.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class DelegationVerdict(Enum):
    ORIGIN_DIRECT = auto()
    DELEGATED_VERIFIED = auto()
    DELEGATION_CHAIN_UNTRUSTED = auto()
    STALE_CACHE_DETECTED = auto()

@dataclass(frozen=True)
class DelegationHop:
    intermediary_id: str
    trust_attestation: str | None
    hop_epoch: float

@dataclass(frozen=True)
class DelegatedResolution:
    reference_id: str
    origin_reachable: bool
    delegation_chain: tuple[DelegationHop, ...]
    origin_signature_on_resource: str | None
    current_epoch: float
    max_acceptable_freshness_sec: float

@dataclass(frozen=True)
class DelegationPolicy:
    require_origin_signature: bool
    max_trusted_hops: int

@dataclass(frozen=True)
class DelegationManifest:
    verdict: DelegationVerdict
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_resolution(
        cls, resolution: DelegatedResolution, policy: DelegationPolicy
    ) -> DelegationManifest:
        
        # Gate 1: Origin reachable
        if resolution.origin_reachable:
            digest = cls._hash(json.dumps({
                "reference": resolution.reference_id,
                "status": "DIRECT"
            }, sort_keys=True))
            return DelegationManifest(
                verdict=DelegationVerdict.ORIGIN_DIRECT,
                directive=f"PROCEED: Resolve {resolution.reference_id} directly from origin.",
                manifest_digest=digest
            )

        # Gate 2: Chain length
        if len(resolution.delegation_chain) > policy.max_trusted_hops:
            return DelegationManifest(
                verdict=DelegationVerdict.DELEGATION_CHAIN_UNTRUSTED,
                directive=f"HALT: Delegation chain length {len(resolution.delegation_chain)} > {policy.max_trusted_hops}.",
                manifest_digest=cls._hash(f"CHAIN_LONG:{resolution.reference_id}")
            )

        # Gate 3: Intermediary trust
        for hop in resolution.delegation_chain:
            if not hop.trust_attestation:
                if policy.require_origin_signature:
                    return DelegationManifest(
                        verdict=DelegationVerdict.DELEGATION_CHAIN_UNTRUSTED,
                        directive=f"HALT: Intermediary {hop.intermediary_id} lacks trust attestation.",
                        manifest_digest=cls._hash(f"UNTRUSTED:{hop.intermediary_id}")
                    )

        # Gate 4: Origin signature
        if policy.require_origin_signature and not resolution.origin_signature_on_resource:
            return DelegationManifest(
                verdict=DelegationVerdict.DELEGATION_CHAIN_UNTRUSTED,
                directive=f"HALT: Resource lacks origin signature. Delegation substitution risk.",
                manifest_digest=cls._hash(f"NO_SIGNATURE:{resolution.reference_id}")
            )

        # Gate 5: Freshness
        latest_hop_epoch = max((h.hop_epoch for h in resolution.delegation_chain), default=0.0)
        age = resolution.current_epoch - latest_hop_epoch
        if age > resolution.max_acceptable_freshness_sec:
            return DelegationManifest(
                verdict=DelegationVerdict.STALE_CACHE_DETECTED,
                directive=f"HALT: Delegated resolution {age:.0f}s old > {resolution.max_acceptable_freshness_sec:.0f}s.",
                manifest_digest=cls._hash(f"STALE:{resolution.reference_id}")
            )

        # Gate 6: Verified
        digest = cls._hash(json.dumps({
            "reference": resolution.reference_id,
            "hops": tuple(h.intermediary_id for h in resolution.delegation_chain),
            "signature": resolution.origin_signature_on_resource,
            "age": f"{age:.0f}"
        }, sort_keys=True))
        
        return DelegationManifest(
            verdict=DelegationVerdict.DELEGATED_VERIFIED,
            directive=f"PROCEED: Delegated resolution verified via {len(resolution.delegation_chain)} hops.",
            manifest_digest=digest
        )