# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/how-must-an-instance-handle-cascading-reference-updates-without-inconsistent-intermediate-states.md # Remnant Warrant: https://corpusfetch.com/c/how-must-an-instance-handle-cascading-reference-updates-without-inconsistent-intermediate-states.warrant.json # Markdown SHA-256: 2c6303be27370a32881919d00af7510620abd837b371cfc1dd1ae663fca5c751 # Code AST SHA-256: 4ddf7e3bc5fd6bafc6a5907c884430827c8211077194476ec1c30b8308fe8447 # Verified Classes: CascadeVerdict, CascadeState, CascadePolicy, CascadeManifest, CascadingReferenceGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class CascadeVerdict(Enum): NOT_A_CASCADE = auto() CASCADE_COMMITTED = auto() CASCADE_IN_PROGRESS = auto() CASCADE_UNTRACKED = auto() @dataclass(frozen=True) class CascadeState: cascade_id: str pre_cascade_snapshot: str | None commit_marker_received: bool references_updated: int references_total: int consumer_follows_protocol: bool @dataclass(frozen=True) class CascadePolicy: require_snapshot: bool require_commit_marker: bool @dataclass(frozen=True) class CascadeManifest: verdict: CascadeVerdict directive: str manifest_digest: str class CascadingReferenceGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_cascade( cls, state: CascadeState, policy: CascadePolicy ) -> CascadeManifest: # Gate 1: Not a cascade if state.references_total <= 1: digest = cls._hash(json.dumps({ "cascade": state.cascade_id, "type": "SINGLE_REFERENCE" }, sort_keys=True)) return CascadeManifest( verdict=CascadeVerdict.NOT_A_CASCADE, directive=f"PROCEED: Single reference update, no cascade.", manifest_digest=digest ) # Gate 2: Snapshot requirement if policy.require_snapshot and not state.pre_cascade_snapshot: return CascadeManifest( verdict=CascadeVerdict.CASCADE_UNTRACKED, directive=f"HALT: Cascade {state.cascade_id} lacks pre-cascade snapshot. Rollback impossible.", manifest_digest=cls._hash(f"NO_SNAPSHOT:{state.cascade_id}") ) # Gate 3: Commit marker if state.commit_marker_received: digest = cls._hash(json.dumps({ "cascade": state.cascade_id, "updated": str(state.references_updated), "total": str(state.references_total), "snapshot": state.pre_cascade_snapshot }, sort_keys=True)) return CascadeManifest( verdict=CascadeVerdict.CASCADE_COMMITTED, directive=f"PROCEED: Cascade {state.cascade_id} committed ({state.references_updated}/{state.references_total}).", manifest_digest=digest ) # Gate 4: In progress if policy.require_commit_marker: if state.consumer_follows_protocol: digest = cls._hash(json.dumps({ "cascade": state.cascade_id, "status": "IN_PROGRESS", "progress": f"{state.references_updated}/{state.references_total}" }, sort_keys=True)) return CascadeManifest( verdict=CascadeVerdict.CASCADE_IN_PROGRESS, directive=f"PROCEED: Cascade in progress, consumer follows observer protocol.", manifest_digest=digest ) return CascadeManifest( verdict=CascadeVerdict.CASCADE_IN_PROGRESS, directive=f"HALT: Cascade in progress, consumer not following observer protocol.", manifest_digest=cls._hash(f"PROTOCOL_VIOLATION:{state.cascade_id}") ) # Gate 5: Default return CascadeManifest( verdict=CascadeVerdict.CASCADE_IN_PROGRESS, directive=f"WAIT: Cascade {state.cascade_id} in progress.", manifest_digest=cls._hash(f"IN_PROGRESS:{state.cascade_id}") )