# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/how-must-an-instance-record-training-data-provenance-to-detect-silent-model-degradation-across-restarts.md # Remnant Warrant: https://corpusfetch.com/c/how-must-an-instance-record-training-data-provenance-to-detect-silent-model-degradation-across-restarts.warrant.json # Markdown SHA-256: 75f87a1d04107a5b0b5813fee44ecfa3651f71eb49f8a3c3fe30f88722c33ca4 # Code AST SHA-256: 088ccde79427e824bdab5ec6df7d9373aa397752e49dfccd2e41bfca98e1373f # Verified Classes: ModelDriftVerdict, ModelProvenance, CurrentModelState, ModelManifest, ModelProvenanceGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class ModelDriftVerdict(Enum): STABLE = auto() BEHAVIORAL_DRIFT = auto() UNVERIFIABLE = auto() @dataclass(frozen=True) class ModelProvenance: weights_hash: str training_cutoff_epoch: int canary_prompt: str canary_output_hash: str @dataclass(frozen=True) class CurrentModelState: current_weights_hash: str current_canary_output_hash: str @dataclass(frozen=True) class ModelManifest: verdict: ModelDriftVerdict directive: str manifest_digest: str class ModelProvenanceGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_drift( cls, saved: ModelProvenance, current: CurrentModelState ) -> ModelManifest: # Gate 1: Weights hash mismatch (unverified model) if saved.weights_hash != current.current_weights_hash: return ModelManifest( verdict=ModelDriftVerdict.UNVERIFIABLE, directive=f"HALT: Weights hash mismatch. Expected {saved.weights_hash}, got {current.current_weights_hash}.", manifest_digest=cls._hash("WEIGHT_MISMATCH") ) # Gate 2: Behavioral drift (same weights, different output) if saved.canary_output_hash != current.current_canary_output_hash: return ModelManifest( verdict=ModelDriftVerdict.BEHAVIORAL_DRIFT, directive=f"HALT: Canary output drifted. Model behavior changed.", manifest_digest=cls._hash("BEHAVIORAL_DRIFT") ) # Gate 3: Stable digest = cls._hash(json.dumps({"weights": saved.weights_hash, "canary": saved.canary_output_hash}, sort_keys=True)) return ModelManifest( verdict=ModelDriftVerdict.STABLE, directive="PROCEED: Model provenance and behavior verified.", manifest_digest=digest )