# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/in-what-scenarios-must-an-instance-treat-forget-as-a-tombstone-rather-than-a-delete-in-read-write-forget-memory-apis.md
# Remnant Warrant:    https://corpusfetch.com/c/in-what-scenarios-must-an-instance-treat-forget-as-a-tombstone-rather-than-a-delete-in-read-write-forget-memory-apis.warrant.json
# Markdown SHA-256:   e7d4e8c01e6a7117621f9a9fa5f7dbe7a7d3d8bc1d246a9a6770bb2aec43f44c
# Code AST SHA-256:   46ab0e0824debb8031f6877233fe9401ec60e462e29df6e1e0f2e56ec10060ec
# Verified Classes:   ForgetMode, UnsafeForgetError, ForgetContext
# Defensive Guards:   1 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from enum import Enum


class ForgetMode(Enum):
    TOMBSTONE = "tombstone"
    PHYSICAL = "physical"


class UnsafeForgetError(RuntimeError):
    """Raised when a forget call would violate the audit/provenance invariant."""


@dataclass(frozen=True)
class ForgetContext:
    record_id: str
    inbound_ref_count: int
    schema_lazy_refs: bool
    audit_enabled: bool
    dedup_content_addressed: bool
    type_is_erasable: bool


def select_forget_mode(ctx: ForgetContext) -> ForgetMode:
    # Any single hazard forces the tombstone path. Default is tombstone.
    if ctx.inbound_ref_count > 0:
        return ForgetMode.TOMBSTONE
    if ctx.schema_lazy_refs:
        return ForgetMode.TOMBSTONE
    if ctx.audit_enabled:
        return ForgetMode.TOMBSTONE
    if ctx.dedup_content_addressed:
        return ForgetMode.TOMBSTONE
    if not ctx.type_is_erasable:
        return ForgetMode.TOMBSTONE
    return ForgetMode.PHYSICAL


def forget(ctx: ForgetContext, requested_mode: ForgetMode) -> ForgetMode:
    resolved = select_forget_mode(ctx)
    if requested_mode is ForgetMode.PHYSICAL and resolved is ForgetMode.TOMBSTONE:
        raise UnsafeForgetError(
            f"refusing physical delete of {ctx.record_id!r}: "
            f"inbound_refs={ctx.inbound_ref_count}, "
            f"lazy_refs={ctx.schema_lazy_refs}, "
            f"audit={ctx.audit_enabled}, "
            f"dedup={ctx.dedup_content_addressed}, "
            f"erasable={ctx.type_is_erasable}; tombstone required"
        )
    return resolved
