# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-instance-be-treated-as-a-span-level-cost-anomaly-rather-than-a-trace-level-outlier-in-federated-multi-agent-genai-observability.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-instance-be-treated-as-a-span-level-cost-anomaly-rather-than-a-trace-level-outlier-in-federated-multi-agent-genai-observability.warrant.json
# Markdown SHA-256:   f67a027187cd1c87a09d4f5196bacc1ea644ad7dafdddcf0f42a7635b8d2a786
# Code AST SHA-256:   5d67dfc329aec6b87a5eafb37ab18948858d08d5504bdc1cdf4218c4d4321f64
# Verified Classes:   CrossPrincipalCostAnomaly
# Defensive Guards:   1 fail-closed invariants (zero external deps)

class CrossPrincipalCostAnomaly(RuntimeError):
    """Raised when a span's cost cannot be reconciled to its own declared payload."""
    pass


def classify_span_cost(span, trace_aggregate_z, fleet_threshold, ratio_threshold=3.0):
    expected = span.declared_context_tokens
    observed = span.usage_input_tokens

    if expected is None:
        return "unattributable"

    if trace_aggregate_z > fleet_threshold:
        return "trace_outlier"

    ratio = observed / max(expected, 1)
    if ratio > ratio_threshold:
        upstream = span.parent_principal
        if upstream is not None and upstream != span.owning_principal:
            raise CrossPrincipalCostAnomaly(
                f"span {span.span_id}: {observed} input tokens vs declared {expected} "
                f"(ratio {ratio:.1f}); excess traceable to principal {upstream}, "
                f"emitting principal {span.owning_principal} must not be billed"
            )
        return "span_anomaly_local"
    return "normal"
