{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://modelos.inverence-llull.com/ficha-0.10.schema.json",
  "title": "Ficha de modelo — contrato v0.10, revisión r1",
  "description": "Contrato de RECEPCIÓN de la ficha 0.10, escrito por la plataforma desde los documentos del emisor (TolLlull/doc, commit 30a38c5c) y validado contra las 17 fichas de deliver/ejemplos (ING-2, recon en llull-platform docs/recon-ficha-0-10/). Es NUESTRO contrato: donde un documento del emisor habla, manda el documento; donde calla, la forma es una decisión nuestra, anotada en el nodo con `x-decision`, y si además va en la carta al emisor, con `x-pregunta` (P = petición, F = pregunta). Revisión r1, fijada por sha256: dentro de 0.10 sólo se AÑADE; quitar o endurecer algo exige que el emisor suba a 0.11. La forma: tres claves (schema_version en la raíz y sólo ahí, metadata, model).",
  "x-revision": "r1",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "metadata",
    "model"
  ],
  "properties": {
    "schema_version": {
      "const": "0.10",
      "description": "Cadena, nunca número: 0.10 ≠ 0.1, y como texto 0.10 < 0.9."
    },
    "metadata": {
      "type": "object",
      "description": "Once secciones; lo que el modelo no puede contar de sí mismo. Una sección sin contenido se escribe con {\"content\": \"none\"}, salvo las que llevan un campo obligatorio.",
      "additionalProperties": false,
      "required": [
        "identity",
        "runtime",
        "data",
        "estimation",
        "invocation",
        "outputs",
        "operations",
        "sources",
        "artifact",
        "flex_store_config",
        "limits"
      ],
      "properties": {
        "identity": {
          "$ref": "#/$defs/identity"
        },
        "runtime": {
          "oneOf": [
            {
              "$ref": "#/$defs/runtime"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "data": {
          "oneOf": [
            {
              "$ref": "#/$defs/data"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "estimation": {
          "oneOf": [
            {
              "$ref": "#/$defs/estimation"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "invocation": {
          "oneOf": [
            {
              "$ref": "#/$defs/invocation"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "outputs": {
          "oneOf": [
            {
              "$ref": "#/$defs/outputs"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "operations": {
          "$ref": "#/$defs/operations"
        },
        "sources": {
          "oneOf": [
            {
              "$ref": "#/$defs/sources"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "artifact": {
          "$ref": "#/$defs/artifact"
        },
        "flex_store_config": {
          "oneOf": [
            {
              "$ref": "#/$defs/flex_store_config"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "limits": {
          "$ref": "#/$defs/limits"
        }
      }
    },
    "model": {
      "type": "object",
      "description": "Doce tablas, siempre las doce; la de parámetros se llama parameters_mle o parameters_bys y nunca coexisten.",
      "additionalProperties": false,
      "required": [
        "stats",
        "convergence",
        "relations",
        "workbook",
        "series_fit",
        "series_input_output",
        "forecast",
        "diagnostics",
        "correlations",
        "conditioning",
        "mcmc"
      ],
      "oneOf": [
        {
          "required": [
            "parameters_mle"
          ],
          "not": {
            "required": [
              "parameters_bys"
            ]
          }
        },
        {
          "required": [
            "parameters_bys"
          ],
          "not": {
            "required": [
              "parameters_mle"
            ]
          }
        }
      ],
      "properties": {
        "stats": {
          "type": "array"
        },
        "parameters_mle": {
          "oneOf": [
            {
              "$ref": "#/$defs/parameters_mle"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "parameters_bys": {
          "oneOf": [
            {
              "$ref": "#/$defs/parameters_bys"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "convergence": {
          "oneOf": [
            {
              "$ref": "#/$defs/convergence"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "relations": {
          "oneOf": [
            {
              "$ref": "#/$defs/relations"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "workbook": {
          "oneOf": [
            {
              "$ref": "#/$defs/workbook"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "series_fit": {
          "oneOf": [
            {
              "$ref": "#/$defs/series_fit"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "series_input_output": {
          "oneOf": [
            {
              "$ref": "#/$defs/series_input_output"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "forecast": {
          "type": "object"
        },
        "diagnostics": {
          "oneOf": [
            {
              "$ref": "#/$defs/diagnostics"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        },
        "correlations": {
          "oneOf": [
            {
              "$ref": "#/$defs/correlations"
            },
            {
              "$ref": "#/$defs/encodingNone"
            }
          ]
        },
        "conditioning": {
          "oneOf": [
            {
              "$ref": "#/$defs/conditioning"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ],
          "x-decision": "No es una sección comprimida (va en precisión completa): vacía se declara con {\"content\": \"none\"}, como se emite, y no con encoding."
        },
        "mcmc": {
          "oneOf": [
            {
              "$ref": "#/$defs/mcmc"
            },
            {
              "$ref": "#/$defs/encodingNone"
            }
          ]
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_frame": {
                    "const": "@ModelDef"
                  }
                },
                "required": [
                  "model_frame"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "stats": {
                "$ref": "#/$defs/stats_modeldef"
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_frame": {
                    "const": "ModelExcel"
                  }
                },
                "required": [
                  "model_frame"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "stats": {
                "$ref": "#/$defs/stats_node"
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-MLE"
                  }
                },
                "required": [
                  "model_class"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "required": [
              "parameters_mle"
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-BSR"
                  }
                },
                "required": [
                  "model_class"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "required": [
              "parameters_bys"
            ]
          }
        }
      }
    },
    {
      "x-decision": "XARIMA-BSR con model_frame @ModelDef se rechaza: no está entre las cinco clases que el contrato mide hoy. Se abre cuando el emisor lo emita.",
      "not": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-BSR"
                  },
                  "model_frame": {
                    "const": "@ModelDef"
                  }
                },
                "required": [
                  "model_class",
                  "model_frame"
                ]
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-MLE"
                  },
                  "model_frame": {
                    "const": "@ModelDef"
                  }
                },
                "required": [
                  "model_class",
                  "model_frame"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "convergence": {
                "$ref": "#/$defs/contentNone"
              },
              "relations": {
                "$ref": "#/$defs/contentNone"
              },
              "workbook": {
                "$ref": "#/$defs/contentNone"
              },
              "series_fit": {
                "$ref": "#/$defs/series_fit"
              },
              "mcmc": {
                "$ref": "#/$defs/encodingNone"
              }
            }
          },
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "submodel": {
                    "const": ""
                  },
                  "children": {
                    "maxItems": 0
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-MLE"
                  },
                  "model_frame": {
                    "const": "ModelExcel"
                  },
                  "submodel": {
                    "const": ""
                  }
                },
                "required": [
                  "model_class",
                  "model_frame",
                  "submodel"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "parameters_mle": {
                "$ref": "#/$defs/contentNone"
              },
              "convergence": {
                "$ref": "#/$defs/contentNone"
              },
              "workbook": {
                "$ref": "#/$defs/workbook"
              },
              "series_fit": {
                "$ref": "#/$defs/contentNone"
              },
              "series_input_output": {
                "$ref": "#/$defs/contentNone"
              },
              "diagnostics": {
                "$ref": "#/$defs/contentNone"
              },
              "correlations": {
                "$ref": "#/$defs/encodingNone"
              },
              "conditioning": {
                "$ref": "#/$defs/contentNone"
              },
              "mcmc": {
                "$ref": "#/$defs/encodingNone"
              },
              "forecast": {
                "$ref": "#/$defs/contentNone"
              }
            }
          },
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "children": {
                    "minItems": 1
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-MLE"
                  },
                  "model_frame": {
                    "const": "ModelExcel"
                  },
                  "submodel": {
                    "minLength": 1
                  }
                },
                "required": [
                  "model_class",
                  "model_frame",
                  "submodel"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "convergence": {
                "$ref": "#/$defs/contentNone"
              },
              "relations": {
                "$ref": "#/$defs/contentNone"
              },
              "workbook": {
                "$ref": "#/$defs/contentNone"
              },
              "series_fit": {
                "$ref": "#/$defs/series_fit"
              },
              "mcmc": {
                "$ref": "#/$defs/encodingNone"
              }
            }
          },
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "children": {
                    "maxItems": 0
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-BSR"
                  },
                  "model_frame": {
                    "const": "ModelExcel"
                  },
                  "submodel": {
                    "const": ""
                  }
                },
                "required": [
                  "model_class",
                  "model_frame",
                  "submodel"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "convergence": {
                "$ref": "#/$defs/convergence"
              },
              "workbook": {
                "$ref": "#/$defs/workbook"
              },
              "series_fit": {
                "$ref": "#/$defs/contentNone"
              },
              "series_input_output": {
                "$ref": "#/$defs/contentNone"
              },
              "diagnostics": {
                "$ref": "#/$defs/contentNone"
              },
              "correlations": {
                "$ref": "#/$defs/encodingNone"
              },
              "conditioning": {
                "$ref": "#/$defs/contentNone"
              },
              "forecast": {
                "$ref": "#/$defs/contentNone"
              }
            }
          },
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "children": {
                    "minItems": 1
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "model_class": {
                    "const": "XARIMA-BSR"
                  },
                  "model_frame": {
                    "const": "ModelExcel"
                  },
                  "submodel": {
                    "minLength": 1
                  }
                },
                "required": [
                  "model_class",
                  "model_frame",
                  "submodel"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "parameters_bys": {
                "$ref": "#/$defs/parameters_bys"
              },
              "convergence": {
                "$ref": "#/$defs/convergence"
              },
              "relations": {
                "$ref": "#/$defs/contentNone"
              },
              "workbook": {
                "$ref": "#/$defs/contentNone"
              },
              "series_fit": {
                "$ref": "#/$defs/series_fit"
              },
              "diagnostics": {
                "$ref": "#/$defs/contentNone"
              },
              "correlations": {
                "$ref": "#/$defs/encodingNone"
              },
              "conditioning": {
                "$ref": "#/$defs/contentNone"
              },
              "mcmc": {
                "$ref": "#/$defs/encodingNone"
              }
            }
          },
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "children": {
                    "maxItems": 0
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "forecast_method": {
                    "const": "point.modal"
                  }
                },
                "required": [
                  "forecast_method"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "forecast": {
                "oneOf": [
                  {
                    "$ref": "#/$defs/forecast_point_modal"
                  },
                  {
                    "$ref": "#/$defs/contentNone"
                  }
                ]
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "forecast_method": {
                    "const": "point.median"
                  }
                },
                "required": [
                  "forecast_method"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "forecast": {
                "oneOf": [
                  {
                    "$ref": "#/$defs/forecast_point_median"
                  },
                  {
                    "$ref": "#/$defs/contentNone"
                  }
                ]
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "metadata": {
            "properties": {
              "identity": {
                "properties": {
                  "forecast_method": {
                    "const": "point.mean"
                  }
                },
                "required": [
                  "forecast_method"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "model": {
            "properties": {
              "forecast": {
                "oneOf": [
                  {
                    "$ref": "#/$defs/forecast_point_mean"
                  },
                  {
                    "$ref": "#/$defs/contentNone"
                  }
                ]
              }
            }
          }
        }
      }
    }
  ],
  "$defs": {
    "nan": {
      "const": "NaN",
      "description": "Real desconocido (las-secciones-comprimidas, «Los no finitos y las fechas»)."
    },
    "real": {
      "description": "Real: número, o \"NaN\" / \"+Inf\" / \"-Inf\" como CADENA. Nunca null ni literal pelado.",
      "oneOf": [
        {
          "type": "number"
        },
        {
          "enum": [
            "+Inf",
            "-Inf",
            "NaN"
          ]
        }
      ]
    },
    "realOrNaN": {
      "oneOf": [
        {
          "type": "number"
        },
        {
          "$ref": "#/$defs/nan"
        }
      ]
    },
    "intOrNaN": {
      "oneOf": [
        {
          "type": "integer"
        },
        {
          "$ref": "#/$defs/nan"
        }
      ]
    },
    "flag01": {
      "enum": [
        0,
        1
      ],
      "description": "Bandera numérica 0/1."
    },
    "flag01OrNaN": {
      "oneOf": [
        {
          "enum": [
            0,
            1
          ]
        },
        {
          "$ref": "#/$defs/nan"
        }
      ]
    },
    "date": {
      "description": "Fecha: 10 caracteres día completo, 19 intradía, o \"NaT\" (las-secciones-comprimidas).",
      "oneOf": [
        {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
        },
        {
          "const": "NaT"
        }
      ]
    },
    "text": {
      "type": "string"
    },
    "textList": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "realList": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/real"
      }
    },
    "intList": {
      "type": "array",
      "items": {
        "type": "integer"
      }
    },
    "dateList": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/date"
      }
    },
    "contentNone": {
      "description": "Sección corriente declarada vacía (regla de autodescripción): exactamente {\"content\": \"none\"}.",
      "type": "object",
      "properties": {
        "content": {
          "const": "none"
        }
      },
      "required": [
        "content"
      ],
      "additionalProperties": false
    },
    "encodingNone": {
      "description": "Sección comprimida declarada vacía: exactamente {\"encoding\": \"none\"}, SIN scale.",
      "type": "object",
      "properties": {
        "encoding": {
          "const": "none"
        }
      },
      "required": [
        "encoding"
      ],
      "additionalProperties": false
    },
    "identity": {
      "type": "object",
      "description": "Quién es este modelo (contrato, «identity»). Veintitrés campos + `scope` opcional.",
      "additionalProperties": false,
      "required": [
        "client",
        "project",
        "model_id",
        "model_version",
        "submodel",
        "children",
        "model_class",
        "model_frame",
        "model_name",
        "purpose",
        "task_type",
        "task_type_other",
        "task_parameters",
        "owner",
        "client_phase",
        "creation_time",
        "frequency",
        "arima_label",
        "constant_term",
        "forecast_method",
        "keep_instance",
        "model_comment",
        "version_comment"
      ],
      "properties": {
        "client": {
          "type": "string",
          "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
        },
        "project": {
          "type": "string",
          "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
        },
        "model_id": {
          "type": "string",
          "pattern": "^[A-Za-z0-9._-]+$",
          "description": "Concepto, no ejecución. OBLIGATORIO."
        },
        "model_version": {
          "type": "string",
          "pattern": "^\\d+\\.\\d+(\\.\\d+)?$",
          "description": "OBLIGATORIO con forma x.y o x.y.z (changes.0.10, «Lo que se exige»)."
        },
        "submodel": {
          "type": "string",
          "pattern": "^[A-Za-z0-9._-]*$",
          "description": "\"\" en la raíz y en un modelo suelto."
        },
        "children": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._-]+$"
          },
          "uniqueItems": true,
          "description": "Hijos que declara la raíz; vacía en una hoja y en un modelo suelto."
        },
        "model_class": {
          "enum": [
            "XARIMA-MLE",
            "XARIMA-BSR"
          ]
        },
        "model_frame": {
          "enum": [
            "@ModelDef",
            "ModelExcel"
          ]
        },
        "model_name": {
          "type": "string"
        },
        "purpose": {
          "type": "string",
          "minLength": 1,
          "description": "OBLIGATORIO."
        },
        "task_type": {
          "type": "string"
        },
        "task_type_other": {
          "type": "string"
        },
        "task_parameters": {
          "type": "string"
        },
        "owner": {
          "type": "string"
        },
        "client_phase": {
          "enum": [
            "exploracion",
            "piloto",
            "produccion",
            ""
          ],
          "x-decision": "Los tokens tal como los emite el emisor, sin tildes (el documento del emisor los escribe en prosa con ellas)."
        },
        "creation_time": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
          "description": "Instante de la estimación, en UTC y explícito."
        },
        "frequency": {
          "enum": [
            "Daily",
            "T.monthly",
            "Mensual"
          ],
          "x-decision": "Vocabulario CERRADO con las tres grafías que se emiten hoy; otro valor se rechaza. La plataforma las lleva a un canónico propio (diario, mensual). La clave del fechado de las tablas de series se llama como este valor (regla R3 del decoder).",
          "x-pregunta": "P3"
        },
        "arima_label": {
          "type": "string"
        },
        "constant_term": {
          "$ref": "#/$defs/realOrNaN",
          "x-decision": "Real o \"NaN\"; informativo, la plataforma no lo lee.",
          "x-pregunta": "F4"
        },
        "forecast_method": {
          "enum": [
            "point.modal",
            "point.median",
            "point.mean"
          ],
          "x-decision": "sample.mean se RECHAZA hasta que el contrato del emisor diga cómo se llaman las claves de los veintisiete cuantiles en forecast (ninguna ficha lo emite hoy).",
          "x-pregunta": "F6"
        },
        "keep_instance": {
          "$ref": "#/$defs/flag01OrNaN",
          "x-decision": "0, 1 o \"NaN\"; es la política de purga del archivo del emisor y la plataforma no la lee.",
          "x-pregunta": "F4"
        },
        "model_comment": {
          "type": "string"
        },
        "version_comment": {
          "type": "string"
        }
      },
      "x-decision": "`scope` («las dimensiones del modelo; si está vacío no viaja») NO tiene sitio: presente = rechazo hasta que el emisor especifique su tipo y su forma. Un campo que no sabemos leer no entra en silencio.",
      "x-pregunta": "P5"
    },
    "runtime": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "emitter",
        "engine",
        "hostname",
        "operating_system",
        "source_encoding",
        "source_locale",
        "packaging",
        "build_artifacts"
      ],
      "properties": {
        "emitter": {
          "type": "string"
        },
        "engine": {
          "type": "string",
          "description": "Con el nombre del lenguaje delante: «TOL v4.1 p000 …»."
        },
        "hostname": {
          "type": "string"
        },
        "operating_system": {
          "type": "string"
        },
        "source_encoding": {
          "type": "string"
        },
        "source_locale": {
          "type": "string"
        },
        "packaging": {
          "type": "string"
        },
        "build_artifacts": {
          "type": "string"
        }
      }
    },
    "transform": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "kind",
        "formula",
        "exponent",
        "shift",
        "regularized"
      ],
      "properties": {
        "kind": {
          "enum": [
            "box_cox"
          ],
          "x-decision": "Vocabulario CERRADO: box_cox, la única transformación que se emite hoy; otra se rechaza."
        },
        "formula": {
          "type": "string"
        },
        "exponent": {
          "type": "number"
        },
        "shift": {
          "type": "number"
        },
        "regularized": {
          "$ref": "#/$defs/flag01",
          "x-decision": "0/1 aceptado; «distingue las dos Box-Cox que existen». Deshacer la regularizada es de serving, no de recepción, y espera a su fórmula.",
          "x-pregunta": "P17"
        }
      }
    },
    "data": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "granularity",
        "units_and_scale",
        "drivers",
        "transform"
      ],
      "properties": {
        "granularity": {
          "type": "string"
        },
        "units_and_scale": {
          "type": "string"
        },
        "drivers": {
          "type": "string"
        },
        "transform": {
          "oneOf": [
            {
              "$ref": "#/$defs/transform"
            },
            {
              "$ref": "#/$defs/contentNone"
            }
          ]
        }
      }
    },
    "estimation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "algorithm",
        "estimation_method",
        "estimation_window",
        "estimation_call",
        "is_deterministic"
      ],
      "properties": {
        "algorithm": {
          "type": "string"
        },
        "estimation_method": {
          "type": "string"
        },
        "estimation_window": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}:\\d{2})? \\.\\. \\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}:\\d{2})?$",
          "x-decision": "Parte de la CLAVE del modelo: la gramática que se emite hoy, «AAAA-MM-DD[ hh:mm:ss] .. AAAA-MM-DD[ hh:mm:ss]», queda fijada.",
          "x-pregunta": "P7"
        },
        "estimation_call": {
          "type": "string"
        },
        "is_deterministic": {
          "$ref": "#/$defs/flag01OrNaN",
          "x-decision": "0, 1 o \"NaN\"; informativo."
        }
      }
    },
    "invocation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "run_arguments",
        "resulting_objects"
      ],
      "properties": {
        "run_arguments": {
          "type": "string"
        },
        "resulting_objects": {
          "type": "string"
        }
      }
    },
    "outputs": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "produces",
        "other_output",
        "forecast_entry_point",
        "band_entry_point",
        "band_level",
        "needs_extra_step",
        "output_scale",
        "result_format_units"
      ],
      "properties": {
        "produces": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "uniqueItems": true,
          "x-decision": "Lista de texto; informativa, la plataforma no la lee (viaja [] en las 17)."
        },
        "other_output": {
          "type": "string"
        },
        "forecast_entry_point": {
          "type": "string"
        },
        "band_entry_point": {
          "type": "string"
        },
        "band_level": {
          "type": "string",
          "x-decision": "Texto libre e informativo («0.05» en el M30, una frase en los árboles, \"\" en el resto). El nivel con el que sirve la plataforma lo fija el anexo de alta, no este campo.",
          "x-pregunta": "P18"
        },
        "needs_extra_step": {
          "type": "string"
        },
        "output_scale": {
          "type": "string"
        },
        "result_format_units": {
          "type": "string"
        }
      }
    },
    "operations": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "reestimation_cadence",
        "resource_profile"
      ],
      "properties": {
        "reestimation_cadence": {
          "type": "string",
          "minLength": 1,
          "description": "OBLIGATORIO."
        },
        "resource_profile": {
          "type": "string"
        }
      }
    },
    "sources": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "repo",
        "files"
      ],
      "properties": {
        "repo": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "url",
            "branch",
            "commit",
            "dirty"
          ],
          "properties": {
            "url": {
              "type": "string",
              "pattern": "^https://"
            },
            "branch": {
              "type": "string"
            },
            "commit": {
              "type": "string",
              "pattern": "^[0-9a-f]{40}$"
            },
            "dirty": {
              "enum": [
                "yes",
                "no"
              ],
              "x-decision": "\"yes\"/\"no\", tal como se emite (semántica booleana en la prosa del emisor).",
              "x-pregunta": "P13"
            }
          }
        },
        "files": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "path",
              "size",
              "sha256",
              "in_repo"
            ],
            "properties": {
              "path": {
                "type": "string",
                "minLength": 1,
                "description": "Relativa al repositorio."
              },
              "size": {
                "type": "integer",
                "minimum": 0
              },
              "sha256": {
                "type": "string",
                "pattern": "^[0-9a-f]{64}$"
              },
              "in_repo": {
                "enum": [
                  "yes",
                  "no"
                ],
                "x-decision": "\"yes\"/\"no\", tal como se emite."
              },
              "role": {
                "type": "string",
                "x-decision": "Opcional e informativo: viaja en las 17 y el contrato del emisor no lo nombra."
              }
            }
          }
        }
      }
    },
    "artifact": {
      "oneOf": [
        {
          "$ref": "#/$defs/contentNone"
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "serialized"
          ],
          "properties": {
            "serialized": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "additionalProperties": true,
                "required": [
                  "path",
                  "sha256",
                  "size"
                ],
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "loader": {
                    "type": "string"
                  },
                  "load_path": {
                    "type": "string"
                  },
                  "sha256": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{64}$"
                  },
                  "size": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "x-decision": "La forma de la 0.9 (path, sha256, size, loader, load_path). Sin esta declaración, con los bytes que la casen, no hay grado ejecutable.",
                "x-pregunta": "P12"
              }
            }
          }
        }
      ]
    },
    "flex_store_config": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "full_distrib_round",
        "in_out_ts",
        "res_fcst_ts",
        "periodic_purge"
      ],
      "properties": {
        "full_distrib_round": {
          "type": "integer",
          "minimum": 0,
          "description": "0 = la conjunta ni se guarda ni se envía."
        },
        "in_out_ts": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "relational",
            "card"
          ],
          "properties": {
            "relational": {
              "$ref": "#/$defs/flag01"
            },
            "card": {
              "$ref": "#/$defs/flag01"
            }
          }
        },
        "res_fcst_ts": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "relational",
            "card",
            "nu_sigmas_purge",
            "nu_sigmas_outlier"
          ],
          "properties": {
            "relational": {
              "$ref": "#/$defs/flag01"
            },
            "card": {
              "$ref": "#/$defs/flag01"
            },
            "nu_sigmas_purge": {
              "type": "number"
            },
            "nu_sigmas_outlier": {
              "type": "number"
            }
          }
        },
        "periodic_purge": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "day",
            "week",
            "month",
            "year"
          ],
          "properties": {
            "day": {
              "type": "string"
            },
            "week": {
              "type": "string"
            },
            "month": {
              "type": "string"
            },
            "year": {
              "type": "string"
            }
          },
          "x-decision": "Cuatro claves de texto; es la política de purga del archivo del emisor y la plataforma no la lee."
        }
      }
    },
    "limits": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "max_forecasts",
        "max_horizon",
        "licit_aggregations",
        "band_caveats",
        "invalidation_conditions"
      ],
      "properties": {
        "max_forecasts": {
          "type": "integer",
          "minimum": 0,
          "description": "OBLIGATORIO; el que manda."
        },
        "max_horizon": {
          "type": "string"
        },
        "licit_aggregations": {
          "type": "string"
        },
        "band_caveats": {
          "type": "string"
        },
        "invalidation_conditions": {
          "type": "string"
        }
      }
    },
    "parameters_mle": {
      "type": "object",
      "description": "Traspuesta sin escalar, ocho cifras significativas. Listas paralelas de la misma longitud.",
      "additionalProperties": false,
      "required": [
        "Name",
        "Factor",
        "Order",
        "Value",
        "StDs",
        "TStudent",
        "RefuseProb",
        "Role",
        "Gradient",
        "Fixed"
      ],
      "properties": {
        "Name": {
          "$ref": "#/$defs/textList"
        },
        "Factor": {
          "$ref": "#/$defs/intList"
        },
        "Order": {
          "$ref": "#/$defs/intList"
        },
        "Value": {
          "$ref": "#/$defs/realList"
        },
        "StDs": {
          "$ref": "#/$defs/realList"
        },
        "TStudent": {
          "$ref": "#/$defs/realList"
        },
        "RefuseProb": {
          "$ref": "#/$defs/realList"
        },
        "Role": {
          "type": "array",
          "items": {
            "enum": [
              "transfer",
              "ar",
              "ma",
              "sigma",
              "hyper"
            ]
          },
          "x-decision": "Vocabulario CERRADO, el mismo en las dos clases: transfer, ar, ma (las dos) y sigma, hyper (sólo bayesiano). Otro valor se rechaza.",
          "x-pregunta": "F5"
        },
        "Gradient": {
          "$ref": "#/$defs/realList",
          "description": "Alineada con TODAS las filas; un fijo lleva \"NaN\" en su posición."
        },
        "Fixed": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/flag01"
          }
        }
      }
    },
    "parameters_bys": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "Name",
        "Role",
        "Factor",
        "Order",
        "Scope",
        "Mean",
        "Sd",
        "SeTmser",
        "RhatSplit",
        "Ess",
        "PIsZero",
        "Mode",
        "ModeAtBound",
        "BoundLow",
        "BoundHigh",
        "Quantiles"
      ],
      "properties": {
        "Name": {
          "$ref": "#/$defs/textList"
        },
        "Role": {
          "type": "array",
          "items": {
            "enum": [
              "transfer",
              "ar",
              "ma",
              "sigma",
              "hyper"
            ]
          },
          "x-decision": "Vocabulario CERRADO, el mismo en las dos clases: transfer, ar, ma (las dos) y sigma, hyper (sólo bayesiano). Otro valor se rechaza.",
          "x-pregunta": "F5"
        },
        "Factor": {
          "$ref": "#/$defs/intList"
        },
        "Order": {
          "$ref": "#/$defs/intList"
        },
        "Scope": {
          "type": "array",
          "items": {
            "enum": [
              "own",
              "shared",
              "hyper"
            ]
          },
          "x-decision": "Vocabulario CERRADO: own, shared (documentados) y hyper (lo emite la raíz). Otro valor se rechaza.",
          "x-pregunta": "F5"
        },
        "Mean": {
          "$ref": "#/$defs/realList"
        },
        "Sd": {
          "$ref": "#/$defs/realList"
        },
        "SeTmser": {
          "$ref": "#/$defs/realList"
        },
        "RhatSplit": {
          "$ref": "#/$defs/realList"
        },
        "Ess": {
          "$ref": "#/$defs/realList"
        },
        "PIsZero": {
          "$ref": "#/$defs/realList"
        },
        "Mode": {
          "$ref": "#/$defs/realList"
        },
        "ModeAtBound": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/flag01OrNaN"
          }
        },
        "BoundLow": {
          "type": "array",
          "items": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "enum": [
                  "-Inf",
                  "NaN"
                ]
              }
            ]
          },
          "description": "Sin cota = \"-Inf\", no \"NaN\"."
        },
        "BoundHigh": {
          "type": "array",
          "items": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "enum": [
                  "+Inf",
                  "NaN"
                ]
              }
            ]
          },
          "description": "Sin cota = \"+Inf\", no \"NaN\"."
        },
        "ModeMethod": {
          "type": "string",
          "x-decision": "Escalar de la TABLA entera, no una lista paralela (lo nombra el árbol de fichas del emisor, no su contrato).",
          "x-pregunta": "F7"
        },
        "DiagSource": {
          "type": "string",
          "x-decision": "Ídem ModeMethod.",
          "x-pregunta": "F7"
        },
        "Quantiles": {
          "type": "array",
          "items": {
            "type": "array",
            "minItems": 27,
            "maxItems": 27,
            "items": {
              "$ref": "#/$defs/real"
            }
          },
          "description": "Una fila por parámetro, 27 columnas en el orden 0, 0.001, 0.01, 0.025, 0.05, 0.10 … 0.90, 0.95, 0.975, 0.99, 0.999, 1."
        }
      }
    },
    "convergence": {
      "type": "object",
      "description": "Objeto de ESCALARES, la excepción a la forma del resto de model.",
      "additionalProperties": false,
      "required": [
        "RhatMax",
        "RhatMaxName",
        "EssMin",
        "EssMinName",
        "Unknowns",
        "Draws",
        "Verdict"
      ],
      "properties": {
        "RhatMax": {
          "$ref": "#/$defs/real"
        },
        "RhatMaxName": {
          "type": "string"
        },
        "EssMin": {
          "$ref": "#/$defs/real"
        },
        "EssMinName": {
          "type": "string"
        },
        "Unknowns": {
          "type": "integer",
          "minimum": 0
        },
        "Draws": {
          "type": "integer",
          "minimum": 0
        },
        "Verdict": {
          "enum": [
            "unknown",
            "not converged",
            "short sample",
            "ok"
          ]
        }
      }
    },
    "relations": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "Name",
        "Kind",
        "Parameters",
        "Submodels"
      ],
      "properties": {
        "Name": {
          "$ref": "#/$defs/textList"
        },
        "Kind": {
          "type": "array",
          "items": {
            "const": "equivalence"
          },
          "description": "Hoy sólo viajan las equivalencias."
        },
        "Parameters": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/textList"
          }
        },
        "Submodels": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/textList"
          }
        }
      }
    },
    "workbook": {
      "type": "object",
      "description": "El libro ya interpretado: doce tablas, cada una con columns + rows, con la forma de las tablas del almacén.",
      "additionalProperties": false,
      "required": [
        "main",
        "submodels",
        "parameters",
        "hierarchies",
        "hierarchies_term",
        "hierarchies_def",
        "hierarchies_def_coef",
        "hyperparameters",
        "equations",
        "equations_def",
        "variables",
        "variables_open"
      ],
      "properties": {
        "main": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 4,
              "maxItems": 4,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "module",
                  "attribute",
                  "value"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 4,
                "maxItems": 4,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "submodels": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 12,
              "maxItems": 12,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "output",
                  "description",
                  "type",
                  "grammar",
                  "transformation",
                  "noise_type",
                  "arima_label",
                  "is_active",
                  "begins",
                  "ends",
                  "weight"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 12,
                "maxItems": 12,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "parameters": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 15,
              "maxItems": 15,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "output",
                  "input",
                  "is_active",
                  "is_additive",
                  "initial",
                  "minimum",
                  "maximum",
                  "prior_mean",
                  "prior_sigma",
                  "degree",
                  "is_fixed",
                  "order_group",
                  "order_index",
                  "order_coefficient"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 15,
                "maxItems": 15,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "hierarchies": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 5,
              "maxItems": 5,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "hierarchy",
                  "is_active",
                  "sigma",
                  "sigma_weight"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 5,
                "maxItems": 5,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "hierarchies_term": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 3,
              "maxItems": 3,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "term_index",
                  "term"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 3,
                "maxItems": 3,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "hierarchies_def": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 6,
              "maxItems": 6,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "hierarchy",
                  "output",
                  "input",
                  "degree",
                  "relative_sigma"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 6,
                "maxItems": 6,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "hierarchies_def_coef": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 3,
              "maxItems": 3,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "term_index",
                  "coefficient"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 3,
                "maxItems": 3,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "hyperparameters": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 9,
              "maxItems": 9,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "hierarchy",
                  "term",
                  "initial",
                  "minimum",
                  "maximum",
                  "prior_mean",
                  "prior_sigma",
                  "is_fixed"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 9,
                "maxItems": 9,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "equations": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 8,
              "maxItems": 8,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "type",
                  "equation",
                  "minimum",
                  "maximum",
                  "prior_mean",
                  "prior_sigma",
                  "initial"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 8,
                "maxItems": 8,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "equations_def": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 6,
              "maxItems": 6,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "equation",
                  "output",
                  "input",
                  "degree",
                  "coefficient"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 6,
                "maxItems": 6,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "variables": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 22,
              "maxItems": 22,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "sheet",
                  "name",
                  "scenario",
                  "description",
                  "type",
                  "expression",
                  "use_cache",
                  "is_trivial",
                  "data_concatenation",
                  "extension_rule",
                  "var_group",
                  "deco_medio",
                  "deco_canal",
                  "medio_cdm_calc",
                  "submedio_calc",
                  "clasif_submedio_calc",
                  "inv_expression",
                  "nature",
                  "sat_varname",
                  "is_grps",
                  "in_ma364"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 22,
                "maxItems": 22,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        },
        "variables_open": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "columns",
            "rows"
          ],
          "properties": {
            "columns": {
              "type": "array",
              "minItems": 5,
              "maxItems": 5,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "row_index",
                  "sheet",
                  "column_name",
                  "role",
                  "value"
                ]
              }
            },
            "rows": {
              "type": "array",
              "items": {
                "type": "array",
                "minItems": 5,
                "maxItems": 5,
                "items": {
                  "type": [
                    "number",
                    "string"
                  ]
                }
              }
            }
          },
          "x-decision": "El conjunto de columnas es el del contrato; el ORDEN no importa, porque la cabecera `columns` viaja y el decoder direcciona cada celda por el nombre de su columna y la tipa con el tipo que el árbol de fichas declara para ella."
        }
      }
    },
    "series_fit": {
      "type": "object",
      "description": "El fechado (clave = nombre del fechado) + las MISMAS siete series en las dos clases.",
      "required": [
        "Residuals",
        "DifNoise",
        "Noise",
        "Interruptions",
        "FullTransformed",
        "Transformed",
        "PrevHistTrans"
      ],
      "properties": {
        "Residuals": {
          "$ref": "#/$defs/realList"
        },
        "DifNoise": {
          "$ref": "#/$defs/realList"
        },
        "Noise": {
          "$ref": "#/$defs/realList"
        },
        "Interruptions": {
          "$ref": "#/$defs/realList"
        },
        "FullTransformed": {
          "$ref": "#/$defs/realList"
        },
        "Transformed": {
          "$ref": "#/$defs/realList"
        },
        "PrevHistTrans": {
          "$ref": "#/$defs/realList"
        }
      },
      "additionalProperties": {
        "$ref": "#/$defs/dateList"
      },
      "minProperties": 8,
      "maxProperties": 8,
      "x-decision": "La clave del fechado es la única clave adicional, con fechas, y se llama como metadata.identity.frequency (regla R3 del decoder)."
    },
    "series_input_output": {
      "type": "object",
      "description": "Datos con los que se estimó: el fechado, la salida observada y un driver por término.",
      "minProperties": 2,
      "additionalProperties": {
        "type": "array",
        "items": {
          "oneOf": [
            {
              "$ref": "#/$defs/real"
            },
            {
              "$ref": "#/$defs/date"
            }
          ]
        }
      },
      "x-decision": "La clave del fechado se llama como metadata.identity.frequency (R3). La salida es la ÚNICA clave que no es el fechado ni el Name de un parámetro (R7); ninguna, o más de una, se rechaza.",
      "x-pregunta": "P4"
    },
    "diagnostics": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "DiagCode",
        "Title",
        "Value",
        "Punctuation",
        "Accept",
        "Refuse",
        "Qualification"
      ],
      "properties": {
        "DiagCode": {
          "$ref": "#/$defs/textList",
          "x-decision": "Texto. Los once códigos que se emiten hoy son los conocidos; uno nuevo se acepta y se marca «no interpretado»."
        },
        "Title": {
          "$ref": "#/$defs/textList"
        },
        "Value": {
          "$ref": "#/$defs/realList"
        },
        "Punctuation": {
          "$ref": "#/$defs/realList"
        },
        "Accept": {
          "$ref": "#/$defs/realList"
        },
        "Refuse": {
          "$ref": "#/$defs/realList"
        },
        "Qualification": {
          "type": "array",
          "items": {
            "enum": [
              "UNNECESSARY",
              "GOOD",
              "ACCEPTABLE",
              "REFUSED"
            ]
          }
        }
      }
    },
    "correlations": {
      "type": "object",
      "description": "encoding-spec-v1, lower-triangle-fixed-point. Congelada: idéntica byte a byte a la 0.9.",
      "additionalProperties": false,
      "required": [
        "encoding",
        "scale",
        "names",
        "rows"
      ],
      "properties": {
        "encoding": {
          "const": "lower-triangle-fixed-point"
        },
        "scale": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "names": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^.+\\[-?\\d+,-?\\d+\\]$"
          }
        },
        "rows": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^(-?\\d+( -?\\d+)*)?$"
          }
        }
      }
    },
    "conditioning": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "condition_number",
        "eigenvalues"
      ],
      "properties": {
        "condition_number": {
          "$ref": "#/$defs/real"
        },
        "eigenvalues": {
          "$ref": "#/$defs/realList"
        }
      }
    },
    "mcmc": {
      "type": "object",
      "description": "encoding-spec-v1, standardize-rectangle-fixed-point. Congelada: los miembros son encoding, scale, names, mean, sd, rows.",
      "additionalProperties": false,
      "required": [
        "encoding",
        "scale",
        "names",
        "mean",
        "sd",
        "rows"
      ],
      "properties": {
        "encoding": {
          "const": "standardize-rectangle-fixed-point"
        },
        "scale": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "names": {
          "$ref": "#/$defs/textList"
        },
        "mean": {
          "$ref": "#/$defs/realList"
        },
        "sd": {
          "$ref": "#/$defs/realList"
        },
        "rows": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^(-?\\d+( -?\\d+)*)?$"
          }
        }
      }
    },
    "stats_modeldef": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1,
      "description": "Una lista de un elemento, como la lee el archivo.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "FirstDate",
          "LastDate",
          "DataNumber",
          "VarNumber",
          "Sigma",
          "R2",
          "RSS",
          "Swartz",
          "Pearson",
          "Kurtosis",
          "Asymmetry",
          "Variance",
          "MaxLHSigma",
          "MarquardtIterNumber",
          "Qualification",
          "ArimaLabel",
          "Average",
          "DiagnosysLogPrior",
          "normMaxLH"
        ],
        "properties": {
          "FirstDate": {
            "$ref": "#/$defs/date"
          },
          "LastDate": {
            "$ref": "#/$defs/date"
          },
          "DataNumber": {
            "type": "integer",
            "minimum": 0,
            "description": "Observaciones que el motor usó; NO es el largo de series_fit."
          },
          "VarNumber": {
            "type": "integer",
            "minimum": 0,
            "description": "Variables del modelo, no filas de la tabla de parámetros."
          },
          "Sigma": {
            "$ref": "#/$defs/real"
          },
          "R2": {
            "$ref": "#/$defs/real"
          },
          "RSS": {
            "$ref": "#/$defs/real"
          },
          "Swartz": {
            "$ref": "#/$defs/real"
          },
          "Pearson": {
            "$ref": "#/$defs/real"
          },
          "Kurtosis": {
            "$ref": "#/$defs/real"
          },
          "Asymmetry": {
            "$ref": "#/$defs/real"
          },
          "Variance": {
            "$ref": "#/$defs/real"
          },
          "MaxLHSigma": {
            "$ref": "#/$defs/real"
          },
          "MarquardtIterNumber": {
            "type": "integer",
            "minimum": 0
          },
          "Qualification": {
            "enum": [
              "UNNECESSARY",
              "GOOD",
              "ACCEPTABLE",
              "REFUSED",
              "?"
            ],
            "x-decision": "Los cuatro valores que declara el archivo de modelos del emisor, más \"?\" = «no calificado» (diagnóstico apagado).",
            "x-pregunta": "F3"
          },
          "ArimaLabel": {
            "type": "string"
          },
          "Average": {
            "$ref": "#/$defs/real"
          },
          "DiagnosysLogPrior": {
            "$ref": "#/$defs/real"
          },
          "normMaxLH": {
            "$ref": "#/$defs/real"
          }
        }
      }
    },
    "stats_node": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1,
      "description": "Una lista de un elemento, como la lee el archivo.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "FirstDate",
          "LastDate",
          "DataNumber",
          "VarNumber",
          "Sigma",
          "R2"
        ],
        "properties": {
          "FirstDate": {
            "$ref": "#/$defs/date"
          },
          "LastDate": {
            "$ref": "#/$defs/date"
          },
          "DataNumber": {
            "type": "integer",
            "minimum": 0,
            "description": "Observaciones que el motor usó; NO es el largo de series_fit."
          },
          "VarNumber": {
            "type": "integer",
            "minimum": 0,
            "description": "Variables del modelo, no filas de la tabla de parámetros."
          },
          "Sigma": {
            "$ref": "#/$defs/real"
          },
          "R2": {
            "$ref": "#/$defs/real"
          }
        }
      }
    },
    "forecast_point_modal": {
      "type": "object",
      "required": [
        "modal",
        "sd"
      ],
      "properties": {
        "modal": {
          "$ref": "#/$defs/realList"
        },
        "sd": {
          "$ref": "#/$defs/realList"
        }
      },
      "additionalProperties": {
        "$ref": "#/$defs/dateList"
      },
      "minProperties": 3,
      "maxProperties": 3
    },
    "forecast_point_median": {
      "type": "object",
      "required": [
        "median"
      ],
      "properties": {
        "median": {
          "$ref": "#/$defs/realList"
        }
      },
      "additionalProperties": {
        "$ref": "#/$defs/dateList"
      },
      "minProperties": 2,
      "maxProperties": 2
    },
    "forecast_point_mean": {
      "type": "object",
      "required": [
        "mean"
      ],
      "properties": {
        "mean": {
          "$ref": "#/$defs/realList"
        }
      },
      "additionalProperties": {
        "$ref": "#/$defs/dateList"
      },
      "minProperties": 2,
      "maxProperties": 2
    }
  }
}
