{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://dsp.dev/schemas/scene.schema.json",
    "title": "Diagram Scene Protocol Scene Schema",
    "description": "Draft JSON Schema for the canonical DSP scene document.",
    "type": "object",
    "additionalProperties": false,
    "required": ["schemaVersion", "scene", "elements"],
    "properties": {
      "schemaVersion": {
        "type": "string",
        "const": "0.1"
      },
      "scene": {
        "$ref": "#/$defs/scene"
      },
      "elements": {
        "type": "array",
        "items": {
          "$ref": "#/$defs/element"
        },
        "default": []
      },
      "styles": {
        "$ref": "#/$defs/styleRegistry"
      },
      "assets": {
        "$ref": "#/$defs/assetRegistry"
      },
      "constraints": {
        "type": "array",
        "items": {
          "$ref": "#/$defs/constraint"
        },
        "default": []
      },
      "computed": {
        "$ref": "#/$defs/computed"
      },
      "extensions": {
        "type": "object",
        "description": "Reserved extension point for protocol additions. Recognised keys include `showLifelineFeet` (sequence diagrams only).",
        "additionalProperties": true,
        "default": {},
        "properties": {
          "showLifelineFeet": {
            "type": "boolean",
            "default": true,
            "description": "Sequence-diagram only. When true (default), the renderer draws a foot bar at the bottom of each lifeline mirroring the head (UML / PlantUML / Mermaid convention). Set to false to suppress foot bars - useful when the author authors their own bottom row of shapes."
          }
        }
      },
      "diagramFamily": {
        "type": "string",
        "enum": ["architecture", "workflow", "entityRelationship", "sequence", "network", "orgchart", "uiflow"],
        "description": "Diagram family declaration. Technically optional in the schema but effectively load-bearing: gates family-specific validation, layout, and rendering behaviour the engine and downstream tooling rely on (sequence-family fan-in exemption, ER auto-promote-fk-labels, workflow BPMN conventions, family-namespaced node types). Omitting it triggers a MISSING_DIAGRAM_FAMILY info diagnostic on the render response. Always declare on every scene."
      },
      "layoutStrategy": {
        "type": "object",
        "properties": {
          "algorithm": {
            "type": "string",
            "enum": ["hierarchical", "flow", "grid", "forceDirected"],
            "description": "Auto-layout algorithm"
          },
          "direction": {
            "type": "string",
            "enum": ["TB", "BT", "LR", "RL"],
            "default": "TB",
            "description": "Layout direction (top-to-bottom, left-to-right, etc.)"
          },
          "nodeSpacing": { "type": "number", "default": 50, "description": "Spacing between nodes in same rank" },
          "rankSpacing": { "type": "number", "default": 80, "description": "Spacing between ranks/layers" },
          "nodeWidth": { "type": "number", "default": 150, "description": "Default node width for auto-positioned nodes" },
          "nodeHeight": { "type": "number", "default": 60, "description": "Default node height for auto-positioned nodes" }
        },
        "required": ["algorithm"]
      },
      "palette": {
        "type": "object",
        "description": "Scene-level color palette that overrides theme defaults for unstyled elements. All properties optional - only specify the colors you want to override. Cascade: element style > palette > theme > fallback.",
        "properties": {
          "background": { "type": "string", "description": "Canvas background color" },
          "foreground": { "type": "string", "description": "Default text color for nodes" },
          "nodeFill": { "type": "string", "description": "Default node fill color" },
          "nodeStroke": { "type": "string", "description": "Default node border color" },
          "edgeStroke": { "type": "string", "description": "Default edge line color" },
          "accentPrimary": { "type": "string", "description": "Primary accent color (org chart stripes, ER headers)" },
          "accentSecondary": { "type": "string", "description": "Secondary accent color" },
          "mutedForeground": { "type": "string", "description": "Edge label text color" },
          "containerFill": { "type": "string", "description": "Default frame/group fill color" },
          "containerStroke": { "type": "string", "description": "Default frame/group border color" }
        }
      }
    },
    "$defs": {
      "id": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "pattern": "^[A-Za-z0-9._:-]+$"
      },
      "nonEmptyString": {
        "type": "string",
        "minLength": 1
      },
      "nonNegativeNumber": {
        "type": "number",
        "minimum": 0
      },
      "zIndex": {
        "type": "integer"
      },
      "color": {
        "type": "string",
        "description": "CSS-compatible color string. Implementations may choose to restrict this further.",
        "minLength": 1
      },
      "timestamp": {
        "type": "string",
        "format": "date-time"
      },
      "metadata": {
        "type": "object",
        "description": "Freeform metadata for provenance or custom annotations.",
        "additionalProperties": true,
        "default": {}
      },
      "point": {
        "type": "object",
        "additionalProperties": false,
        "required": ["x", "y"],
        "properties": {
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          }
        }
      },
      "size": {
        "type": "object",
        "additionalProperties": false,
        "required": ["width", "height"],
        "properties": {
          "width": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "height": {
            "$ref": "#/$defs/nonNegativeNumber"
          }
        }
      },
      "bounds": {
        "type": "object",
        "additionalProperties": false,
        "required": ["x", "y", "width", "height"],
        "properties": {
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "width": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "height": {
            "$ref": "#/$defs/nonNegativeNumber"
          }
        }
      },
      "rotation": {
        "type": "number",
        "default": 0
      },
      "units": {
        "type": "string",
        "enum": ["px"]
      },
      "scene": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id"],
        "properties": {
          "id": {
            "$ref": "#/$defs/id"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "units": {
            "$ref": "#/$defs/units"
          },
          "canvas": {
            "$ref": "#/$defs/canvas"
          },
          "viewport": {
            "$ref": "#/$defs/viewport"
          },
          "defaults": {
            "$ref": "#/$defs/sceneDefaults"
          },
          "metadata": {
            "$ref": "#/$defs/sceneMetadata"
          },
          "extensions": {
            "type": "object",
            "additionalProperties": true,
            "default": {}
          }
        }
      },
      "canvas": {
        "type": "object",
        "additionalProperties": false,
        "required": [],
        "properties": {
          "width": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "height": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "background": {
            "$ref": "#/$defs/color"
          },
          "grid": {
            "$ref": "#/$defs/nonNegativeNumber",
            "default": 0
          },
          "snap": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "viewport": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "originX": {
            "type": "number",
            "default": 0
          },
          "originY": {
            "type": "number",
            "default": 0
          },
          "zoom": {
            "type": "number",
            "exclusiveMinimum": 0,
            "default": 1
          }
        },
        "default": {
          "originX": 0,
          "originY": 0,
          "zoom": 1
        }
      },
      "sceneDefaults": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "fontFamily": {
            "type": "string"
          },
          "fontSize": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "strokeWidth": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "router": {
            "$ref": "#/$defs/router"
          }
        },
        "default": {}
      },
      "sceneMetadata": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "createdBy": {
            "type": "string"
          },
          "createdAt": {
            "$ref": "#/$defs/timestamp"
          },
          "updatedAt": {
            "$ref": "#/$defs/timestamp"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "provenance": {
            "$ref": "#/$defs/metadata"
          }
        },
        "default": {}
      },
      "elementBase": {
        "type": "object",
        "required": ["id", "kind"],
        "properties": {
          "id": {
            "$ref": "#/$defs/id"
          },
          "kind": {
            "type": "string",
            "enum": ["node", "edge", "group", "text", "image", "frame", "guide"]
          },
          "name": {
            "type": "string"
          },
          "zIndex": {
            "$ref": "#/$defs/zIndex",
            "default": 0
          },
          "locked": {
            "type": "boolean",
            "default": false
          },
          "visible": {
            "type": "boolean",
            "default": true
          },
          "style": {
            "oneOf": [
              { "type": "string", "description": "Reference to a named style in scene.styles" },
              { "$ref": "#/$defs/styleValue", "description": "Inline style object" }
            ],
            "description": "Element style: either a named-style string key (resolved against scene.styles) or an inline StyleValue object"
          },
          "metadata": {
            "$ref": "#/$defs/metadata"
          },
          "extensions": {
            "type": "object",
            "additionalProperties": true,
            "default": {}
          },
          "x": {
            "type": "number",
            "description": "Shorthand for layout.x - sets layout.mode to 'absolute' automatically"
          },
          "y": {
            "type": "number",
            "description": "Shorthand for layout.y - sets layout.mode to 'absolute' automatically"
          },
          "width": {
            "type": "number",
            "description": "Shorthand for layout.width - sets layout.mode to 'absolute' automatically"
          },
          "height": {
            "type": "number",
            "description": "Shorthand for layout.height - sets layout.mode to 'absolute' automatically"
          }
        }
      },
      "element": {
        "oneOf": [
          {
            "$ref": "#/$defs/nodeElement"
          },
          {
            "$ref": "#/$defs/edgeElement"
          },
          {
            "$ref": "#/$defs/groupElement"
          },
          {
            "$ref": "#/$defs/frameElement"
          },
          {
            "$ref": "#/$defs/textElement"
          },
          {
            "$ref": "#/$defs/imageElement"
          },
          {
            "$ref": "#/$defs/guideElement"
          }
        ]
      },
      "nodeType": {
        "type": "string",
        "enum": [
          "generic",
          "service",
          "database",
          "queue",
          "actor",
          "note",
          "decision",
          "document",
          "process",
          "container",
          "externalSystem",
          "storage",
          "event",
          "iconNode",
          "workflow.start",
          "workflow.end",
          "workflow.task",
          "workflow.decision",
          "workflow.gateway",
          "workflow.gatewayParallel",
          "workflow.gatewayInclusive",
          "workflow.subprocess",
          "workflow.timer",
          "workflow.error",
          "er.entity",
          "er.weakEntity",
          "er.attribute",
          "er.relationship",
          "sequence.lifeline",
          "sequence.activation",
          "sequence.actor",
          "sequence.note",
          "network.server",
          "network.router",
          "network.switch",
          "network.firewall",
          "network.cloud",
          "network.client",
          "org.person",
          "org.role",
          "org.department",
          "workflow.intermediateTimer",
          "workflow.intermediateMessage",
          "workflow.intermediateError",
          "workflow.intermediateThrowMessage",
          "workflow.terminate",
          "workflow.messageStart",
          "workflow.messageEnd",
          "workflow.gatewayEvent",
          "uiflow.screen",
          "uiflow.modal",
          "uiflow.entry",
          "uiflow.exit"
        ]
      },
      "shape": {
        "type": "string",
        "enum": [
          "rect",
          "roundedRect",
          "ellipse",
          "diamond",
          "cylinder",
          "pill",
          "hexagon",
          "parallelogram",
          "cloud",
          "box3d",
          "textBox",
          "iconBox"
        ]
      },
      "side": {
        "type": "string",
        "enum": ["top", "right", "bottom", "left"]
      },
      "port": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "side"],
        "properties": {
          "id": {
            "$ref": "#/$defs/id"
          },
          "side": {
            "$ref": "#/$defs/side"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "default": 0
          },
          "label": {
            "type": "string"
          },
          "metadata": {
            "$ref": "#/$defs/metadata"
          }
        }
      },
      "absoluteLayout": {
        "type": "object",
        "additionalProperties": false,
        "required": ["mode", "x", "y", "width", "height"],
        "properties": {
          "mode": {
            "type": "string",
            "const": "absolute"
          },
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "width": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "height": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "rotation": {
            "$ref": "#/$defs/rotation"
          },
          "autoSize": {
            "type": "string",
            "enum": ["content", "none"],
            "default": "none",
            "description": "When set to 'content', the node height auto-expands to fit wrapped text"
          }
        }
      },
      "placeClause": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "above": {
            "$ref": "#/$defs/id"
          },
          "below": {
            "$ref": "#/$defs/id"
          },
          "leftOf": {
            "$ref": "#/$defs/id"
          },
          "rightOf": {
            "$ref": "#/$defs/id"
          },
          "inside": {
            "$ref": "#/$defs/id"
          },
          "gap": {
            "$ref": "#/$defs/nonNegativeNumber",
            "default": 0
          },
          "alignX": {
            "type": "string",
            "enum": ["left", "center", "right"]
          },
          "alignY": {
            "type": "string",
            "enum": ["top", "center", "bottom"]
          }
        },
        "allOf": [
          {
            "oneOf": [
              { "required": ["above"] },
              { "required": ["below"] },
              { "required": ["leftOf"] },
              { "required": ["rightOf"] },
              { "required": ["inside"] }
            ]
          }
        ]
      },
      "relativeLayout": {
        "type": "object",
        "additionalProperties": false,
        "required": ["mode", "place"],
        "properties": {
          "mode": {
            "type": "string",
            "const": "relative"
          },
          "place": {
            "$ref": "#/$defs/placeClause"
          },
          "preferredSize": {
            "$ref": "#/$defs/size"
          },
          "rotation": {
            "$ref": "#/$defs/rotation"
          }
        }
      },
      "layout": {
        "oneOf": [
          {
            "$ref": "#/$defs/absoluteLayout"
          },
          {
            "$ref": "#/$defs/relativeLayout"
          }
        ]
      },
      "nodeElement": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/elementBase"
          },
          {
            "type": "object",
            "required": ["kind", "nodeType", "shape"],
            "properties": {
              "kind": {
                "type": "string",
                "const": "node"
              },
              "nodeType": {
                "$ref": "#/$defs/nodeType"
              },
              "shape": {
                "$ref": "#/$defs/shape"
              },
              "label": {
                "type": "string"
              },
              "layout": {
                "$ref": "#/$defs/layout"
              },
              "ports": {
                "type": "array",
                "items": {
                  "$ref": "#/$defs/port"
                },
                "default": []
              },
              "icon": {
                "type": "string",
                "description": "Icon key ({family}:{id}, e.g. lucide:database) or URL"
              },
              "textStyle": {
                "$ref": "#/$defs/textStyle"
              }
            }
          }
        ]
      },
      "router": {
        "type": "string",
        "enum": ["straight", "orthogonal", "curved", "polyline"]
      },
      "anchor": {
        "type": "object",
        "additionalProperties": false,
        "required": ["side", "offset"],
        "properties": {
          "side": {
            "$ref": "#/$defs/side"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          }
        }
      },
      "endpoint": {
        "type": "object",
        "description": "Edge endpoint. elementId may reference any element kind - typically a node, but frame and group IDs are also valid targets. An edge to a frame terminates at the frame's border using cardinal anchors; useful for abstract group dependencies (e.g. an edge to a 'Regional Services' sidebar rather than to a specific service inside). On entityRelationship diagrams, set `column` to anchor the edge at a specific column row inside the entity (matching the dbdiagram.io / DBeaver convention where FK edges point at the FK column itself rather than the entity rectangle as a whole).",
        "additionalProperties": false,
        "required": ["elementId"],
        "properties": {
          "elementId": {
            "$ref": "#/$defs/id"
          },
          "portId": {
            "$ref": "#/$defs/id"
          },
          "anchor": {
            "$ref": "#/$defs/anchor"
          },
          "column": {
            "type": "string",
            "description": "Optional column-row anchor for ER entities. When set, must match the `name` of a column declared in the endpoint entity's `extensions.columns` array. The edge's segment touching this endpoint anchors at the column row inside the entity instead of the entity's outer face. Mismatched names emit an EDGE_COLUMN_NOT_FOUND warning."
          },
          "cardinality": {
            "type": "string",
            "enum": ["one", "many", "zero-or-one", "zero-or-many", "one-or-many"],
            "description": "ER-style cardinality marker for this endpoint"
          }
        },
        "allOf": [
          {
            "not": {
              "required": ["portId", "anchor"]
            }
          }
        ]
      },
      "arrowhead": {
        "type": "string",
        "enum": ["none", "triangle", "diamond", "circle", "bar", "openTriangle", "openCircle"]
      },
      "edgeEndpoints": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "startArrow": {
            "$ref": "#/$defs/arrowhead",
            "default": "none"
          },
          "endArrow": {
            "$ref": "#/$defs/arrowhead",
            "default": "none"
          }
        },
        "default": {
          "startArrow": "none",
          "endArrow": "none"
        }
      },
      "edgeElement": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/elementBase"
          },
          {
            "type": "object",
            "required": ["kind", "from", "to"],
            "properties": {
              "kind": {
                "type": "string",
                "const": "edge"
              },
              "from": {
                "$ref": "#/$defs/endpoint"
              },
              "to": {
                "$ref": "#/$defs/endpoint"
              },
              "router": {
                "$ref": "#/$defs/router"
              },
              "label": {
                "type": "string",
                "description": "Edge label text. Plain strings render as a single tspan. Labels matching the state-machine / SCXML / BPMN convention 'EVENT [guard] / action' render with multi-tier typography: event 12px, guard 10px muted, action 10px muted italic. Detection is content-based (balanced [...] OR ' / ' separator) and family-agnostic. Multi-line labels (containing \\n) skip the convention parse."
              },
              "endpoints": {
                "$ref": "#/$defs/edgeEndpoints"
              },
              "waypoints": {
                "type": "array",
                "items": {
                  "$ref": "#/$defs/point"
                },
                "default": []
              },
              "edgeType": {
                "type": "string",
                "enum": ["default", "workflow.sequenceFlow", "workflow.messageFlow", "er.relationship", "er.identifying", "sequence.message", "sequence.reply", "sequence.create", "sequence.async", "sequence.destroy", "network.dataFlow", "network.controlFlow", "org.directReport", "org.dottedLine", "uiflow.navigate", "uiflow.back", "uiflow.action"],
                "default": "default",
                "description": "Family-specific edge type for typed connection semantics"
              }
            }
          }
        ]
      },
      "groupLayout": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "padding": {
            "$ref": "#/$defs/nonNegativeNumber",
            "default": 0
          },
          "titleBar": {
            "$ref": "#/$defs/nonNegativeNumber",
            "default": 0
          },
          "autoResize": {
            "type": "boolean",
            "default": false
          }
        },
        "default": {}
      },
      "groupElement": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/elementBase"
          },
          {
            "type": "object",
            "required": ["kind", "children"],
            "properties": {
              "kind": {
                "type": "string",
                "const": "group"
              },
              "title": {
                "type": "string"
              },
              "children": {
                "type": "array",
                "items": {
                  "$ref": "#/$defs/id"
                }
              },
              "layout": {
                "$ref": "#/$defs/groupLayout"
              }
            }
          }
        ]
      },
      "frameElement": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/elementBase"
          },
          {
            "type": "object",
            "required": ["kind", "children"],
            "properties": {
              "kind": {
                "type": "string",
                "const": "frame"
              },
              "title": {
                "type": "string"
              },
              "children": {
                "type": "array",
                "items": {
                  "$ref": "#/$defs/id"
                }
              },
              "layout": {
                "$ref": "#/$defs/layout"
              },
              "containerType": {
                "type": "string",
                "enum": ["generic", "pool", "lane", "subprocess", "partition", "package", "boundary", "fragment"],
                "default": "generic",
                "description": "Semantic container type for swimlane and process layout"
              },
              "laneDirection": {
                "type": "string",
                "enum": ["horizontal", "vertical"],
                "description": "Direction for lane-based layout within this container"
              }
            }
          }
        ]
      },
      "textStyle": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "wrap": {
            "type": "string",
            "enum": ["none", "word", "character"],
            "default": "none"
          },
          "align": {
            "type": "string",
            "enum": ["left", "center", "right"],
            "default": "left"
          },
          "verticalAlign": {
            "type": "string",
            "enum": ["top", "middle", "bottom"]
          }
        },
        "default": {}
      },
      "textElement": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/elementBase"
          },
          {
            "type": "object",
            "required": ["kind", "text", "layout"],
            "properties": {
              "kind": {
                "type": "string",
                "const": "text"
              },
              "text": {
                "type": "string"
              },
              "layout": {
                "$ref": "#/$defs/layout"
              },
              "textStyle": {
                "$ref": "#/$defs/textStyle"
              }
            }
          }
        ]
      },
      "fitMode": {
        "type": "string",
        "enum": ["contain", "cover", "stretch", "original"]
      },
      "imageElement": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/elementBase"
          },
          {
            "type": "object",
            "required": ["kind", "assetRef", "layout"],
            "properties": {
              "kind": {
                "type": "string",
                "const": "image"
              },
              "assetRef": {
                "$ref": "#/$defs/id"
              },
              "layout": {
                "$ref": "#/$defs/layout"
              },
              "fit": {
                "$ref": "#/$defs/fitMode"
              }
            }
          }
        ]
      },
      "guideOrientation": {
        "type": "string",
        "enum": ["horizontal", "vertical"]
      },
      "guideElement": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/elementBase"
          },
          {
            "type": "object",
            "required": ["kind", "orientation", "position"],
            "properties": {
              "kind": {
                "type": "string",
                "const": "guide"
              },
              "orientation": {
                "$ref": "#/$defs/guideOrientation"
              },
              "position": {
                "type": "number"
              }
            }
          }
        ]
      },
      "styleValue": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "fill": {
            "$ref": "#/$defs/color"
          },
          "stroke": {
            "$ref": "#/$defs/color"
          },
          "strokeWidth": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "cornerRadius": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "fontFamily": {
            "type": "string"
          },
          "fontSize": {
            "$ref": "#/$defs/nonNegativeNumber"
          },
          "fontWeight": {
            "oneOf": [
              {
                "type": "integer",
                "minimum": 100,
                "maximum": 900,
                "multipleOf": 100
              },
              {
                "type": "string",
                "enum": ["normal", "bold", "lighter", "bolder"]
              }
            ]
          },
          "textColor": {
            "$ref": "#/$defs/color"
          },
          "dash": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/nonNegativeNumber"
            },
            "default": []
          },
          "labelBackground": {
            "$ref": "#/$defs/color"
          },
          "opacity": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "accentColor": {
            "$ref": "#/$defs/color",
            "description": "Accent stripe color for org chart cards and department grouping"
          },
          "color": {
            "$ref": "#/$defs/color",
            "description": "Alias for textColor (normalized to textColor at runtime)"
          },
          "forceLabel": {
            "type": "boolean",
            "description": "Edge-only opt-out for the column-row auto-promotion. When an edge's label exactly matches the name of a column declared in either endpoint's extensions.columns, the platform automatically promotes the edge to a column-row anchor (the FK edge terminates at the named column row inside the entity, matching the dbdiagram.io / DBeaver convention) and drops the label because the column position now carries the FK identity. Set this to true to keep the label visible and skip the auto-promotion on this edge - useful when the label is genuinely an annotation rather than an FK column reference."
          }
        }
      },
      "styleRegistry": {
        "type": "object",
        "default": {},
        "patternProperties": {
          "^[A-Za-z0-9._:-]+$": {
            "$ref": "#/$defs/styleValue"
          }
        },
        "additionalProperties": false
      },
      "assetEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": ["kind", "mimeType", "uri"],
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["image"]
          },
          "mimeType": {
            "type": "string",
            "minLength": 1
          },
          "uri": {
            "type": "string",
            "format": "uri"
          },
          "integrity": {
            "type": "string"
          },
          "metadata": {
            "$ref": "#/$defs/metadata"
          }
        }
      },
      "assetRegistry": {
        "type": "object",
        "default": {},
        "patternProperties": {
          "^[A-Za-z0-9._:-]+$": {
            "$ref": "#/$defs/assetEntry"
          }
        },
        "additionalProperties": false
      },
      "constraint": {
        "oneOf": [
          {
            "$ref": "#/$defs/alignConstraint"
          },
          {
            "$ref": "#/$defs/distributeConstraint"
          },
          {
            "$ref": "#/$defs/containConstraint"
          },
          {
            "$ref": "#/$defs/stackConstraint"
          },
          {
            "$ref": "#/$defs/gridConstraint"
          },
          {
            "$ref": "#/$defs/sameSizeConstraint"
          },
          {
            "$ref": "#/$defs/minGapConstraint"
          },
          {
            "$ref": "#/$defs/noOverlapConstraint"
          },
          {
            "$ref": "#/$defs/centerInConstraint"
          },
          {
            "$ref": "#/$defs/orderConstraint"
          }
        ]
      },
      "constraintBase": {
        "type": "object",
        "required": ["type"],
        "properties": {
          "type": {
            "type": "string"
          },
          "id": {
            "$ref": "#/$defs/id"
          },
          "required": {
            "type": "boolean",
            "default": false
          },
          "metadata": {
            "$ref": "#/$defs/metadata"
          }
        }
      },
      "axis": {
        "type": "string",
        "enum": ["x", "y"]
      },
      "elementIdList": {
        "type": "array",
        "items": {
          "$ref": "#/$defs/id"
        },
        "minItems": 1
      },
      "alignConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "axis", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "align"
              },
              "axis": {
                "$ref": "#/$defs/axis"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              }
            }
          }
        ]
      },
      "distributeConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "axis", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "distribute"
              },
              "axis": {
                "$ref": "#/$defs/axis"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              },
              "gap": {
                "$ref": "#/$defs/nonNegativeNumber"
              }
            }
          }
        ]
      },
      "containConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "containerId", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "contain"
              },
              "containerId": {
                "$ref": "#/$defs/id"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              },
              "padding": {
                "$ref": "#/$defs/nonNegativeNumber"
              }
            }
          }
        ]
      },
      "stackConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "axis", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "stack"
              },
              "axis": {
                "$ref": "#/$defs/axis"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              },
              "gap": {
                "$ref": "#/$defs/nonNegativeNumber"
              }
            }
          }
        ]
      },
      "gridConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "grid"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              },
              "columns": {
                "type": "integer",
                "minimum": 1
              },
              "rows": {
                "type": "integer",
                "minimum": 1
              },
              "columnGap": {
                "$ref": "#/$defs/nonNegativeNumber"
              },
              "rowGap": {
                "$ref": "#/$defs/nonNegativeNumber"
              }
            }
          }
        ]
      },
      "sameSizeConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "sameSize"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              },
              "dimension": {
                "type": "string",
                "enum": ["width", "height", "both"],
                "default": "both"
              }
            }
          }
        ]
      },
      "minGapConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "axis", "elements", "gap"],
            "properties": {
              "type": {
                "type": "string",
                "const": "minGap"
              },
              "axis": {
                "$ref": "#/$defs/axis"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              },
              "gap": {
                "$ref": "#/$defs/nonNegativeNumber"
              }
            }
          }
        ]
      },
      "noOverlapConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "noOverlap"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              }
            }
          }
        ]
      },
      "centerInConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "containerId", "elements"],
            "properties": {
              "type": {
                "type": "string",
                "const": "centerIn"
              },
              "containerId": {
                "$ref": "#/$defs/id"
              },
              "elements": {
                "$ref": "#/$defs/elementIdList"
              },
              "axis": {
                "type": "string",
                "enum": ["x", "y", "both"],
                "default": "both"
              }
            }
          }
        ]
      },
      "orderRelation": {
        "type": "string",
        "enum": ["leftOf", "rightOf", "above", "below", "sameRank"]
      },
      "orderConstraint": {
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/$defs/constraintBase"
          },
          {
            "type": "object",
            "required": ["type", "source", "target", "relation"],
            "properties": {
              "type": {
                "type": "string",
                "const": "order"
              },
              "source": {
                "$ref": "#/$defs/id"
              },
              "target": {
                "$ref": "#/$defs/id"
              },
              "relation": {
                "$ref": "#/$defs/orderRelation"
              }
            }
          }
        ]
      },
      "computedLayoutRegistry": {
        "type": "object",
        "default": {},
        "patternProperties": {
          "^[A-Za-z0-9._:-]+$": {
            "$ref": "#/$defs/bounds"
          }
        },
        "additionalProperties": false
      },
      "computedEdgePath": {
        "type": "object",
        "additionalProperties": false,
        "required": ["points"],
        "properties": {
          "points": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/point"
            },
            "minItems": 2
          },
          "labelPosition": {
            "$ref": "#/$defs/point"
          },
          "labelWidth": {
            "type": "number",
            "description": "Measured label width including padding. Used by the renderer to draw a background rect behind edge labels."
          },
          "labelHeight": {
            "type": "number",
            "description": "Measured label height including padding."
          },
          "router": {
            "type": "string",
            "enum": ["polyline", "curved"],
            "description": "Engine's actual routing decision after fallbacks. Independent of the author-set `edge.router` preference: an authored `orthogonal` edge can render with `router: \"curved\"` after the long-haul back-edge fallback (orthogonal route ≥1.5× the manhattan distance with 4+ corners). When `\"curved\"`, the renderer draws the 2-point points list as a quadratic Bezier with a perpendicular-offset control point."
          }
        }
      },
      "computedEdgePathRegistry": {
        "type": "object",
        "default": {},
        "patternProperties": {
          "^[A-Za-z0-9._:-]+$": {
            "$ref": "#/$defs/computedEdgePath"
          }
        },
        "additionalProperties": false
      },
      "diagnostic": {
        "type": "object",
        "additionalProperties": false,
        "required": ["code", "message", "severity"],
        "properties": {
          "code": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "enum": ["info", "warning", "error", "fatal"]
          }
        }
      },
      "computed": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "layout": {
            "$ref": "#/$defs/computedLayoutRegistry"
          },
          "edgePaths": {
            "$ref": "#/$defs/computedEdgePathRegistry"
          },
          "diagnostics": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/diagnostic"
            },
            "default": []
          },
          "normalizedHash": {
            "type": "string"
          }
        },
        "default": {}
      }
    }
  }
  