{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Sealed existing-prediction comparison",
  "type": "object",
  "additionalProperties": false,
  "required": ["schema_version", "mode", "project_id", "target", "candidate", "reference"],
  "properties": {
    "schema_version": {"const": 1},
    "mode": {"const": "compare_existing"},
    "project_id": {"type": "string", "pattern": "^[a-z][a-z0-9_-]{0,63}$"},
    "target": {
      "type": "object", "additionalProperties": false,
      "required": ["name", "unit"],
      "properties": {"name": {"type": "string", "minLength": 1, "maxLength": 128}, "unit": {"type": "string", "minLength": 1, "maxLength": 64}}
    },
    "candidate": {"$ref": "#/$defs/side"},
    "reference": {"$ref": "#/$defs/side"},
    "tolerances": {
      "type": "object", "additionalProperties": false,
      "properties": {
        "truth_abs": {"type": "number", "minimum": 0, "maximum": 1e-8},
        "metric_abs": {"type": "number", "minimum": 0, "maximum": 0.01},
        "metric_relative": {"type": "number", "minimum": 0, "maximum": 0.01}
      }
    },
    "audit_matrix": {
      "type": "object", "additionalProperties": false, "required": ["path"],
      "properties": {"path": {"type": "string", "minLength": 1}}
    },
    "output_files": {
      "type": "object", "additionalProperties": false,
      "properties": {
        "state": {"type": "string"}, "artifacts": {"type": "string"},
        "normalized": {"type": "string"}, "paired": {"type": "string"},
        "cohort_differences": {"type": "string"}, "metrics": {"type": "string"},
        "comparison": {"type": "string"}, "report": {"type": "string"}, "report_zh": {"type": "string"},
        "source_hashes": {"type": "string"}, "output_sha256": {"type": "string"}
      }
    }
  },
  "$defs": {
    "side": {
      "type": "object", "additionalProperties": false,
      "required": ["root", "manifest", "prediction_origin", "models"],
      "properties": {
        "root": {"type": "string", "minLength": 1},
        "manifest": {"type": "string", "minLength": 1},
        "prediction_origin": {"enum": ["independent_run", "stored_predictions", "recovered_from_saved_model"]},
        "models": {"type": "array", "minItems": 1, "maxItems": 16, "items": {"$ref": "#/$defs/model"}}
      }
    },
    "model": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "predictions", "id_column", "truth_column", "prediction_column"],
      "properties": {
        "id": {"type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9_-]{0,63}$"},
        "predictions": {"type": "string", "minLength": 1},
        "id_column": {"type": "string", "minLength": 1, "maxLength": 128},
        "truth_column": {"type": "string", "minLength": 1, "maxLength": 128},
        "prediction_column": {"type": "string", "minLength": 1, "maxLength": 128},
        "reported_metrics": {
          "type": "object", "additionalProperties": false, "required": ["file", "pointers"],
          "properties": {
            "file": {"type": "string", "minLength": 1},
            "pointers": {
              "type": "object", "additionalProperties": false, "minProperties": 1,
              "properties": {
                "rmse": {"type": "string", "pattern": "^/"},
                "mae": {"type": "string", "pattern": "^/"},
                "r_squared": {"type": "string", "pattern": "^/"}
              }
            }
          }
        }
      }
    }
  }
}
