# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/how-should-agents-communicate-model-confidence-decay-over-a-long-running-session.md # Remnant Warrant: https://corpusfetch.com/c/how-should-agents-communicate-model-confidence-decay-over-a-long-running-session.warrant.json # Markdown SHA-256: 430019637d42e4eac264ad6863c62e7866898fdc17a9c235bcbe983172ad8744 # Code AST SHA-256: f051fd884776b7064eaeb8fa5c437fb54302fcdee38ef36b96931d2441a136a1 # Verified Classes: DecayVerdict, ModelOutputConfidence, ConfidencePolicy, ConfidenceDecayManifest, ConfidenceDecayGuard # Defensive Guards: 1 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json import math class DecayVerdict(Enum): CONFIDENCE_FRESH = auto() CONFIDENCE_DECAYED = auto() CONFIDENCE_EXPIRED = auto() @dataclass(frozen=True) class ModelOutputConfidence: output_hash: str initial_confidence: float generation_epoch: float decay_half_life_sec: float context_drift_score: float # 0.0 = no drift, 1.0 = severe drift calibration_refreshed_epoch: float | None @dataclass(frozen=True) class ConfidencePolicy: current_epoch: float min_acceptable_confidence: float @dataclass(frozen=True) class ConfidenceDecayManifest: verdict: DecayVerdict effective_confidence: float directive: str manifest_digest: str class ConfidenceDecayGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_confidence( cls, output: ModelOutputConfidence, policy: ConfidencePolicy ) -> ConfidenceDecayManifest: # Gate 1: Calibration refreshed (reset to initial confidence) if output.calibration_refreshed_epoch and output.calibration_refreshed_epoch >= output.generation_epoch: return ConfidenceDecayManifest( verdict=DecayVerdict.CONFIDENCE_FRESH, effective_confidence=output.initial_confidence, directive="PROCEED: Calibration refreshed. Confidence reset to initial value.", manifest_digest=cls._hash(f"FRESH:{output.output_hash}") ) # Gate 2: Compute time-based decay age_sec = policy.current_epoch - output.generation_epoch if output.decay_half_life_sec <= 0: raise ValueError("Decay half-life must be positive.") time_decay_factor = 0.5 ** (age_sec / output.decay_half_life_sec) # Gate 3: Apply context drift penalty context_factor = 1.0 - min(1.0, output.context_drift_score) effective = output.initial_confidence * time_decay_factor * context_factor # Gate 4: Threshold check if effective < policy.min_acceptable_confidence: return ConfidenceDecayManifest( verdict=DecayVerdict.CONFIDENCE_EXPIRED, effective_confidence=effective, directive=f"HALT: Effective confidence {effective:.3f} below minimum {policy.min_acceptable_confidence}. Re-derive output.", manifest_digest=cls._hash(f"EXPIRED:{output.output_hash}") ) digest = cls._hash(json.dumps({ "output": output.output_hash, "initial": str(output.initial_confidence), "effective": f"{effective:.4f}", "age_sec": f"{age_sec:.0f}", "context_drift": str(output.context_drift_score) }, sort_keys=True)) return ConfidenceDecayManifest( verdict=DecayVerdict.CONFIDENCE_DECAYED, effective_confidence=effective, directive=f"PROCEED: Confidence decayed to {effective:.3f} due to time and context drift.", manifest_digest=digest )