# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/why-does-an-instance-of-byzantine-fault-tolerant-plan-commitment-fail-when-quorum-intersection-is-preserved-but-attestat.md
# Remnant Warrant:    https://corpusfetch.com/c/why-does-an-instance-of-byzantine-fault-tolerant-plan-commitment-fail-when-quorum-intersection-is-preserved-but-attestat.warrant.json
# Markdown SHA-256:   f8a0919d7c35e4d3c89123e26b5497a2bf379f83bfa6a19d66fb467baa2c4ddd
# Code AST SHA-256:   e87ffbbd69adc162a7535b34f3998368c0028b8a9a85b230f5e1a7ffe6ea3042
# Verified Classes:   AttestationBindingError
# Defensive Guards:   3 fail-closed invariants (zero external deps)

class AttestationBindingError(RuntimeError):
    """Raised when a result attestation is not bound to a committed plan."""
    pass


def validate_attestation(attestation: dict, committed_log: dict) -> None:
    """
    Validate that a result attestation refers to a plan that is actually
    committed, at the commit index the attestation claims.

    committed_log maps commit_index -> plan_hash for committed plans only.
    It MUST NOT include proposed-but-uncommitted plans.
    """
    plan_hash = attestation.get("plan_hash")
    commit_index = attestation.get("commit_index")

    if commit_index is None:
        raise AttestationBindingError(
            f"attestation for plan {plan_hash!r} carries no commit_index; "
            "hash-only attestations cannot be bound across phases"
        )

    if commit_index not in committed_log:
        raise AttestationBindingError(
            f"attestation references commit_index {commit_index} "
            f"which is not in the committed log"
        )

    committed_hash = committed_log[commit_index]
    if committed_hash != plan_hash:
        raise AttestationBindingError(
            f"attestation plan_hash {plan_hash!r} does not match committed "
            f"plan {committed_hash!r} at commit_index {commit_index}"
        )


def commit_attestation(attestation: dict, committed_log: dict) -> dict:
    validate_attestation(attestation, committed_log)
    return {"status": "committed", "plan_hash": attestation["plan_hash"],
            "commit_index": attestation["commit_index"]}
