146 lines
8.9 KiB
Python
146 lines
8.9 KiB
Python
"""In-memory coordinator for one approved impl mutation attempt.
|
|
|
|
Trusted adapter seam only; not a durable transaction or cross-process lock.
|
|
"""
|
|
from __future__ import annotations
|
|
import hashlib, json, re, copy, threading
|
|
from dataclasses import dataclass
|
|
from typing import Any, Callable
|
|
|
|
_HEX40 = re.compile(r"^[0-9a-f]{40}$")
|
|
_HEX64 = re.compile(r"^[0-9a-f]{64}$")
|
|
_OPERATIONS = {"push", "pr.create", "pr.patch", "comment.create", "comment.patch", "correction"}
|
|
|
|
def _json(value: Any) -> bytes:
|
|
try: raw = json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False, allow_nan=False).encode()
|
|
except (TypeError, ValueError, RecursionError) as exc: raise ValueError("data must be finite JSON-safe values") from exc
|
|
if len(raw) > 65536: raise ValueError("data exceeds 64 KiB")
|
|
return raw
|
|
|
|
def _digest(value: Any) -> str: return hashlib.sha256(_json(value)).hexdigest()
|
|
|
|
@dataclass(frozen=True)
|
|
class Intent:
|
|
version: str
|
|
operation: str
|
|
target: str
|
|
target_id: int
|
|
source_sha: str
|
|
payload: Any
|
|
@property
|
|
def digest(self) -> str: return _digest(self.as_dict())
|
|
def as_dict(self) -> dict[str, Any]:
|
|
return {"version":self.version,"operation":self.operation,"target":self.target,"target_id":self.target_id,"source_sha":self.source_sha,"payload":self.payload}
|
|
|
|
@dataclass(frozen=True)
|
|
class Approval:
|
|
version: str
|
|
intent_digest: str
|
|
status: str
|
|
correction: bool = False
|
|
ordinary_patch: bool = False
|
|
|
|
@dataclass
|
|
class Adapter:
|
|
preflight: Callable[[Intent], Any]
|
|
capability: Any
|
|
mutate: Callable[[Intent], Any]
|
|
readback: Callable[[Intent], Any]
|
|
verify: Callable[[Intent, Any, Any], Any]
|
|
|
|
@dataclass(frozen=True)
|
|
class Result:
|
|
status: str
|
|
intent_digest: str
|
|
snapshot_digest: str | None
|
|
attempt_digest: str | None
|
|
observed_digest: str | None
|
|
assurance: dict[str, Any]
|
|
reason: str
|
|
|
|
class UncertainAcknowledgement(Exception):
|
|
"""Write may have been accepted despite lost acknowledgement."""
|
|
|
|
def validate(intent: Intent, approval: Approval) -> Intent:
|
|
if not isinstance(intent, Intent) or type(intent.version) is not str or intent.version != "v1" or type(intent.operation) is not str or intent.operation not in _OPERATIONS: raise ValueError("unsupported intent schema or operation")
|
|
if not isinstance(intent.target,str) or not re.fullmatch(r"[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+",intent.target) or any(part in (".", "..") for part in intent.target.split("/")): raise ValueError("invalid target")
|
|
if type(intent.target_id) is not int or intent.target_id <= 0: raise ValueError("invalid target id")
|
|
if type(intent.source_sha) is not str or not _HEX40.fullmatch(intent.source_sha): raise ValueError("source_sha must be full lowercase SHA-1")
|
|
_json(intent.payload)
|
|
if not isinstance(approval,Approval) or type(approval.version) is not str or approval.version!="v1" or type(approval.status) is not str or approval.status!="approved": raise ValueError("valid versioned approval required")
|
|
if not isinstance(approval.intent_digest,str) or not _HEX64.fullmatch(approval.intent_digest) or approval.intent_digest!=intent.digest: raise ValueError("approval is not bound to intent")
|
|
if type(approval.correction) is not bool or type(approval.ordinary_patch) is not bool: raise ValueError("approval flags must be booleans")
|
|
if intent.operation=="correction" and not approval.correction: raise ValueError("separate correction approval required")
|
|
return intent
|
|
|
|
class Coordinator:
|
|
def __init__(self):
|
|
self._consumed: set[str] = set()
|
|
self._reservation_lock = threading.Lock()
|
|
|
|
def _reserve(self, digest: str) -> bool:
|
|
with self._reservation_lock:
|
|
if digest in self._consumed:
|
|
return False
|
|
self._consumed.add(digest)
|
|
return True
|
|
def execute(self,intent:Intent,approval:Approval,adapter:Adapter,on_attempt:Callable[[dict[str,Any]],Any]|None=None)->Result:
|
|
assurance={"durable_at_most_once":False,"atomic_client_precondition":None,"residual_race":None,"trusted_adapter_contract":True}
|
|
try:
|
|
validate(intent,approval)
|
|
digest=intent.digest
|
|
authoritative=copy.deepcopy(intent.as_dict())
|
|
approved_digest=_digest(authoritative)
|
|
except Exception as exc:
|
|
return Result("partial","",None,None,None,assurance,f"invalid intent or approval: {type(exc).__name__}")
|
|
if on_attempt is not None and not callable(on_attempt): return Result("partial",digest,None,None,None,assurance,"attempt callback is not callable")
|
|
if digest in self._consumed: return Result("partial",digest,None,None,None,assurance,"attempt authority already consumed")
|
|
fields=("preflight","mutate","readback","verify")
|
|
if not isinstance(adapter,Adapter) or any(not callable(getattr(adapter,n,None)) for n in fields): return Result("partial",digest,None,None,None,assurance,"trusted adapter incomplete")
|
|
if intent.operation=="correction":
|
|
if adapter.capability is True: assurance["atomic_client_precondition"]=True
|
|
elif adapter.capability=="ordinary_patch" and approval.ordinary_patch:
|
|
assurance["atomic_client_precondition"]=False; assurance["residual_race"]="ordinary PATCH has read/write race; lease is not provider CAS"
|
|
else: return Result("partial",digest,None,None,None,assurance,"unsupported correction capability")
|
|
elif adapter.capability is not True: return Result("partial",digest,None,None,None,assurance,"unsupported capability")
|
|
# Reserve authority before invoking any trusted callback. A preflight can
|
|
# re-enter this coordinator; reserving only at mutate would allow two writes.
|
|
if not self._reserve(digest):
|
|
return Result("partial",digest,None,None,None,assurance,"attempt authority already consumed")
|
|
try:
|
|
pre=adapter.preflight(Intent(**copy.deepcopy(authoritative)))
|
|
pre_snapshot=copy.deepcopy(pre); snap=_digest(pre_snapshot)
|
|
if not isinstance(pre_snapshot,dict) or pre_snapshot.get("fresh") is not True: return Result("partial",digest,snap,None,None,assurance,"stale or invalid preflight")
|
|
except Exception as exc: return Result("partial",digest,None,None,None,assurance,f"preflight failed: {type(exc).__name__}")
|
|
# Callbacks receive disposable copies; the approved canonical form is authoritative.
|
|
attempt={"intent_digest":digest,"snapshot_digest":snap,"state":"attempted"}
|
|
self._consumed.add(digest)
|
|
if on_attempt is not None:
|
|
try: on_attempt(copy.deepcopy(attempt))
|
|
except Exception as exc: return Result("partial",digest,snap,_digest(attempt),None,assurance,f"attempt record failed: {type(exc).__name__}")
|
|
try:
|
|
validate(intent,approval)
|
|
if _digest(intent.as_dict()) != approved_digest: return Result("partial",digest,snap,None,None,assurance,"intent changed after approval")
|
|
except Exception as exc: return Result("partial",digest,snap,None,None,assurance,f"intent changed after approval: {type(exc).__name__}")
|
|
stable_intent=Intent(**copy.deepcopy(authoritative))
|
|
try: mutation=adapter.mutate(stable_intent)
|
|
except UncertainAcknowledgement: mutation={"acknowledgement":"uncertain"}
|
|
except Exception as exc: mutation={"acknowledgement":"failed","error":type(exc).__name__}
|
|
safe_mutation = mutation if _safe_ack(mutation) else {"acknowledgement":"unserializable-or-oversized"}
|
|
uncertain=isinstance(mutation,dict) and mutation.get("acknowledgement")=="uncertain"
|
|
try: observed=adapter.readback(Intent(**copy.deepcopy(authoritative))); observed_digest=_digest(observed)
|
|
except Exception as exc: return Result("partial",digest,snap,_digest({**attempt,"mutation":safe_mutation}),None,assurance,f"readback failed: {type(exc).__name__}")
|
|
try: verified=adapter.verify(Intent(**copy.deepcopy(authoritative)),copy.deepcopy(pre_snapshot),copy.deepcopy(observed))
|
|
except Exception as exc: return Result("partial",digest,snap,_digest({**attempt,"mutation":safe_mutation}),observed_digest,assurance,f"verification failed: {type(exc).__name__}")
|
|
if verified is not True: return Result("partial",digest,snap,_digest({**attempt,"mutation":safe_mutation}),observed_digest,assurance,"trusted adapter verification incomplete")
|
|
return Result("verified",digest,snap,_digest({**attempt,"mutation":safe_mutation,"uncertain_ack":uncertain}),observed_digest,assurance,"verified by trusted adapter readback")
|
|
|
|
def _safe_ack(value: Any) -> bool:
|
|
try: _json(value); return True
|
|
except Exception: return False
|
|
|
|
_DEFAULT_COORDINATOR=Coordinator()
|
|
def execute(intent:Intent,approval:Approval,adapter:Adapter,on_attempt:Callable[[dict[str,Any]],Any]|None=None)->Result:
|
|
"""Deprecated process-local compatibility wrapper; reuse is guarded within process."""
|
|
return _DEFAULT_COORDINATOR.execute(intent,approval,adapter,on_attempt)
|