{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://github.com/eff3ct0/teckel-spec/spec/v3.0/teckel-schema.json",
  "title": "Teckel Pipeline Specification v3.0",
  "description": "JSON Schema for validating Teckel v3.0 YAML pipeline documents.",
  "type": "object",
  "required": ["version", "input", "output"],
  "additionalProperties": false,
  "patternProperties": {
    "^x-": {
      "description": "Extension fields (ignored by conforming implementations)."
    }
  },
  "properties": {
    "version": {
      "type": "string",
      "const": "3.0",
      "description": "Teckel specification version."
    },
    "pipeline": { "$ref": "#/$defs/PipelineMetadata" },
    "config": { "$ref": "#/$defs/Config" },
    "secrets": { "$ref": "#/$defs/Secrets" },
    "hooks": { "$ref": "#/$defs/Hooks" },
    "quality": {
      "type": "array",
      "items": { "$ref": "#/$defs/QualitySuite" },
      "description": "Data quality check suites. See spec §17."
    },
    "templates": {
      "type": "array",
      "items": { "$ref": "#/$defs/Template" }
    },
    "input": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/Input" }
    },
    "streamingInput": {
      "type": "array",
      "items": { "$ref": "#/$defs/StreamingInput" }
    },
    "transformation": {
      "type": "array",
      "items": { "$ref": "#/$defs/Transformation" }
    },
    "output": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/Output" }
    },
    "streamingOutput": {
      "type": "array",
      "items": { "$ref": "#/$defs/StreamingOutput" }
    },
    "exposures": {
      "type": "array",
      "items": { "$ref": "#/$defs/Exposure" },
      "description": "Downstream consumer declarations. See spec §19."
    }
  },

  "$defs": {
    "AssetRef": {
      "type": "string",
      "pattern": "^[a-zA-Z][a-zA-Z0-9_-]{0,127}$",
      "description": "Unique asset identifier."
    },
    "Expression": {
      "type": "string",
      "minLength": 1,
      "description": "A Teckel expression (SQL-like)."
    },
    "Condition": {
      "type": "string",
      "minLength": 1,
      "description": "A boolean expression."
    },
    "Primitive": {
      "oneOf": [
        { "type": "string" },
        { "type": "number" },
        { "type": "integer" },
        { "type": "boolean" }
      ]
    },

    "Owner": {
      "type": "object",
      "required": ["name", "email"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string", "description": "Person or team name." },
        "email": { "type": "string", "description": "Contact email." },
        "type": {
          "type": "string",
          "enum": ["technical", "business", "steward"],
          "default": "technical",
          "description": "Owner role."
        }
      }
    },

    "Link": {
      "type": "object",
      "required": ["label", "url"],
      "additionalProperties": false,
      "properties": {
        "label": { "type": "string" },
        "url": { "type": "string" }
      }
    },

    "Contact": {
      "type": "object",
      "required": ["name", "email"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string" },
        "role": { "type": "string" }
      }
    },

    "CatalogConfig": {
      "type": "object",
      "required": ["target"],
      "additionalProperties": false,
      "properties": {
        "target": { "type": "string", "description": "Catalog system identifier (e.g., openmetadata, datahub, atlas)." },
        "namespace": { "type": "string", "description": "Namespace within the catalog." }
      }
    },

    "ColumnMetadata": {
      "type": "object",
      "required": ["name"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string", "description": "Column name (MUST match a column in the dataset)." },
        "description": { "type": "string" },
        "tags": { "type": "array", "items": { "type": "string" } },
        "constraints": { "type": "array", "items": { "type": "string" } },
        "meta": { "type": "object", "additionalProperties": true },
        "glossaryTerm": { "type": "string" }
      }
    },

    "PipelineMetadata": {
      "type": "object",
      "additionalProperties": false,
      "description": "Pipeline-level metadata. See spec §18.2.",
      "properties": {
        "name": { "type": "string", "description": "Human-readable pipeline name." },
        "namespace": { "type": "string", "description": "Globally unique namespace (e.g., com.company.finance)." },
        "version": { "type": "string", "description": "Semantic version of the pipeline." },
        "description": { "type": "string", "description": "Markdown-formatted pipeline description." },
        "owner": { "$ref": "#/$defs/Owner" },
        "tags": { "type": "array", "items": { "type": "string" } },
        "meta": { "type": "object", "additionalProperties": true },
        "schedule": { "type": "string", "description": "Cron expression or ISO 8601 duration." },
        "freshness": { "type": "string", "description": "Expected freshness as ISO 8601 duration." },
        "links": { "type": "array", "items": { "$ref": "#/$defs/Link" } },
        "contacts": { "type": "array", "items": { "$ref": "#/$defs/Contact" } },
        "catalog": { "$ref": "#/$defs/CatalogConfig" }
      }
    },

    "Input": {
      "type": "object",
      "required": ["name", "format", "path"],
      "additionalProperties": false,
      "properties": {
        "name": { "$ref": "#/$defs/AssetRef" },
        "format": { "type": "string", "minLength": 1 },
        "path": { "type": "string" },
        "options": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/Primitive" }
        },
        "description": { "type": "string" },
        "tags": { "type": "array", "items": { "type": "string" } },
        "meta": { "type": "object", "additionalProperties": true },
        "owner": { "$ref": "#/$defs/Owner" },
        "columns": {
          "type": "array",
          "items": { "$ref": "#/$defs/ColumnMetadata" }
        }
      }
    },

    "Output": {
      "type": "object",
      "required": ["name", "format", "path"],
      "additionalProperties": false,
      "properties": {
        "name": { "$ref": "#/$defs/AssetRef" },
        "format": { "type": "string", "minLength": 1 },
        "path": { "type": "string" },
        "mode": {
          "type": "string",
          "enum": ["error", "overwrite", "append", "ignore"],
          "default": "error"
        },
        "options": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/Primitive" }
        },
        "description": { "type": "string" },
        "tags": { "type": "array", "items": { "type": "string" } },
        "meta": { "type": "object", "additionalProperties": true },
        "freshness": { "type": "string", "description": "Expected update frequency as ISO 8601 duration." },
        "maturity": {
          "type": "string",
          "enum": ["high", "medium", "low", "deprecated"],
          "description": "Dataset lifecycle stage."
        }
      }
    },

    "StreamingInput": {
      "type": "object",
      "required": ["name", "format"],
      "additionalProperties": false,
      "properties": {
        "name": { "$ref": "#/$defs/AssetRef" },
        "format": { "type": "string", "minLength": 1 },
        "path": { "type": "string" },
        "options": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/Primitive" }
        },
        "trigger": { "type": "string" }
      }
    },

    "StreamingOutput": {
      "type": "object",
      "required": ["name", "format"],
      "additionalProperties": false,
      "properties": {
        "name": { "$ref": "#/$defs/AssetRef" },
        "format": { "type": "string", "minLength": 1 },
        "path": { "type": "string" },
        "options": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/Primitive" }
        },
        "outputMode": {
          "type": "string",
          "enum": ["append", "update", "complete"]
        },
        "checkpointLocation": { "type": "string" },
        "trigger": { "type": "string" }
      }
    },

    "Transformation": {
      "type": "object",
      "required": ["name"],
      "properties": {
        "name": { "$ref": "#/$defs/AssetRef" },
        "description": { "type": "string" },
        "tags": { "type": "array", "items": { "type": "string" } },
        "removeTags": { "type": "array", "items": { "type": "string" } },
        "meta": { "type": "object", "additionalProperties": true }
      },
      "unevaluatedProperties": false,
      "oneOf": [
        { "required": ["select"], "properties": { "select": { "$ref": "#/$defs/SelectOp" } } },
        { "required": ["where"], "properties": { "where": { "$ref": "#/$defs/WhereOp" } } },
        { "required": ["group"], "properties": { "group": { "$ref": "#/$defs/GroupOp" } } },
        { "required": ["orderBy"], "properties": { "orderBy": { "$ref": "#/$defs/OrderByOp" } } },
        { "required": ["join"], "properties": { "join": { "$ref": "#/$defs/JoinOp" } } },
        { "required": ["union"], "properties": { "union": { "$ref": "#/$defs/UnionOp" } } },
        { "required": ["intersect"], "properties": { "intersect": { "$ref": "#/$defs/IntersectOp" } } },
        { "required": ["except"], "properties": { "except": { "$ref": "#/$defs/ExceptOp" } } },
        { "required": ["distinct"], "properties": { "distinct": { "$ref": "#/$defs/DistinctOp" } } },
        { "required": ["limit"], "properties": { "limit": { "$ref": "#/$defs/LimitOp" } } },
        { "required": ["addColumns"], "properties": { "addColumns": { "$ref": "#/$defs/AddColumnsOp" } } },
        { "required": ["dropColumns"], "properties": { "dropColumns": { "$ref": "#/$defs/DropColumnsOp" } } },
        { "required": ["renameColumns"], "properties": { "renameColumns": { "$ref": "#/$defs/RenameColumnsOp" } } },
        { "required": ["castColumns"], "properties": { "castColumns": { "$ref": "#/$defs/CastColumnsOp" } } },
        { "required": ["window"], "properties": { "window": { "$ref": "#/$defs/WindowOp" } } },
        { "required": ["pivot"], "properties": { "pivot": { "$ref": "#/$defs/PivotOp" } } },
        { "required": ["unpivot"], "properties": { "unpivot": { "$ref": "#/$defs/UnpivotOp" } } },
        { "required": ["flatten"], "properties": { "flatten": { "$ref": "#/$defs/FlattenOp" } } },
        { "required": ["sample"], "properties": { "sample": { "$ref": "#/$defs/SampleOp" } } },
        { "required": ["conditional"], "properties": { "conditional": { "$ref": "#/$defs/ConditionalOp" } } },
        { "required": ["split"], "properties": { "split": { "$ref": "#/$defs/SplitOp" } } },
        { "required": ["sql"], "properties": { "sql": { "$ref": "#/$defs/SqlOp" } } },
        { "required": ["rollup"], "properties": { "rollup": { "$ref": "#/$defs/RollupOp" } } },
        { "required": ["cube"], "properties": { "cube": { "$ref": "#/$defs/CubeOp" } } },
        { "required": ["scd2"], "properties": { "scd2": { "$ref": "#/$defs/SCD2Op" } } },
        { "required": ["enrich"], "properties": { "enrich": { "$ref": "#/$defs/EnrichOp" } } },
        { "required": ["schemaEnforce"], "properties": { "schemaEnforce": { "$ref": "#/$defs/SchemaEnforceOp" } } },
        { "required": ["assertion"], "properties": { "assertion": { "$ref": "#/$defs/AssertionOp" } } },
        { "required": ["repartition"], "properties": { "repartition": { "$ref": "#/$defs/RepartitionOp" } } },
        { "required": ["coalesce"], "properties": { "coalesce": { "$ref": "#/$defs/CoalesceOp" } } },
        { "required": ["custom"], "properties": { "custom": { "$ref": "#/$defs/CustomOp" } } },
        { "required": ["offset"], "properties": { "offset": { "$ref": "#/$defs/OffsetOp" } } },
        { "required": ["tail"], "properties": { "tail": { "$ref": "#/$defs/TailOp" } } },
        { "required": ["fillNa"], "properties": { "fillNa": { "$ref": "#/$defs/FillNaOp" } } },
        { "required": ["dropNa"], "properties": { "dropNa": { "$ref": "#/$defs/DropNaOp" } } },
        { "required": ["replace"], "properties": { "replace": { "$ref": "#/$defs/ReplaceOp" } } },
        { "required": ["merge"], "properties": { "merge": { "$ref": "#/$defs/MergeOp" } } },
        { "required": ["parse"], "properties": { "parse": { "$ref": "#/$defs/ParseOp" } } },
        { "required": ["asOfJoin"], "properties": { "asOfJoin": { "$ref": "#/$defs/AsOfJoinOp" } } },
        { "required": ["lateralJoin"], "properties": { "lateralJoin": { "$ref": "#/$defs/LateralJoinOp" } } },
        { "required": ["transpose"], "properties": { "transpose": { "$ref": "#/$defs/TransposeOp" } } },
        { "required": ["groupingSets"], "properties": { "groupingSets": { "$ref": "#/$defs/GroupingSetsOp" } } },
        { "required": ["describe"], "properties": { "describe": { "$ref": "#/$defs/DescribeOp" } } },
        { "required": ["crosstab"], "properties": { "crosstab": { "$ref": "#/$defs/CrosstabOp" } } },
        { "required": ["hint"], "properties": { "hint": { "$ref": "#/$defs/HintOp" } } }
      ]
    },

    "SelectOp": {
      "type": "object",
      "required": ["from", "columns"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Expression" } }
      }
    },
    "WhereOp": {
      "type": "object",
      "required": ["from", "filter"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "filter": { "$ref": "#/$defs/Condition" }
      }
    },
    "GroupOp": {
      "type": "object",
      "required": ["from", "by", "agg"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "by": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "agg": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Expression" } }
      }
    },
    "SortColumn": {
      "oneOf": [
        { "type": "string" },
        {
          "type": "object",
          "required": ["column"],
          "additionalProperties": false,
          "properties": {
            "column": { "type": "string" },
            "direction": { "type": "string", "enum": ["asc", "desc"], "default": "asc" },
            "nulls": { "type": "string", "enum": ["first", "last"], "default": "last" }
          }
        }
      ]
    },
    "OrderByOp": {
      "type": "object",
      "required": ["from", "columns"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/SortColumn" } }
      }
    },
    "JoinTarget": {
      "type": "object",
      "required": ["name", "type", "on"],
      "additionalProperties": false,
      "properties": {
        "name": { "$ref": "#/$defs/AssetRef" },
        "type": { "type": "string", "enum": ["inner", "left", "right", "outer", "cross", "left_semi", "left_anti"] },
        "on": { "type": "array", "items": { "$ref": "#/$defs/Condition" } }
      }
    },
    "JoinOp": {
      "type": "object",
      "required": ["left", "right"],
      "additionalProperties": false,
      "properties": {
        "left": { "$ref": "#/$defs/AssetRef" },
        "right": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/JoinTarget" } }
      }
    },
    "UnionOp": {
      "type": "object",
      "required": ["sources"],
      "additionalProperties": false,
      "properties": {
        "sources": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/AssetRef" } },
        "all": { "type": "boolean", "default": true },
        "byName": { "type": "boolean", "default": false, "description": "Match columns by name instead of position." },
        "allowMissingColumns": { "type": "boolean", "default": false, "description": "Fill missing columns with NULL. Requires byName: true." }
      }
    },
    "IntersectOp": {
      "type": "object",
      "required": ["sources"],
      "additionalProperties": false,
      "properties": {
        "sources": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/AssetRef" } },
        "all": { "type": "boolean", "default": false },
        "byName": { "type": "boolean", "default": false, "description": "Match columns by name instead of position." },
        "allowMissingColumns": { "type": "boolean", "default": false, "description": "Fill missing columns with NULL. Requires byName: true." }
      }
    },
    "ExceptOp": {
      "type": "object",
      "required": ["left", "right"],
      "additionalProperties": false,
      "properties": {
        "left": { "$ref": "#/$defs/AssetRef" },
        "right": { "$ref": "#/$defs/AssetRef" },
        "all": { "type": "boolean", "default": false },
        "byName": { "type": "boolean", "default": false, "description": "Match columns by name instead of position." },
        "allowMissingColumns": { "type": "boolean", "default": false, "description": "Fill missing columns with NULL. Requires byName: true." }
      }
    },
    "DistinctOp": {
      "type": "object",
      "required": ["from"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "items": { "type": "string" } }
      }
    },
    "LimitOp": {
      "type": "object",
      "required": ["from", "count"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "count": { "type": "integer", "minimum": 0 }
      }
    },
    "ColumnDef": {
      "type": "object",
      "required": ["name", "expression"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "expression": { "$ref": "#/$defs/Expression" }
      }
    },
    "AddColumnsOp": {
      "type": "object",
      "required": ["from", "columns"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/ColumnDef" } }
      }
    },
    "DropColumnsOp": {
      "type": "object",
      "required": ["from", "columns"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "minItems": 1, "items": { "type": "string" } }
      }
    },
    "RenameColumnsOp": {
      "type": "object",
      "required": ["from", "mappings"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "mappings": {
          "type": "object",
          "minProperties": 1,
          "additionalProperties": { "type": "string" }
        }
      }
    },
    "CastDef": {
      "type": "object",
      "required": ["name", "targetType"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "targetType": { "type": "string" }
      }
    },
    "CastColumnsOp": {
      "type": "object",
      "required": ["from", "columns"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/CastDef" } }
      }
    },
    "WindowFuncDef": {
      "type": "object",
      "required": ["expression", "alias"],
      "additionalProperties": false,
      "properties": {
        "expression": { "$ref": "#/$defs/Expression" },
        "alias": { "type": "string" }
      }
    },
    "FrameSpec": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": { "type": "string", "enum": ["rows", "range"], "default": "range" },
        "start": { "type": "string", "default": "unbounded preceding" },
        "end": { "type": "string", "default": "current row" }
      }
    },
    "WindowOp": {
      "type": "object",
      "required": ["from", "partitionBy", "functions"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "partitionBy": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "orderBy": { "type": "array", "items": { "$ref": "#/$defs/SortColumn" } },
        "frame": { "$ref": "#/$defs/FrameSpec" },
        "functions": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/WindowFuncDef" } }
      }
    },
    "PivotOp": {
      "type": "object",
      "required": ["from", "groupBy", "pivotColumn", "agg"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "groupBy": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "pivotColumn": { "type": "string" },
        "values": { "type": "array", "items": { "type": "string" } },
        "agg": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Expression" } }
      }
    },
    "UnpivotOp": {
      "type": "object",
      "required": ["from", "ids", "values", "variableColumn", "valueColumn"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "ids": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "values": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "variableColumn": { "type": "string" },
        "valueColumn": { "type": "string" }
      }
    },
    "FlattenOp": {
      "type": "object",
      "required": ["from"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "separator": { "type": "string", "default": "_" },
        "explodeArrays": { "type": "boolean", "default": false }
      }
    },
    "SampleOp": {
      "type": "object",
      "required": ["from"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "fraction": { "type": "number", "exclusiveMinimum": 0, "maximum": 1 },
        "withReplacement": { "type": "boolean", "default": false },
        "seed": { "type": "integer" },
        "lowerBound": { "type": "number", "minimum": 0, "maximum": 1, "description": "Lower bound of sampling range. Alternative to fraction." },
        "upperBound": { "type": "number", "minimum": 0, "maximum": 1, "description": "Upper bound of sampling range. Alternative to fraction." },
        "deterministicOrder": { "type": "boolean", "default": false, "description": "If true, output maintains deterministic ordering." }
      }
    },
    "Branch": {
      "type": "object",
      "required": ["condition", "value"],
      "additionalProperties": false,
      "properties": {
        "condition": { "$ref": "#/$defs/Condition" },
        "value": { "$ref": "#/$defs/Expression" }
      }
    },
    "ConditionalOp": {
      "type": "object",
      "required": ["from", "outputColumn", "branches"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "outputColumn": { "type": "string" },
        "branches": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Branch" } },
        "otherwise": { "$ref": "#/$defs/Expression" }
      }
    },
    "SplitOp": {
      "type": "object",
      "required": ["from", "condition", "pass", "fail"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "condition": { "$ref": "#/$defs/Condition" },
        "pass": { "$ref": "#/$defs/AssetRef" },
        "fail": { "$ref": "#/$defs/AssetRef" }
      }
    },
    "SqlOp": {
      "type": "object",
      "required": ["query", "views"],
      "additionalProperties": false,
      "properties": {
        "query": { "type": "string", "minLength": 1 },
        "views": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/AssetRef" } }
      }
    },
    "RollupOp": {
      "type": "object",
      "required": ["from", "by", "agg"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "by": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "agg": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Expression" } }
      }
    },
    "CubeOp": {
      "type": "object",
      "required": ["from", "by", "agg"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "by": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "agg": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Expression" } }
      }
    },
    "SCD2Op": {
      "type": "object",
      "required": ["current", "incoming", "keyColumns", "trackColumns", "startDateColumn", "endDateColumn", "currentFlagColumn"],
      "additionalProperties": false,
      "properties": {
        "current": { "$ref": "#/$defs/AssetRef" },
        "incoming": { "$ref": "#/$defs/AssetRef" },
        "keyColumns": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "trackColumns": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "startDateColumn": { "type": "string" },
        "endDateColumn": { "type": "string" },
        "currentFlagColumn": { "type": "string" }
      }
    },
    "EnrichOp": {
      "type": "object",
      "required": ["from", "url", "keyColumn", "responseColumn"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "url": { "type": "string" },
        "method": { "type": "string", "default": "GET" },
        "keyColumn": { "type": "string" },
        "responseColumn": { "type": "string" },
        "headers": { "type": "object", "additionalProperties": { "type": "string" } },
        "onError": { "type": "string", "enum": ["null", "fail", "skip"], "default": "null" },
        "timeout": { "type": "integer", "minimum": 1, "default": 30000 },
        "maxRetries": { "type": "integer", "minimum": 0, "default": 3 }
      }
    },
    "SchemaColumn": {
      "type": "object",
      "required": ["name", "dataType"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "dataType": { "type": "string" },
        "nullable": { "type": "boolean", "default": true },
        "default": { "$ref": "#/$defs/Expression" }
      }
    },
    "SchemaEnforceOp": {
      "type": "object",
      "required": ["from", "columns"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "mode": { "type": "string", "enum": ["strict", "evolve"], "default": "strict" },
        "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/SchemaColumn" } }
      }
    },
    "QualityCheck": {
      "type": "object",
      "required": ["rule"],
      "additionalProperties": false,
      "properties": {
        "column": { "type": "string" },
        "rule": { "type": "string" },
        "description": { "type": "string" }
      }
    },
    "AssertionOp": {
      "type": "object",
      "required": ["from", "checks"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "checks": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/QualityCheck" } },
        "onFailure": { "type": "string", "enum": ["fail", "warn", "drop"], "default": "fail" }
      }
    },
    "RepartitionOp": {
      "type": "object",
      "required": ["from", "numPartitions"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "numPartitions": { "type": "integer", "minimum": 1 },
        "columns": { "type": "array", "items": { "type": "string" } }
      }
    },
    "CoalesceOp": {
      "type": "object",
      "required": ["from", "numPartitions"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "numPartitions": { "type": "integer", "minimum": 1 }
      }
    },
    "CustomOp": {
      "type": "object",
      "required": ["from", "component"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "component": { "type": "string" },
        "options": { "type": "object", "additionalProperties": { "type": "string" } }
      }
    },
    "OffsetOp": {
      "type": "object",
      "required": ["from", "count"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "count": { "type": "integer", "minimum": 0 }
      }
    },
    "TailOp": {
      "type": "object",
      "required": ["from", "count"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "count": { "type": "integer", "minimum": 0 }
      }
    },
    "FillNaOp": {
      "type": "object",
      "required": ["from"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "items": { "type": "string" } },
        "value": { "$ref": "#/$defs/Primitive" },
        "values": { "type": "object", "additionalProperties": { "$ref": "#/$defs/Primitive" } }
      }
    },
    "DropNaOp": {
      "type": "object",
      "required": ["from"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "items": { "type": "string" } },
        "how": { "type": "string", "enum": ["any", "all"], "default": "any" },
        "minNonNulls": { "type": "integer", "minimum": 0 }
      }
    },
    "Replacement": {
      "type": "object",
      "required": ["old", "new"],
      "additionalProperties": false,
      "properties": {
        "old": { "$ref": "#/$defs/Primitive" },
        "new": { "$ref": "#/$defs/Primitive" }
      }
    },
    "ReplaceOp": {
      "type": "object",
      "required": ["from", "mappings"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "items": { "type": "string" } },
        "mappings": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Replacement" } }
      }
    },
    "MergeAction": {
      "type": "object",
      "required": ["action"],
      "additionalProperties": false,
      "properties": {
        "action": { "type": "string", "enum": ["update", "insert", "delete"] },
        "condition": { "$ref": "#/$defs/Condition" },
        "set": { "type": "object", "additionalProperties": { "$ref": "#/$defs/Expression" } },
        "star": { "type": "boolean", "default": false }
      }
    },
    "MergeOp": {
      "type": "object",
      "required": ["target", "source", "on"],
      "additionalProperties": false,
      "properties": {
        "target": { "$ref": "#/$defs/AssetRef" },
        "source": { "$ref": "#/$defs/AssetRef" },
        "on": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Condition" } },
        "whenMatched": { "type": "array", "items": { "$ref": "#/$defs/MergeAction" } },
        "whenNotMatched": { "type": "array", "items": { "$ref": "#/$defs/MergeAction" } },
        "whenNotMatchedBySource": { "type": "array", "items": { "$ref": "#/$defs/MergeAction" } }
      }
    },
    "ParseOp": {
      "type": "object",
      "required": ["from", "column", "format"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "column": { "type": "string" },
        "format": { "type": "string", "enum": ["json", "csv"] },
        "schema": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["name", "dataType"],
            "additionalProperties": false,
            "properties": {
              "name": { "type": "string" },
              "dataType": { "type": "string" },
              "nullable": { "type": "boolean", "default": true }
            }
          }
        },
        "options": { "type": "object", "additionalProperties": { "type": "string" } }
      }
    },
    "AsOfJoinOp": {
      "type": "object",
      "required": ["left", "right", "leftAsOf", "rightAsOf"],
      "additionalProperties": false,
      "properties": {
        "left": { "$ref": "#/$defs/AssetRef" },
        "right": { "$ref": "#/$defs/AssetRef" },
        "leftAsOf": { "type": "string" },
        "rightAsOf": { "type": "string" },
        "on": { "type": "array", "items": { "$ref": "#/$defs/Condition" } },
        "type": { "type": "string", "enum": ["inner", "left"], "default": "left" },
        "direction": { "type": "string", "enum": ["backward", "forward", "nearest"], "default": "backward" },
        "tolerance": { "$ref": "#/$defs/Expression" },
        "allowExactMatches": { "type": "boolean", "default": true }
      }
    },
    "LateralJoinOp": {
      "type": "object",
      "required": ["left", "right"],
      "additionalProperties": false,
      "properties": {
        "left": { "$ref": "#/$defs/AssetRef" },
        "right": { "$ref": "#/$defs/AssetRef" },
        "type": { "type": "string", "enum": ["inner", "left", "cross"], "default": "inner" },
        "on": { "type": "array", "items": { "$ref": "#/$defs/Condition" } }
      }
    },
    "TransposeOp": {
      "type": "object",
      "required": ["from"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "indexColumns": { "type": "array", "items": { "type": "string" } }
      }
    },
    "GroupingSetsOp": {
      "type": "object",
      "required": ["from", "sets", "agg"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "sets": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "array",
            "items": { "type": "string" }
          }
        },
        "agg": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Expression" } }
      }
    },
    "DescribeOp": {
      "type": "object",
      "required": ["from"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "columns": { "type": "array", "items": { "type": "string" } },
        "statistics": {
          "type": "array",
          "items": { "type": "string", "enum": ["count", "mean", "stddev", "min", "max", "25%", "50%", "75%"] }
        }
      }
    },
    "CrosstabOp": {
      "type": "object",
      "required": ["from", "col1", "col2"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "col1": { "type": "string" },
        "col2": { "type": "string" }
      }
    },
    "HintSpec": {
      "type": "object",
      "required": ["name"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "parameters": { "type": "array", "items": { "$ref": "#/$defs/Expression" } }
      }
    },
    "HintOp": {
      "type": "object",
      "required": ["from", "hints"],
      "additionalProperties": false,
      "properties": {
        "from": { "$ref": "#/$defs/AssetRef" },
        "hints": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/HintSpec" } }
      }
    },

    "BoundSpec": {
      "type": "object",
      "additionalProperties": false,
      "description": "Numeric bound specification for quality checks.",
      "properties": {
        "min": { "type": "number" },
        "max": { "type": "number" },
        "between": {
          "type": "array",
          "items": { "type": "number" },
          "minItems": 2,
          "maxItems": 2
        }
      }
    },

    "RangeSpec": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "min": { "type": "number" },
        "max": { "type": "number" },
        "strictMin": { "type": "boolean", "default": false },
        "strictMax": { "type": "boolean", "default": false }
      }
    },

    "EscalateSpec": {
      "type": "object",
      "required": ["threshold", "severity"],
      "additionalProperties": false,
      "properties": {
        "threshold": { "type": "number", "minimum": 0, "maximum": 1 },
        "severity": { "type": "string", "enum": ["error", "warn", "info"] }
      }
    },

    "QualityCheckEntry": {
      "type": "object",
      "required": ["type"],
      "description": "A quality check within a suite. Discriminated by the 'type' field.",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["schema", "completeness", "uniqueness", "validity", "statistical", "volume", "freshness", "referential", "crossColumn", "custom"]
        },
        "column": { "type": "string" },
        "columns": {
          "oneOf": [
            { "type": "array", "items": { "type": "string" } },
            { "type": "object", "properties": { "required": { "type": "array", "items": { "type": "string" } }, "forbidden": { "type": "array", "items": { "type": "string" } } }, "additionalProperties": false }
          ]
        },
        "threshold": { "type": "number", "minimum": 0, "maximum": 1 },
        "severity": { "type": "string", "enum": ["error", "warn", "info"] },
        "escalate": { "$ref": "#/$defs/EscalateSpec" },
        "description": { "type": "string" },
        "acceptedValues": { "type": "array", "items": { "type": "string" } },
        "range": { "$ref": "#/$defs/RangeSpec" },
        "pattern": { "type": "string" },
        "format": { "type": "string" },
        "lengthBetween": { "type": "array", "items": { "type": "integer" }, "minItems": 2, "maxItems": 2 },
        "mean": { "$ref": "#/$defs/BoundSpec" },
        "min": { "$ref": "#/$defs/BoundSpec" },
        "max": { "$ref": "#/$defs/BoundSpec" },
        "sum": { "$ref": "#/$defs/BoundSpec" },
        "stdev": { "$ref": "#/$defs/BoundSpec" },
        "quantiles": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/BoundSpec" }
        },
        "rowCount": { "$ref": "#/$defs/BoundSpec" },
        "columnCount": { "$ref": "#/$defs/BoundSpec" },
        "maxAge": { "type": "string", "description": "ISO 8601 duration." },
        "reference": {
          "type": "object",
          "required": ["asset", "column"],
          "additionalProperties": false,
          "properties": {
            "asset": { "$ref": "#/$defs/AssetRef" },
            "column": { "type": "string" }
          }
        },
        "condition": { "$ref": "#/$defs/Condition" },
        "types": {
          "type": "object",
          "additionalProperties": { "type": "string" }
        }
      }
    },

    "QualitySuite": {
      "type": "object",
      "required": ["suite", "target", "checks"],
      "additionalProperties": false,
      "description": "A data quality check suite. See spec §17.",
      "properties": {
        "suite": { "type": "string", "description": "Suite name (for reporting)." },
        "description": { "type": "string" },
        "target": { "$ref": "#/$defs/AssetRef" },
        "filter": { "$ref": "#/$defs/Condition" },
        "severity": {
          "type": "string",
          "enum": ["error", "warn", "info"],
          "default": "error",
          "description": "Default severity for all checks in this suite."
        },
        "checks": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/QualityCheckEntry" }
        }
      }
    },

    "Exposure": {
      "type": "object",
      "required": ["name", "type", "depends_on"],
      "additionalProperties": false,
      "description": "Downstream consumer declaration. See spec §19.",
      "properties": {
        "name": { "type": "string", "description": "Exposure identifier." },
        "type": {
          "type": "string",
          "enum": ["dashboard", "notebook", "analysis", "ml", "application", "pipeline"],
          "description": "Consumer type."
        },
        "description": { "type": "string" },
        "url": { "type": "string" },
        "maturity": { "type": "string", "enum": ["high", "medium", "low"] },
        "owner": { "$ref": "#/$defs/Owner" },
        "depends_on": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/AssetRef" },
          "description": "Assets consumed by this exposure."
        },
        "tags": { "type": "array", "items": { "type": "string" } },
        "meta": { "type": "object", "additionalProperties": true }
      }
    },

    "Config": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "backend": { "type": "string" },
        "cache": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "autoCacheThreshold": { "type": "integer", "minimum": 1 },
            "defaultStorageLevel": { "type": "string" }
          }
        },
        "notifications": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "onSuccess": { "type": "array", "items": { "$ref": "#/$defs/NotificationTarget" } },
            "onFailure": { "type": "array", "items": { "$ref": "#/$defs/NotificationTarget" } }
          }
        },
        "components": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "readers": { "type": "array" },
            "transformers": { "type": "array" },
            "writers": { "type": "array" }
          }
        }
      }
    },
    "NotificationTarget": {
      "type": "object",
      "required": ["channel"],
      "additionalProperties": false,
      "properties": {
        "channel": { "type": "string", "enum": ["log", "webhook", "file"] },
        "url": { "type": "string" },
        "path": { "type": "string" }
      }
    },
    "Secrets": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "keys": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "required": ["key"],
            "additionalProperties": false,
            "properties": {
              "scope": { "type": "string" },
              "key": { "type": "string" }
            }
          }
        }
      }
    },
    "Hook": {
      "type": "object",
      "required": ["name", "command"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "command": { "type": "string" }
      }
    },
    "Hooks": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "preExecution": { "type": "array", "items": { "$ref": "#/$defs/Hook" } },
        "postExecution": { "type": "array", "items": { "$ref": "#/$defs/Hook" } }
      }
    },
    "Template": {
      "type": "object",
      "required": ["name", "parameters"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "parameters": { "type": "object", "additionalProperties": { "$ref": "#/$defs/Primitive" } }
      }
    }
  }
}
