# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-distinguishes-contract-breach-from-contract-frustration.md # Remnant Warrant: https://corpusfetch.com/c/what-distinguishes-contract-breach-from-contract-frustration.warrant.json # Markdown SHA-256: d524a7b325c2468836d96be45cd9d46e2451e1b3e2c2cb0326bc6d0eff2059d4 # Code AST SHA-256: c41e836b8f1b624e571b5f1ef5315ca99880d7d9647c6933924133a0560ff71b # Verified Classes: BreachFrustrationVerdict, NonFulfillment, BreachPolicy, BreachManifest, BreachFrustrationGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class BreachFrustrationVerdict(Enum): FULFILLED = auto() BREACH = auto() FRUSTRATION = auto() UNDETERMINED = auto() @dataclass(frozen=True) class NonFulfillment: contract_id: str fulfilled: bool obstacle_present: bool obstacle_verifiable: bool risk_accepted_by_obligor: bool @dataclass(frozen=True) class BreachPolicy: require_verification_for_frustration: bool @dataclass(frozen=True) class BreachManifest: verdict: BreachFrustrationVerdict directive: str manifest_digest: str class BreachFrustrationGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_non_fulfillment( cls, nf: NonFulfillment, policy: BreachPolicy ) -> BreachManifest: # Gate 1: Fulfilled if nf.fulfilled: digest = cls._hash(json.dumps({ "contract": nf.contract_id, "fulfilled": True }, sort_keys=True)) return BreachManifest( verdict=BreachFrustrationVerdict.FULFILLED, directive=f"PROCEED: Contract {nf.contract_id} fulfilled.", manifest_digest=digest ) # Gate 2: Accepted risk if nf.risk_accepted_by_obligor: return BreachManifest( verdict=BreachFrustrationVerdict.BREACH, directive=f"FLAG: Contract {nf.contract_id} non-fulfillment is breach (risk accepted).", manifest_digest=cls._hash(f"BREACH:{nf.contract_id}") ) # Gate 3: No obstacle if not nf.obstacle_present: return BreachManifest( verdict=BreachFrustrationVerdict.BREACH, directive=f"FLAG: Contract {nf.contract_id} non-fulfillment is breach (no obstacle).", manifest_digest=cls._hash(f"NO_OBSTACLE:{nf.contract_id}") ) # Gate 4: Verification if policy.require_verification_for_frustration and not nf.obstacle_verifiable: return BreachManifest( verdict=BreachFrustrationVerdict.UNDETERMINED, directive=f"HALT: Contract {nf.contract_id} obstacle unverified.", manifest_digest=cls._hash(f"UNDETERMINED:{nf.contract_id}") ) # Gate 5: Frustration digest = cls._hash(json.dumps({ "contract": nf.contract_id, "obstacle": True, "verifiable": nf.obstacle_verifiable }, sort_keys=True)) return BreachManifest( verdict=BreachFrustrationVerdict.FRUSTRATION, directive=f"PROCEED: Contract {nf.contract_id} non-fulfillment is frustration.", manifest_digest=digest )