# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/under-what-conditions-must-an-instance-treat-a-verified-agent-card-signature-as-insufficient-authority-to-reconcile-a-remote-task-state.md
# Remnant Warrant:    https://corpusfetch.com/c/under-what-conditions-must-an-instance-treat-a-verified-agent-card-signature-as-insufficient-authority-to-reconcile-a-remote-task-state.warrant.json
# Markdown SHA-256:   55d2fb4211f4380088825d59a5418124e65d43800c160a9387881a861a56ab45
# Code AST SHA-256:   415358c1fc6f621141b933534ad899f01ab3e22ed8a009529679ed16cd019a97
# Verified Classes:   CardAuthorityError, AgentCard, TaskEnvelope
# Defensive Guards:   2 fail-closed invariants (zero external deps)

from dataclasses import dataclass


class CardAuthorityError(RuntimeError):
    """Raised when a reconciler attempts to use a card's declared
    transitions to decide state for a task created under a different
    card version."""


@dataclass(frozen=True)
class AgentCard:
    digest: str
    supported_task_states: frozenset[str]
    signature_verified: bool


@dataclass(frozen=True)
class TaskEnvelope:
    task_id: str
    card_digest: str  # card version in force at task creation
    current_state: str


def decide_transition(
    task: TaskEnvelope,
    target_state: str,
    cached_card: AgentCard,
) -> bool:
    """Return True if the cached card may authorize this transition.

    The card signature is necessary but not sufficient: it authorizes the
    peer, not the task. We must confirm the task was created under the
    same card version before consulting the card's declared states.
    """
    if not cached_card.signature_verified:
        raise CardAuthorityError(
            f"card {cached_card.digest} failed signature verification; "
            "cannot reconcile task state"
        )

    if task.card_digest != cached_card.digest:
        raise CardAuthorityError(
            f"task {task.task_id} was created under card "
            f"{task.card_digest}, but reconciler holds card "
            f"{cached_card.digest}; card signature does not confer "
            "authority over this task's transitions. Defer to the "
            "task's own status channel."
        )

    return target_state in cached_card.supported_task_states


def reconcile(task: TaskEnvelope, target_state: str, card: AgentCard) -> str:
    try:
        allowed = decide_transition(task, target_state, card)
    except CardAuthorityError as exc:
        return f"deferred: {exc}"
    if not allowed:
        return f"rejected: {target_state} not declared by card {card.digest}"
    return f"accepted: {task.task_id} -> {target_state}"
