{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://yarramate.org/schema/visual-graph/v1",
  "title": "YarraMate visual graph",
  "description": "Canvas-ready projection of a semantic graph into nodes and edges for native rendering.",
  "type": "object",
  "additionalProperties": false,
  "required": ["nodes", "edges"],
  "properties": {
    "nodes": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/canvasNode"
      }
    },
    "edges": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/canvasEdge"
      }
    }
  },
  "$defs": {
    "canvasNode": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "localId",
        "document",
        "kind",
        "kindLabel",
        "coreKindLabel",
        "portKinds",
        "layer",
        "aspect",
        "name",
        "description",
        "aka",
        "status",
        "owner",
        "folder",
        "distinctFrom",
        "supersedes",
        "constraints",
        "references",
        "presentIn",
        "attestations"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "localId": {
          "type": "string",
          "minLength": 1
        },
        "document": {
          "type": "string",
          "minLength": 1
        },
        "kind": {
          "type": "string"
        },
        "kindLabel": {
          "type": "string"
        },
        "portKinds": {
          "description": "The core relationship kinds this node's pattern ports, or [] where its kind has no pattern with ports (#268 phase 3, ADR 0124). A macro edge needs both ends to port its kind, so an editor offering a palette between two instances intersects the two lists.",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string"
          }
        },
        "coreKindLabel": {
          "type": "string"
        },
        "layer": {
          "anyOf": [
            {
              "enum": [
                "motivation",
                "strategy",
                "business",
                "application",
                "technology",
                "physical",
                "implementation",
                "composite"
              ]
            },
            { "type": "null" }
          ]
        },
        "aspect": {
          "anyOf": [
            {
              "enum": [
                "motivation",
                "active-structure",
                "behavior",
                "passive-structure",
                "composite"
              ]
            },
            { "type": "null" }
          ]
        },
        "name": {
          "type": "string"
        },
        "description": {
          "type": ["string", "null"]
        },
        "aka": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "status": {
          "type": ["string", "null"]
        },
        "owner": {
          "type": ["string", "null"]
        },
        "folder": {
          "type": ["string", "null"]
        },
        "distinctFrom": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "supersedes": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "constraints": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/constraint"
          }
        },
        "references": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/identifiedReference"
          }
        },
        "presentIn": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "attestations": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/attestation"
          }
        }
      }
    },
    "canvasEdge": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "localId",
        "document",
        "kind",
        "kindLabel",
        "coreKindLabel",
        "from",
        "to",
        "name",
        "description",
        "mode",
        "content",
        "status",
        "references",
        "presentIn"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "localId": {
          "type": "string",
          "minLength": 1
        },
        "document": {
          "type": "string",
          "minLength": 1
        },
        "kind": {
          "type": "string"
        },
        "kindLabel": {
          "type": "string"
        },
        "coreKindLabel": {
          "type": "string"
        },
        "readingKind": {
          "description": "The kind whose reading the edge label speaks (ADR 0159): an extension identity with a reading of its own, else the core kind label.",
          "type": "string"
        },
        "responsibility": {
          "description": "The responsibility letter the edge carries (#557, ADR 0159): R, C or I for the shipped responsibility kinds and their subkinds, null otherwise. Drawn only when the view's presentation says showResponsibility.",
          "enum": ["R", "C", "I", null]
        },
        "reading": {
          "description": "A reading the endpoints decided (ADR 0160): threatens, mitigates, bears on. Absent, the kind's own reading.",
          "type": "string"
        },
        "from": {
          "type": "string"
        },
        "to": {
          "type": "string"
        },
        "name": {
          "type": ["string", "null"]
        },
        "description": {
          "type": ["string", "null"]
        },
        "mode": {
          "type": ["string", "null"]
        },
        "content": {
          "type": ["string", "null"]
        },
        "status": {
          "type": ["string", "null"]
        },
        "references": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/identifiedReference"
          }
        },
        "presentIn": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "identifiedReference": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "ref"],
      "properties": {
        "id": {
          "type": "string"
        },
        "ref": {
          "type": "string"
        }
      }
    },
    "constraint": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "ref", "expects"],
      "properties": {
        "id": {
          "type": "string"
        },
        "ref": {
          "type": "string"
        },
        "expects": {
          "oneOf": [
            {
              "type": "object",
              "additionalProperties": false,
              "required": ["provider", "key", "value"],
              "properties": {
                "provider": {
                  "type": "string"
                },
                "key": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              }
            },
            {
              "type": "null"
            }
          ]
        }
      }
    },
    "attestation": {
      "type": "object",
      "additionalProperties": false,
      "required": ["topic", "by", "on", "recordedBy"],
      "properties": {
        "topic": {
          "type": "string"
        },
        "by": {
          "type": "string"
        },
        "on": {
          "type": "string"
        },
        "recordedBy": {
          "type": ["string", "null"]
        }
      }
    }
  }
}
