{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://terminode.io/docs/pilot-evidence-pack.schema.json",
  "title": "TermiNode Pilot Evidence Pack",
  "description": "Machine-readable pilot scope, privacy boundary, process metrics, and customer acceptance outcome.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema",
    "generated_at",
    "updated_at",
    "pilot",
    "scope",
    "privacy",
    "metrics",
    "customer_acceptance"
  ],
  "properties": {
    "schema": {
      "const": "terminode.pilot_evidence_pack.v1"
    },
    "generated_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    },
    "pilot": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "pilot_id",
        "title",
        "customer_alias",
        "status",
        "sector_pattern",
        "started_at",
        "completed_at"
      ],
      "properties": {
        "pilot_id": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{2,79}$"
        },
        "title": {
          "type": "string",
          "minLength": 3,
          "maxLength": 160
        },
        "customer_alias": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{2,79}$"
        },
        "status": {
          "enum": ["draft", "in_review", "accepted", "accepted_with_actions", "rejected"]
        },
        "sector_pattern": {
          "type": "string",
          "minLength": 3,
          "maxLength": 100
        },
        "started_at": {
          "type": ["string", "null"],
          "format": "date-time"
        },
        "completed_at": {
          "type": ["string", "null"],
          "format": "date-time"
        }
      }
    },
    "scope": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "problem_statement",
        "acceptance_question",
        "dataset_count",
        "feature_target",
        "geometry_profile",
        "crs",
        "out_of_scope"
      ],
      "properties": {
        "problem_statement": {
          "type": "string",
          "minLength": 20
        },
        "acceptance_question": {
          "type": "string",
          "minLength": 20
        },
        "dataset_count": {
          "type": "integer",
          "minimum": 1
        },
        "feature_target": {
          "type": "object",
          "additionalProperties": false,
          "required": ["minimum", "maximum"],
          "properties": {
            "minimum": {
              "type": "integer",
              "minimum": 1
            },
            "maximum": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "geometry_profile": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "enum": ["Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon"]
          }
        },
        "crs": {
          "const": "EPSG:4326"
        },
        "out_of_scope": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "minLength": 3
          }
        }
      }
    },
    "privacy": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "data_classification",
        "personal_data_allowed",
        "raw_media_allowed",
        "secrets_allowed",
        "public_metadata_review",
        "retention_rule"
      ],
      "properties": {
        "data_classification": {
          "enum": ["synthetic", "public", "restricted"]
        },
        "personal_data_allowed": {
          "const": false
        },
        "raw_media_allowed": {
          "const": false
        },
        "secrets_allowed": {
          "const": false
        },
        "public_metadata_review": {
          "enum": ["pending", "pass", "fail"]
        },
        "retention_rule": {
          "type": "string",
          "minLength": 10
        }
      }
    },
    "metrics": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "time_to_first_import_minutes",
        "time_to_evidence_minutes",
        "accepted_feature_count",
        "rejected_feature_count",
        "rework_event_count",
        "reproduction_without_developer_support",
        "metric_notes"
      ],
      "properties": {
        "time_to_first_import_minutes": {
          "$ref": "#/$defs/beforeAfterMetric"
        },
        "time_to_evidence_minutes": {
          "$ref": "#/$defs/beforeAfterMetric"
        },
        "accepted_feature_count": {
          "type": ["integer", "null"],
          "minimum": 0
        },
        "rejected_feature_count": {
          "type": ["integer", "null"],
          "minimum": 0
        },
        "rework_event_count": {
          "type": ["integer", "null"],
          "minimum": 0
        },
        "reproduction_without_developer_support": {
          "enum": ["not_tested", "pass", "fail"]
        },
        "metric_notes": {
          "type": "string"
        }
      }
    },
    "customer_acceptance": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "decision",
        "decided_at",
        "decision_owner_alias",
        "repeat_use_interest",
        "rejection_reason",
        "open_actions"
      ],
      "properties": {
        "decision": {
          "enum": ["pending", "accepted", "accepted_with_actions", "rejected"]
        },
        "decided_at": {
          "type": ["string", "null"],
          "format": "date-time"
        },
        "decision_owner_alias": {
          "type": "string"
        },
        "repeat_use_interest": {
          "enum": ["not_asked", "yes", "no", "conditional"]
        },
        "rejection_reason": {
          "type": "string"
        },
        "open_actions": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    }
  },
  "$defs": {
    "beforeAfterMetric": {
      "type": "object",
      "additionalProperties": false,
      "required": ["baseline", "observed"],
      "properties": {
        "baseline": {
          "type": ["number", "null"],
          "minimum": 0
        },
        "observed": {
          "type": ["number", "null"],
          "minimum": 0
        }
      }
    }
  }
}
