Source code for tabench.core.capabilities
"""Model capability declarations and harness-enforced compatibility (P4, P7)."""
from __future__ import annotations
from dataclasses import dataclass
from .scenario import Scenario
__all__ = ["Capabilities", "ContaminationError", "assert_fair_evaluation"]
PARADIGMS = frozenset(
{
"static_ue",
"static_ue_elastic",
"static_ue_combined",
"static_br_ue",
"static_sc_ue",
"static_ue_vi",
"static_ue_multiclass",
"static_so",
"sue",
"dta",
"day_to_day",
"learned",
"heuristic",
"estimation",
}
)
[docs]
@dataclass(frozen=True)
class Capabilities:
"""What a model declares about itself; the harness trusts nothing else.
``provides_gap`` means the model self-certifies an equilibrium gap. The
harness still recomputes every scored metric externally (P1); self-reports
are only diffed against harness values as an honesty check.
``trained_on`` lists scenario families in the model's training lineage
(learned models). The fairness gate refuses evaluation on scenarios whose
family appears here.
"""
paradigm: str
deterministic: bool
provides_gap: bool
seedable: bool
inputs_required: frozenset[str] = frozenset({"od_matrix"})
outputs: frozenset[str] = frozenset({"link_flows"})
trained_on: tuple[str, ...] = ()
def __post_init__(self) -> None:
if self.paradigm not in PARADIGMS:
raise ValueError(
f"Unknown paradigm {self.paradigm!r}; expected one of {sorted(PARADIGMS)}"
)
[docs]
class ContaminationError(RuntimeError):
"""Raised when a model's training lineage intersects the evaluation scenario."""
[docs]
def assert_fair_evaluation(capabilities: Capabilities, scenario: Scenario) -> None:
"""Fairness gate (P7): refuse train/test contamination.
Declared lineage tokens are matched against both the scenario's family
name and its content hash. Declaring **content hashes** is robust to
scenario renaming; declaring only family names is not (a byte-identical
scenario republished under a new family name will not match). Learned
models should therefore declare content hashes of their training
scenarios whenever available, and family names as a coarser fallback.
"""
lineage = set(capabilities.trained_on)
if not lineage:
return
if scenario.family in lineage or scenario.content_hash() in lineage:
raise ContaminationError(
f"Model trained on {sorted(lineage)} may not be evaluated on scenario "
f"'{scenario.name}' (family '{scenario.family}')."
)