from __future__ import annotations from dataclasses import asdict, dataclass from typing import Any @dataclass(frozen=True) class Condition: """A predicate over immutable inputs or mutable simulator state.""" source: str key: str operator: str value: Any @dataclass(frozen=True) class HiddenRule: """One executable rule in the hidden system language.""" id: str on_event: str conditions: tuple[Condition, ...] probability: float action: str target: str @dataclass(frozen=True) class HiddenSystem: """The latent program. This object must never be sent to the renderer.""" initial_record: str conflict_policy: str rules: tuple[HiddenRule, ...] @dataclass(frozen=True) class BehaviorCase: """Observable inputs and aggregate output from repeated independent trials.""" id: str attributes: dict[str, Any] events: tuple[str, ...] trials: int observed_present: int | None observed_absent: int | None @dataclass(frozen=True) class BehaviorSkeleton: """A hidden program plus its public behavioral evidence and answer-bearing query.""" id: str family: str complexity: int event_vocabulary: tuple[str, ...] attribute_vocabulary: dict[str, str] observation_protocol: tuple[str, ...] hidden_system: HiddenSystem support_cases: tuple[BehaviorCase, ...] query_case: BehaviorCase answer_options: tuple[str, ...] gold_answer: str gold_present_probability: float latent_trace: tuple[str, ...] def to_dict(self) -> dict[str, Any]: return asdict(self) def renderer_payload(self) -> dict[str, Any]: """Expose behavior only: no program, probability, trace, or answer.""" return { "family": self.family, "complexity": self.complexity, "event_vocabulary": self.event_vocabulary, "attribute_vocabulary": self.attribute_vocabulary, "observation_protocol": self.observation_protocol, "support_cases": [asdict(case) for case in self.support_cases], "query_case": asdict(self.query_case), "answer_options": self.answer_options, }