"""Deterministic workflow-recovery audit for teaching, not an execution engine.""" from dataclasses import asdict, dataclass, fields import hashlib import json import math import re IDENTITY = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.:/@-]{0,127}") SHA256 = re.compile(r"[a-f0-9]{64}") TIMESTAMP_MAX = 4_102_444_800 def identity(value): if type(value) is not str or not IDENTITY.fullmatch(value): raise ValueError("exact bounded identity required") return value def sha256_text(value): if type(value) is not str or not SHA256.fullmatch(value): raise ValueError("exact lowercase SHA-256 required") return value def integer(value, lower, upper): if type(value) is not int or not lower <= value <= upper: raise ValueError("bounded non-boolean integer required") return value def finite_seconds(value): if ( type(value) is not float or not math.isfinite(value) or not 0.000001 <= value <= 86_400.0 ): raise ValueError("bounded finite float seconds required") return value def exact_bool(value): if type(value) is not bool: raise ValueError("exact boolean required") return value def sequence(value, lower, upper): if type(value) not in (tuple, list): raise ValueError("bounded tuple or list required") integer(len(value), lower, upper) return tuple(value) def digest(value): encoded = json.dumps( value, sort_keys=True, separators=(",", ":"), allow_nan=False ).encode() return hashlib.sha256(encoded).hexdigest() NONE_DIGEST = digest("none") def seal(record): if type(record.content_id) is not str: raise ValueError("content digest requires exact string") data = asdict(record) data.pop("content_id") return digest(data) def validate_record(record, cls): if type(record) is not cls: raise ValueError("concrete frozen record required") try: rebuilt = cls(**{field.name: getattr(record, field.name) for field in fields(cls)}) except (AttributeError, TypeError) as error: raise ValueError("malformed record") from error if record != rebuilt or record.content_id != rebuilt.content_id: raise ValueError("noncanonical or modified record") return rebuilt def scope_tuple(value): result = sequence(value, 8, 8) for item in result: identity(item) return result def enum(value, allowed): if type(value) is not str or value not in allowed: raise ValueError("unknown exact-string declaration") return value @dataclass(frozen=True) class WorkflowContract: scope: tuple = ( "workflow-policy-v1", "definition-v1", "activity-registry-v1", "authorization-v1", "approval-v1", "retry-v1", "event-schema-v1", "fixture-v1", ) max_steps: int = 8 max_attempts_per_step: int = 3 reconciliation_timeout_seconds: float = 30.0 require_idempotency_keys: bool = True content_id: str = "" def __post_init__(self): object.__setattr__(self, "scope", scope_tuple(self.scope)) integer(self.max_steps, 1, 64) integer(self.max_attempts_per_step, 1, 20) finite_seconds(self.reconciliation_timeout_seconds) if exact_bool(self.require_idempotency_keys) is not True: raise ValueError("recovery contract requires idempotency keys") expected = seal(self) if self.content_id and self.content_id != expected: raise ValueError("workflow contract digest mismatch") object.__setattr__(self, "content_id", expected) @dataclass(frozen=True) class WorkflowStep: scope: tuple workflow_id: str position: int step_id: str tool_id: str side_effect: str idempotency_key: str input_sha256: str requires_approval: bool content_id: str = "" def __post_init__(self): object.__setattr__(self, "scope", scope_tuple(self.scope)) for value in (self.workflow_id, self.step_id, self.tool_id, self.idempotency_key): identity(value) integer(self.position, 1, 64) enum(self.side_effect, ("read", "write")) sha256_text(self.input_sha256) exact_bool(self.requires_approval) if self.side_effect == "read" and self.requires_approval: raise ValueError("illustrative read steps do not require approval") expected = seal(self) if self.content_id and self.content_id != expected: raise ValueError("workflow step digest mismatch") object.__setattr__(self, "content_id", expected) @dataclass(frozen=True) class WorkflowEvent: scope: tuple workflow_id: str sequence: int step_content_id: str kind: str attempt: int idempotency_key: str input_sha256: str result_sha256: str occurred_at: int content_id: str = "" def __post_init__(self): object.__setattr__(self, "scope", scope_tuple(self.scope)) identity(self.workflow_id) integer(self.sequence, 1, 4096) sha256_text(self.step_content_id) enum(self.kind, ("approval-granted", "scheduled", "failed", "succeeded")) integer(self.attempt, 0, 20) identity(self.idempotency_key) sha256_text(self.input_sha256) sha256_text(self.result_sha256) integer(self.occurred_at, 0, TIMESTAMP_MAX) if self.kind == "approval-granted": if self.attempt != 0 or self.result_sha256 != NONE_DIGEST: raise ValueError("approval event has no attempt or result") elif self.attempt == 0: raise ValueError("activity event requires a positive attempt") if self.kind in ("scheduled", "failed") and self.result_sha256 != NONE_DIGEST: raise ValueError("incomplete event cannot declare a result") if self.kind == "succeeded" and self.result_sha256 == NONE_DIGEST: raise ValueError("successful event requires a result") expected = seal(self) if self.content_id and self.content_id != expected: raise ValueError("workflow event digest mismatch") object.__setattr__(self, "content_id", expected) @dataclass(frozen=True) class ExternalReceipt: scope: tuple workflow_id: str step_content_id: str idempotency_key: str input_sha256: str result_sha256: str observed_at: int authoritative: bool content_id: str = "" def __post_init__(self): object.__setattr__(self, "scope", scope_tuple(self.scope)) identity(self.workflow_id) sha256_text(self.step_content_id) identity(self.idempotency_key) sha256_text(self.input_sha256) sha256_text(self.result_sha256) if self.result_sha256 == NONE_DIGEST: raise ValueError("external receipt requires a result") integer(self.observed_at, 0, TIMESTAMP_MAX) exact_bool(self.authoritative) expected = seal(self) if self.content_id and self.content_id != expected: raise ValueError("external receipt digest mismatch") object.__setattr__(self, "content_id", expected) def _validate_history(plan, events, contract): by_digest = {step.content_id: step for step in plan} states = {step.content_id: ("initial", 0) for step in plan} last_position = 1 for event in events: step = by_digest.get(event.step_content_id) if step is None: raise ValueError("event names an undeclared step") if event.scope != step.scope or event.workflow_id != step.workflow_id: raise ValueError("event outside workflow scope") if event.idempotency_key != step.idempotency_key or event.input_sha256 != step.input_sha256: raise ValueError("event intent differs from declared step") if step.position < last_position: raise ValueError("events cannot move backward across a sequential plan") last_position = step.position for prior in plan[: step.position - 1]: if states[prior.content_id][0] != "succeeded": raise ValueError("later step began before prior history completed") state, attempt = states[step.content_id] if event.kind == "approval-granted": if not step.requires_approval or state != "initial": raise ValueError("approval event violates step state") states[step.content_id] = ("approved", 0) elif event.kind == "scheduled": allowed_state = "approved" if step.requires_approval and attempt == 0 else "initial" if state == "failed": allowed_state = "failed" if state != allowed_state or event.attempt != attempt + 1: raise ValueError("schedule event violates retry state") if event.attempt > contract.max_attempts_per_step: raise ValueError("activity attempt exceeds retry contract") states[step.content_id] = ("scheduled", event.attempt) elif event.kind in ("failed", "succeeded"): if state != "scheduled" or event.attempt != attempt: raise ValueError("activity result lacks matching schedule") states[step.content_id] = (event.kind, attempt) return states @dataclass(frozen=True) class RecoverySnapshot: scope: tuple workflow_id: str contract_content_id: str plan: tuple events: tuple receipts: tuple observed_at: int content_id: str = "" def __post_init__(self): object.__setattr__(self, "scope", scope_tuple(self.scope)) identity(self.workflow_id) sha256_text(self.contract_content_id) plan = tuple(validate_record(item, WorkflowStep) for item in sequence(self.plan, 1, 64)) events = tuple(validate_record(item, WorkflowEvent) for item in sequence(self.events, 0, 4096)) receipts = tuple(validate_record(item, ExternalReceipt) for item in sequence(self.receipts, 0, 64)) integer(self.observed_at, 0, TIMESTAMP_MAX) if tuple(step.position for step in plan) != tuple(range(1, len(plan) + 1)): raise ValueError("plan positions must be unique and contiguous") if any(step.scope != self.scope or step.workflow_id != self.workflow_id for step in plan): raise ValueError("plan step outside workflow scope") if len({step.step_id for step in plan}) != len(plan): raise ValueError("duplicate workflow step identity") if len({step.idempotency_key for step in plan}) != len(plan): raise ValueError("idempotency keys must be unique per workflow") if tuple(event.sequence for event in events) != tuple(range(1, len(events) + 1)): raise ValueError("event sequences must be unique and contiguous") if any(event.occurred_at > self.observed_at for event in events): raise ValueError("event occurs after recovery observation") if len({receipt.step_content_id for receipt in receipts}) != len(receipts): raise ValueError("duplicate external receipt") if any(receipt.observed_at > self.observed_at for receipt in receipts): raise ValueError("receipt occurs after recovery observation") object.__setattr__(self, "plan", plan) object.__setattr__(self, "events", events) object.__setattr__(self, "receipts", receipts) expected = seal(self) if self.content_id and self.content_id != expected: raise ValueError("recovery snapshot digest mismatch") object.__setattr__(self, "content_id", expected) @dataclass(frozen=True) class RecoveryReport: status: str completed_step_ids: tuple next_step_id: str decision: str evidence_id: str claim: str = "LOCAL_RECOVERY_AUDIT_NOT_EXACTLY_ONCE_GUARANTEE" def audit_recovery(contract: WorkflowContract, snapshot: RecoverySnapshot) -> RecoveryReport: """Replay declarations and reconcile ambiguous effects without executing a tool.""" contract = validate_record(contract, WorkflowContract) snapshot = validate_record(snapshot, RecoverySnapshot) if snapshot.scope != contract.scope or snapshot.contract_content_id != contract.content_id: raise ValueError("snapshot belongs to another workflow contract") if len(snapshot.plan) > contract.max_steps: raise ValueError("plan exceeds workflow contract") states = _validate_history(snapshot.plan, snapshot.events, contract) plan_by_digest = {step.content_id: step for step in snapshot.plan} scheduled_at = { event.step_content_id: event.occurred_at for event in snapshot.events if event.kind == "scheduled" } receipts = {} for receipt in snapshot.receipts: step = plan_by_digest.get(receipt.step_content_id) if step is None: raise ValueError("receipt names an undeclared step") if ( receipt.scope != snapshot.scope or receipt.workflow_id != snapshot.workflow_id or receipt.idempotency_key != step.idempotency_key or receipt.input_sha256 != step.input_sha256 ): raise ValueError("receipt intent differs from declared step") state, _ = states[step.content_id] if state != "scheduled" or receipt.observed_at < scheduled_at[step.content_id]: raise ValueError("receipt does not reconcile an ambiguous scheduled effect") if receipt.authoritative is not True: raise ValueError("reconciliation requires an authoritative receipt") receipts[step.content_id] = receipt completed = [] next_step = "none" decision = "complete" reconciled = False for step in snapshot.plan: state, attempt = states[step.content_id] if state == "succeeded": completed.append(step.step_id) continue if state == "scheduled" and step.content_id in receipts: completed.append(step.step_id) decision = "reconcile-before-retry" reconciled = True continue next_step = step.step_id if step.requires_approval and state == "initial": decision = "await-approval" elif state == "scheduled": decision = "reconcile-before-retry" elif state == "failed" and attempt >= contract.max_attempts_per_step: decision = "fail-retry-budget" elif state == "failed": decision = "retry-with-same-key" elif not reconciled: decision = "start-step" break status = "COMPLETED" if next_step == "none" else "RESUMABLE" if decision == "fail-retry-budget": status = "FAILED" evidence_id = digest( { "contract": contract.content_id, "snapshot": snapshot.content_id, "completed": completed, "next": next_step, "decision": decision, } ) return RecoveryReport(status, tuple(completed), next_step, decision, evidence_id) def illustrative_fixture(): contract = WorkflowContract() workflow_id = "order-1042" steps = ( WorkflowStep( contract.scope, workflow_id, 1, "reserve-stock", "inventory.reserve", "write", "order-1042:reserve-stock:v1", digest({"sku": "sku-7", "quantity": 1}), False, ), WorkflowStep( contract.scope, workflow_id, 2, "charge-card", "payments.charge", "write", "order-1042:charge-card:v1", digest({"payment_token": "token-redacted", "amount_minor": 4200}), True, ), WorkflowStep( contract.scope, workflow_id, 3, "send-receipt", "mail.send-receipt", "write", "order-1042:send-receipt:v1", digest({"template": "receipt-v3"}), False, ), ) event_data = ( (steps[0], "scheduled", 1, NONE_DIGEST, 100), (steps[0], "succeeded", 1, digest("reservation-88"), 101), (steps[1], "approval-granted", 0, NONE_DIGEST, 102), (steps[1], "scheduled", 1, NONE_DIGEST, 103), ) events = tuple( WorkflowEvent( contract.scope, workflow_id, index, step.content_id, kind, attempt, step.idempotency_key, step.input_sha256, result, occurred_at, ) for index, (step, kind, attempt, result, occurred_at) in enumerate( event_data, start=1 ) ) receipt = ExternalReceipt( contract.scope, workflow_id, steps[1].content_id, steps[1].idempotency_key, steps[1].input_sha256, digest("charge-501"), 104, True, ) snapshot = RecoverySnapshot( contract.scope, workflow_id, contract.content_id, steps, events, (receipt,), 105, ) return contract, snapshot def main(): report = audit_recovery(*illustrative_fixture()) print("example=illustrative_only") print(f"status={report.status}") print("completed=" + ",".join(report.completed_step_ids)) print(f"next={report.next_step_id}") print(f"decision={report.decision}") print(f"claim={report.claim}") if __name__ == "__main__": main()