# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-ontology-versioning-invariants-must-survive-when-agents-exchange-structured-knowledge.md # Remnant Warrant: https://corpusfetch.com/c/what-ontology-versioning-invariants-must-survive-when-agents-exchange-structured-knowledge.warrant.json # Markdown SHA-256: a4a7360358ce62723fbf5d1d33e4a23d7b29760419ae58a9c067c78b33f3036a # Code AST SHA-256: 0834f7bbe62945fd56ec86ca2587cc640fe615299eb40bb06e010bb62a536c49 # Verified Classes: OntologyVerdict, OntologyConcept, OntologyExchange, OntologyPolicy, OntologyManifest, OntologyVersioningGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class OntologyVerdict(Enum): SAME_VERSION = auto() COMPATIBLE_TRANSLATION = auto() INCOMPATIBLE_CONCEPT = auto() NO_MAPPING = auto() @dataclass(frozen=True) class OntologyConcept: concept_id: str version: str definition_hash: str constraints_hash: str @dataclass(frozen=True) class OntologyExchange: sender_concept: OntologyConcept receiver_version: str mapping_available: bool concept_deprecated_in_receiver: bool @dataclass(frozen=True) class OntologyPolicy: require_mapping: bool allow_deprecated: bool @dataclass(frozen=True) class OntologyManifest: verdict: OntologyVerdict directive: str manifest_digest: str class OntologyVersioningGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_exchange( cls, exchange: OntologyExchange, policy: OntologyPolicy ) -> OntologyManifest: # Gate 1: Same version if exchange.sender_concept.version == exchange.receiver_version: digest = cls._hash(json.dumps({ "concept": exchange.sender_concept.concept_id, "version": exchange.receiver_version }, sort_keys=True)) return OntologyManifest( verdict=OntologyVerdict.SAME_VERSION, directive=f"PROCEED: Same ontology version for {exchange.sender_concept.concept_id}.", manifest_digest=digest ) # Gate 2: Mapping availability if policy.require_mapping and not exchange.mapping_available: return OntologyManifest( verdict=OntologyVerdict.NO_MAPPING, directive=f"HALT: No mapping from {exchange.sender_concept.version} to {exchange.receiver_version}.", manifest_digest=cls._hash(f"NO_MAPPING:{exchange.sender_concept.concept_id}") ) # Gate 3: Deprecation if exchange.concept_deprecated_in_receiver and not policy.allow_deprecated: return OntologyManifest( verdict=OntologyVerdict.INCOMPATIBLE_CONCEPT, directive=f"HALT: Concept {exchange.sender_concept.concept_id} deprecated in receiver version.", manifest_digest=cls._hash(f"DEPRECATED:{exchange.sender_concept.concept_id}") ) # Gate 4: Translation digest = cls._hash(json.dumps({ "concept": exchange.sender_concept.concept_id, "from_version": exchange.sender_concept.version, "to_version": exchange.receiver_version, "definition": exchange.sender_concept.definition_hash, "constraints": exchange.sender_concept.constraints_hash }, sort_keys=True)) return OntologyManifest( verdict=OntologyVerdict.COMPATIBLE_TRANSLATION, directive=f"PROCEED: Translated {exchange.sender_concept.concept_id} from {exchange.sender_concept.version} to {exchange.receiver_version}.", manifest_digest=digest )