{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://moelzanaty3.github.io/geopilot/schema/config/v1.json",
  "title": "geo.config.json",
  "description": "geopilot configuration. JSON only; unknown keys are errors. GEO never infers site.origin, site.language, crawler policy or app identifiers.",
  "type": "object",
  "properties": {
    "$schema": {
      "type": "string"
    },
    "version": {
      "const": 1
    },
    "framework": {
      "enum": [
        "auto",
        "nextjs-app",
        "static",
        "generic"
      ]
    },
    "profile": {
      "enum": [
        "web",
        "app"
      ],
      "description": "app enables GEO-101 and GEO-102"
    },
    "site": {
      "type": "object",
      "properties": {
        "origin": {
          "type": [
            "string",
            "null"
          ],
          "format": "uri"
        },
        "language": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "additionalProperties": false
    },
    "routes": {
      "type": "object",
      "properties": {
        "include": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "exclude": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": false
    },
    "crawl": {
      "type": "object",
      "properties": {
        "maxPages": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 200
        },
        "maxDepth": {
          "type": "integer",
          "minimum": 0,
          "maximum": 10
        },
        "render": {
          "enum": [
            "auto",
            "always",
            "never"
          ]
        },
        "requestTimeoutMs": {
          "type": "integer",
          "minimum": 1000,
          "maximum": 10000
        }
      },
      "additionalProperties": false
    },
    "policy": {
      "type": "object",
      "properties": {
        "aiSearchCrawlers": {
          "enum": [
            "allow",
            "block",
            "undecided"
          ]
        },
        "aiTrainingCrawlers": {
          "enum": [
            "allow",
            "block",
            "undecided"
          ]
        },
        "userTriggeredFetchers": {
          "enum": [
            "allow",
            "block",
            "undecided"
          ]
        }
      },
      "additionalProperties": false
    },
    "appLinks": {
      "type": "object",
      "properties": {
        "ios": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "properties": {
                "appIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "additionalProperties": false,
              "required": [
                "appIds"
              ]
            }
          ]
        },
        "android": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "properties": {
                "packageName": {
                  "type": "string"
                },
                "sha256CertFingerprints": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "additionalProperties": false,
              "required": [
                "packageName",
                "sha256CertFingerprints"
              ]
            }
          ]
        }
      },
      "additionalProperties": false
    },
    "rules": {
      "type": "object",
      "propertyNames": {
        "enum": [
          "GEO-002",
          "GEO-003",
          "GEO-004",
          "GEO-009",
          "GEO-010",
          "GEO-011",
          "GEO-012",
          "GEO-013",
          "GEO-014",
          "GEO-015",
          "GEO-016",
          "GEO-017",
          "GEO-101",
          "GEO-102"
        ]
      },
      "additionalProperties": {
        "oneOf": [
          {
            "const": "off"
          },
          {
            "type": "object",
            "properties": {
              "severity": {
                "enum": [
                  "high",
                  "medium",
                  "low",
                  "info"
                ]
              }
            },
            "additionalProperties": false,
            "required": [
              "severity"
            ]
          }
        ]
      }
    },
    "suppress": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "rule": {
            "enum": [
              "GEO-002",
              "GEO-003",
              "GEO-004",
              "GEO-009",
              "GEO-010",
              "GEO-011",
              "GEO-012",
              "GEO-013",
              "GEO-014",
              "GEO-015",
              "GEO-016",
              "GEO-017",
              "GEO-101",
              "GEO-102"
            ]
          },
          "routes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reason": {
            "type": "string",
            "minLength": 1
          },
          "expires": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          }
        },
        "additionalProperties": false,
        "required": [
          "rule",
          "reason"
        ]
      }
    },
    "fix": {
      "type": "object",
      "properties": {
        "verifyCommands": {
          "type": "array",
          "items": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          }
        },
        "runtimeTimeoutSeconds": {
          "type": "integer",
          "minimum": 5,
          "maximum": 600
        },
        "serve": {
          "type": "object",
          "properties": {
            "command": {
              "oneOf": [
                {
                  "type": "null"
                },
                {
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            "url": {
              "type": [
                "string",
                "null"
              ],
              "description": "loopback URL only"
            },
            "readyTimeoutSeconds": {
              "type": "integer",
              "minimum": 5,
              "maximum": 600
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "thresholds": {
      "type": "object",
      "properties": {
        "failOn": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "enum": [
                "high",
                "medium",
                "low",
                "info"
              ]
            }
          ]
        },
        "minReadiness": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "maximum": 100
        },
        "minCoverage": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        }
      },
      "additionalProperties": false
    },
    "hook": {
      "type": "object",
      "properties": {
        "failOn": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "enum": [
                "high",
                "medium",
                "low",
                "info"
              ]
            }
          ]
        },
        "timeoutSeconds": {
          "type": "integer",
          "minimum": 1,
          "maximum": 60
        }
      },
      "additionalProperties": false
    },
    "experimental": {
      "type": "boolean"
    }
  },
  "additionalProperties": false,
  "required": [
    "version"
  ]
}
