{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://hydro-look.vercel.app/api/schema/adequacy.schema.json",
  "title": "adequacy.json",
  "description": "Expected national energy deficit in GWh/day at 7 to 90 days, the four-level risk tier, the ceilings it assumes and its backtest.",
  "type": "object",
  "required": [
    "schema_version",
    "generated_at",
    "data_date",
    "run_id",
    "origin_date",
    "model",
    "data",
    "assumptions",
    "current",
    "horizons",
    "tiers",
    "tier_history",
    "crisis_check",
    "license",
    "attribution",
    "see_also"
  ],
  "properties": {
    "schema_version": {
      "type": "integer",
      "const": 1,
      "description": "The format version. Changes only when a field is removed, renamed or retyped; added fields do not change it."
    },
    "generated_at": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$",
      "description": "When the document was written, UTC."
    },
    "data_date": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "The Ecuadorian calendar day the document's readings describe."
    },
    "run_id": {
      "type": "string"
    },
    "origin_date": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "The day the model stands on; equal to data_date."
    },
    "units": {
      "type": "string"
    },
    "disclaimer": {
      "type": "string"
    },
    "model": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "label": {
          "type": "string"
        },
        "backtest_origins": {
          "type": "integer"
        }
      },
      "required": [
        "id",
        "label",
        "backtest_origins"
      ]
    },
    "data": {
      "type": "object",
      "properties": {
        "usable_days": {
          "type": "integer"
        },
        "rejected_days": {
          "type": "integer"
        },
        "hydro_anomaly": {
          "type": "number"
        },
        "demand_growth_pct_per_year": {
          "type": "number"
        }
      },
      "required": [
        "usable_days",
        "rejected_days",
        "hydro_anomaly",
        "demand_growth_pct_per_year"
      ]
    },
    "assumptions": {
      "type": "object",
      "properties": {
        "thermal_gwh_day": {
          "type": "number"
        },
        "import_gwh_day": {
          "type": "number"
        },
        "stressed_import_gwh_day": {
          "type": "number"
        },
        "other_gwh_day": {
          "type": "number"
        },
        "editable_at": {
          "type": "string"
        }
      },
      "required": [
        "thermal_gwh_day",
        "import_gwh_day",
        "stressed_import_gwh_day",
        "other_gwh_day",
        "editable_at"
      ]
    },
    "current": {
      "type": "object",
      "properties": {
        "tier": {
          "type": "string",
          "enum": [
            "holgado",
            "vigilancia",
            "ajustado",
            "deficit"
          ],
          "description": "The model's Spanish word. Kept in schema_version 1; use the *_code field beside it."
        },
        "tier_code": {
          "type": "string",
          "enum": [
            "comfortable",
            "watch",
            "tight",
            "deficit"
          ]
        },
        "tier_label_es": {
          "type": "string"
        },
        "worst_tier": {
          "type": "string",
          "enum": [
            "holgado",
            "vigilancia",
            "ajustado",
            "deficit"
          ],
          "description": "The model's Spanish word. Kept in schema_version 1; use the *_code field beside it."
        },
        "worst_tier_code": {
          "type": "string",
          "enum": [
            "comfortable",
            "watch",
            "tight",
            "deficit"
          ]
        },
        "worst_tier_label_es": {
          "type": "string"
        },
        "worst_tier_horizon_days": {
          "type": "integer"
        },
        "worst_deficit_gwh_day": {
          "type": "number"
        },
        "narrative_tier_field": {
          "type": "string",
          "const": "worst_tier",
          "description": "Which of tier and worst_tier the daily narrative is written about."
        }
      },
      "required": [
        "tier",
        "tier_code",
        "tier_label_es",
        "worst_tier",
        "worst_tier_code",
        "worst_tier_label_es",
        "worst_tier_horizon_days",
        "worst_deficit_gwh_day",
        "narrative_tier_field"
      ]
    },
    "horizons": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "properties": {
          "horizon_days": {
            "type": "integer"
          },
          "target_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "demand_gwh_day": {
            "type": "number"
          },
          "hydro_gwh_day": {
            "type": "number"
          },
          "hydro_p10": {
            "type": [
              "number",
              "null"
            ]
          },
          "hydro_p90": {
            "type": [
              "number",
              "null"
            ]
          },
          "requirement_gwh_day": {
            "type": "number"
          },
          "deficit_gwh_day": {
            "type": "number"
          },
          "deficit_p10": {
            "type": [
              "number",
              "null"
            ]
          },
          "deficit_p90": {
            "type": [
              "number",
              "null"
            ]
          },
          "stressed_deficit_gwh_day": {
            "type": "number"
          },
          "margin_pct": {
            "type": "number"
          },
          "tier": {
            "type": "string",
            "enum": [
              "holgado",
              "vigilancia",
              "ajustado",
              "deficit"
            ],
            "description": "The model's Spanish word. Kept in schema_version 1; use the *_code field beside it."
          },
          "tier_code": {
            "type": "string",
            "enum": [
              "comfortable",
              "watch",
              "tight",
              "deficit"
            ]
          },
          "tier_label_es": {
            "type": "string"
          },
          "backtest": {
            "type": "object"
          }
        },
        "required": [
          "horizon_days",
          "target_date",
          "demand_gwh_day",
          "hydro_gwh_day",
          "hydro_p10",
          "hydro_p90",
          "requirement_gwh_day",
          "deficit_gwh_day",
          "deficit_p10",
          "deficit_p90",
          "stressed_deficit_gwh_day",
          "margin_pct",
          "tier",
          "tier_code",
          "tier_label_es",
          "backtest"
        ]
      }
    },
    "tiers": {
      "type": "object",
      "properties": {
        "definition": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          }
        },
        "codes": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "comfortable",
                  "watch",
                  "tight",
                  "deficit"
                ]
              },
              "label_es": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "label_es"
            ]
          }
        }
      },
      "required": [
        "definition",
        "codes"
      ]
    },
    "band_method": {
      "type": "object",
      "description": "How the requirement's p10–p90 band is calibrated. Additive; absent before 2026-09-23.",
      "properties": {
        "method": {
          "type": "string"
        },
        "quantiles": {
          "type": "array",
          "items": {
            "type": "number"
          }
        },
        "nominal_coverage": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "stretch_by_horizon": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "horizon_days": {
                "type": "integer"
              },
              "stretch": {
                "type": [
                  "number",
                  "null"
                ]
              }
            },
            "required": [
              "horizon_days",
              "stretch"
            ]
          }
        }
      },
      "required": [
        "method",
        "quantiles",
        "nominal_coverage",
        "stretch_by_horizon"
      ]
    },
    "import_sensitivity": {
      "type": "object",
      "description": "The deficit and tier under each import assumption from Colombia (ENHANCEMENTS §5.5), so a reader sees how much the tier rests on it. The central case is one of these rows. Additive; absent before 2026-09-23.",
      "properties": {
        "note": {
          "type": "string"
        },
        "central_case": {
          "type": "string",
          "enum": [
            "demonstrated",
            "stressed",
            "current_regime"
          ]
        },
        "cases": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "case": {
                "type": "string",
                "enum": [
                  "demonstrated",
                  "stressed",
                  "current_regime"
                ]
              },
              "import_gwh_day": {
                "type": "number"
              },
              "worst_tier": {
                "type": "string",
                "enum": [
                  "holgado",
                  "vigilancia",
                  "ajustado",
                  "deficit"
                ]
              },
              "worst_tier_horizon_days": {
                "type": "integer"
              },
              "horizons": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "horizon_days": {
                      "type": "integer"
                    },
                    "deficit_gwh_day": {
                      "type": "number"
                    },
                    "deficit_p90": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "GWh/day: the deficit with the requirement at its p90."
                    },
                    "tier": {
                      "type": "string",
                      "enum": [
                        "holgado",
                        "vigilancia",
                        "ajustado",
                        "deficit"
                      ]
                    }
                  },
                  "required": [
                    "horizon_days",
                    "deficit_gwh_day",
                    "deficit_p90",
                    "tier"
                  ]
                }
              }
            },
            "required": [
              "case",
              "import_gwh_day",
              "worst_tier",
              "worst_tier_horizon_days",
              "horizons"
            ]
          }
        }
      },
      "required": [
        "note",
        "central_case",
        "cases"
      ]
    },
    "plant_outage": {
      "type": "object",
      "description": "The deficit and tier if Coca Codo Sinclair were out of service for the whole horizon (PLAN §8a gap 5): its recent share of national hydro is removed from the hydro forecast, with imports and thermal as in the central case. Not a forecast. Additive; absent before 2026-09-24.",
      "required": [
        "note",
        "site",
        "available"
      ],
      "properties": {
        "note": {
          "type": "string"
        },
        "site": {
          "type": "string"
        },
        "available": {
          "type": "boolean",
          "description": "False when too few days of the plant's energy were in the share window; `reason` then says why and no horizons are given."
        },
        "reason": {
          "type": [
            "string",
            "null"
          ]
        },
        "share_of_hydro": {
          "type": "number",
          "minimum": 0,
          "description": "Plant energy over SMEC national hydro across the matched days of the window."
        },
        "plant_gwh_day": {
          "type": "number"
        },
        "share_days": {
          "type": "integer"
        },
        "share_from": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "share_to": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "horizons": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "horizon_days",
              "lost_gwh_day",
              "hydro_gwh_day",
              "deficit_gwh_day",
              "deficit_p90",
              "tier"
            ],
            "properties": {
              "horizon_days": {
                "type": "integer"
              },
              "lost_gwh_day": {
                "type": "number"
              },
              "hydro_gwh_day": {
                "type": "number"
              },
              "deficit_gwh_day": {
                "type": "number"
              },
              "deficit_p90": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "tier": {
                "type": "string",
                "enum": [
                  "holgado",
                  "vigilancia",
                  "ajustado",
                  "deficit"
                ]
              }
            }
          }
        }
      }
    },
    "scorecard": {
      "$ref": "#/$defs/scorecard"
    },
    "tier_history": {
      "type": "object",
      "properties": {
        "horizon_days": {
          "type": "integer"
        },
        "origins": {
          "type": "integer"
        },
        "origins_followed_by_rationing": {
          "type": "integer"
        },
        "origins_flagged": {
          "type": "integer"
        },
        "share_of_flagged_that_preceded_cuts": {
          "type": [
            "number",
            "null"
          ]
        },
        "share_of_cuts_that_were_flagged": {
          "type": [
            "number",
            "null"
          ]
        }
      },
      "required": [
        "horizon_days",
        "origins",
        "origins_followed_by_rationing",
        "origins_flagged",
        "share_of_flagged_that_preceded_cuts",
        "share_of_cuts_that_were_flagged"
      ]
    },
    "crisis_check": {
      "type": "object",
      "properties": {
        "episodes": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "end": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "days": {
                "type": "integer"
              },
              "measured_suppression_gwh_day": {
                "type": "number"
              },
              "implied_deficit_gwh_day": {
                "type": "number"
              }
            },
            "required": [
              "start",
              "end",
              "days",
              "measured_suppression_gwh_day",
              "implied_deficit_gwh_day"
            ]
          }
        }
      },
      "required": [
        "episodes"
      ]
    },
    "license": {
      "$ref": "#/$defs/license"
    },
    "attribution": {
      "$ref": "#/$defs/attribution"
    },
    "see_also": {
      "$ref": "#/$defs/see_also"
    }
  },
  "$defs": {
    "license": {
      "type": "object",
      "properties": {
        "code": {
          "type": "string",
          "const": "MIT"
        },
        "code_url": {
          "type": "string",
          "pattern": "^https?://"
        },
        "data": {
          "type": "string"
        },
        "data_es": {
          "type": "string"
        }
      },
      "required": [
        "code",
        "code_url",
        "data",
        "data_es"
      ]
    },
    "attribution": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "provides": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "pattern": "^https?://"
          },
          "terms": {
            "type": "string"
          },
          "terms_es": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "provides",
          "url",
          "terms",
          "terms_es"
        ]
      }
    },
    "see_also": {
      "type": "object",
      "required": [
        "schema",
        "documentation"
      ],
      "description": "Absolute URLs to the other documents, this document's schema and the documentation page.",
      "additionalProperties": {
        "type": "string",
        "pattern": "^https?://"
      }
    },
    "deprecated": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Fields kept for one more schema version, each with what replaces it."
    },
    "scorecard": {
      "type": "object",
      "description": "How the published adequacy runs (the net requirement, demand minus hydro, mean over the horizon window, GWh/day) did once their horizons passed (ENHANCEMENTS §5.1): every published run scored under the model and version that made it, the last run per origin and version only. Additive; absent in documents written before 2026-09-23.",
      "properties": {
        "generated_at": {
          "type": "string",
          "description": "When the scorecard was computed, UTC."
        },
        "observed_through": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "description": "The last day with an observation to score against."
        },
        "target": {
          "type": "string",
          "description": "The quantity scored, in words."
        },
        "units": {
          "type": "string",
          "enum": [
            "m",
            "GWh/day"
          ]
        },
        "runs_considered": {
          "type": "integer",
          "minimum": 0
        },
        "runs_superseded": {
          "type": "integer",
          "minimum": 0,
          "description": "Runs left out because a later run for the same origin and version replaced them."
        },
        "rows_scored": {
          "type": "integer",
          "minimum": 0
        },
        "rows_pending": {
          "type": "integer",
          "minimum": 0,
          "description": "Published rows whose target date is after observed_through."
        },
        "rows_excluded": {
          "type": "integer",
          "minimum": 0,
          "description": "Rows whose date passed with no usable observation."
        },
        "method": {
          "type": "string"
        },
        "by_horizon": {
          "type": "array",
          "description": "One row per model, model version and horizon with at least one scored row.",
          "items": {
            "type": "object",
            "properties": {
              "model_id": {
                "type": "string"
              },
              "model_version": {
                "type": "string"
              },
              "horizon_days": {
                "type": "integer"
              },
              "n": {
                "type": "integer",
                "minimum": 0
              },
              "mae": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Mean absolute error of the p50, in units."
              },
              "bias": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Mean of observed minus p50, in units."
              },
              "n_band": {
                "type": "integer",
                "minimum": 0,
                "description": "Rows that carried a p10 and a p90."
              },
              "coverage_p10_p90": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Share of banded rows observed inside p10–p90, 0–1."
              },
              "pinball_mean": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Mean pinball loss over p10, p50 and p90."
              },
              "first_origin": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "last_origin": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              }
            },
            "required": [
              "model_id",
              "model_version",
              "horizon_days",
              "n",
              "mae",
              "bias",
              "n_band",
              "coverage_p10_p90",
              "pinball_mean",
              "first_origin",
              "last_origin"
            ]
          }
        },
        "recent": {
          "type": "array",
          "description": "The most recent scored rows, newest target date first.",
          "items": {
            "type": "object",
            "properties": {
              "run_id": {
                "type": "string"
              },
              "model_id": {
                "type": "string"
              },
              "model_version": {
                "type": "string"
              },
              "origin_date": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "horizon_days": {
                "type": "integer"
              },
              "target_date": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "p10": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "p50": {
                "type": "number"
              },
              "p90": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "observed": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "error": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Observed minus p50."
              },
              "in_band": {
                "type": [
                  "boolean",
                  "null"
                ]
              }
            },
            "required": [
              "run_id",
              "model_id",
              "model_version",
              "origin_date",
              "horizon_days",
              "target_date",
              "p10",
              "p50",
              "p90",
              "observed",
              "error",
              "in_band"
            ]
          }
        }
      },
      "required": [
        "generated_at",
        "observed_through",
        "target",
        "units",
        "runs_considered",
        "runs_superseded",
        "rows_scored",
        "rows_pending",
        "rows_excluded",
        "method",
        "by_horizon",
        "recent"
      ]
    }
  }
}
