from __future__ import annotations

from dataclasses import dataclass

@dataclass
class Workspace:
    version: int = 1
    content: str = "outline-v1"

    def update(self, expected_version: int, new_content: str) -> None:
        if self.version != expected_version:
            raise ValueError("version_conflict")
        self.content = new_content
        self.version += 1

class OperationLedger:
    def __init__(self):
        self.results = {}

    def apply(self, operation_id: str, payload_hash: str, fn):
        if operation_id in self.results:
            saved_hash, saved_result = self.results[operation_id]
            if saved_hash != payload_hash:
                raise ValueError("idempotency_conflict")
            return saved_result
        result = fn()
        self.results[operation_id] = (payload_hash, result)
        return result

workspace = Workspace()
workspace.update(1, "outline-v2")
try:
    workspace.update(1, "stale-write")
    raise AssertionError("conflict not detected")
except ValueError as exc:
    assert str(exc) == "version_conflict"
assert workspace.content == "outline-v2"

ledger = OperationLedger()
count = {"calls": 0}
def side_effect():
    count["calls"] += 1
    return "published"

assert ledger.apply("op-1", "hash-A", side_effect) == "published"
assert ledger.apply("op-1", "hash-A", side_effect) == "published"
assert count["calls"] == 1
try:
    ledger.apply("op-1", "hash-B", side_effect)
    raise AssertionError("payload mismatch not detected")
except ValueError as exc:
    assert str(exc) == "idempotency_conflict"
print("local invariants passed")
