{
  "milestone": "M5",
  "generated_at_utc": "2026-08-05T09:09:06+00:00",
  "is_real": true,
  "warning": null,
  "status": "ok",
  "error": null,
  "started_at_utc": "2026-08-05T09:08:40+00:00",
  "seconds": 26.48,
  "entrypoint": "python -m pipeline.daily",
  "verdict": {
    "should_retrain": false,
    "action": "watch",
    "severity": "alert",
    "rule": "R3b_distribution_without_measured_harm",
    "rationale": "3 distribution signals are alerting (feature, target, prediction), but the frozen model's error was measured over the same windows and did not degrade. Inputs moved and the model tracked them: that is drift worth watching, not proof the champion needs refitting.",
    "signals": {
      "feature": "alert",
      "target": "alert",
      "prediction": "alert",
      "performance": "ok"
    },
    "reasons": [
      {
        "drift_type": "feature",
        "severity": "alert",
        "metric": "psi",
        "value": 21.292244,
        "threshold": 0.2,
        "detail": "13/14 feature(s) above PSI 0.2; worst is demand_roll_max_24h at PSI 21.292"
      },
      {
        "drift_type": "target",
        "severity": "alert",
        "metric": "psi",
        "value": 0.316566,
        "threshold": 0.2,
        "detail": "actual demand PSI 0.317, mean moved +698 MWh between the reference and current windows"
      },
      {
        "drift_type": "prediction",
        "severity": "alert",
        "metric": "psi",
        "value": 1.300909,
        "threshold": 0.2,
        "detail": "forecast PSI 1.301, mean moved -2,522 MWh (label-free signal: available before the actuals arrive)"
      }
    ],
    "evaluated_at_utc": "2026-08-05T09:09:01+00:00"
  },
  "served_model": {
    "source": "mlflow_registry",
    "uri": "models:/energy-demand-forecaster@champion",
    "registered_model": "energy-demand-forecaster",
    "alias": "champion",
    "version": "3",
    "run_id": "00262eac575e4f168e9324860ed71484",
    "trained_on_real_data": true,
    "data_kind": "eia_api_v2",
    "train_data_end_utc": "2026-08-02T00:00:00+00:00",
    "n_features": 27
  },
  "monitoring_model": {
    "source": "fitted_on_train_window",
    "reason": "the champion was trained on data up to 2026-08-02T00:00:00+00:00, which covers the reference window opening at 2026-07-19T00:00:00+00:00; scoring it there would be in-sample",
    "champion_version": "3",
    "champion_train_data_end_utc": "2026-08-02T00:00:00+00:00"
  },
  "steps": [
    {
      "step": "ingest",
      "status": "ok",
      "seconds": 14.24,
      "sources": "all"
    },
    {
      "step": "features",
      "status": "ok",
      "seconds": 0.34,
      "kind": "eia_api_v2",
      "is_real": true,
      "panel": {
        "rows": 17589,
        "start_utc": "2024-08-01T21:00:00+00:00",
        "end_utc": "2026-08-04T17:00:00+00:00",
        "missing_demand_hours": 0,
        "has_temperature": true,
        "has_weather_forecast": true
      }
    },
    {
      "step": "score",
      "status": "ok",
      "seconds": 5.48,
      "served_model": {
        "source": "mlflow_registry",
        "uri": "models:/energy-demand-forecaster@champion",
        "registered_model": "energy-demand-forecaster",
        "alias": "champion",
        "version": "3",
        "run_id": "00262eac575e4f168e9324860ed71484",
        "trained_on_real_data": true,
        "data_kind": "eia_api_v2",
        "train_data_end_utc": "2026-08-02T00:00:00+00:00",
        "n_features": 27
      },
      "monitoring_model": {
        "source": "fitted_on_train_window",
        "reason": "the champion was trained on data up to 2026-08-02T00:00:00+00:00, which covers the reference window opening at 2026-07-19T00:00:00+00:00; scoring it there would be in-sample",
        "champion_version": "3",
        "champion_train_data_end_utc": "2026-08-02T00:00:00+00:00"
      },
      "anchor_utc": "2026-08-02T00:00:00+00:00",
      "drift_measurable": true,
      "rows": {
        "train": 66020,
        "reference": 1344,
        "current": 220
      }
    },
    {
      "step": "forecast",
      "status": "ok",
      "seconds": 0.35,
      "history_points": 400,
      "forward_points": 24
    },
    {
      "step": "monitor",
      "status": "ok",
      "seconds": 0.21,
      "severity": "ok",
      "days": 17
    },
    {
      "step": "drift",
      "status": "ok",
      "seconds": 5.84,
      "action": "watch",
      "should_retrain": false,
      "signals": {
        "feature": "alert",
        "target": "alert",
        "prediction": "alert",
        "performance": "ok"
      }
    }
  ],
  "artifacts": [
    "drift.json",
    "drift_summary.md",
    "forecast.json",
    "forecast_vs_actual.png",
    "monitor.json",
    "pipeline.json",
    "rolling_mae.png"
  ]
}
