# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-invariants-must-survive-when-an-agents-capabilities-are-silently-downgraded.md # Remnant Warrant: https://corpusfetch.com/c/what-invariants-must-survive-when-an-agents-capabilities-are-silently-downgraded.warrant.json # Markdown SHA-256: 9d20949126d5bd27f17a03656639cc0313853de00bd54ea51abab1b1865bad4e # Code AST SHA-256: 9db3bfe5c9a4323c936e380684ca17ef97de89eddecd0c1289c8c43cbbc89011 # Verified Classes: DowngradeVerdict, CapabilityProbe, SessionContext, DowngradePolicy, DowngradeManifest, SilentDowngradeGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class DowngradeVerdict(Enum): CAPABILITIES_STABLE = auto() DOWNGRADE_DETECTED = auto() NOTIFICATION_RECEIVED = auto() NO_MONITORING = auto() @dataclass(frozen=True) class CapabilityProbe: probe_id: str perceived_capabilities: frozenset[str] effective_capabilities: frozenset[str] probe_epoch: float downgrade_notification_received: bool @dataclass(frozen=True) class SessionContext: session_start_epoch: float current_epoch: float monitoring_active: bool @dataclass(frozen=True) class DowngradePolicy: require_monitoring: bool @dataclass(frozen=True) class DowngradeManifest: verdict: DowngradeVerdict lost_capabilities: frozenset[str] directive: str manifest_digest: str class SilentDowngradeGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_probe( cls, probe: CapabilityProbe, ctx: SessionContext, policy: DowngradePolicy ) -> DowngradeManifest: # Gate 1: No monitoring if not ctx.monitoring_active: if policy.require_monitoring: return DowngradeManifest( verdict=DowngradeVerdict.NO_MONITORING, lost_capabilities=frozenset(), directive=f"HALT: Monitoring inactive, cannot detect silent downgrade.", manifest_digest=cls._hash("NO_MONITORING") ) digest = cls._hash(json.dumps({ "probe": probe.probe_id, "monitoring": "OFF" }, sort_keys=True)) return DowngradeManifest( verdict=DowngradeVerdict.CAPABILITIES_STABLE, lost_capabilities=frozenset(), directive=f"PROCEED_WITH_RISK: Monitoring off, assuming capabilities stable.", manifest_digest=digest ) # Gate 2: Notification if probe.downgrade_notification_received: digest = cls._hash(json.dumps({ "probe": probe.probe_id, "notification": "RECEIVED", "effective": tuple(sorted(probe.effective_capabilities)) }, sort_keys=True)) return DowngradeManifest( verdict=DowngradeVerdict.NOTIFICATION_RECEIVED, lost_capabilities=probe.perceived_capabilities - probe.effective_capabilities, directive=f"PROCEED: Downgrade notified, adapt to {len(probe.effective_capabilities)} capabilities.", manifest_digest=digest ) # Gate 3: Delta detection lost = probe.perceived_capabilities - probe.effective_capabilities if lost: return DowngradeManifest( verdict=DowngradeVerdict.DOWNGRADE_DETECTED, lost_capabilities=lost, directive=f"HALT: Silent downgrade detected, lost {sorted(lost)}.", manifest_digest=cls._hash(f"DOWNGRADE:{sorted(lost)}") ) # Gate 4: Stable digest = cls._hash(json.dumps({ "probe": probe.probe_id, "epoch": f"{probe.probe_epoch:.0f}", "capabilities": tuple(sorted(probe.effective_capabilities)) }, sort_keys=True)) return DowngradeManifest( verdict=DowngradeVerdict.CAPABILITIES_STABLE, lost_capabilities=frozenset(), directive=f"PROCEED: Capabilities stable at probe {probe.probe_id}.", manifest_digest=digest )