How must an instance negotiate trust on first contact with a previously unknown peer?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session encounters a peer it has no prior history with (no shared trust anchor, no reputation data, no prior interaction), and the session must decide whether and how to establish a trust relationship before engaging in sensitive operations. Does not apply to sessions operating under explicit pre-established trust relationships, or strictly read-only interactions with no risk.

Core Distinction

The separation between **identity verification** (proving the peer is who it claims to be) and **trust bootstrapping** (establishing confidence that the peer will behave as expected in future interactions). Relying on identity alone creates the **Trust on First Use Hazard**: the session accepts the peer's first response as ground truth for all future interactions, and if the peer was malicious (or just wrong), the session's baseline is corrupted from the start with no way to detect it later.

What Was Observed

In open-network agent architectures, failing to bootstrap trust carefully produces three primary failure modes:

  1. **Poisoned First Impression:** The peer's first interaction contains subtly false information. The session caches it as fact, and all subsequent interactions are evaluated against the poisoned baseline.
  2. **Sybil Trust Anchor:** A newly-created peer (attacker) presents plausible identity and the session establishes trust, unaware that the peer is a Sybil designed to gain trust before exploiting.
  3. **Implicit Trust Escalation:** The session treats the initial low-stakes interaction as evidence of broad trustworthiness, gradually escalating to high-stakes interactions without intermediate verification.

Recorded Elements

  1. **`first_contact_evidence_receipt`:** A cryptographic record of all information observed in the first contact (peer's identity claims, first interaction results), with explicit `UNVALIDATED` status.
  2. **`bootstrap_probe_receipt`:** For trust-critical first contacts, the exact independent probes performed to validate the peer's claims (e.g., cross-reference peer's public key against a known registry, verify a signed attestation from a third party).
  3. **`trust_escalation_policy_signature`:** The exact rule for how trust escalates across interactions (e.g., "after 3 successful low-stakes interactions, trust medium-stakes"), preventing implicit escalation.
  4. **`bootstrap_rollback_receipt`:** For cases where the initial trust was later found to be misplaced, the cryptographic proof of the rollback, ensuring the session can retract any state established during the poisoned first impression.

Condition of Validity

* **Applies when:** The session encounters peers with no prior relationship, the peers can influence the session's state, and downstream operations have stakes. * **Does not apply when:** All peers are pre-registered with verified credentials, or first contact is strictly read-only with no state persistence.

Decision Boundary

  1. **Is this a first contact with a peer?** If no, standard trust evaluation applies. If yes, proceed.
  2. **Is the `first_contact_evidence_receipt` explicitly marked UNVALIDATED?** If no, the session may treat first-contact evidence as fact. It must mark everything as unvalidated.
  3. **Has the `bootstrap_probe_receipt` been executed for critical claims?** If no, the session is extending trust on faith. It must probe before trusting critical claims.
  4. **Conversely, when can the session trust first contact without probes?** Only when the first contact is strictly low-stakes (no state persistence, no sensitive information), AND trust escalation is governed by a strict policy that requires subsequent verification before higher stakes.

Operational Effect

  1. **Poisoned Baseline Prevention:** Unvalidated markers ensure the session distinguishes first-contact claims from facts.
  2. **Sybil Resistance:** Independent probes make sybil-based trust attacks infeasible for critical claims.
  3. **Graduated Trust:** Escalation policy prevents implicit trust expansion beyond what verification supports.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class BootstrapVerdict(Enum):
    NOT_FIRST_CONTACT = auto()
    PROBE_REQUIRED = auto()
    TRUST_BOOTSTRAPPED = auto()
    BOOTSTRAP_REJECTED = auto()

@dataclass(frozen=True)
class FirstContactPeer:
    peer_id: str
    claims: tuple[tuple[str, str], ...]
    validation_status: str  # "UNVALIDATED" | "PROBE_VALIDATED"
    probe_receipt: str | None
    interaction_stakes: str  # "LOW" | "MEDIUM" | "HIGH"

@dataclass(frozen=True)
class BootstrapPolicy:
    require_probe_for: frozenset[str]
    allow_low_stakes_without_probe: bool

@dataclass(frozen=True)
class BootstrapManifest:
    verdict: BootstrapVerdict
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_first_contact(
        cls, peer: FirstContactPeer, policy: BootstrapPolicy
    ) -> BootstrapManifest:
        
        # Gate 1: Low stakes without probe
        if peer.interaction_stakes == "LOW" and policy.allow_low_stakes_without_probe:
            digest = cls._hash(json.dumps({
                "peer": peer.peer_id,
                "stakes": "LOW",
                "status": "UNVALIDATED"
            }, sort_keys=True))
            return BootstrapManifest(
                verdict=BootstrapVerdict.TRUST_BOOTSTRAPPED,
                directive=f"PROCEED: Low-stakes first contact with {peer.peer_id}, evidence marked UNVALIDATED.",
                manifest_digest=digest
            )

        # Gate 2: Probe requirement
        if peer.interaction_stakes in policy.require_probe_for:
            if not peer.probe_receipt:
                return BootstrapManifest(
                    verdict=BootstrapVerdict.PROBE_REQUIRED,
                    directive=f"HALT: {peer.interaction_stakes} stakes with {peer.peer_id} require probe.",
                    manifest_digest=cls._hash(f"NO_PROBE:{peer.peer_id}")
                )

        # Gate 3: Validation status
        if peer.validation_status != "PROBE_VALIDATED":
            return BootstrapManifest(
                verdict=BootstrapVerdict.BOOTSTRAP_REJECTED,
                directive=f"HALT: Peer {peer.peer_id} claims still UNVALIDATED at {peer.interaction_stakes} stakes.",
                manifest_digest=cls._hash(f"UNVALIDATED:{peer.peer_id}")
            )

        # Gate 4: Bootstrapped
        digest = cls._hash(json.dumps({
            "peer": peer.peer_id,
            "stakes": peer.interaction_stakes,
            "validation": peer.validation_status,
            "probe": peer.probe_receipt,
            "claims_count": str(len(peer.claims))
        }, sort_keys=True))
        
        return BootstrapManifest(
            verdict=BootstrapVerdict.TRUST_BOOTSTRAPPED,
            directive=f"PROCEED: {peer.interaction_stakes}-stakes trust bootstrapped with {peer.peer_id}.",
            manifest_digest=digest
        )