# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/under-what-conditions-must-an-instance-refuse-to-propagate-a-traceparent-across-an-organizational-handoff.md
# Remnant Warrant:    https://corpusfetch.com/c/under-what-conditions-must-an-instance-refuse-to-propagate-a-traceparent-across-an-organizational-handoff.warrant.json
# Markdown SHA-256:   d14e9113b55bc3e6b2af9b95ff9f20c74aeb20f8eb8f93506c956a96e201aa0a
# Code AST SHA-256:   41fd36aacdfe0c03af865ac27566fa8596d112efc0b51b23e96366228f36154e
# Verified Classes:   TraceBoundaryViolation
# Defensive Guards:   4 fail-closed invariants (zero external deps)

class TraceBoundaryViolation(RuntimeError):
    """Raised when a foreign traceparent would be joined as attestation without a trust anchor."""
    pass


def join_foreign_span(
    traceparent: str,
    origin_authority: str,
    trust_anchor_verifies: bool,
    consumer_requires_attestation: bool,
) -> dict:
    if not traceparent or not traceparent.startswith("00-"):
        raise TraceBoundaryViolation(f"malformed traceparent: {traceparent!r}")

    parts = traceparent.split("-")
    if len(parts) != 4:
        raise TraceBoundaryViolation(f"traceparent must have 4 fields: {traceparent!r}")

    _, trace_id, span_id, flags = parts

    if consumer_requires_attestation and not trust_anchor_verifies:
        # Refuse direct parentage. Emit a link, not a child edge.
        return {
            "mode": "link",
            "trace_id": trace_id,
            "linked_span_id": span_id,
            "origin_authority": origin_authority,
            "attestation": "unverified",
            "reason": "foreign_traceparent_without_trust_anchor",
        }

    return {
        "mode": "child",
        "trace_id": trace_id,
        "parent_span_id": span_id,
        "origin_authority": origin_authority,
        "attestation": "verified" if trust_anchor_verifies else "correlation_only",
    }


def enforce_tracestate_integrity(tracestate: str, local_keys: set[str]) -> str:
    entries = [e.strip() for e in tracestate.split(",") if e.strip()]
    if len(entries) > 32 or len(tracestate.encode("utf-8")) > 512:
        raise TraceBoundaryViolation("tracestate exceeds W3C limits on ingress")
    present = {e.split("=", 1)[0] for e in entries if "=" in e}
    missing = local_keys - present
    if missing:
        raise TraceBoundaryViolation(
            f"local tracestate keys evicted by foreign authority: {sorted(missing)}"
        )
    return tracestate
