from __future__ import annotations

from dataclasses import dataclass

@dataclass
class Publication:
    version: int
    approved_version: int | None = None
    published: bool = False

    def approve(self, version: int) -> None:
        if version != self.version:
            raise ValueError("stale approval target")
        self.approved_version = version

    def edit(self) -> None:
        self.version += 1
        self.approved_version = None

    def publish(self, version: int) -> None:
        if version != self.version or self.approved_version != version:
            raise PermissionError("approval mismatch")
        if self.published:
            raise ValueError("already published")
        self.published = True

def test_version_bound_approval():
    doc = Publication(version=3)
    doc.approve(3)
    doc.edit()
    try:
        doc.publish(4)
    except PermissionError:
        pass
    else:
        raise AssertionError("stale approval was accepted")

def test_duplicate_publish_rejected():
    doc = Publication(version=7)
    doc.approve(7)
    doc.publish(7)
    try:
        doc.publish(7)
    except ValueError:
        pass
    else:
        raise AssertionError("duplicate publish was accepted")

if __name__ == "__main__":
    test_version_bound_approval()
    test_duplicate_publish_rejected()
    print("2 deterministic checks passed")
