{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://schemas.corva.ai/fe-ai-tools/migration/v2",
  "$comment": "This schema validates descriptor structure. The CLI additionally enforces relational invariants such as no toolkit or revision downgrade.",
  "title": "Ask Corva fleet migration descriptor",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "id",
    "from",
    "to",
    "impact",
    "allowedPaths",
    "requiresSourceReview",
    "requiresLiveValidation"
  ],
  "properties": {
    "$schema": { "type": "string" },
    "schemaVersion": { "const": 2 },
    "id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9.-]+$" },
    "from": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kitRange", "contractRevision", "canonRevision"],
      "properties": {
        "kitRange": { "type": "string", "pattern": "^\\^[0-9]+\\.[0-9]+\\.[0-9]+$" },
        "contractRevision": { "type": "integer", "minimum": 1 },
        "canonRevision": { "type": "integer", "minimum": 1 }
      }
    },
    "to": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kitRange", "contractRevision", "canonRevision"],
      "properties": {
        "kitRange": { "type": "string", "pattern": "^\\^[0-9]+\\.[0-9]+\\.[0-9]+$" },
        "contractRevision": { "type": "integer", "minimum": 1 },
        "canonRevision": { "type": "integer", "minimum": 1 }
      }
    },
    "impact": { "enum": ["dependency-only", "mechanical", "semantic"] },
    "allowedPaths": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "minLength": 1,
        "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*(?:^|/)(?:\\.git|\\.env(?:\\.[^/]*)?|\\.npmrc|\\.yarnrc(?:\\.[^/]*)?)(?:/|$))[A-Za-z0-9._@/-]+$"
      }
    },
    "requiresSourceReview": { "type": "boolean" },
    "requiresLiveValidation": { "type": "boolean" },
    "notes": { "type": "string" }
  },
  "allOf": [
    {
      "if": { "properties": { "impact": { "const": "dependency-only" } }, "required": ["impact"] },
      "then": {
        "properties": {
          "allowedPaths": {
            "type": "array",
            "items": { "enum": ["package.json", "yarn.lock", "package-lock.json", "pnpm-lock.yaml"] },
            "allOf": [
              { "contains": { "const": "package.json" }, "minContains": 1, "maxContains": 1 },
              {
                "contains": { "enum": ["yarn.lock", "package-lock.json", "pnpm-lock.yaml"] },
                "minContains": 1,
                "maxContains": 1
              }
            ]
          },
          "requiresSourceReview": { "const": false },
          "requiresLiveValidation": { "const": false }
        }
      }
    },
    {
      "if": { "properties": { "impact": { "const": "semantic" } }, "required": ["impact"] },
      "then": {
        "properties": {
          "requiresSourceReview": { "const": true },
          "requiresLiveValidation": { "const": true }
        }
      }
    }
  ]
}
