ADR 0006: Event Hierarchy and Taxonomy¶
Status: Accepted
Date: 2026-02-15
Deciders: Development Team
Context¶
The Orpheus event pipeline is fragmented. Agents define their own implicit data models, which leads to:
- Crashes: The Crow agent emitted raw dicts that could fail validation in downstream consumers such as the Event Correlator.
- Silent failures: The Correlator ignored Bird events because it expected
sub-detections exclusively inside
metadata.detections, while legacy BirdNET payloads placed them at the root level. - No single source of truth: There was no formal document describing how
AudioMotion,Detection, andEntityevents relate.
ADR-0005 introduced OrpheusBaseEvent and the JSON sidecar
persistence pattern. This ADR extends that work by formalising the complete
event hierarchy, promoting causal lineage (source_event_id) to the base
class, flattening the hierarchy by removing the intermediate InferenceEvent
class, defining the standard detection_type taxonomy, and mandating that all
agents use orpheus_common models exclusively.
Decision¶
1. Event Hierarchy¶
All events must inherit from OrpheusBaseEvent (defined in
orpheus_common.events) or use the Detection model (defined in
orpheus_common.detection). No agent may define its own event class.
classDiagram
class OrpheusBaseEvent {
+str event_id
+datetime event_timestamp
+SpatiotemporalContext context
+str source_event_id
}
class Detection {
+str detection_type
+str species_code
+float confidence
+dict metadata
}
class EntityEvent {
+str entity_id
+str species_code
+List~Detection~ evidence
}
OrpheusBaseEvent <|-- Detection
Detection ..> EntityEvent : evidence
EntityEvent deliberately does not inherit OrpheusBaseEvent — see
ADR 0016 for why (field collision on event_id,
event_timestamp and context). Its evidence is list[EntityEvidence], and
the persisted sibling Entity names its species field species.
2. Detection-Type Taxonomy¶
detection_type |
Producer | Description |
|---|---|---|
audio.motion |
orpheus-agent-audio-motion | Raw audio energy trigger |
species.detected |
orpheus-agent-bird-detection | BirdNET species classification |
crow.analyzed |
orpheus-agent-crow-detection | Crow behavior analysis |
audio.classified |
orpheus-agent-audio-events | PANNs/AudioSet sound-event classification (ADR 0011) |
New agents must register their detection_type string in this table via a
follow-up ADR or PR update.
3. Agent Compliance Rules¶
- Agents must publish events using
Detection.model_dump(mode="json"). - Agents must not construct raw dicts for MQTT payloads when a Pydantic
model exists in
orpheus_common. - The Event Correlator must handle both legacy (root-level
detections) and V2 (metadata-leveldetections) schemas to avoid dropping events during the migration window.
4. Centralised Site Configuration¶
Location data (latitude, longitude, elevation) is centralised in
OrpheusConfig.site (SiteConfig dataclass). Agents and services that need
location must read from this config rather than defining their own location
fields.
Consequences¶
Positive¶
- Single source of truth for event models in
orpheus_common. - Crow agent no longer emits invalid JSON that crashes the Correlator.
- Correlator processes both Bird and Crow events correctly.
- Location config is DRY — defined once in
orpheus.yaml.
Negative¶
- Existing agents require migration to use
Detection.model_dump(). - Correlator must maintain backward-compatible parsing during the transition.
Risks¶
- Agents deployed before the migration will still emit legacy payloads. The Correlator's dual-schema parsing mitigates this.