# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-reconcile-speculative-branches-when-rollback-cost-exceeds-the-speculative-window.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-reconcile-speculative-branches-when-rollback-cost-exceeds-the-speculative-window.warrant.json
# Markdown SHA-256:   49647b0a2a6ee1130d868d37f71555b75d71f2e3278fa783949242b6f286c530
# Code AST SHA-256:   0c98d1d29f514b65d5822aa82b69c104bb844fd585d73a20602fca9b66445fb9
# Verified Classes:   SpeculativeRollbackOverflow, SideEffect, Branch
# Defensive Guards:   2 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass, field
from typing import Literal


class SpeculativeRollbackOverflow(RuntimeError):
    """Raised when abandoning a speculative branch would exceed the compensation budget."""
    pass


@dataclass
class SideEffect:
    effect_id: str
    kind: Literal["reversible", "compensable", "irreversible"]
    compensation_cost_s: float
    committed_at: float


@dataclass
class Branch:
    branch_id: str
    verifier_score: float
    effects: list[SideEffect] = field(default_factory=list)

    def rollback_cost(self) -> float:
        # Irreversible effects cannot be compensated; treat as unbounded.
        if any(e.kind == "irreversible" for e in self.effects):
            return float("inf")
        return sum(e.compensation_cost_s for e in self.effects if e.kind == "compensable")


def reconcile(
    branches: list[Branch],
    speculative_window_s: float,
    score_noise_band: float,
) -> Branch:
    if not branches:
        raise SpeculativeRollbackOverflow("reconcile called with no branches")

    ranked = sorted(branches, key=lambda b: b.verifier_score, reverse=True)
    winner = ranked[0]
    losers = ranked[1:]

    aggregate_rollback = sum(b.rollback_cost() for b in losers)

    if aggregate_rollback > speculative_window_s:
        runner_up = ranked[1]
        gap = winner.verifier_score - runner_up.verifier_score

        # Counterintuitive branch: rollback cost is a legitimate tiebreaker.
        if gap < score_noise_band and runner_up.rollback_cost() <= speculative_window_s:
            return runner_up

        # Otherwise we cannot silently proceed: the caller must choose
        # block-and-compensate vs commit-and-quarantine explicitly.
        raise SpeculativeRollbackOverflow(
            f"aggregate rollback cost {aggregate_rollback:.1f}s exceeds window "
            f"{speculative_window_s:.1f}s; winner={winner.branch_id} "
            f"score_gap={gap:.3f}; explicit reconciliation required"
        )

    return winner
