{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://opendataproducts.org/odpr-v1.0/schema/odpr.yaml",
  "title": "Data Product Recipe Specification",
  "description": "Lightweight workflow recipes for repeatable data product delivery.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema",
    "version",
    "kind"
  ],
  "properties": {
    "schema": {
      "type": "string",
      "const": "https://opendataproducts.org/odpr-v1.0/schema/odpr.yaml"
    },
    "version": {
      "type": "string",
      "const": "1.0"
    },
    "kind": {
      "type": "string",
      "enum": [
        "Recipe",
        "RuntimeProfile",
        "RecipeCatalog",
        "DataProductRecipe"
      ]
    },
    "recipe": {
      "$ref": "#/$defs/Recipe"
    },
    "runtimeProfile": {
      "$ref": "#/$defs/RuntimeProfile"
    },
    "recipeCatalog": {
      "$ref": "#/$defs/RecipeCatalog"
    },
    "dataProductRecipe": {
      "$ref": "#/$defs/DataProductRecipe"
    }
  },
  "oneOf": [
    {
      "required": [
        "recipe"
      ],
      "properties": {
        "kind": {
          "const": "Recipe"
        }
      },
      "not": {
        "anyOf": [
          {
            "required": [
              "provider"
            ]
          },
          {
            "required": [
              "recipeCatalog"
            ]
          },
          {
            "required": [
              "dataProductRecipe"
            ]
          }
        ]
      }
    },
    {
      "required": [
        "runtimeProfile"
      ],
      "properties": {
        "kind": {
          "const": "RuntimeProfile"
        }
      },
      "not": {
        "anyOf": [
          {
            "required": [
              "recipe"
            ]
          },
          {
            "required": [
              "recipeCatalog"
            ]
          },
          {
            "required": [
              "dataProductRecipe"
            ]
          }
        ]
      }
    },
    {
      "required": [
        "recipeCatalog"
      ],
      "properties": {
        "kind": {
          "const": "RecipeCatalog"
        }
      },
      "not": {
        "anyOf": [
          {
            "required": [
              "recipe"
            ]
          },
          {
            "required": [
              "provider"
            ]
          },
          {
            "required": [
              "dataProductRecipe"
            ]
          }
        ]
      }
    },
    {
      "required": [
        "dataProductRecipe"
      ],
      "properties": {
        "kind": {
          "const": "DataProductRecipe"
        }
      },
      "not": {
        "anyOf": [
          {
            "required": [
              "recipe"
            ]
          },
          {
            "required": [
              "provider"
            ]
          },
          {
            "required": [
              "recipeCatalog"
            ]
          }
        ]
      }
    }
  ],
  "$defs": {
    "LocalizedText": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "minProperties": 1,
      "properties": {
        "en": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "Text": {
      "oneOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "$ref": "#/$defs/LocalizedText"
        }
      ]
    },
    "Metadata": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "id",
        "name"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "name": {
          "$ref": "#/$defs/LocalizedText"
        },
        "description": {
          "$ref": "#/$defs/LocalizedText"
        },
        "owner": {
          "type": "string"
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "NamedPath": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "id",
        "path"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "path": {
          "$ref": "#/$defs/RelativePath"
        },
        "description": {
          "$ref": "#/$defs/Text"
        }
      }
    },
    "RelativePath": {
      "type": "string",
      "minLength": 1,
      "pattern": "^(?!/)(?!.*(^|/)\\.\\.(/|$)).+"
    },
    "RecipeScope": {
      "type": "string",
      "enum": [
        "data-product",
        "catalog",
        "graph",
        "portfolio"
      ]
    },
    "GraphNodeType": {
      "type": "string",
      "enum": [
        "DataProduct",
        "BusinessObjective",
        "UseCase",
        "Signal",
        "Policy",
        "DataContract",
        "DataService",
        "API",
        "Owner",
        "System",
        "*"
      ]
    },
    "GraphTriggerAttributeValue": {
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "number"
        },
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ]
    },
    "GraphTriggerAttribute": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "pattern": "^(?!\\*$).+"
        },
        "from": {
          "$ref": "#/$defs/GraphTriggerAttributeValue"
        },
        "to": {
          "$ref": "#/$defs/GraphTriggerAttributeValue"
        }
      },
      "anyOf": [
        {
          "required": [
            "from"
          ]
        },
        {
          "required": [
            "to"
          ]
        }
      ]
    },
    "GraphTriggerSubject": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "nodeType": {
          "$ref": "#/$defs/GraphNodeType"
        },
        "edgeType": {
          "type": "string",
          "minLength": 1
        },
        "fromNodeType": {
          "$ref": "#/$defs/GraphNodeType"
        },
        "toNodeType": {
          "$ref": "#/$defs/GraphNodeType"
        },
        "attribute": {
          "$ref": "#/$defs/GraphTriggerAttribute"
        }
      }
    },
    "GraphTriggerCondition": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "GraphTrigger": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "source",
        "event"
      ],
      "properties": {
        "source": {
          "type": "string",
          "enum": [
            "odpg"
          ]
        },
        "event": {
          "type": "string",
          "enum": [
            "node.added",
            "node.removed",
            "node.attributeChanged",
            "edge.added",
            "edge.removed",
            "edge.attributeChanged",
            "graph.conditionMatched"
          ]
        },
        "subject": {
          "$ref": "#/$defs/GraphTriggerSubject"
        },
        "condition": {
          "$ref": "#/$defs/GraphTriggerCondition"
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "event": {
                "enum": [
                  "node.added",
                  "node.removed"
                ]
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "required": [
              "subject"
            ],
            "properties": {
              "subject": {
                "required": [
                  "nodeType"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "node.attributeChanged"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "required": [
              "subject"
            ],
            "properties": {
              "subject": {
                "required": [
                  "attribute"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "enum": [
                  "edge.added",
                  "edge.removed"
                ]
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "required": [
              "subject"
            ],
            "properties": {
              "subject": {
                "required": [
                  "edgeType"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "edge.attributeChanged"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "required": [
              "subject"
            ],
            "properties": {
              "subject": {
                "required": [
                  "edgeType",
                  "attribute"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "graph.conditionMatched"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "required": [
              "condition"
            ]
          }
        }
      ]
    },
    "GraphContext": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "graphRef",
        "start"
      ],
      "properties": {
        "graphRef": {
          "oneOf": [
            {
              "$ref": "#/$defs/RelativePath"
            },
            {
              "type": "string",
              "pattern": "^https?://.+"
            }
          ]
        },
        "start": {
          "type": "string",
          "minLength": 1
        },
        "depth": {
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "ContextPolicy": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "format"
      ],
      "properties": {
        "format": {
          "type": "string",
          "enum": [
            "yaml",
            "toon",
            "gcf",
            "auto"
          ]
        },
        "fallback": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "yaml",
              "toon",
              "gcf",
              "auto"
            ]
          }
        }
      }
    },
    "ExecutionPolicy": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "local",
            "hosted",
            "hybrid",
            "none"
          ]
        },
        "runtimeRef": {
          "$ref": "#/$defs/RuntimeRef"
        }
      }
    },
    "RuntimeRef": {
      "type": "string",
      "minLength": 1,
      "format": "uri-reference",
      "pattern": "^(?=.*(?:/|#|:)).+$",
      "description": "URI-reference to an ODPR RuntimeProfile document. A fragment identifies the runtime profile when the target contains or exposes multiple profiles."
    },
    "Step": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "id",
        "command"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "command": {
          "type": "string",
          "minLength": 1
        },
        "runtimeRef": {
          "$ref": "#/$defs/RuntimeRef"
        },
        "model": {
          "type": "string",
          "minLength": 1
        },
        "context": {
          "$ref": "#/$defs/ContextPolicy"
        },
        "input": {
          "$ref": "#/$defs/RelativePath"
        },
        "output": {
          "$ref": "#/$defs/RelativePath"
        },
        "document": {
          "$ref": "#/$defs/RelativePath"
        },
        "kind": {
          "type": "string"
        },
        "graph": {
          "$ref": "#/$defs/RelativePath"
        },
        "start": {
          "type": "string",
          "minLength": 1
        },
        "depth": {
          "type": "integer",
          "minimum": 1
        },
        "languages": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$"
          }
        },
        "defaultLanguage": {
          "type": "string",
          "pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$"
        },
        "objectives": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/RelativePath"
          }
        },
        "useCases": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/RelativePath"
          }
        },
        "signals": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/RelativePath"
          }
        },
        "products": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/RelativePath"
          }
        },
        "title": {
          "$ref": "#/$defs/Text"
        },
        "config": {
          "$ref": "#/$defs/RelativePath"
        },
        "prompts": {
          "$ref": "#/$defs/RelativePath"
        },
        "profile": {
          "type": "string"
        },
        "includeComponents": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "maxSourceChars": {
          "type": "integer",
          "minimum": 1
        },
        "ollamaUrl": {
          "type": "string"
        },
        "html": {
          "$ref": "#/$defs/RelativePath"
        },
        "toon": {
          "$ref": "#/$defs/RelativePath"
        },
        "gcf": {
          "$ref": "#/$defs/RelativePath"
        },
        "contextGraph": {
          "$ref": "#/$defs/RelativePath"
        },
        "name": {
          "$ref": "#/$defs/Text"
        },
        "description": {
          "$ref": "#/$defs/Text"
        },
        "recursive": {
          "type": "boolean"
        },
        "validate": {
          "type": "boolean"
        },
        "allSources": {
          "type": "boolean"
        },
        "strictValidation": {
          "type": "boolean"
        },
        "optional": {
          "type": "boolean"
        },
        "timeoutSeconds": {
          "type": "integer",
          "minimum": 1
        }
      },
      "allOf": [
        {
          "$ref": "#/$defs/GenerateStepRule"
        },
        {
          "$ref": "#/$defs/OdpcBuildStepRule"
        },
        {
          "$ref": "#/$defs/OdpgBuildStepRule"
        },
        {
          "$ref": "#/$defs/OdpgAgentContextStepRule"
        },
        {
          "$ref": "#/$defs/OdpgRenderStepRule"
        },
        {
          "$ref": "#/$defs/PortfolioBuildStepRule"
        },
        {
          "$ref": "#/$defs/PortfolioRefreshStepRule"
        },
        {
          "$ref": "#/$defs/PortfolioSyncStepRule"
        },
        {
          "$ref": "#/$defs/PortfolioLocalizeStepRule"
        },
        {
          "$ref": "#/$defs/PortfolioRenderStepRule"
        },
        {
          "$ref": "#/$defs/PortfolioExplainStepRule"
        },
        {
          "$ref": "#/$defs/ValidateStepRule"
        },
        {
          "$ref": "#/$defs/ExplainStepRule"
        },
        {
          "if": {
            "properties": {
              "command": {
                "enum": [
                  "odpc.build",
                  "odpg.agent-context",
                  "odpg.render",
                  "portfolio.sync",
                  "portfolio.render",
                  "portfolio.explain",
                  "validate",
                  "explain"
                ]
              }
            },
            "required": [
              "command"
            ]
          },
          "then": {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "runtimeRef"
                  ]
                },
                {
                  "required": [
                    "model"
                  ]
                }
              ]
            }
          }
        }
      ]
    },
    "GenerateStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "generate"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "input",
          "kind",
          "output"
        ],
        "properties": {
          "kind": {
            "enum": [
              "data-product-delivery-plan",
              "product-reference",
              "odps-product",
              "use-case",
              "objective",
              "signal",
              "graph"
            ]
          }
        }
      }
    },
    "OdpcBuildStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "odpc.build"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "input",
          "output"
        ]
      }
    },
    "OdpgBuildStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "odpg.build"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "input",
          "output"
        ]
      }
    },
    "OdpgAgentContextStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "odpg.agent-context"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "graph",
          "start",
          "output"
        ]
      }
    },
    "OdpgRenderStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "odpg.render"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "graph",
          "output"
        ]
      }
    },
    "PortfolioBuildStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "portfolio.build"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "output"
        ],
        "anyOf": [
          {
            "required": [
              "objectives"
            ]
          },
          {
            "required": [
              "useCases"
            ]
          },
          {
            "required": [
              "signals"
            ]
          },
          {
            "required": [
              "products"
            ]
          }
        ]
      }
    },
    "PortfolioRefreshStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "portfolio.refresh"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "properties": {}
      }
    },
    "PortfolioSyncStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "portfolio.sync"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "properties": {}
      }
    },
    "PortfolioLocalizeStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "portfolio.localize"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "languages"
        ]
      }
    },
    "PortfolioRenderStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "portfolio.render"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "properties": {}
      }
    },
    "PortfolioExplainStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "portfolio.explain"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "properties": {}
      }
    },
    "ValidateStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "validate"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "document"
        ]
      }
    },
    "ExplainStepRule": {
      "if": {
        "properties": {
          "command": {
            "const": "explain"
          }
        },
        "required": [
          "command"
        ]
      },
      "then": {
        "required": [
          "document"
        ]
      }
    },
    "Gate": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "id",
        "type"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "type": {
          "type": "string",
          "enum": [
            "validation",
            "quality",
            "review",
            "publication"
          ]
        },
        "required": {
          "type": "boolean",
          "default": false
        },
        "description": {
          "$ref": "#/$defs/Text"
        }
      }
    },
    "ReviewPolicy": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "required": {
          "type": "boolean"
        },
        "mode": {
          "type": "string",
          "enum": [
            "human",
            "agent",
            "both",
            "none"
          ]
        },
        "reviewer": {
          "type": "string"
        },
        "instructions": {
          "$ref": "#/$defs/Text"
        }
      }
    },
    "RunPolicy": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "timeoutSeconds": {
          "type": "integer",
          "minimum": 1
        },
        "stopOnFailure": {
          "type": "boolean",
          "default": true
        },
        "maxRetries": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "RuntimeProfile": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "provider",
        "providers"
      ],
      "properties": {
        "provider": {
          "type": "string",
          "minLength": 1
        },
        "model": {
          "type": "string",
          "minLength": 1
        },
        "input": {
          "type": "string",
          "minLength": 1
        },
        "output": {
          "type": "string",
          "minLength": 1
        },
        "prompts": {
          "type": "string",
          "minLength": 1
        },
        "baseUrl": {
          "type": "string",
          "minLength": 1
        },
        "version": {
          "type": "string",
          "minLength": 1
        },
        "maxTokens": {
          "type": "integer",
          "minimum": 1
        },
        "modelPath": {
          "type": "string",
          "minLength": 1
        },
        "contextWindow": {
          "type": "integer",
          "minimum": 1
        },
        "gpuLayers": {
          "type": "integer"
        },
        "portfolio": {
          "$ref": "#/$defs/RuntimeProfilePortfolioPolicy"
        },
        "providers": {
          "type": "object",
          "minProperties": 1,
          "additionalProperties": {
            "$ref": "#/$defs/RuntimeProviderProfile"
          }
        }
      }
    },
    "RuntimeProviderProfile": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "anthropic",
            "llama-cpp",
            "ollama",
            "openai",
            "openai-chat"
          ]
        },
        "model": {
          "type": "string",
          "minLength": 1
        },
        "baseUrl": {
          "type": "string",
          "minLength": 1
        },
        "apiKeyEnv": {
          "type": "string",
          "minLength": 1
        },
        "version": {
          "type": "string",
          "minLength": 1
        },
        "maxTokens": {
          "type": "integer",
          "minimum": 1
        },
        "modelPath": {
          "type": "string",
          "minLength": 1
        },
        "contextWindow": {
          "type": "integer",
          "minimum": 1
        },
        "gpuLayers": {
          "type": "integer"
        }
      }
    },
    "RuntimeProfilePortfolioPolicy": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "sourceBudget": {
          "$ref": "#/$defs/RuntimeProfilePortfolioSourceBudget"
        },
        "privacy": {
          "$ref": "#/$defs/RuntimeProfilePortfolioPrivacy"
        }
      }
    },
    "RuntimeProfilePortfolioSourceBudget": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "maxSourceChars": {
          "type": "integer",
          "minimum": 1
        },
        "maxPromptChars": {
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "RuntimeProfilePortfolioPrivacy": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "properties": {
        "obfuscatePersonalData": {
          "type": "boolean"
        }
      }
    },
    "RecipeCatalogEntry": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "path",
        "id",
        "version",
        "type",
        "name"
      ],
      "properties": {
        "path": {
          "$ref": "#/$defs/RelativePath"
        },
        "id": {
          "type": "string",
          "minLength": 1
        },
        "groupRef": {
          "type": "string",
          "minLength": 1
        },
        "version": {
          "type": "string",
          "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+([A-Za-z0-9.+-]*)?$"
        },
        "type": {
          "type": "string",
          "minLength": 1
        },
        "scope": {
          "$ref": "#/$defs/RecipeScope"
        },
        "name": {
          "$ref": "#/$defs/LocalizedText"
        },
        "description": {
          "$ref": "#/$defs/LocalizedText"
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "environment": {
          "type": "string"
        },
        "executionMode": {
          "type": "string",
          "enum": [
            "local",
            "hosted",
            "hybrid",
            "none"
          ]
        },
        "runtimeRef": {
          "$ref": "#/$defs/RuntimeRef"
        },
        "contextFormat": {
          "type": "string",
          "enum": [
            "yaml",
            "toon",
            "gcf",
            "auto"
          ]
        },
        "requiresReview": {
          "type": "boolean"
        },
        "commands": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "RecipeCatalogGroup": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "id",
        "name"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "name": {
          "$ref": "#/$defs/LocalizedText"
        },
        "description": {
          "$ref": "#/$defs/LocalizedText"
        }
      }
    },
    "DataProductRecipeSection": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "id",
        "path",
        "format"
      ],
      "properties": {
        "id": {
          "type": "string",
          "enum": [
            "recipe-readme",
            "source-product-spec",
            "product-summary",
            "delivery-plan",
            "product-interface-plan",
            "access-plan",
            "contract-plan",
            "pricing-plan",
            "quality-plan",
            "sla-plan",
            "lifecycle-plan",
            "relationship-plan",
            "validation-plan",
            "test-plan",
            "operational-readiness",
            "risk-register",
            "open-questions",
            "developer-review-checklist",
            "ai-agent-brief",
            "implementation-constraints",
            "backlog-items",
            "portfolio-context",
            "relationship-context"
          ]
        },
        "path": {
          "$ref": "#/$defs/RelativePath"
        },
        "format": {
          "type": "string",
          "enum": [
            "markdown",
            "yaml",
            "json",
            "directory"
          ]
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "id": {
                "const": "contract-plan"
              }
            },
            "required": [
              "id"
            ]
          },
          "then": {
            "properties": {
              "format": {
                "const": "yaml"
              }
            }
          }
        }
      ]
    },
    "DataProductRecipeReadiness": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "score",
        "status"
      ],
      "properties": {
        "score": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        },
        "status": {
          "type": "string",
          "enum": [
            "missing",
            "partial",
            "ready"
          ]
        }
      }
    },
    "DataProductRecipeReview": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "required",
        "status"
      ],
      "properties": {
        "required": {
          "type": "boolean"
        },
        "status": {
          "type": "string",
          "enum": [
            "pending",
            "approved",
            "changes-requested"
          ]
        }
      }
    },
    "DataProductRecipe": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "metadata",
        "version",
        "status",
        "sections",
        "readiness",
        "review"
      ],
      "properties": {
        "metadata": {
          "allOf": [
            {
              "$ref": "#/$defs/Metadata"
            },
            {
              "type": "object",
              "required": [
                "description"
              ]
            }
          ]
        },
        "version": {
          "type": "string",
          "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+([A-Za-z0-9.+-]*)?$"
        },
        "recipeRef": {
          "$ref": "#/$defs/RelativePath"
        },
        "status": {
          "type": "string",
          "enum": [
            "announcement",
            "draft",
            "development",
            "testing",
            "acceptance",
            "production",
            "sunset",
            "retired"
          ]
        },
        "sections": {
          "type": "array",
          "minItems": 7,
          "items": {
            "$ref": "#/$defs/DataProductRecipeSection"
          },
          "allOf": [
            {
              "contains": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "const": "recipe-readme"
                  }
                }
              }
            },
            {
              "contains": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "const": "source-product-spec"
                  }
                }
              }
            },
            {
              "contains": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "const": "product-summary"
                  }
                }
              }
            },
            {
              "contains": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "const": "delivery-plan"
                  }
                }
              }
            },
            {
              "contains": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "const": "open-questions"
                  }
                }
              }
            },
            {
              "contains": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "const": "ai-agent-brief"
                  }
                }
              }
            },
            {
              "contains": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "const": "relationship-context"
                  }
                }
              }
            }
          ]
        },
        "readiness": {
          "$ref": "#/$defs/DataProductRecipeReadiness"
        },
        "review": {
          "$ref": "#/$defs/DataProductRecipeReview"
        }
      }
    },
    "RecipeCatalog": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "metadata",
        "version",
        "recipes"
      ],
      "properties": {
        "metadata": {
          "$ref": "#/$defs/Metadata"
        },
        "version": {
          "type": "string",
          "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+([A-Za-z0-9.+-]*)?$"
        },
        "groups": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/RecipeCatalogGroup"
          }
        },
        "recipes": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/RecipeCatalogEntry"
          }
        }
      }
    },
    "Recipe": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x-": {}
      },
      "required": [
        "metadata",
        "version",
        "type",
        "steps"
      ],
      "properties": {
        "metadata": {
          "$ref": "#/$defs/Metadata"
        },
        "version": {
          "type": "string",
          "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+([A-Za-z0-9.+-]*)?$"
        },
        "type": {
          "type": "string",
          "enum": [
            "dev",
            "ci",
            "release",
            "localization",
            "hybrid",
            "agent"
          ]
        },
        "scope": {
          "$ref": "#/$defs/RecipeScope"
        },
        "inputs": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/NamedPath"
          }
        },
        "outputs": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/NamedPath"
          }
        },
        "context": {
          "$ref": "#/$defs/ContextPolicy"
        },
        "trigger": {
          "$ref": "#/$defs/GraphTrigger"
        },
        "graphContext": {
          "$ref": "#/$defs/GraphContext"
        },
        "execution": {
          "$ref": "#/$defs/ExecutionPolicy"
        },
        "steps": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/Step"
          }
        },
        "gates": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/Gate"
          }
        },
        "review": {
          "$ref": "#/$defs/ReviewPolicy"
        },
        "environment": {
          "type": "string"
        },
        "runPolicy": {
          "$ref": "#/$defs/RunPolicy"
        }
      }
    }
  }
}
