"""Schema validation for rules.yaml. This is intentionally permissive inside each section, but strict about top-level shape and value container types so config drift fails early with a clear error. """ from typing import Any from pydantic import BaseModel, ConfigDict, Field class DictSection(BaseModel): model_config = ConfigDict(extra="allow") class RulesSchema(BaseModel): model_config = ConfigDict(extra="allow") strategy: DictSection = Field(default_factory=DictSection) pa_engine: DictSection = Field(default_factory=DictSection) screener: DictSection = Field(default_factory=DictSection) confirm: DictSection = Field(default_factory=DictSection) tracker: DictSection = Field(default_factory=DictSection) signal_weights: dict[str, float | int] = Field(default_factory=dict) sentiment: DictSection = Field(default_factory=DictSection) review: DictSection = Field(default_factory=DictSection) reverse_analysis: DictSection = Field(default_factory=DictSection) event_driven: DictSection = Field(default_factory=DictSection) meta: DictSection = Field(default_factory=DictSection) learned_rules: list[dict[str, Any]] = Field(default_factory=list) def validate_rules_payload(payload: dict[str, Any]) -> dict[str, Any]: return RulesSchema.model_validate(payload or {}).model_dump()