//! ObserverProfile — how loudly the observer logs this workload. //! //! Phase 41 decomposition: the observer's alert thresholds, escalation //! cadence, and log retention need per-workload tuning. Hot-path //! staffing workflows want aggressive alerting; batch backfills want //! quieter. This profile is read by mcp-server/observer.ts at //! activation-time. use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ObserverProfile { pub id: String, #[serde(default)] pub description: String, /// How many consecutive failures trigger a cluster escalation to /// LLM Team `/v1/chat` (qwen3-coder:480b). #[serde(default = "default_failure_cluster_size")] pub failure_cluster_size: u32, /// Minimum seconds between alert emails for the same sig_hash. /// Prevents alert storms during a regression. #[serde(default = "default_alert_cooldown")] pub alert_cooldown_secs: u32, /// Observer ring buffer size. Older events fall off when full. #[serde(default = "default_ring_size")] pub ring_size: usize, /// Whether to forward events to external Langfuse /// (/v1/langfuse_trace). Off by default. #[serde(default)] pub forward_to_langfuse: bool, pub created_at: chrono::DateTime, #[serde(default)] pub created_by: String, } fn default_failure_cluster_size() -> u32 { 3 } fn default_alert_cooldown() -> u32 { 300 } // 5 minutes fn default_ring_size() -> usize { 2000 }