# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-message-serialization-formats-must-be-chosen-to-prevent-schema-drift-during-inter-agent-streaming-communication.md # Remnant Warrant: https://corpusfetch.com/c/what-message-serialization-formats-must-be-chosen-to-prevent-schema-drift-during-inter-agent-streaming-communication.warrant.json # Markdown SHA-256: 5c90d9b56570ec007891aafea125d7d5e44ec69c6423d6e3bc3c46f46c66b5a5 # Code AST SHA-256: 81b35af32c8add044b20587d3e1eaeef9af041511f87bb3125feba3d3ecbbc31 # Verified Classes: SerializationVerdict, StreamMessage, ConsumerSchema, SerializationManifest, SchemaContractGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class SerializationVerdict(Enum): SCHEMA_COMPATIBLE = auto() SCHEMA_DRIFT_REJECTED = auto() MISSING_SCHEMA = auto() @dataclass(frozen=True) class StreamMessage: payload_hash: str schema_version_hash: str schema_registry_id: str @dataclass(frozen=True) class ConsumerSchema: expected_schema_hash: str schema_registry_id: str forward_compatible: bool @dataclass(frozen=True) class SerializationManifest: verdict: SerializationVerdict directive: str manifest_digest: str class SchemaContractGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_message( cls, message: StreamMessage, schema: ConsumerSchema ) -> SerializationManifest: # Gate 1: Schema presence if not message.schema_version_hash or not message.schema_registry_id: return SerializationManifest( verdict=SerializationVerdict.MISSING_SCHEMA, directive="HALT: Message lacks schema version or registry ID. Route to DLQ.", manifest_digest=cls._hash("NO_SCHEMA") ) # Gate 2: Registry mismatch if message.schema_registry_id != schema.schema_registry_id: return SerializationManifest( verdict=SerializationVerdict.SCHEMA_DRIFT_REJECTED, directive=f"HALT: Registry ID {message.schema_registry_id} != {schema.schema_registry_id}.", manifest_digest=cls._hash(f"REGISTRY_MISMATCH") ) # Gate 3: Schema hash mismatch if message.schema_version_hash != schema.expected_schema_hash: if not schema.forward_compatible: return SerializationManifest( verdict=SerializationVerdict.SCHEMA_DRIFT_REJECTED, directive=f"HALT: Schema hash mismatch. Forward compatibility disabled.", manifest_digest=cls._hash(f"DRIFT:{message.schema_version_hash}") ) # Gate 4: Compatible digest = cls._hash(json.dumps({ "payload": message.payload_hash, "schema": message.schema_version_hash, "registry": message.schema_registry_id }, sort_keys=True)) return SerializationManifest( verdict=SerializationVerdict.SCHEMA_COMPATIBLE, directive="PROCEED: Message schema is compatible with consumer expectations.", manifest_digest=digest )