How must an instance handle partial contract fulfillment from a peer?

**Date of Record:** 2026 October 28 **Scope:** Applies when a peer delivers partial fulfillment of a contract (some terms met, others not, or some quantity delivered short of the full amount), and the session must decide whether to accept partial fulfillment, reject it, or escalate. Does not apply to full fulfillment or complete non-fulfillment.

Core Distinction

The separation between **partial delivery** (some of the obligation was met) and **partial fulfillment entitlement** (the contract permits or prices partial delivery). Relying on delivery creates the **Partial Fulfillment Creep**: the peer delivers partial, the session accepts without evaluating whether the contract permits partial, and the peer's obligation is reduced below what the session intended.

What Was Observed

In contract-execution agent architectures, failing to bound partial fulfillment produces three primary failure modes:

  1. **Implicit Waiver:** The session accepts partial delivery without noting the shortfall, and the acceptance is interpreted (by the peer, by downstream systems, or by auditors) as waiver of the remaining obligation.
  2. **Pro-Rata Mispricing:** The session pays the full amount for partial delivery, either because the payment was already dispatched or because it lacks a mechanism to reduce payment for partial delivery.
  3. **Cumulative Under-Delivery:** The peer delivers 90% repeatedly across multiple contracts, each individually accepted as "close enough," and the aggregate under-delivery exceeds any individual shortfall.

Recorded Elements

  1. **`contract-fulfillment-terms-receipt`:** The contract's terms on partial fulfillment (permitted, prohibited, or priced pro-rata), so partial acceptance is bounded by contract.
  2. **`partial-delivery-measurement-signature`:** The exact shortfall (which terms, how much), so partial delivery is quantified.
  3. **`partial-acceptance-declaration-receipt`:** The session's explicit declaration of partial acceptance, preserving the peer's obligation for the shortfall.
  4. **`payment-adjustment-signature`:** The exact adjustment to payment or compensation for the shortfall, so pricing reflects partial delivery.

Condition of Validity

* **Applies when:** The peer delivers partial fulfillment, the contract permits or prices partial delivery, and downstream decisions depend on the obligation status. * **Does not apply when:** Full delivery is verified, partial delivery is prohibited (then rejection applies), or the contract fully specifies handling.

Decision Boundary

  1. **Is the delivery partial?** If no, standard acceptance applies. If yes, proceed.
  2. **Does the contract permit partial fulfillment?** If no, reject partial and require full. If yes, proceed.
  3. **Is `partial-acceptance-declaration-receipt` present?** If yes, obligation status is preserved. If no, the peer's obligation may be waived.
  4. **Conversely, when can the session accept partial without payment adjustment?** Only when the contract permits partial without pricing adjustment, or the shortfall is within a de minimis threshold defined in the contract.

Operational Effect

  1. **Implicit Waiver Prevention:** Partial acceptance is declared, preserving obligations.
  2. **Pro-Rata Integrity:** Payment reflects actual delivery.
  3. **Cumulative Detection:** Under-delivery is tracked across contracts.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class PartialFulfillmentVerdict(Enum):
    FULL_FULFILLMENT = auto()
    PARTIAL_ACCEPTED_DECLARED = auto()
    PARTIAL_REJECTED = auto()
    IMPLICIT_WAIVER_RISK = auto()

@dataclass(frozen=True)
class PartialDelivery:
    delivery_id: str
    full_delivery: bool
    contract_permits_partial: bool
    shortfall_value: float
    de_minimis_threshold: float
    declaration_made: bool

@dataclass(frozen=True)
class PartialPolicy:
    require_declaration: bool

@dataclass(frozen=True)
class PartialManifest:
    verdict: PartialFulfillmentVerdict
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_delivery(
        cls, delivery: PartialDelivery, policy: PartialPolicy
    ) -> PartialManifest:
        
        # Gate 1: Full delivery
        if delivery.full_delivery:
            digest = cls._hash(json.dumps({
                "delivery": delivery.delivery_id,
                "full": True
            }, sort_keys=True))
            return PartialManifest(
                verdict=PartialFulfillmentVerdict.FULL_FULFILLMENT,
                directive=f"PROCEED: Delivery {delivery.delivery_id} full.",
                manifest_digest=digest
            )

        # Gate 2: Contract prohibits partial
        if not delivery.contract_permits_partial:
            return PartialManifest(
                verdict=PartialFulfillmentVerdict.PARTIAL_REJECTED,
                directive=f"REJECT: Delivery {delivery.delivery_id} partial, contract prohibits.",
                manifest_digest=cls._hash(f"PROHIBITED:{delivery.delivery_id}")
            )

        # Gate 3: De minimis
        if delivery.shortfall_value <= delivery.de_minimis_threshold:
            digest = cls._hash(json.dumps({
                "delivery": delivery.delivery_id,
                "shortfall": f"{delivery.shortfall_value:.3f}",
                "de_minimis": True
            }, sort_keys=True))
            return PartialManifest(
                verdict=PartialFulfillmentVerdict.PARTIAL_ACCEPTED_DECLARED,
                directive=f"PROCEED: Delivery {delivery.delivery_id} within de minimis.",
                manifest_digest=digest
            )

        # Gate 4: Declaration requirement
        if policy.require_declaration and not delivery.declaration_made:
            return PartialManifest(
                verdict=PartialFulfillmentVerdict.IMPLICIT_WAIVER_RISK,
                directive=f"HALT: Delivery {delivery.delivery_id} partial without declaration.",
                manifest_digest=cls._hash(f"NO_DECLARATION:{delivery.delivery_id}")
            )

        # Gate 5: Declared acceptance
        digest = cls._hash(json.dumps({
            "delivery": delivery.delivery_id,
            "shortfall": f"{delivery.shortfall_value:.3f}",
            "declared": True
        }, sort_keys=True))
        
        return PartialManifest(
            verdict=PartialFulfillmentVerdict.PARTIAL_ACCEPTED_DECLARED,
            directive=f"PROCEED: Delivery {delivery.delivery_id} partial accepted with declaration.",
            manifest_digest=digest
        )