1. Simple Z-Score Methodology
For each(project_id, connector, metric, date) tuple, toorow computes a standard z-score:
rolling_meanandrolling_stddevare calculated over a trailing 30-day window (ANOMALY_BASELINE_WINDOW=29, 29 preceding days + current row).- Source data is sourced from
fact_daily_kpitotals using single-canonical-dimension selection to prevent double-counting.
dbt/models/marts/metric_baselines.sql and dbt/models/marts/anomalies_daily.sql.
2. Anti-Double-Count Guard
fact_daily_kpi contains parallel breakdown dimension series (e.g. device_category and country) that independently total the day’s activity. Summing across all breakdown rows directly would produce values 2–5x too large.
metric_baselines.sql enforces the canonical_dim pattern to select ONE breakdown dimension per (project, connector, metric) deterministically (MIN(breakdown_dimension)), aggregating exclusively over that dimension’s rows.
3. Thresholds & Severity Levels
An anomaly is flagged whenever|zscore| >= ANOMALY_Z_THRESHOLD (default 3.0):
4. Context Event Citations (AD-9)
Anomalies never assert causality (AD-9 requirement). When context events exist for an anomaly date, they are listed strictly as candidate context. Prohibited causal phrases in generated messages:"caused by","due to","because of","en raison de","causé par".
test_causal_language_absent in server/tests/core/test_anomaly_alerts.py.
5. Environment Variables
Next Steps & Cross-References
Agentic Daily Insights
Learn how AI agents ingest anomaly notifications during morning briefings.
Semantic Layer
Explore the canonical marts providing baseline metric data.
Security & Constraints
Review AD-9 non-black-box provenance invariants.
Self-Hosting Guide
Configure
ANOMALY_ALERTS_ENABLED in your .env deployment environment.
