refactor: unify impl operation gates and correction verification
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user