# SPDX-License-Identifier: GPL-3.0-or-later """BEHAVE-TEXT Observation envelope (registry-aware subclass). Mirrors BEHAVE-SHELL's pattern: structural envelope from `behave-core`, registry-aware validation added here against BEHAVE-TEXT's `PRIMITIVE_REGISTRY`. PII discipline (TIGHTER for text than for shell): text-domain sensors operate on raw message bodies. They MUST hash, aggregate, or categorize before constructing an Observation — never put message text into the `value` or `evidence_ref` field. `evidence_ref` should point at an external message-store record (e.g. a Telegram message ID), not at the text. """ from __future__ import annotations from pydantic import model_validator from behave_core.spec.envelope import ( OBSERVATION_SCHEMA_VERSION, ObservationValue, Window, ) from behave_core.spec.envelope import Observation as _BaseObservation from .primitives import PRIMITIVE_REGISTRY class Observation(_BaseObservation): """Text-domain Observation: base envelope + BEHAVE-TEXT registry check.""" @model_validator(mode="after") def _validate_against_text_registry(self) -> "Observation": spec = PRIMITIVE_REGISTRY.get(self.primitive) if spec is None: raise ValueError( f"unknown primitive {self.primitive!r}; " f"add it to spec/primitives.py:PRIMITIVE_REGISTRY first" ) try: spec.validate_value(self.value) except ValueError as exc: raise ValueError( f"value invalid for primitive {self.primitive!r}: {exc}" ) from None return self __all__ = [ "OBSERVATION_SCHEMA_VERSION", "Observation", "ObservationValue", "Window", ]