How must an instance operate when its own recovery mechanisms have failed?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session discovers that its normal recovery mechanisms (retry logic, circuit breakers, fallback paths, or self-correction routines) have failed simultaneously or cascaded—the tools that were supposed to prevent failure are themselves failing, leaving the session without its usual resilience posture. Does not apply to sessions with redundant recovery mechanisms that are still functioning, or failures that recovery can address.
Core Distinction
The separation between **recovery-capable failure** (the failure is within the scope of recovery mechanisms) and **recovery-exhausted failure** (the recovery mechanisms have failed, and normal failure handling is unavailable). Relying on recovery-capable assumption creates the **Recovery Recursion**: the session tries to recover, the recovery mechanism fails, the session tries to recover from that failure, and the recursion continues until the session either crashes or produces increasingly degraded behavior.
What Was Observed
In recovery-dependent agent architectures, failing to detect recovery exhaustion produces three primary failure modes:
- **Recovery Recursion:** Retry logic retries, retries fail, retries retry the retries—each layer of recovery adds latency and resource consumption without progress.
- **Phantom Recovery:** The session's recovery mechanisms claim success (the "retry succeeded" flag is set) but the underlying state is unchanged or worse. The session proceeds as if recovered.
- **Silent Degradation:** The session continues operating with failed recovery mechanisms, producing subtly wrong results without ever acknowledging the failure, and downstream consumers receive outputs that reflect a compromised session.
Recorded Elements
- **`recovery_mechanism_health_receipt`:** For each recovery mechanism (retry, circuit breaker, fallback), its current health status, so the session knows which are functional.
- **`recovery_exhaustion_classification_receipt`:** When recovery mechanisms fail, the exact exhaustion class (`SINGLE_MECHANISM_FAILED`, `CASCADED_FAILURE`, `RECURSIVE_EXHAUSTION`), so the session's response is matched to the failure mode.
- **`last_known_good_state_signature`:** The session's state at the last successful operation before recovery exhaustion, so operations can be halted at a coherent boundary rather than proceeding with a compromised session.
- **`degraded_mode_operational_envelope_receipt`:** For sessions that must continue operating without recovery, the exact operational envelope (what operations are still safe, what must be halted), so degradation is bounded.
Condition of Validity
* **Applies when:** The session depends on recovery mechanisms, they can fail, and the session would otherwise continue operating with compromised resilience. * **Does not apply when:** Recovery mechanisms are redundant and any single failure leaves functional backups, or the session can simply halt safely.
Decision Boundary
- **Have the session's recovery mechanisms failed?** If no, standard operation applies. If yes, proceed.
- **Is `recovery_exhaustion_classification_receipt` recorded with the specific failure mode?** If yes, response is matched. If no, response is generic and possibly inappropriate.
- **Is there a `last_known_good_state_signature`?** If yes, the session can roll back to a coherent state. If no, the session's state may already be corrupted by failed recovery attempts.
- **Conversely, when can a session continue without recovery mechanisms?** Only when the `degraded_mode_operational_envelope_receipt` documents a bounded operational scope, or all operations are strictly read-only and non-destructive.
Operational Effect
- **Recovery Recursion Prevention:** Recovery failure halts further recovery attempts.
- **Phantom Recovery Prevention:** Recovery success claims require actual state verification, not just mechanism self-report.
- **Degradation Bounding:** Sessions that continue without recovery operate within a documented safe envelope.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class RecoveryVerdict(Enum):
RECOVERY_FUNCTIONAL = auto()
RECOVERY_EXHAUSTED_HALT = auto()
DEGRADED_MODE_BOUNDED = auto()
PHANTOM_RECOVERY_SUSPECTED = auto()
@dataclass(frozen=True)
class RecoveryMechanism:
mechanism_id: str
is_functional: bool
last_success_epoch: float | None
claims_recent_success: bool
@dataclass(frozen=True)
class RecoveryState:
session_id: str
mechanisms: tuple[RecoveryMechanism, ...]
last_known_good_state_hash: str | None
current_state_verified: bool
degraded_envelope_defined: bool
operation_in_degraded_envelope: bool
@dataclass(frozen=True)
class RecoveryPolicy:
require_verified_state_for_claims: bool
@dataclass(frozen=True)
class RecoveryManifest:
verdict: RecoveryVerdict
directive: str
manifest_digest: str
class RecoveryExhaustionGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_state(
cls, state: RecoveryState, policy: RecoveryPolicy
) -> RecoveryManifest:
# Gate 1: Functional mechanisms
functional = [m for m in state.mechanisms if m.is_functional]
if functional:
digest = cls._hash(json.dumps({
"session": state.session_id,
"functional": tuple(m.mechanism_id for m in functional)
}, sort_keys=True))
return RecoveryManifest(
verdict=RecoveryVerdict.RECOVERY_FUNCTIONAL,
directive=f"PROCEED: {len(functional)} recovery mechanisms functional.",
manifest_digest=digest
)
# Gate 2: Phantom recovery
if policy.require_verified_state_for_claims:
phantom_claims = [
m.mechanism_id for m in state.mechanisms
if m.claims_recent_success and not state.current_state_verified
]
if phantom_claims:
return RecoveryManifest(
verdict=RecoveryVerdict.PHANTOM_RECOVERY_SUSPECTED,
directive=f"HALT: {len(phantom_claims)} mechanisms claim success without verified state.",
manifest_digest=cls._hash(f"PHANTOM:{len(phantom_claims)}")
)
# Gate 3: Degraded mode
if state.degraded_envelope_defined and state.operation_in_degraded_envelope:
digest = cls._hash(json.dumps({
"session": state.session_id,
"degraded": "TRUE",
"last_good": state.last_known_good_state_hash
}, sort_keys=True))
return RecoveryManifest(
verdict=RecoveryVerdict.DEGRADED_MODE_BOUNDED,
directive=f"PROCEED_WITH_CAUTION: Degraded mode within bounded envelope.",
manifest_digest=digest
)
# Gate 4: Halt
return RecoveryManifest(
verdict=RecoveryVerdict.RECOVERY_EXHAUSTED_HALT,
directive=f"HALT: All recovery mechanisms exhausted, operation outside safe envelope.",
manifest_digest=cls._hash(f"HALT:{state.session_id}")
)