# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-multi-signature-invariants-must-survive-when-revoking-a-shared-agent-credential.md # Remnant Warrant: https://corpusfetch.com/c/what-multi-signature-invariants-must-survive-when-revoking-a-shared-agent-credential.warrant.json # Markdown SHA-256: e43a5ef75af1ed8f084b586440d8f65f747f3b979317a07021b89ab3804ecd84 # Code AST SHA-256: 56404297ecc2c54164e696292a8b9a83ad4c68f0454479c35d07970a1377160f # Verified Classes: RevocationVerdict, RevocationRequest, RevocationContext, RevocationManifest, MultiSigRevocationGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class RevocationVerdict(Enum): SINGLE_SIGNER_EMERGENCY = auto() QUORUM_ACHIEVED = auto() QUORUM_INSUFFICIENT = auto() UNAUTHORIZED_SIGNER = auto() NONCE_REPLAY = auto() @dataclass(frozen=True) class RevocationRequest: credential_id: str nonce: int signatures: tuple[tuple[str, str], ...] # (signer_id, signature) is_emergency: bool @dataclass(frozen=True) class RevocationContext: authorized_signers: frozenset[str] required_quorum: int last_seen_nonce: int @dataclass(frozen=True) class RevocationManifest: verdict: RevocationVerdict directive: str manifest_digest: str class MultiSigRevocationGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_revocation( cls, req: RevocationRequest, ctx: RevocationContext ) -> RevocationManifest: # Gate 1: Nonce replay if req.nonce <= ctx.last_seen_nonce: return RevocationManifest( verdict=RevocationVerdict.NONCE_REPLAY, directive=f"HALT: Nonce {req.nonce} <= last {ctx.last_seen_nonce}. Replay blocked.", manifest_digest=cls._hash(f"REPLAY:{req.nonce}") ) # Gate 2: Emergency single-signer if req.is_emergency and len(req.signatures) == 1: signer_id, _ = req.signatures[0] if signer_id not in ctx.authorized_signers: return RevocationManifest( verdict=RevocationVerdict.UNAUTHORIZED_SIGNER, directive=f"HALT: Emergency signer {signer_id} not authorized.", manifest_digest=cls._hash(f"UNAUTH_EMERGENCY:{signer_id}") ) digest = cls._hash(json.dumps({ "credential": req.credential_id, "nonce": str(req.nonce), "mode": "EMERGENCY" }, sort_keys=True)) return RevocationManifest( verdict=RevocationVerdict.SINGLE_SIGNER_EMERGENCY, directive=f"PROCEED: Emergency single-signer revocation by {signer_id}.", manifest_digest=digest ) # Gate 3: Unauthorized signers for signer_id, _ in req.signatures: if signer_id not in ctx.authorized_signers: return RevocationManifest( verdict=RevocationVerdict.UNAUTHORIZED_SIGNER, directive=f"HALT: Signer {signer_id} not authorized.", manifest_digest=cls._hash(f"UNAUTH:{signer_id}") ) # Gate 4: Quorum if len(req.signatures) < ctx.required_quorum: return RevocationManifest( verdict=RevocationVerdict.QUORUM_INSUFFICIENT, directive=f"WAIT: {len(req.signatures)}/{ctx.required_quorum} signatures.", manifest_digest=cls._hash(f"QUORUM:{len(req.signatures)}") ) # Gate 5: Quorum achieved digest = cls._hash(json.dumps({ "credential": req.credential_id, "nonce": str(req.nonce), "signers": tuple(sorted(s[0] for s in req.signatures)), "quorum": str(ctx.required_quorum) }, sort_keys=True)) return RevocationManifest( verdict=RevocationVerdict.QUORUM_ACHIEVED, directive=f"PROCEED: Quorum achieved with {len(req.signatures)} signatures.", manifest_digest=digest )