{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://botlandscape.com/ecosystem.schema.json",
  "title": "Bot Landscape temporal evidence graph",
  "type": "object",
  "additionalProperties": false,
  "required": ["$schema", "schema_version", "site", "data_release", "data_audited", "source_schema_version", "counts", "dimensions", "stack_layers", "nodes", "edges", "release_events", "sources"],
  "properties": {
    "$schema": {"const": "https://botlandscape.com/ecosystem.schema.json"},
    "schema_version": {"const": 1},
    "site": {"type": "string", "format": "uri"},
    "data_release": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
    "data_audited": {"type": "string", "format": "date"},
    "source_schema_version": {"type": "integer", "minimum": 1},
    "counts": {"$ref": "#/$defs/counts"},
    "dimensions": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/dimension"}},
    "stack_layers": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/stack-layer"}},
    "nodes": {"type": "array", "items": {"$ref": "#/$defs/node"}},
    "edges": {"type": "array", "items": {"$ref": "#/$defs/edge"}},
    "release_events": {"type": "array", "items": {"$ref": "#/$defs/release-event"}},
    "sources": {"type": "array", "items": {"$ref": "#/$defs/source"}}
  },
  "$defs": {
    "id": {"type": "string", "pattern": "^[a-z]+--[a-z0-9]+(?:-+[a-z0-9]+)*$"},
    "counts": {
      "type": "object",
      "additionalProperties": false,
      "required": ["nodes", "edges", "predicates", "bound_claims", "evidence_sources", "release_events", "dossiers"],
      "properties": {
        "nodes": {"type": "integer", "minimum": 0},
        "edges": {"type": "integer", "minimum": 0},
        "predicates": {"type": "integer", "minimum": 0},
        "bound_claims": {"type": "integer", "minimum": 0},
        "evidence_sources": {"type": "integer", "minimum": 0},
        "release_events": {"type": "integer", "minimum": 0},
        "dossiers": {"type": "integer", "minimum": 0}
      }
    },
    "metric": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "label", "value", "unit"],
      "properties": {
        "id": {"type": "string", "pattern": "^[a-z0-9]+(?:-+[a-z0-9]+)*$"},
        "label": {"type": "string", "minLength": 1},
        "value": {"type": "integer", "minimum": 0},
        "unit": {"type": "string", "minLength": 1}
      }
    },
    "dimension": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "label", "description", "metrics"],
      "properties": {
        "id": {"type": "string", "pattern": "^[a-z0-9]+(?:-+[a-z0-9]+)*$"},
        "label": {"type": "string", "minLength": 1},
        "description": {"type": "string", "minLength": 1},
        "metrics": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/metric"}}
      }
    },
    "stack-layer": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "label", "description", "kinds", "predicates", "transit"],
      "properties": {
        "id": {"type": "string"},
        "label": {"type": "string"},
        "description": {"type": "string"},
        "kinds": {"type": "array", "items": {"type": "string"}},
        "predicates": {"type": "array", "items": {"type": "string"}},
        "transit": {"type": "boolean"}
      }
    },
    "binding": {
      "type": "object",
      "additionalProperties": false,
      "required": ["page_path", "table_id"],
      "properties": {
        "page_path": {"type": "string"},
        "table_id": {"type": "string"},
        "subject_id": {"type": "string"},
        "row_id": {"type": "string"}
      },
      "oneOf": [
        {"required": ["subject_id"]},
        {"required": ["row_id"]}
      ]
    },
    "facet": {
      "type": "object",
      "additionalProperties": false,
      "required": ["dimension", "key", "label", "state", "claim_ids", "source_ids", "last_reviewed"],
      "properties": {
        "dimension": {"type": "string"},
        "key": {"type": "string"},
        "label": {"type": "string"},
        "state": {"type": "string"},
        "claim_ids": {"type": "array", "uniqueItems": true, "items": {"type": "string"}},
        "source_ids": {"type": "array", "uniqueItems": true, "items": {"type": "string"}},
        "last_reviewed": {"type": ["string", "null"], "format": "date"}
      }
    },
    "claim-counts": {
      "type": "object",
      "additionalProperties": false,
      "required": ["total", "reported", "missing"],
      "properties": {
        "total": {"type": "integer", "minimum": 0},
        "reported": {"type": "integer", "minimum": 0},
        "missing": {"type": "integer", "minimum": 0}
      }
    },
    "node": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "kind", "name", "summary", "url", "dossier_url", "aliases", "category", "publication_state", "deployment_stage", "bindings", "facets", "claim_ids", "claim_counts", "evidence_source_ids", "evidence_grades", "last_reviewed"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "kind": {"type": "string"},
        "name": {"type": "string"},
        "summary": {"type": "string"},
        "url": {"type": "string", "format": "uri"},
        "dossier_url": {"type": "string", "format": "uri"},
        "aliases": {"type": "array", "uniqueItems": true, "items": {"type": "string"}},
        "category": {"type": ["string", "null"]},
        "publication_state": {"type": "string"},
        "deployment_stage": {"type": "string"},
        "bindings": {"type": "array", "items": {"$ref": "#/$defs/binding"}},
        "facets": {"type": "array", "items": {"$ref": "#/$defs/facet"}},
        "claim_ids": {"type": "array", "uniqueItems": true, "items": {"type": "string"}},
        "claim_counts": {"$ref": "#/$defs/claim-counts"},
        "evidence_source_ids": {"type": "array", "uniqueItems": true, "items": {"type": "string"}},
        "evidence_grades": {"type": "object", "additionalProperties": {"type": "integer", "minimum": 0}},
        "last_reviewed": {"type": ["string", "null"], "format": "date"}
      }
    },
    "edge": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "from", "predicate", "label", "to", "status", "scope", "note", "claim_ids", "source_ids", "evidence_grades", "first_observed", "last_reviewed", "valid_from", "valid_to", "url"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "from": {"$ref": "#/$defs/id"},
        "predicate": {"type": "string"},
        "label": {"type": "string"},
        "to": {"$ref": "#/$defs/id"},
        "status": {"type": "string"},
        "scope": {"type": "string"},
        "note": {"type": "string"},
        "claim_ids": {"type": "array", "uniqueItems": true, "items": {"type": "string"}},
        "source_ids": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string"}},
        "evidence_grades": {"type": "object", "additionalProperties": {"type": "integer", "minimum": 0}},
        "first_observed": {"type": ["string", "null"], "format": "date"},
        "last_reviewed": {"type": "string", "format": "date"},
        "valid_from": {"type": ["string", "null"], "format": "date"},
        "valid_to": {"type": ["string", "null"], "format": "date"},
        "url": {"type": "string", "format": "uri"}
      }
    },
    "release-event": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "id", "date", "url", "counts"],
      "properties": {
        "type": {"const": "data-release"},
        "id": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
        "date": {"type": "string", "format": "date"},
        "url": {"type": "string", "format": "uri"},
        "counts": {"type": "object", "additionalProperties": {"type": "integer", "minimum": 0}}
      }
    },
    "source": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "marker", "grade", "citation", "retrieved", "registry_url", "direct_url"],
      "properties": {
        "id": {"type": "string"},
        "marker": {"type": "string"},
        "grade": {"type": "string"},
        "citation": {"type": "string"},
        "retrieved": {"type": "string", "format": "date"},
        "registry_url": {"type": "string", "format": "uri"},
        "direct_url": {"type": "string", "format": "uri"}
      }
    }
  }
}
