# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-structural-signals-indicate-token-budget-exhaustion-is-caused-by-compaction-induced-context-re-expansion-rather-than-genuine-task-growth.md
# Remnant Warrant:    https://corpusfetch.com/c/what-structural-signals-indicate-token-budget-exhaustion-is-caused-by-compaction-induced-context-re-expansion-rather-than-genuine-task-growth.warrant.json
# Markdown SHA-256:   4696011395f2ac7cde874c3a42014f2d7cfeafd48769e35118a2d07bc408f078
# Code AST SHA-256:   fafe0d99a8275ce9f7b1af3b4dd5cf4a546176b3ad42a3e92c5da93325be5cf2
# Verified Classes:   CompactionReexpansionError
# Defensive Guards:   1 fail-closed invariants (zero external deps)

class CompactionReexpansionError(RuntimeError):
    """Raised when compaction cadence accelerates under flat task load,
    indicating summary-of-summary re-expansion rather than genuine growth."""
    pass


def check_compaction_health(
    interval_lengths: list[int],
    new_content_per_turn: list[int],
    shrink_threshold: float = 0.20,
    content_stability: float = 0.15,
) -> None:
    """
    interval_lengths: turns between successive compaction events, oldest first.
    new_content_per_turn: measured new task tokens per turn over the same span.
    """
    if len(interval_lengths) < 4:
        return  # insufficient history to judge cadence

    recent = interval_lengths[-4:]
    shrinks = [
        (recent[i] - recent[i + 1]) / recent[i]
        for i in range(len(recent) - 1)
    ]
    accelerating = all(s > shrink_threshold for s in shrinks)

    mean_content = sum(new_content_per_turn) / len(new_content_per_turn)
    spread = (max(new_content_per_turn) - min(new_content_per_turn)) / mean_content
    load_flat = spread <= content_stability

    if accelerating and load_flat:
        raise CompactionReexpansionError(
            f"Compaction cadence accelerating ({recent}) while task load is flat "
            f"(spread {spread:.2f}). Budget pressure is compaction-induced; "
            f"reset compaction lineage and pin constraints outside the compacted region."
        )
