{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://chris-page-gov.github.io/okf-explorer/profile/federation/v1/descriptor.schema.json",
  "title": "OKF Explorer federation descriptor v1",
  "description": "A lightweight federation control plane. Child descriptors and data planes are loaded only after explicit selection.",
  "type": "object",
  "required": [
    "schema",
    "kind",
    "okf_version",
    "title",
    "version",
    "status",
    "generated_at",
    "snapshot",
    "profile",
    "publisher",
    "license",
    "discovery",
    "counts",
    "children",
    "relationship_summary"
  ],
  "properties": {
    "@context": {},
    "@id": {
      "$ref": "#/$defs/httpUrl"
    },
    "schema": {
      "const": "okf-explorer-federation.v1"
    },
    "kind": {
      "const": "okf-federation"
    },
    "okf_version": {
      "const": "0.2"
    },
    "title": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "version": {
      "type": "string",
      "minLength": 1
    },
    "status": {
      "type": "string",
      "minLength": 1
    },
    "generated_at": {
      "type": "string",
      "format": "date-time"
    },
    "snapshot": {
      "type": "string",
      "minLength": 1
    },
    "profile": {
      "$ref": "#/$defs/httpUrl"
    },
    "publisher": {
      "$ref": "#/$defs/httpUrl"
    },
    "license": {
      "$ref": "#/$defs/httpUrl"
    },
    "discovery": {
      "$ref": "#/$defs/discovery"
    },
    "counts": {
      "$ref": "#/$defs/counts"
    },
    "children": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/child"
      }
    },
    "relationships": {
      "type": "array",
      "items": {
        "$ref": "relationship-assertion.schema.json"
      }
    },
    "relationship_summary": {
      "$ref": "#/$defs/relationshipSummary"
    },
    "notices": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "extensions": {
      "type": "object"
    }
  },
  "additionalProperties": true,
  "$defs": {
    "httpUrl": {
      "type": "string",
      "pattern": "^https?://"
    },
    "availability": {
      "enum": [
        "available",
        "partial",
        "restricted",
        "unavailable",
        "planned"
      ]
    },
    "counts": {
      "type": "object",
      "additionalProperties": {
        "type": "integer",
        "minimum": 0
      }
    },
    "route": {
      "type": "object",
      "required": [
        "kind",
        "url"
      ],
      "properties": {
        "kind": {
          "type": "string",
          "minLength": 1
        },
        "url": {
          "$ref": "#/$defs/httpUrl"
        },
        "purpose": {
          "enum": [
            "descriptor",
            "source",
            "documentation",
            "archive",
            "semantic"
          ]
        },
        "media_type": {
          "type": "string",
          "minLength": 1
        },
        "priority": {
          "type": "integer",
          "minimum": 0
        },
        "label": {
          "type": "string",
          "minLength": 1
        }
      },
      "additionalProperties": false
    },
    "discovery": {
      "type": "object",
      "required": [
        "repository",
        "documentation",
        "raw_subpath",
        "release_archive",
        "routes"
      ],
      "properties": {
        "repository": {
          "$ref": "#/$defs/httpUrl"
        },
        "documentation": {
          "$ref": "#/$defs/httpUrl"
        },
        "raw_subpath": {
          "type": "string",
          "minLength": 1,
          "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))[^\\\\]+$"
        },
        "release_archive": {
          "$ref": "#/$defs/httpUrl"
        },
        "semantic_descriptor": {
          "$ref": "#/$defs/httpUrl"
        },
        "routes": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/route"
          }
        }
      },
      "additionalProperties": false
    },
    "authority": {
      "type": "object",
      "required": [
        "class"
      ],
      "properties": {
        "class": {
          "enum": [
            "official",
            "derived",
            "model-assisted",
            "unclassified"
          ]
        },
        "label": {
          "type": "string",
          "minLength": 1
        },
        "source": {
          "$ref": "#/$defs/httpUrl"
        }
      },
      "additionalProperties": false
    },
    "coverage": {
      "type": "object",
      "required": [
        "status"
      ],
      "properties": {
        "status": {
          "$ref": "#/$defs/availability"
        },
        "applicable": {
          "type": "integer",
          "minimum": 0
        },
        "represented": {
          "type": "integer",
          "minimum": 0
        },
        "assertions": {
          "type": "integer",
          "minimum": 0
        },
        "percent": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        },
        "as_of": {
          "type": "string",
          "format": "date"
        },
        "notes": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "additionalProperties": false
    },
    "freshness": {
      "type": "object",
      "properties": {
        "state": {
          "enum": [
            "current",
            "stale",
            "unknown"
          ]
        },
        "observed_at": {
          "type": "string",
          "format": "date-time"
        },
        "snapshot": {
          "type": "string",
          "minLength": 1
        },
        "stale_after": {
          "type": "string",
          "format": "date-time"
        }
      },
      "additionalProperties": false
    },
    "child": {
      "type": "object",
      "required": [
        "id",
        "title",
        "role",
        "status",
        "authority",
        "coverage",
        "freshness",
        "discovery"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "title": {
          "type": "string",
          "minLength": 1
        },
        "description": {
          "type": "string"
        },
        "role": {
          "type": "string",
          "minLength": 1
        },
        "status": {
          "$ref": "#/$defs/availability"
        },
        "descriptor": {
          "$ref": "#/$defs/httpUrl"
        },
        "semantic_descriptor": {
          "$ref": "#/$defs/httpUrl"
        },
        "authority": {
          "$ref": "#/$defs/authority"
        },
        "coverage": {
          "$ref": "#/$defs/coverage"
        },
        "freshness": {
          "$ref": "#/$defs/freshness"
        },
        "discovery": {
          "$ref": "#/$defs/discovery"
        },
        "counts": {
          "$ref": "#/$defs/counts"
        },
        "extensions": {
          "type": "object"
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "status": {
                "enum": [
                  "available",
                  "partial"
                ]
              }
            },
            "required": [
              "status"
            ]
          },
          "then": {
            "anyOf": [
              {
                "required": [
                  "descriptor"
                ]
              },
              {
                "properties": {
                  "discovery": {
                    "properties": {
                      "routes": {
                        "contains": {
                          "properties": {
                            "purpose": {
                              "const": "descriptor"
                            }
                          },
                          "required": [
                            "purpose"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      ],
      "additionalProperties": false
    },
    "relationshipSummary": {
      "type": "object",
      "required": [
        "scope",
        "total",
        "by_predicate",
        "by_authority",
        "by_freshness"
      ],
      "properties": {
        "scope": {
          "enum": [
            "federated-data-plane",
            "federation-control-plane"
          ]
        },
        "total": {
          "type": "integer",
          "minimum": 0
        },
        "by_predicate": {
          "$ref": "#/$defs/counts"
        },
        "by_authority": {
          "allOf": [
            {
              "$ref": "#/$defs/counts"
            },
            {
              "required": [
                "official",
                "derived",
                "model-assisted"
              ]
            }
          ]
        },
        "by_freshness": {
          "allOf": [
            {
              "$ref": "#/$defs/counts"
            },
            {
              "required": [
                "current",
                "stale",
                "unknown"
              ]
            }
          ]
        },
        "observed_at": {
          "type": "string",
          "format": "date-time"
        },
        "snapshot": {
          "type": "string",
          "minLength": 1
        }
      },
      "additionalProperties": false
    }
  }
}
