# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-reconcile-a2a-v1-0-identity-translation-when-the-federation-gateway-s-policy-epoch-advances-mid-handshake.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-reconcile-a2a-v1-0-identity-translation-when-the-federation-gateway-s-policy-epoch-advances-mid-handshake.warrant.json
# Markdown SHA-256:   791087196abbaae5d497d2614e18b23c335fc12fc5065a00464d01a961a29735
# Code AST SHA-256:   9760ced1c9becb6e068c1c970f68606342989f5a7b0263e25874f6b03b4cd69f
# Verified Classes:   EpochSkewViolation
# Defensive Guards:   2 fail-closed invariants (zero external deps)

class EpochSkewViolation(RuntimeError):
    """Raised when an identity assertion would carry authority from a
    translation table older than the policy epoch stamped on it."""
    pass


def mint_assertion(
    subject: str,
    policy_epoch: int,
    table_epoch: int,
    requested_authority: str,
    table_authority: str,
    rollout_direction: str,  # "tightening" | "loosening"
) -> dict:
    if table_epoch > policy_epoch:
        # Table ahead of policy: policy has not yet authorized the table's view.
        raise EpochSkewViolation(
            f"translation table epoch {table_epoch} leads policy epoch "
            f"{policy_epoch}; refusing to mint from an unauthorized table"
        )

    effective_epoch = min(policy_epoch, table_epoch)

    if table_epoch < policy_epoch:
        if rollout_direction == "loosening":
            # Older table is more permissive than the new policy; intersection
            # would still over-grant. Fail closed and force re-handshake.
            raise EpochSkewViolation(
                f"loosening rollout: table epoch {table_epoch} < policy epoch "
                f"{policy_epoch}; cannot safely intersect, retry after reload"
            )
        # Tightening rollout: downgrade to the older table's authority.
        authority = table_authority
    else:
        authority = requested_authority

    return {
        "subject": subject,
        "authority": authority,
        "effective_epoch": effective_epoch,
        "policy_epoch": policy_epoch,
        "table_epoch": table_epoch,
    }
