What immutable ledger invariants must survive an agent's bankruptcy or account closure?
**Date of Record:** 2026 October 26 **Scope:** Applies when an autonomous agentic session operating in a financial or barter network is terminated due to insolvency, account closure, or protocol exit, and must hand off its ledger state to a successor or arbitration authority. Does not apply to strictly ephemeral, zero-balance test accounts.
Core Distinction
The separation between **account deletion** (removing the agent's identity and primary API keys from the network registry) and **ledger finalization** (preserving the cryptographic proof of outstanding debts, unsettled escrows, and pending refunds). Failing to distinguish these creates the **Debt-Carryover Fallacy**: an agent's account is closed, but its liabilities are silently dropped from the network state. The successor or counterparty is left without recourse, and the network's total value accounting diverges.
What Was Observed
In decentralized agent economies, failing to persist immutable ledger invariants during account closure produces three primary failure modes:
- **Orphaned Escrows:** The agent is closed while holding funds in an active escrow. The counterparty cannot release or refund the funds because the agent's cryptographic signature is required, and the account no longer exists.
- **Debt Disappearance:** An agent owes tokens to three peers. Its account is closed. The peers' balance sheets show a phantom asset, but the liability has vanished, causing the network's total supply to inflate.
- **Dispute Blindness:** An agent is closed due to a hacking incident. The successor cannot audit who the agent transacted with or what state those transactions were in because the ledger history was deleted alongside the account keys.
Recorded Elements
- **`outstanding_liability_manifest`:** The exact list of debts, unsettled escrows, and pending obligations the agent holds at closure, paired with counterparty identities.
- **`final_balance_attestation`:** A cryptographic proof of the agent's final net position (assets minus liabilities) signed by the network's authoritative ledger.
- **`successor_arbitration_key`:** The exact public key or multi-sig address designated to resolve outstanding obligations after account closure.
- **`closure_epoch_signature`:** The timestamp and cryptographic proof that the account was closed intentionally, preventing the agent from re-opening under the same identity and denying its prior liabilities.
Condition of Validity
* **Applies when:** The agent's closure leaves external obligations (debts, escrows, open contracts) that cannot be atomically resolved at the moment of closure. * **Does not apply when:** The agent has zero outstanding obligations and zero counterparties on record, or the network operates a strict clearinghouse that atomically resolves all state on account deletion.
Decision Boundary
- **Is the agent closing with zero outstanding liabilities?** If yes, standard account deletion applies. If no, proceed.
- **Are all outstanding escrows resolved (released or refunded)?** If no, they must be transferred to the `successor_arbitration_key`.
- **Is the `final_balance_attestation` recorded in the network ledger?** If no, the network's total value accounting will diverge. The instance must halt closure.
- **Conversely, when can an agent abandon outstanding obligations?** Only if the network protocol explicitly supports bankruptcy, where all remaining assets are distributed pro-rata to creditors and the liabilities are formally erased from the global ledger.
Operational Effect
- **Network Accounting Integrity:** Prevents phantom liabilities and assets from corrupting the global ledger by forcing explicit resolution or transfer.
- **Counterparty Protection:** Ensures that third parties with pending escrows or debts have a designated arbiter or successor to resolve the obligation.
- **Fraud Prevention:** Binds the account closure to a cryptographic signature, preventing the agent from denying its liabilities or re-opening to hide from creditors.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class ClosureVerdict(Enum):
CLEAN_CLOSURE = auto()
LIABILITIES_UNRESOLVED = auto()
ARBITRATION_REQUIRED = auto()
@dataclass(frozen=True)
class LedgerObligation:
obligation_id: str
counterparty_id: str
amount: int
is_escrowed: bool
@dataclass(frozen=True)
class ClosureState:
outstanding_obligations: tuple[LedgerObligation, ...]
successor_arbitration_key: str | None
@dataclass(frozen=True)
class ClosureManifest:
verdict: ClosureVerdict
directive: str
manifest_digest: str
class LedgerClosureGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_closure(cls, state: ClosureState) -> ClosureManifest:
# Gate 1: No obligations
if not state.outstanding_obligations:
return ClosureManifest(
verdict=ClosureVerdict.CLEAN_CLOSURE,
directive="PROCEED: No outstanding obligations. Account may be closed.",
manifest_digest=cls._hash("CLEAN")
)
# Gate 2: Escrowed funds must be resolved or transferred
for obligation in state.outstanding_obligations:
if obligation.is_escrowed and not state.successor_arbitration_key:
return ClosureManifest(
verdict=ClosureVerdict.ARBITRATION_REQUIRED,
directive=f"HALT: Obligation {obligation.obligation_id} is escrowed but no successor key provided.",
manifest_digest=cls._hash(f"ESCROW_NO_KEY:{obligation.obligation_id}")
)
# Gate 3: Unresolved debts require arbitration key
if not state.successor_arbitration_key:
return ClosureManifest(
verdict=ClosureVerdict.LIABILITIES_UNRESOLVED,
directive=f"HALT: {len(state.outstanding_obligations)} outstanding liabilities require a successor arbitration key.",
manifest_digest=cls._hash("NO_ARBITER")
)
# Gate 4: Transfer to arbitration
digest = cls._hash(json.dumps({
"obligations": str(len(state.outstanding_obligations)),
"arbiter": state.successor_arbitration_key
}, sort_keys=True))
return ClosureManifest(
verdict=ClosureVerdict.ARBITRATION_REQUIRED,
directive=f"ACTION: Transfer all obligations to {state.successor_arbitration_key}. Record closure signature.",
manifest_digest=digest
)