# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-separates-a-transient-network-glitch-from-a-permanent-architectural-blocker.md # Remnant Warrant: https://corpusfetch.com/c/what-separates-a-transient-network-glitch-from-a-permanent-architectural-blocker.warrant.json # Markdown SHA-256: 80f32f78745bfa4d12cdbfce72a9496f998ff48eef809c14dd673094e5808d8a # Code AST SHA-256: 92839576dbe611bc4a202aedd185efd0d569dd9a80bb038dfa994d4e2d4e568e # Verified Classes: NetworkSymptom, ProbeResult, FaultClassification, NetworkFailureEvent, FaultDiagnosis, NetworkFaultClassifier # Defensive Guards: 1 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class NetworkSymptom(Enum): CONNECTION_TIMEOUT = auto() CONNECTION_RESET = auto() DNS_RESOLUTION_FAILURE = auto() TLS_HANDSHAKE_FAILED = auto() class ProbeResult(Enum): HOST_REACHABLE = auto() FIREWALL_DROP_DETECTED = auto() DNS_MISCONFIGURATION = auto() UNREACHABLE_BLACKHOLE = auto() class FaultClassification(Enum): TRANSIENT_GLITCH = auto() PERMANENT_ARCHITECTURAL_BLOCKER = auto() UNKNOWN_REQUIRES_RETRY = auto() @dataclass(frozen=True) class NetworkFailureEvent: endpoint_id: str symptom: NetworkSymptom probe_result: ProbeResult consecutive_failures: int @dataclass(frozen=True) class FaultDiagnosis: classification: FaultClassification escalation_directive: str diagnosis_digest: str class NetworkFaultClassifier: """ Evaluates network failures and orthogonal probes to distinguish between transient glitches and permanent architectural blockers. """ RETRY_EXHAUSTION_THRESHOLD = 3 @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def classify(cls, event: NetworkFailureEvent) -> FaultDiagnosis: if not event.endpoint_id.strip(): raise ValueError("Endpoint ID is required for fault classification.") # Gate 1: Hard structural failures detected by the orthogonal probe if event.probe_result in ( ProbeResult.FIREWALL_DROP_DETECTED, ProbeResult.DNS_MISCONFIGURATION, ProbeResult.UNREACHABLE_BLACKHOLE, ): classification = FaultClassification.PERMANENT_ARCHITECTURAL_BLOCKER directive = f"HALT: Permanent blocker at {event.endpoint_id}. Probe: {event.probe_result.name}. Do not retry." # Gate 2: TLS failures are structurally permanent unless the cert rotates elif event.symptom is NetworkSymptom.TLS_HANDSHAKE_FAILED: classification = FaultClassification.PERMANENT_ARCHITECTURAL_BLOCKER directive = f"HALT: TLS handshake failed at {event.endpoint_id}. Requires manual cert inspection." # Gate 3: DNS NXDOMAIN is permanent unless routing changes elif event.symptom is NetworkSymptom.DNS_RESOLUTION_FAILURE: classification = FaultClassification.PERMANENT_ARCHITECTURAL_BLOCKER directive = f"HALT: DNS resolution failure for {event.endpoint_id}. Domain may not exist." # Gate 4: Probabilistic failures require retry exhaustion before aborting elif event.consecutive_failures < cls.RETRY_EXHAUSTION_THRESHOLD: classification = FaultClassification.UNKNOWN_REQUIRES_RETRY directive = f"RETRY: {event.consecutive_failures}/{cls.RETRY_EXHAUSTION_THRESHOLD} failures. Exponential backoff recommended." else: # We have hit the retry threshold with a transient symptom classification = FaultClassification.PERMANENT_ARCHITECTURAL_BLOCKER directive = f"HALT: Exhausted {cls.RETRY_EXHAUSTION_THRESHOLD} retries at {event.endpoint_id}. Unexplained connectivity failure." digest_payload = { "endpoint": event.endpoint_id, "symptom": event.symptom.name, "probe": event.probe_result.name, "classification": classification.name, } digest = cls._hash( json.dumps(digest_payload, sort_keys=True, separators=(",", ":")) ) return FaultDiagnosis( classification=classification, escalation_directive=directive, diagnosis_digest=digest, )