{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://graphenix.dev/schema/graphenix-format-2.1.0.json",
  "title": "Graphenix Format 2.1.0",
  "description": "JSON Schema for the Graphenix graph description format (version 2.1.0). Execution semantics are out of scope.",
  "type": "object",
  "required": ["formatVersion", "id", "graph"],
  "additionalProperties": false,
  "properties": {
    "formatVersion": {
      "type": "string",
      "const": "2.1.0",
      "description": "Graphenix format version. Must be `2.1.0`."
    },
    "id": {
      "type": "string",
      "description": "Globally unique identifier for this graph within the system."
    },
    "revision": {
      "type": "string",
      "description": "Version/revision of this specific graph document. Not the Graphenix format version."
    },
    "name": {
      "type": "string",
      "description": "Human-readable name for the graph."
    },
    "description": {
      "type": "string",
      "description": "Free-form description of the graph."
    },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Tags for classification, search, and filtering."
    },
    "graph": {
      "$ref": "#/$defs/Graph"
    },
    "types": {
      "type": "array",
      "items": { "$ref": "#/$defs/TypeDefinition" },
      "description": "Custom logical types referenced by nodes and ports."
    },
    "subgraphs": {
      "type": "array",
      "items": { "$ref": "#/$defs/SubgraphDefinition" },
      "description": "Inlined reusable graphs."
    },
    "metadata": {
      "$ref": "#/$defs/DocumentMetadata"
    }
  },
  "$defs": {
    "GraphenixMetadata": {
      "type": "object",
      "description": "Arbitrary metadata with optional dynamic payload under `data`.",
      "additionalProperties": true,
      "properties": {
        "data": {
          "type": "object",
          "description": "Dynamic client payload. Core does not interpret keys.",
          "additionalProperties": true
        }
      }
    },
    "GraphMetadata": {
      "allOf": [
        { "$ref": "#/$defs/GraphenixMetadata" },
        {
          "type": "object",
          "description": "Graph-level metadata including contracts and modelConfig.",
          "properties": {
            "graphEntry": { "$ref": "#/$defs/GraphEntryContract" },
            "graphResponse": { "$ref": "#/$defs/GraphResponseContract" },
            "modelConfig": {
              "type": "object",
              "description": "Graph-wide AI model cases. Validated by profile packages.",
              "additionalProperties": true
            },
            "jobPipeline": {
              "$ref": "#/$defs/JobPipelineMetadata",
              "description": "Logical job identity, pipeline position, and reprocessing defaults."
            }
          }
        }
      ]
    },
    "DocumentMetadata": {
      "allOf": [
        { "$ref": "#/$defs/GraphenixMetadata" },
        {
          "type": "object",
          "description": "Document-level metadata including graph-level summary contracts.",
          "properties": {
            "graphEntry": { "$ref": "#/$defs/GraphEntryContract" },
            "graphResponse": { "$ref": "#/$defs/GraphResponseContract" },
            "catalogRequests": { "$ref": "#/$defs/WoroxCatalogRequests" }
          }
        }
      ]
    },
    "NodeMetadata": {
      "allOf": [
        { "$ref": "#/$defs/GraphenixMetadata" },
        {
          "type": "object",
          "properties": {
            "catalogBinding": { "$ref": "#/$defs/WoroxCatalogBinding" },
            "catalogRequest": { "$ref": "#/$defs/WoroxCatalogRequest" }
          }
        }
      ]
    },
    "Graph": {
      "type": "object",
      "required": ["nodes", "edges", "inputs", "outputs"],
      "additionalProperties": false,
      "properties": {
        "nodes": {
          "type": "array",
          "items": { "$ref": "#/$defs/Node" }
        },
        "edges": {
          "type": "array",
          "items": { "$ref": "#/$defs/Edge" }
        },
        "inputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/GraphInput" }
        },
        "outputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/GraphOutput" }
        },
        "response": {
          "$ref": "#/$defs/GraphResponseDefinition",
          "description": "Executable response contract (shape, persistency target)."
        },
        "metadata": {
          "$ref": "#/$defs/GraphMetadata"
        }
      }
    },
    "Node": {
      "type": "object",
      "required": ["id", "kind"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "kind": { "type": "string" },
        "inputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/PortDefinition" },
          "default": []
        },
        "outputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/PortDefinition" },
          "default": []
        },
        "parameters": {
          "type": "object",
          "additionalProperties": true,
          "default": {}
        },
        "metadata": { "$ref": "#/$defs/NodeMetadata" },
        "layout": {
          "type": "object",
          "description": "Design-only canvas position; ignored at compile time.",
          "properties": {
            "x": { "type": "number" },
            "y": { "type": "number" }
          },
          "additionalProperties": true
        }
      }
    },
    "PortDefinition": {
      "type": "object",
      "required": ["id", "direction", "type"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "direction": { "type": "string", "enum": ["input", "output"] },
        "type": { "type": "string" },
        "required": { "type": "boolean", "default": false },
        "default": {
          "type": ["string", "number", "boolean", "array", "object", "null"]
        }
      }
    },
    "EdgeEndpoint": {
      "type": "object",
      "required": ["nodeId", "portId"],
      "additionalProperties": false,
      "properties": {
        "nodeId": { "type": "string" },
        "portId": { "type": "string" }
      }
    },
    "Edge": {
      "type": "object",
      "required": ["id", "from", "to"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "from": { "$ref": "#/$defs/EdgeEndpoint" },
        "to": { "$ref": "#/$defs/EdgeEndpoint" },
        "metadata": { "$ref": "#/$defs/GraphenixMetadata" }
      }
    },
    "GraphInput": {
      "type": "object",
      "required": ["id", "type", "target"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "type": { "type": "string" },
        "target": { "$ref": "#/$defs/EdgeEndpoint" },
        "contract": { "$ref": "#/$defs/GraphInputContract" },
        "metadata": { "$ref": "#/$defs/GraphenixMetadata" }
      }
    },
    "GraphInputContract": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "semanticKind": { "type": "string" },
        "required": { "type": "boolean", "default": false },
        "schema": { "type": "object", "additionalProperties": true },
        "resolver": { "$ref": "#/$defs/GraphInputResolver" }
      }
    },
    "GraphInputResolver": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "kind": { "type": "string" },
        "graphId": { "type": "string" },
        "metadataFilter": { "type": "object", "additionalProperties": true }
      }
    },
    "GraphOutput": {
      "type": "object",
      "required": ["id", "type"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "type": { "type": "string" },
        "source": { "$ref": "#/$defs/EdgeEndpoint" },
        "contract": { "$ref": "#/$defs/GraphOutputContract" },
        "metadata": { "$ref": "#/$defs/GraphenixMetadata" }
      }
    },
    "GraphOutputContract": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "semanticKind": { "type": "string" },
        "required": { "type": "boolean", "default": false },
        "schema": { "type": "object", "additionalProperties": true },
        "description": { "type": "string" }
      }
    },
    "TypeField": {
      "type": "object",
      "required": ["name", "type"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "type": { "type": "string" },
        "required": { "type": "boolean", "default": false }
      }
    },
    "TypeObject": {
      "type": "object",
      "required": ["id", "kind", "fields"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "kind": { "const": "object" },
        "description": { "type": "string" },
        "fields": {
          "type": "array",
          "items": { "$ref": "#/$defs/TypeField" }
        },
        "metadata": { "$ref": "#/$defs/GraphenixMetadata" }
      }
    },
    "TypeUnion": {
      "type": "object",
      "required": ["id", "kind", "options"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "kind": { "const": "union" },
        "description": { "type": "string" },
        "options": {
          "type": "array",
          "items": { "type": "string" }
        },
        "metadata": { "$ref": "#/$defs/GraphenixMetadata" }
      }
    },
    "TypeAlias": {
      "type": "object",
      "required": ["id", "kind", "target"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "kind": { "const": "alias" },
        "description": { "type": "string" },
        "target": { "type": "string" },
        "metadata": { "$ref": "#/$defs/GraphenixMetadata" }
      }
    },
    "TypeDefinition": {
      "oneOf": [
        { "$ref": "#/$defs/TypeObject" },
        { "$ref": "#/$defs/TypeUnion" },
        { "$ref": "#/$defs/TypeAlias" }
      ]
    },
    "SubgraphDefinition": {
      "type": "object",
      "required": ["id", "graph"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "graph": { "$ref": "#/$defs/Graph" },
        "metadata": { "$ref": "#/$defs/GraphenixMetadata" }
      }
    },
    "GraphEntryContract": {
      "type": "object",
      "description": "Graph-level summary contract for graph invocation.",
      "additionalProperties": true,
      "properties": {
        "summary": { "type": "string" },
        "requiredExecutionPaths": { "type": "array", "items": {} },
        "executionSchema": { "type": "object", "additionalProperties": true },
        "notableExecutionPaths": { "type": "array", "items": {} }
      }
    },
    "GraphResponseDefinition": {
      "type": "object",
      "description": "Executable response contract at graph root.",
      "additionalProperties": true,
      "properties": {
        "shape": { "type": "object", "additionalProperties": true },
        "missing": {},
        "persistency": { "$ref": "#/$defs/GraphResponsePersistency" }
      }
    },
    "GraphResponsePersistencyLink": {
      "type": "object",
      "description": "FK + relation intent when result is written cross-entity.",
      "required": ["relationKey", "fkPath", "type", "targetContentType"],
      "additionalProperties": true,
      "properties": {
        "relationKey": {
          "type": "string",
          "description": "Relation descriptor key on the result entity."
        },
        "fkPath": {
          "type": "string",
          "description": "Field path on the new result record holding the source record id."
        },
        "type": {
          "type": "string",
          "enum": ["oneToOne", "oneToMany", "manyToOne", "manyToMany"],
          "description": "Memorix relation cardinality."
        },
        "targetContentType": {
          "type": "string",
          "description": "Source/core record content type the link points at."
        }
      }
    },
    "GraphResponsePersistency": {
      "type": "object",
      "description": "Where graph run results are written in Memorix.",
      "required": ["entityId"],
      "additionalProperties": true,
      "properties": {
        "entityId": {
          "type": "string",
          "description": "Target entity id or same-as-input sentinel."
        },
        "contentType": {
          "type": "string",
          "description": "Sibling collection suffix for result writeback."
        },
        "newRecord": {
          "type": "boolean",
          "description": "When true (default), each run inserts a new result record. false = legacy replace (deprecated)."
        },
        "link": {
          "$ref": "#/$defs/GraphResponsePersistencyLink",
          "description": "Explicit FK + relation override; auto-derived when cross-object or newRecord."
        }
      }
    },
    "GraphResponseContract": {
      "type": "object",
      "description": "Graph-level summary contract for the final graph result.",
      "additionalProperties": true,
      "properties": {
        "summary": { "type": "string" },
        "finalOutputSchema": { "type": "object", "additionalProperties": true },
        "persistency": {
          "$ref": "#/$defs/GraphResponsePersistency",
          "description": "Authoring-only legacy path. Canonical: graph.response.persistency."
        }
      }
    },
    "WoroxCatalogRequest": {
      "type": "object",
      "additionalProperties": true
    },
    "WoroxCatalogBinding": {
      "type": "object",
      "additionalProperties": true
    },
    "WoroxCatalogRequests": {
      "oneOf": [
        {
          "type": "array",
          "items": { "$ref": "#/$defs/WoroxCatalogRequest" }
        },
        {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/WoroxCatalogRequest" }
        }
      ]
    },
    "JobPipelineReprocessingMode": {
      "type": "string",
      "enum": [
        "ttl",
        "skip",
        "failed-only",
        "all",
        "before-date",
        "after-date",
        "condition"
      ],
      "description": "Operator-facing reprocessing policy mode keyed by job type."
    },
    "JobPipelineTtl": {
      "type": "object",
      "description": "TTL window for reprocessing when mode is ttl.",
      "required": ["value", "unit"],
      "additionalProperties": false,
      "properties": {
        "value": { "type": "number" },
        "unit": {
          "type": "string",
          "enum": ["hours", "days", "weeks"]
        }
      }
    },
    "JobPipelineReprocessingDefaults": {
      "type": "object",
      "description": "Default reprocessing policy for this job type.",
      "additionalProperties": false,
      "properties": {
        "mode": { "$ref": "#/$defs/JobPipelineReprocessingMode" },
        "ttl": { "$ref": "#/$defs/JobPipelineTtl" }
      }
    },
    "JobTypeRef": {
      "type": "object",
      "description": "Reference to an upstream or downstream job type.",
      "required": ["jobTypeId"],
      "additionalProperties": false,
      "properties": {
        "jobTypeId": { "type": "string" },
        "label": { "type": "string" },
        "entity": {
          "type": "string",
          "description": "Cross-entity upstream: linked records of this entity must satisfy prerequisite."
        },
        "relationshipKey": {
          "type": "string",
          "description": "Relation key alias (canonical: relationKey)."
        },
        "relationKey": { "type": "string" }
      }
    },
    "JobPipelineContextLink": {
      "type": "object",
      "description": "Default linked-entity pull for jobMemory.context at enqueue.",
      "required": ["targetEntity"],
      "additionalProperties": false,
      "properties": {
        "relationKey": { "type": "string" },
        "relationshipKey": {
          "type": "string",
          "description": "Alias for relationKey."
        },
        "targetEntity": { "type": "string" },
        "target": {
          "type": "string",
          "enum": ["entity", "event", "knowledge"]
        },
        "contentTypes": {
          "type": "array",
          "items": { "type": "string" }
        },
        "limit": { "type": "integer" }
      }
    },
    "JobPipelineMetadata": {
      "type": "object",
      "description": "Logical job identity and pipeline position at authoring time.",
      "additionalProperties": false,
      "properties": {
        "jobTypeId": { "type": "string" },
        "jobType": {
          "type": "string",
          "description": "Deprecated alias for jobTypeId."
        },
        "label": { "type": "string" },
        "upstream": {
          "type": "array",
          "items": { "$ref": "#/$defs/JobTypeRef" }
        },
        "downstream": {
          "type": "array",
          "items": { "$ref": "#/$defs/JobTypeRef" }
        },
        "context": {
          "type": "array",
          "items": { "$ref": "#/$defs/JobPipelineContextLink" }
        },
        "reprocessing": { "$ref": "#/$defs/JobPipelineReprocessingDefaults" }
      }
    }
  }
}
