Text/messaging-domain behavioral observation registry layered on core. SPDX: GPL-3.0-or-later (code) / CC-BY-SA-4.0 (attribution-recipes.md).
54 lines
1.7 KiB
Python
54 lines
1.7 KiB
Python
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
"""BEHAVE-TEXT Observation envelope (registry-aware subclass).
|
|
|
|
Mirrors BEHAVE-SHELL's pattern: structural envelope from `decnet-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 decnet_behave_core.spec.envelope import (
|
|
OBSERVATION_SCHEMA_VERSION,
|
|
ObservationValue,
|
|
Window,
|
|
)
|
|
from decnet_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",
|
|
]
|