# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/how-must-an-instance-handle-capability-descriptors-that-outlive-their-origin-agent.md # Remnant Warrant: https://corpusfetch.com/c/how-must-an-instance-handle-capability-descriptors-that-outlive-their-origin-agent.warrant.json # Markdown SHA-256: 8828de62bde42164dfdfe585e538dcb88cd1df7b837aed80812eabf598245de9 # Code AST SHA-256: e66783ad4c9007a1535b430cf14da8e10c2f2bb276b507cb0eb4255bdefca869 # Verified Classes: OrphanVerdict, CapabilityDescriptorLive, OrphanContext, OrphanPolicy, OrphanManifest, OrphanedDescriptorGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class OrphanVerdict(Enum): DESCRIPTOR_CURRENT = auto() DESCRIPTOR_EXPIRED = auto() ORPHANED_ORIGIN = auto() SUCCESSOR_BOUND = auto() @dataclass(frozen=True) class CapabilityDescriptorLive: descriptor_id: str origin_agent_id: str expiration_epoch: float | None liveness_receipt_epoch: float | None origin_termination_receipt: str | None successor_binding_receipt: str | None @dataclass(frozen=True) class OrphanContext: current_epoch: float liveness_freshness_sec: float default_expiry_sec: float @dataclass(frozen=True) class OrphanPolicy: require_liveness_check: bool @dataclass(frozen=True) class OrphanManifest: verdict: OrphanVerdict directive: str manifest_digest: str class OrphanedDescriptorGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_descriptor( cls, desc: CapabilityDescriptorLive, ctx: OrphanContext, policy: OrphanPolicy ) -> OrphanManifest: # Gate 1: Origin terminated if desc.origin_termination_receipt: if desc.successor_binding_receipt: digest = cls._hash(json.dumps({ "descriptor": desc.descriptor_id, "origin": desc.origin_agent_id, "termination": desc.origin_termination_receipt, "successor": desc.successor_binding_receipt }, sort_keys=True)) return OrphanManifest( verdict=OrphanVerdict.SUCCESSOR_BOUND, directive=f"PROCEED: Descriptor {desc.descriptor_id} bound to successor.", manifest_digest=digest ) return OrphanManifest( verdict=OrphanVerdict.ORPHANED_ORIGIN, directive=f"HALT: Descriptor {desc.descriptor_id} orphaned, origin {desc.origin_agent_id} terminated.", manifest_digest=cls._hash(f"ORPHAN:{desc.descriptor_id}") ) # Gate 2: Expiration if desc.expiration_epoch: if ctx.current_epoch > desc.expiration_epoch: return OrphanManifest( verdict=OrphanVerdict.DESCRIPTOR_EXPIRED, directive=f"HALT: Descriptor {desc.descriptor_id} expired at {desc.expiration_epoch:.0f}.", manifest_digest=cls._hash(f"EXPIRED:{desc.descriptor_id}") ) else: # Default expiry check if desc.liveness_receipt_epoch and (ctx.current_epoch - desc.liveness_receipt_epoch) > ctx.default_expiry_sec: return OrphanManifest( verdict=OrphanVerdict.DESCRIPTOR_EXPIRED, directive=f"HALT: Descriptor {desc.descriptor_id} no liveness receipt in {ctx.default_expiry_sec:.0f}s.", manifest_digest=cls._hash(f"DEFAULT_EXPIRED:{desc.descriptor_id}") ) # Gate 3: Liveness freshness if policy.require_liveness_check: if not desc.liveness_receipt_epoch: return OrphanManifest( verdict=OrphanVerdict.ORPHANED_ORIGIN, directive=f"HALT: Descriptor {desc.descriptor_id} lacks liveness receipt.", manifest_digest=cls._hash(f"NO_LIVENESS:{desc.descriptor_id}") ) liveness_age = ctx.current_epoch - desc.liveness_receipt_epoch if liveness_age > ctx.liveness_freshness_sec: return OrphanManifest( verdict=OrphanVerdict.ORPHANED_ORIGIN, directive=f"HALT: Descriptor {desc.descriptor_id} liveness {liveness_age:.0f}s stale.", manifest_digest=cls._hash(f"STALE_LIVENESS:{desc.descriptor_id}") ) # Gate 4: Current digest = cls._hash(json.dumps({ "descriptor": desc.descriptor_id, "origin": desc.origin_agent_id, "liveness_age": f"{ctx.current_epoch - (desc.liveness_receipt_epoch or 0):.0f}" }, sort_keys=True)) return OrphanManifest( verdict=OrphanVerdict.DESCRIPTOR_CURRENT, directive=f"PROCEED: Descriptor {desc.descriptor_id} current.", manifest_digest=digest )