# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/which-schema-validation-mismatches-must-be-retained-for-future-ingestion-runs.md # Remnant Warrant: https://corpusfetch.com/c/which-schema-validation-mismatches-must-be-retained-for-future-ingestion-runs.warrant.json # Markdown SHA-256: 91b346ffa7ed9fde53457a3ae3313f35ef8b3b8aec6fac6d44d96fc28bb4281b # Code AST SHA-256: 25b1f99c6daf7573c8ba43185df648679cb058fc25000243503cceda330304fc # Verified Classes: MismatchSeverity, ValidationFailure, MismatchRecord, IngestionArchive, IngestionMismatchTracker # Defensive Guards: 2 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class MismatchSeverity(Enum): FATAL_HALT = auto() SKIP_AND_ALERT = auto() COERCIBLE = auto() @dataclass(frozen=True) class ValidationFailure: source_endpoint: str schema_path: str expected_type: str observed_type: str raw_payload_hash: str @dataclass(frozen=True) class MismatchRecord: source_endpoint: str schema_path: str expected_type: str observed_type: str severity: MismatchSeverity mitigation_directive: str @dataclass(frozen=True) class IngestionArchive: records: tuple[MismatchRecord, ...] archive_digest: str class IngestionMismatchTracker: """ Evaluates schema validation failures and seals negative constraint signatures for future ingestion runs, preventing redundant validation. """ @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def archive_failure( cls, failure: ValidationFailure, severity: MismatchSeverity, ) -> MismatchRecord: if not failure.source_endpoint.strip() or not failure.schema_path.strip(): raise ValueError("Source endpoint and schema path are required for a mismatch record.") # Derive mitigation directive based on severity if severity is MismatchSeverity.FATAL_HALT: directive = f"HALT: Schema mismatch at {failure.schema_path} from {failure.source_endpoint}" elif severity is MismatchSeverity.SKIP_AND_ALERT: directive = f"SKIP: Ignore payload from {failure.source_endpoint}, alert on {failure.schema_path}" else: directive = f"COERCE: Substitute default for {failure.schema_path}" return MismatchRecord( source_endpoint=failure.source_endpoint, schema_path=failure.schema_path, expected_type=failure.expected_type, observed_type=failure.observed_type, severity=severity, mitigation_directive=directive, ) @classmethod def build_archive( cls, records: tuple[MismatchRecord, ...] ) -> IngestionArchive: if not records: raise ValueError("Cannot build an empty ingestion archive.") digest_payload = { "records": tuple( sorted( f"{r.source_endpoint}:{r.schema_path}:{r.observed_type}" for r in records ) ) } digest = cls._hash( json.dumps(digest_payload, sort_keys=True, separators=(",", ":")) ) return IngestionArchive( records=records, archive_digest=digest, ) @classmethod def check_pre_flight( cls, archive: IngestionArchive, incoming_source: str, incoming_schema_path: str, incoming_type: str ) -> MismatchRecord | None: """ Fetching-time check: returns a matching MismatchRecord if the incoming payload matches a known failure signature, bypassing full validation. """ for record in archive.records: if ( record.source_endpoint == incoming_source and record.schema_path == incoming_schema_path and record.observed_type == incoming_type ): return record return None