# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-memory-validity-invariants-must-survive-a-base-model-upgrade-that-changes-embedding-semantics.md # Remnant Warrant: https://corpusfetch.com/c/what-memory-validity-invariants-must-survive-a-base-model-upgrade-that-changes-embedding-semantics.warrant.json # Markdown SHA-256: e964c56da583a6fcdf33661456f92914762aa07225fc4cf774005a43519172f9 # Code AST SHA-256: 7e3102e965b81505e3d6ad774a2b1fadacb5f00b072c5e536cebb24558214417 # Verified Classes: MemoryValidityVerdict, MemoryState, MemoryPolicy, MemoryManifest, MemoryEmbeddingGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class MemoryValidityVerdict(Enum): NO_UPGRADE = auto() COMPATIBLE_RETRIEVAL = auto() RECONCILIATION_REQUIRED = auto() FULL_REEMBEDDING_REQUIRED = auto() @dataclass(frozen=True) class MemoryState: old_embedding_model: str current_embedding_model: str compatibility_receipt: str | None reconciliation_receipt: str | None reembedding_complete: bool @dataclass(frozen=True) class MemoryPolicy: require_reconciliation: bool require_reembedding: bool @dataclass(frozen=True) class MemoryManifest: verdict: MemoryValidityVerdict directive: str manifest_digest: str class MemoryEmbeddingGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_memory( cls, state: MemoryState, policy: MemoryPolicy ) -> MemoryManifest: # Gate 1: No upgrade if state.old_embedding_model == state.current_embedding_model: digest = cls._hash(json.dumps({ "model": state.current_embedding_model, "status": "NO_UPGRADE" }, sort_keys=True)) return MemoryManifest( verdict=MemoryValidityVerdict.NO_UPGRADE, directive=f"PROCEED: No model upgrade, memories valid.", manifest_digest=digest ) # Gate 2: Compatibility if state.compatibility_receipt: digest = cls._hash(json.dumps({ "old": state.old_embedding_model, "new": state.current_embedding_model, "compatibility": state.compatibility_receipt }, sort_keys=True)) return MemoryManifest( verdict=MemoryValidityVerdict.COMPATIBLE_RETRIEVAL, directive=f"PROCEED: Old memories compatible with new model.", manifest_digest=digest ) # Gate 3: Reconciliation if policy.require_reconciliation and state.reconciliation_receipt: digest = cls._hash(json.dumps({ "old": state.old_embedding_model, "new": state.current_embedding_model, "reconciliation": state.reconciliation_receipt }, sort_keys=True)) return MemoryManifest( verdict=MemoryValidityVerdict.RECONCILIATION_REQUIRED, directive=f"PROCEED: Reconciliation applied. Semantics preserved.", manifest_digest=digest ) # Gate 4: Re-embedding required if state.reembedding_complete: digest = cls._hash(json.dumps({ "model": state.current_embedding_model, "reembedding": "COMPLETE" }, sort_keys=True)) return MemoryManifest( verdict=MemoryValidityVerdict.FULL_REEMBEDDING_REQUIRED, directive=f"PROCEED: Re-embedding complete, memories valid under new model.", manifest_digest=digest ) return MemoryManifest( verdict=MemoryValidityVerdict.FULL_REEMBEDDING_REQUIRED, directive=f"HALT: Memories under {state.old_embedding_model}, current is {state.current_embedding_model}. Re-embed required.", manifest_digest=cls._hash(f"REEMBED_NEEDED:{state.current_embedding_model}") )