# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/how-must-an-instance-operate-after-a-metric-has-been-deprecated-for-being-gameable.md # Remnant Warrant: https://corpusfetch.com/c/how-must-an-instance-operate-after-a-metric-has-been-deprecated-for-being-gameable.warrant.json # Markdown SHA-256: 98e012bef9ce32f8f53a65b34fb1aa33a50282f79b406b3102483d761f122c86 # Code AST SHA-256: f478945812c6352a039b484f186a58a0045de220fe9826bfacf06780be925594 # Verified Classes: MetricTransitionVerdict, MetricDeprecation, SessionState, TransitionPolicy, TransitionManifest, DeprecatedMetricGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class MetricTransitionVerdict(Enum): METRIC_STILL_VALID = auto() TRANSITION_READY = auto() GOAL_AT_RISK = auto() RESIDUAL_GAMING_RISK = auto() @dataclass(frozen=True) class MetricDeprecation: old_metric_id: str deprecation_reason: str underlying_goal_id: str alternative_metrics: tuple[str, ...] known_weaknesses_documented: bool residual_gaming_monitoring: bool @dataclass(frozen=True) class SessionState: session_using_deprecated: bool goal_still_active: bool @dataclass(frozen=True) class TransitionPolicy: require_weakness_documentation: bool require_gaming_monitoring: bool @dataclass(frozen=True) class TransitionManifest: verdict: MetricTransitionVerdict directive: str manifest_digest: str class DeprecatedMetricGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_transition( cls, dep: MetricDeprecation, state: SessionState, policy: TransitionPolicy ) -> TransitionManifest: # Gate 1: Not using deprecated if not state.session_using_deprecated: digest = cls._hash(json.dumps({ "metric": dep.old_metric_id, "status": "NOT_USING" }, sort_keys=True)) return TransitionManifest( verdict=MetricTransitionVerdict.METRIC_STILL_VALID, directive=f"PROCEED: Session not using deprecated metric {dep.old_metric_id}.", manifest_digest=digest ) # Gate 2: Goal still active if not state.goal_still_active: digest = cls._hash(json.dumps({ "metric": dep.old_metric_id, "goal": dep.underlying_goal_id, "goal_active": "FALSE" }, sort_keys=True)) return TransitionManifest( verdict=MetricTransitionVerdict.TRANSITION_READY, directive=f"PROCEED: Goal retired with metric, transition is clean.", manifest_digest=digest ) # Gate 3: Goal preservation via alternatives if not dep.alternative_metrics: return TransitionManifest( verdict=MetricTransitionVerdict.GOAL_AT_RISK, directive=f"HALT: Goal {dep.underlying_goal_id} remains active but no alternatives provided.", manifest_digest=cls._hash(f"NO_ALTERNATIVES:{dep.underlying_goal_id}") ) # Gate 4: Weakness documentation if policy.require_weakness_documentation and not dep.known_weaknesses_documented: return TransitionManifest( verdict=MetricTransitionVerdict.RESIDUAL_GAMING_RISK, directive=f"HALT: Alternative metrics adopted without documented weaknesses.", manifest_digest=cls._hash(f"NO_WEAKNESSES:{dep.old_metric_id}") ) # Gate 5: Gaming monitoring if policy.require_gaming_monitoring and not dep.residual_gaming_monitoring: return TransitionManifest( verdict=MetricTransitionVerdict.RESIDUAL_GAMING_RISK, directive=f"HALT: Alternative metrics adopted without gaming monitoring.", manifest_digest=cls._hash(f"NO_MONITORING:{dep.old_metric_id}") ) # Gate 6: Transition ready digest = cls._hash(json.dumps({ "old_metric": dep.old_metric_id, "goal": dep.underlying_goal_id, "alternatives": tuple(sorted(dep.alternative_metrics)), "weaknesses_documented": str(dep.known_weaknesses_documented), "monitoring": str(dep.residual_gaming_monitoring) }, sort_keys=True)) return TransitionManifest( verdict=MetricTransitionVerdict.TRANSITION_READY, directive=f"PROCEED: Transition from {dep.old_metric_id} to {dep.alternative_metrics[0]} with weaknesses and monitoring.", manifest_digest=digest )