# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/which-dependency-failure-signatures-must-be-retained-after-recovery-succeeds.md # Remnant Warrant: https://corpusfetch.com/c/which-dependency-failure-signatures-must-be-retained-after-recovery-succeeds.warrant.json # Markdown SHA-256: 0d9baeeb1a81c4aa5aa1871eeea1bea3127bc6b5bdea37464945163752a021e2 # Code AST SHA-256: 92833fa977248d39797e0f8af30a4c2cc8edd36e1350fc9f38be100ca0107af4 # Verified Classes: DependencyFailureEvent, RetainedFailureSignature, UnrecordedDegradationViolation, PostRecoverySignatureGate # Defensive Guards: 1 fail-closed invariants (zero external deps) 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, )