# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-to-commit-a-speculated-tool-invocation-whose-side-effect-journal-has-already-been-fsynced-but-whose-dependen.md
# Remnant Warrant:    https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-to-commit-a-speculated-tool-invocation-whose-side-effect-journal-has-already-been-fsynced-but-whose-dependen.warrant.json
# Markdown SHA-256:   bda5e1b6800ca630d95ae106d3ca0a50dab840c1343e2474c5a8dcec68c4fbf1
# Code AST SHA-256:   998cb2297506556f93c25143fc6a2a39502fdd2b388730d4f6311498945c6512
# Verified Classes:   StaleSpeculationError, DependencyToken, JournalEntry
# Defensive Guards:   6 fail-closed invariants (zero external deps)

import hashlib
import time
from dataclasses import dataclass, field
from typing import Optional


class StaleSpeculationError(RuntimeError):
    """Raised when a journaled side effect cannot be committed under its token."""

    def __init__(self, token_id: str, reason: str, sealed_closure_hash: str,
                 current_closure_hash: Optional[str] = None):
        self.token_id = token_id
        self.reason = reason
        self.sealed_closure_hash = sealed_closure_hash
        self.current_closure_hash = current_closure_hash
        super().__init__(
            f"refusing commit under token {token_id}: {reason} "
            f"(sealed={sealed_closure_hash[:12]}, "
            f"current={(current_closure_hash or 'n/a')[:12]})"
        )


@dataclass
class DependencyToken:
    token_id: str
    resource: str
    mint_monotonic: float
    ttl_s: float
    generation: int
    superseded_by: Optional[str] = None

    def expired(self, now: Optional[float] = None) -> bool:
        now = time.monotonic() if now is None else now
        return (now - self.mint_monotonic) > self.ttl_s


@dataclass
class JournalEntry:
    token_id: str
    resource: str
    seal_monotonic: float
    sealed_closure_hash: str
    sealed_generation: int
    sealed: bool = False
    fsynced: bool = False


def commit_journaled_effect(
    entry: JournalEntry,
    token: DependencyToken,
    current_generation: int,
    derive_closure_hash,
    now: Optional[float] = None,
) -> str:
    """Commit a speculated side effect, or refuse. Returns the commit token id."""
    if not (entry.sealed and entry.fsynced):
        raise StaleSpeculationError(
            token.token_id, "journal not durably sealed", entry.sealed_closure_hash
        )

    if entry.token_id != token.token_id:
        raise StaleSpeculationError(
            token.token_id, "token id mismatch", entry.sealed_closure_hash
        )

    if entry.seal_monotonic < token.mint_monotonic:
        raise StaleSpeculationError(
            token.token_id, "clock inversion: sealed before token mint",
            entry.sealed_closure_hash,
        )

    if token.superseded_by is not None:
        raise StaleSpeculationError(
            token.token_id, f"superseded by {token.superseded_by}",
            entry.sealed_closure_hash,
        )

    if current_generation != entry.sealed_generation:
        raise StaleSpeculationError(
            token.token_id, "resource generation advanced",
            entry.sealed_closure_hash,
        )

    current_hash = derive_closure_hash(entry.resource)
    if current_hash != entry.sealed_closure_hash:
        raise StaleSpeculationError(
            token.token_id, "dependency closure changed",
            entry.sealed_closure_hash, current_hash,
        )

    if token.expired(now):
        # Expired but closure identical: re-seal under a fresh token, then commit.
        return _reseal_and_commit(entry, token)

    return token.token_id


def _reseal_and_commit(entry: JournalEntry, old: DependencyToken) -> str:
    new_id = hashlib.sha256(
        f"{old.token_id}:{entry.seal_monotonic}".encode()
    ).hexdigest()[:16]
    entry.token_id = new_id
    return new_id
