# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/which-invariants-prevent-auto-compaction-trigger-heuristics-from-silently-destroying-unrecoverable-context-under-lossy-summarization-recovery.md
# Remnant Warrant:    https://corpusfetch.com/c/which-invariants-prevent-auto-compaction-trigger-heuristics-from-silently-destroying-unrecoverable-context-under-lossy-summarization-recovery.warrant.json
# Markdown SHA-256:   013ec30a8fd810525c872a61ceacf0f5ee1d6846d5718c73886758cd9993b74d
# Code AST SHA-256:   c9f2e9692b5f17c452cd04c98c3a225762fa0e38c979106b8ef1ceb4c8733187
# Verified Classes:   CompactionInvariantError
# Defensive Guards:   1 fail-closed invariants (zero external deps)

class CompactionInvariantError(RuntimeError):
    """Raised when an auto-compaction trigger fires without a verified recovery path."""
    pass


def assert_compaction_is_reversible(
    raw_context_retained: bool,
    recovery_path_tested: bool,
    diff_detectable: bool,
    commit_atomic: bool,
) -> None:
    missing = []
    if not raw_context_retained:
        missing.append("retention: raw pre-compaction context not durably persisted")
    if not recovery_path_tested:
        missing.append("reachability: recovery path not exercised in this deployment")
    if not diff_detectable:
        missing.append("detectability: no raw-vs-summary comparison retained")
    if not commit_atomic:
        missing.append("atomicity: summary commit and raw retention are not one transaction")
    if missing:
        raise CompactionInvariantError(
            "refusing destructive auto-compaction; invariants unsatisfied: "
            + "; ".join(missing)
        )


def maybe_auto_compact(utilization: float, threshold: float, **invariants) -> bool:
    """Returns True only if the trigger fires AND compaction is provably reversible."""
    if utilization < threshold:
        return False
    # Trigger heuristic fired. Correctness does NOT depend on the threshold;
    # it depends on the recovery invariants being true.
    assert_compaction_is_reversible(**invariants)
    return True
