# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-a-speculative-multi-agent-executor-abort-a-branch-instead-of-reconciling-it.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-a-speculative-multi-agent-executor-abort-a-branch-instead-of-reconciling-it.warrant.json
# Markdown SHA-256:   c0ebb6508be228b3eadf515f6d1340b625503a4d096e34d354d6e40f4690c819
# Code AST SHA-256:   3a8766ab56c818bae58d324574bba1fabaaed0d320d9c161cdc530659d7a8998
# Verified Classes:   ContaminationAbort
# Defensive Guards:   3 fail-closed invariants (zero external deps)

class ContaminationAbort(RuntimeError):
    """Raised when a speculative branch set cannot be safely reconciled."""
    pass


def reconcile_branches(branches, tool_layer, base_snapshot):
    # Every read must be served from base_snapshot; every speculative
    # write must be overlay-isolated. Anything else is contamination.
    for branch in branches:
        for read in branch.reads:
            if read.snapshot_id != base_snapshot.id:
                raise ContaminationAbort(
                    f"branch {branch.id} read from snapshot {read.snapshot_id}, "
                    f"not base {base_snapshot.id}; set is contaminated"
                )
            if read.observed_speculative_write_from is not None:
                raise ContaminationAbort(
                    f"branch {branch.id} observed speculative write from "
                    f"{read.observed_speculative_write_from}; abort whole set"
                )
        for call in branch.speculative_calls:
            if call.executed and not tool_layer.is_overlay_isolated(call):
                raise ContaminationAbort(
                    f"branch {branch.id} call {call.tool} escaped overlay "
                    f"and is not provably non-observable; abort whole set"
                )

    # Only reached when the set is snapshot-clean.
    return _merge(branches)
