# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-to-propagate-an-inbound-w3c-traceparent-across-an-agent-handoff-boundary.md
# Remnant Warrant:    https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-to-propagate-an-inbound-w3c-traceparent-across-an-agent-handoff-boundary.warrant.json
# Markdown SHA-256:   2a8fde3083f209456ad7ce589a540608adcbfa85309a5a5757437229cc55e902
# Code AST SHA-256:   f5adc35aec09c216d6f62bafb79ab31d2a9043008b68b6769cc276a4cff5899a
# Verified Classes:   TraceContextRejectedError, InboundContext
# Defensive Guards:   2 fail-closed invariants (zero external deps)

from dataclasses import dataclass


class TraceContextRejectedError(RuntimeError):
    """Raised when an inbound traceparent must not be adopted as parent."""

    def __init__(self, reason: str, trace_id: str, span_id: str) -> None:
        super().__init__(f"{reason} (inbound trace_id={trace_id} span_id={span_id})")
        self.reason = reason
        self.trace_id = trace_id
        self.span_id = span_id


@dataclass(frozen=True)
class InboundContext:
    trace_id: str
    span_id: str
    sampled: bool
    conversation_id: str
    shared_across_siblings: bool
    span_closed: bool
    is_retry: bool


def select_parent_or_link(inbound: InboundContext, local_conversation_id: str) -> str:
    """Return 'parent' or 'link'. Raise if the inbound context is malformed."""
    if len(inbound.trace_id) != 32 or len(inbound.span_id) != 16:
        raise TraceContextRejectedError(
            "malformed W3C traceparent", inbound.trace_id, inbound.span_id
        )
    if inbound.trace_id == "0" * 32 or inbound.span_id == "0" * 16:
        raise TraceContextRejectedError(
            "all-zero trace/span id", inbound.trace_id, inbound.span_id
        )
    if inbound.shared_across_siblings:
        return "link"
    if inbound.conversation_id != local_conversation_id:
        return "link"
    if inbound.span_closed and inbound.is_retry:
        return "link"
    return "parent"
