{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://cfdl.dev/schemas/CFDL_v0_1_package.schema.json",
  "title": "CFDL package manifest",
  "description": "`cfdl.package.json`: a model's files, the run configuration it was run with, the inputs files that configuration names, its results and optionally its IR, each with its role and checksum, with the engine and pack versions, `model_hash` and every ledger hash. `cfdl package` writes it; `cfdl verify` checks a package against it without running the model, and `cfdl reproduce` runs the model and requires every ledger hash to come out the same.",
  "type": "object",
  "required": ["package_version", "engine", "root", "files", "model_hash", "ledger_hashes"],
  "additionalProperties": false,
  "properties": {
    "package_version": {
      "description": "Version of this shape. 0.1 is the first.",
      "const": "0.1"
    },
    "engine": {
      "description": "The engine that produced the results, as their `engine` names it. `cfdl reproduce` runs only on this version; `cfdl verify` on another version checks everything but the recompile, and says so.",
      "$ref": "#/$defs/Named"
    },
    "packs": {
      "description": "The packs the model uses, with their versions, from the IR's provenance. Absent for a model with no pack.",
      "type": "array",
      "items": { "$ref": "#/$defs/Named" }
    },
    "root": {
      "description": "The model file compilation starts from, relative to the package.",
      "type": "string"
    },
    "files": {
      "type": "array",
      "minItems": 3,
      "items": { "$ref": "#/$defs/File" }
    },
    "model_hash": {
      "description": "The results' `model_hash`: the model's identity, which the verifier recompiles the model files to check.",
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "ledger_hashes": {
      "description": "Every result's ledger hash, as the results publish them and as `cfdl verify` recomputes them from the results' contents.",
      "type": "object",
      "required": ["base"],
      "additionalProperties": false,
      "properties": {
        "base": { "$ref": "#/$defs/Hash", "description": "The deterministic run's `ledger_hash`." },
        "scenarios": {
          "description": "Each scenario's `ledger_hash`, by scenario name.",
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/Hash" }
        },
        "monte_carlo": { "$ref": "#/$defs/Hash", "description": "The Monte Carlo trials' `ledger_hash`, when the run has trials." }
      }
    }
  },
  "$defs": {
    "Hash": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
    "Named": {
      "type": "object",
      "required": ["name", "version"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "version": { "type": "string" }
      }
    },
    "File": {
      "type": "object",
      "required": ["path", "role", "sha256"],
      "additionalProperties": false,
      "properties": {
        "path": { "description": "The file's path in the package, with `/` separators.", "type": "string" },
        "role": {
          "description": "`model`: a model source file. `run`: the run configuration. `inputs`: an inputs file the run configuration names. `ir`: the compiled IR. `results`: the results document. A package has one `run` and one `results` file.",
          "enum": ["model", "run", "inputs", "ir", "results"]
        },
        "sha256": { "description": "SHA-256 of the file's bytes, in lowercase hex.", "$ref": "#/$defs/Hash" }
      }
    }
  }
}
