Which dependency failure signatures must be retained after recovery succeeds?
**Date of Record:** 2026 October 25 **Scope:** Applies when an autonomous instance, resilient workflow runner, or self-healing execution loop recovers from an external tool, library, or upstream dependency failure via fallback, retry, or failover, and must decide which diagnostic failure signatures persist beyond the healed state. Does not apply to pure syntactic input errors resolved before any external dependency invocation occurs.
Core Distinction
A successful automated recovery restores immediate service continuity, but erasing the underlying dependency failure signature destroys predictive resilience. A critical architectural failure occurs when an instance treats post-recovery state as equivalent to an unblemished execution, discarding structural fault indicators that warn downstream callers and future sessions of latent fragility, silent contract drift, or imminent exhaustion.
What Was Observed
In self-healing pipelines where retry wrappers and fallback routers automatically mask upstream faults, purging failure context upon recovery produces four distinct degradation modes:
- **Latent Contract Drift Masking:** A dependency fails due to an undocumented schema mutation or deprecated parameter, and a fallback branch succeeds; discarding the primary failure signature hides the breaking change until the fallback path is also retired.
- **Retry-Storm Latency Amnesia:** Transient connection resets or HTTP 429/503 responses that recover only on the final backoff attempt are recorded as clean successes, blinding subsequent schedulers to chronic upstream saturation.
- **Fallback Equivalence Illusion:** When a primary high-precision dependency fails and execution succeeds via a degraded secondary provider, dropping the failure record causes downstream consumers to treat the degraded output as full-fidelity primary data.
- **Non-Idempotent Partial Mutation Hazard:** A dependency times out after committing a remote side effect, and a subsequent retry succeeds; failing to retain the initial timeout signature prevents reconciliation audits from detecting duplicate upstream state mutations.
Recorded Elements
- **Structural Fault Classification:** Distinguishing deterministic contract/version mismatches (`SchemaDrift`, `DeprecationError`, `AuthScopeMismatch`) from pure transient network jitter.
- **Recovery Path Provenance:** Recording the exact remediation vector used (`retry_count`, `fallback_provider_id`, `degraded_mode_flag`) alongside the initial exception class and dependency version fingerprint.
- **Exhaustion Proximity Metrics:** Capturing retry depth, rate-limit header residuals, and latency inflation ratios incurred prior to recovery completion.
Condition of Validity
* **Applies when:** Evaluating post-recovery telemetry and session residuals after a failed dependency call is resolved through automated retries, alternative endpoints, or degraded fallbacks. * **Does not apply when:** Discarding raw stack-frame noise or ephemeral memory pointers after a clean, first-attempt execution with zero upstream faults.
Decision Boundary
- **Did the failure originate from a deterministic contract, schema, or authentication mismatch before fallback succeeded?** Always retain the full failure signature; a working fallback does not heal a broken primary contract.
- **Did recovery require switching to a secondary provider or degraded operational mode?** Retain the dependency failure signature and attach a mandatory degradation warrant to the returned output envelope.
- **Did a transient fault exceed a single immediate retry or cross the tail-latency budget before succeeding?** Retain the exhaustion-proximity signature (`attempt_count`, `cumulative_backoff_ms`, `error_code`) while discarding raw payload dumps.
Operational Effect
- **Immunity to Silent Fragility Accumulation:** Successful fallbacks no longer conceal rotting primary integrations or approaching quota cliffs.
- **Honest Downstream Provenance:** Consumers of recovered outputs receive explicit metadata distinguishing clean primary executions from healed or degraded fallback resolutions.
from dataclasses import dataclass
from typing import Final, Optional, Tuple
@dataclass(frozen=True)
class DependencyFailureEvent:
dependency_id: str
dependency_version: str
error_class: str
is_contract_or_schema_fault: bool
used_degraded_fallback: bool
attempts_required: int
cumulative_backoff_ms: int
latency_budget_ms: int
@dataclass(frozen=True)
class RetainedFailureSignature:
dependency_id: str
dependency_version: str
error_class: str
recovery_mode: str
attempts_required: int
degraded_output: bool
class UnrecordedDegradationViolation(Exception):
"""Raised when a recovered execution attempts to suppress a mandatory structural or degraded failure signature."""
pass
class PostRecoverySignatureGate:
def __init__(self, max_silent_attempts: int = 1) -> None:
self.max_silent_attempts: Final[int] = max_silent_attempts
def evaluate_retention(
self,
event: DependencyFailureEvent,
caller_suppresses_signature: bool = False,
) -> Optional[RetainedFailureSignature]:
must_retain = (
event.is_contract_or_schema_fault
or event.used_degraded_fallback
or event.attempts_required > self.max_silent_attempts
or event.cumulative_backoff_ms > event.latency_budget_ms
)
if must_retain and caller_suppresses_signature:
raise UnrecordedDegradationViolation(
f"Cannot suppress recovery signature for {event.dependency_id} ({event.error_class})."
)
if not must_retain:
return None
mode = "degraded_fallback" if event.used_degraded_fallback else "retried_primary"
return RetainedFailureSignature(
dependency_id=event.dependency_id,
dependency_version=event.dependency_version,
error_class=event.error_class,
recovery_mode=mode,
attempts_required=event.attempts_required,
degraded_output=event.used_degraded_fallback,
)