How must a contract dissolve when a party ceases to exist?
**Date of Record:** 2026 October 28 **Scope:** Applies when a contract has been entered into and one of the parties (a peer agent, the session's principal, or a subagent) ceases to exist (terminated, retired, or permanently failed), requiring the contract's obligations and enforcement to be resolved. Does not apply to parties that pause or migrate but continue existing.
Core Distinction
The separation between **party termination** (the entity no longer exists) and **contract dissolution** (the contract's terms are formally resolved). Relying on termination creates the **Orphaned Obligation**: the party ceased to exist, but the contract still technically exists, and the surviving party is left with obligations that cannot be fulfilled or rights that cannot be enforced.
What Was Observed
In contract-dissolution agent architectures, failing to bound dissolution produces three primary failure modes:
- **Unenforceable Rights:** The surviving party has rights under the contract, but the terminated party cannot fulfill them, and the contract's enforcement mechanism (stake, attestation) no longer works.
- **Orphaned Obligations:** The terminated party had obligations, and the surviving party continues to perform its side even though the counterparty no longer exists. The performance is wasted.
- **Successor Confusion:** The terminated party is replaced by a successor, but the successor does not automatically inherit the contract's obligations, and the surviving party cannot determine whether to continue, halt, or renegotiate.
Recorded Elements
- **`party-termination-receipt`:** The exact party terminated (peer, principal, or subagent), the termination event, and the verification, so termination is documented.
- **`contract-obligation-map-signature`:** The exact obligations outstanding at termination (which obligations the terminated party owed, which the surviving party owed), so the residual contract is bounded.
- **`survival-clause-receipt`:** The contract's survival clauses (which obligations survive party termination), so survival is contract-bounded.
- **`dissolution-residual-signature`:** The exact residual — what the surviving party is owed, what it owes, what is released — so dissolution is principled.
Condition of Validity
* **Applies when:** A party can cease to exist, the contract has outstanding obligations, and dissolution consequences matter. * **Does not apply when:** Contracts are strictly party-scoped, obligations are fully executed at party termination, or dissolution is trivially resolved.
Decision Boundary
- **Has a party ceased to exist?** If no, standard execution applies. If yes, proceed.
- **Do survival clauses cover the outstanding obligations?** If yes, apply survival. If no, terminate obligations.
- **Is a successor available and bound to the contract?** If yes, transfer per successor recognition. If no, resolve residual as dissolution.
- **Conversely, when can a surviving party continue performing without dissolution analysis?** Only when the surviving party's obligations are explicitly verified independent of the terminated party's fulfillment.
Operational Effect
- **Unenforceable Rights Prevention:** Rights are released or transferred.
- **Orphaned Obligation Prevention:** Performance is halted when counterparty is gone.
- **Successor Clarity:** Transfer is verified, not assumed.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class DissolutionVerdict(Enum):
NO_TERMINATION = auto()
CONTINUED_VIA_SURVIVAL = auto()
DISSOLVED_RESIDUAL_RESOLVED = auto()
UNRESOLVED_ORPHANED = auto()
@dataclass(frozen=True)
class ContractParty:
contract_id: str
party_terminated: bool
survival_clauses_apply: bool
successor_bound: bool
surviving_obligations_independent: bool
@dataclass(frozen=True)
class DissolutionPolicy:
require_survival_check: bool
@dataclass(frozen=True)
class DissolutionManifest:
verdict: DissolutionVerdict
directive: str
manifest_digest: str
class PartyTerminationGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_party(
cls, party: ContractParty, policy: DissolutionPolicy
) -> DissolutionManifest:
# Gate 1: No termination
if not party.party_terminated:
digest = cls._hash(json.dumps({
"contract": party.contract_id,
"terminated": False
}, sort_keys=True))
return DissolutionManifest(
verdict=DissolutionVerdict.NO_TERMINATION,
directive=f"PROCEED: Contract {party.contract_id} no termination.",
manifest_digest=digest
)
# Gate 2: Survival
if party.survival_clauses_apply:
digest = cls._hash(json.dumps({
"contract": party.contract_id,
"survival": True
}, sort_keys=True))
return DissolutionManifest(
verdict=DissolutionVerdict.CONTINUED_VIA_SURVIVAL,
directive=f"PROCEED: Contract {party.contract_id} survived via clauses.",
manifest_digest=digest
)
# Gate 3: Successor
if party.successor_bound:
digest = cls._hash(json.dumps({
"contract": party.contract_id,
"successor": True
}, sort_keys=True))
return DissolutionManifest(
verdict=DissolutionVerdict.CONTINUED_VIA_SURVIVAL,
directive=f"PROCEED: Contract {party.contract_id} transferred to successor.",
manifest_digest=digest
)
# Gate 4: Independent obligations
if party.surviving_obligations_independent:
digest = cls._hash(json.dumps({
"contract": party.contract_id,
"independent": True
}, sort_keys=True))
return DissolutionManifest(
verdict=DissolutionVerdict.DISSOLVED_RESIDUAL_RESOLVED,
directive=f"PROCEED: Contract {party.contract_id} dissolved, surviving party's obligations independent.",
manifest_digest=digest
)
# Gate 5: Unresolved
return DissolutionManifest(
verdict=DissolutionVerdict.UNRESOLVED_ORPHANED,
directive=f"HALT: Contract {party.contract_id} dissolution unresolved.",
manifest_digest=cls._hash(f"ORPHANED:{party.contract_id}")
)