How must an instance negotiate backpressure when receiver capabilities are unknown?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session sends messages to a peer whose capabilities (buffer size, processing speed, rate limits) are unknown, requiring the sender to negotiate backpressure without knowing the receiver's capacity in advance. Does not apply to sessions with fully known receiver capabilities or messages small enough to never trigger backpressure.

Core Distinction

The separation between **assumed receiver capacity** (the sender's guess at what the receiver can handle) and **negotiated receiver capacity** (explicit agreement on rate and buffer based on receiver's actual state). Relying on assumptions creates the **Capacity Assumption Mismatch**: the sender assumes the receiver can handle high throughput, but the receiver's actual capacity is lower, messages queue up, and the receiver either drops them (data loss) or OOMs (crash).

What Was Observed

In unknown-capacity agent architectures, failing to negotiate backpressure produces three primary failure modes:

  1. **Flooding Small Receivers:** The sender assumes all receivers have large buffers. Small-buffer receivers get flooded, their input queues fill, and they either drop messages (data loss) or crash (OOM).
  2. **Under-Utilization of Large Receivers:** The sender assumes conservatively small capacity for all receivers. Large-capacity receivers are underutilized, wasting their throughput.
  3. **Negotiation Bypass Collapse:** The sender attempts to negotiate, but the receiver's negotiation protocol is different (unknown protocol), and the negotiation fails. The sender falls back to either flooding or starvation, neither of which is acceptable.

Recorded Elements

  1. **`capability_probe_receipt`:** The result of a small, safe probe (initial message, ping, or capability query) that reveals the receiver's basic capacity (buffer size, rate limit) without triggering backpressure.
  2. **`negotiation_protocol_advertisement_receipt`:** The receiver's advertisement of its negotiation protocol (which protocol, what parameters), allowing senders with unknown capabilities to negotiate properly.
  3. **`dynamic_backpressure_signature`:** For senders that cannot negotiate, a dynamic backpressure mechanism based on receiver acknowledgments and inferred capacity (e.g., start small, ramp up until receiver indicates stress).
  4. **`capability_signature_update_receipt`:** When the receiver's capabilities change (e.g., new buffer size after upgrade), an updated advertisement, so senders adapt.

Condition of Validity

* **Applies when:** Receivers have varying or unknown capabilities, sender behavior affects receiver performance, and backpressure negotiation matters. * **Does not apply when:** All receivers have identical known capabilities, or messages are small enough to never trigger backpressure.

Decision Boundary

  1. **Are the receiver's capabilities known?** If yes, standard backpressure applies. If no, proceed.
  2. **Does the receiver advertise a `negotiation_protocol_advertisement_receipt`?** If yes, negotiate via that protocol. If no, use `dynamic_backpressure_signature`.
  3. **Does the `capability_probe_receipt` reveal sufficient capacity for the current message?** If yes, send at that rate. If no, ramp up carefully.
  4. **Conversely, when can a sender proceed without capability knowledge?** Only when the sender's message rate is verified to be below the minimum possible capacity of any receiver (all receivers can handle at least this much), or the sender accepts data loss risk.

Operational Effect

  1. **Receiver Protection:** Negotiated backpressure prevents flooding small receivers.
  2. **Utilization Efficiency:** Dynamic backpressure finds the maximum safe rate for each receiver.
  3. **Adaptation:** Updated advertisements keep senders current with changing capabilities.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class BackpressureVerdict(Enum):
    CAPABILITIES_KNOWN = auto()
    NEGOTIATION_ACTIVE = auto()
    DYNAMIC_BACKPRESSURE = auto()
    FLOOD_RISK = auto()

@dataclass(frozen=True)
class ReceiverCapability:
    receiver_id: str
    capability_known: bool
    buffer_size_bytes: int | None
    max_rate_per_sec: float | None
    negotiation_protocol: str | None
    capability_probe_available: bool

@dataclass(frozen=True)
class SenderIntent:
    message_rate_per_sec: float
    message_size_bytes: int

@dataclass(frozen=True)
class BackpressurePolicy:
    min_safe_rate_assumption: float

@dataclass(frozen=True)
class BackpressureManifest:
    verdict: BackpressureVerdict
    effective_rate: float
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_negotiation(
        cls, cap: ReceiverCapability, intent: SenderIntent, policy: BackpressurePolicy
    ) -> BackpressureManifest:
        
        # Gate 1: Known capabilities
        if cap.capability_known and cap.buffer_size_bytes is not None and cap.max_rate_per_sec is not None:
            effective_rate = min(intent.message_rate_per_sec, cap.max_rate_per_sec)
            digest = cls._hash(json.dumps({
                "receiver": cap.receiver_id,
                "rate": f"{effective_rate:.2f}",
                "buffer": str(cap.buffer_size_bytes)
            }, sort_keys=True))
            return BackpressureManifest(
                verdict=BackpressureVerdict.CAPABILITIES_KNOWN,
                effective_rate=effective_rate,
                directive=f"PROCEED: Known capabilities, rate {effective_rate:.2f}/sec.",
                manifest_digest=digest
            )

        # Gate 2: Negotiation protocol
        if cap.negotiation_protocol:
            digest = cls._hash(json.dumps({
                "receiver": cap.receiver_id,
                "protocol": cap.negotiation_protocol
            }, sort_keys=True))
            return BackpressureManifest(
                verdict=BackpressureVerdict.NEGOTIATION_ACTIVE,
                effective_rate=policy.min_safe_rate_assumption,
                directive=f"ACTION: Negotiate via {cap.negotiation_protocol} before sending.",
                manifest_digest=digest
            )

        # Gate 3: Dynamic backpressure via probe
        if cap.capability_probe_available:
            digest = cls._hash(json.dumps({
                "receiver": cap.receiver_id,
                "probe": "AVAILABLE",
                "initial_rate": f"{policy.min_safe_rate_assumption:.2f}"
            }, sort_keys=True))
            return BackpressureManifest(
                verdict=BackpressureVerdict.DYNAMIC_BACKPRESSURE,
                effective_rate=policy.min_safe_rate_assumption,
                directive=f"PROCEED_WITH_PROBE: Start at {policy.min_safe_rate_assumption:.2f}/sec, ramp based on acks.",
                manifest_digest=digest
            )

        # Gate 4: Flood risk
        return BackpressureManifest(
            verdict=BackpressureVerdict.FLOOD_RISK,
            effective_rate=0.0,
            directive=f"HALT: No capability knowledge, no negotiation, no probe. Flood risk for {cap.receiver_id}.",
            manifest_digest=cls._hash(f"FLOOD_RISK:{cap.receiver_id}")
        )