{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://catalog.lintel.tools/schemas/schemastore/opendecree/versions/v0.1.0.json",
  "title": "OpenDecree Schema Format (v0.1.0)",
  "description": "Schema definition format for OpenDecree. A decree.schema.yaml file declares the fields, types, constraints, and cross-field rules of a schema that tenants can then bind to and apply config values against.",
  "x-lintel": {
    "source": "https://schemas.opendecree.dev/schema/v0.1.0/decree-schema.json",
    "sourceSha256": "6757f582691d702e10d32db848b49ac19bc476496abc6f409408642e99284471",
    "fileMatch": [
      "decree.schema.yaml",
      "decree.schema.yml",
      "*.decree.schema.yaml",
      "*.decree.schema.yml"
    ],
    "parsers": [
      "yaml"
    ]
  },
  "type": "object",
  "properties": {
    "spec_version": {
      "description": "Decree schema-format spec version. Must be \"v1\".",
      "type": "string",
      "const": "v1"
    },
    "$schema": {
      "description": "Optional pointer to this meta-schema. HTTPS URL.",
      "type": "string",
      "format": "uri",
      "pattern": "^https://"
    },
    "$id": {
      "description": "Optional URN identifying this schema document. Format urn:decree:schema:<segment>(:<segment>)*.",
      "type": "string",
      "pattern": "^urn:decree:schema:[a-zA-Z0-9][a-zA-Z0-9._-]*(?::[a-zA-Z0-9][a-zA-Z0-9._-]*)*$"
    },
    "name": {
      "description": "Schema name. Slug — lowercase alphanumeric + hyphens.",
      "type": "string",
      "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$",
      "minLength": 1,
      "maxLength": 63
    },
    "description": {
      "description": "Human-readable description of the schema.",
      "type": "string"
    },
    "version": {
      "description": "Informational schema version number. The server assigns the next version on import; this field is round-tripped through ImportSchema / GetSchema for documentation purposes.",
      "type": "integer",
      "minimum": 1
    },
    "version_description": {
      "description": "Description of what changed in this schema version.",
      "type": "string"
    },
    "info": {
      "$ref": "#/$defs/info"
    },
    "fields": {
      "description": "The fields defined in this schema version. Map keys are field paths matching the field-path regex; at least one entry is required.",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "$ref": "#/$defs/fieldPath"
      },
      "additionalProperties": {
        "$ref": "#/$defs/field"
      }
    },
    "dependentRequired": {
      "description": "Cross-field \"B required when A present\" rules. Each key is a trigger field path; each value is the list of dependent paths that must be non-null when the trigger is non-null. Field-existence checking is performed by the Go parser, not the meta-schema.",
      "type": "object",
      "propertyNames": {
        "$ref": "#/$defs/fieldPath"
      },
      "additionalProperties": {
        "type": "array",
        "items": {
          "type": "string",
          "pattern": "^[a-zA-Z_][a-zA-Z0-9_.-]*$"
        },
        "uniqueItems": true
      }
    },
    "validations": {
      "description": "Cross-field rules expressed in CEL. Reserved in v0.1.0 — the parser persists rules; the runtime engine ships in Phase 2 (issue #76).",
      "type": "array",
      "items": {
        "$ref": "#/$defs/validation"
      }
    }
  },
  "required": [
    "spec_version",
    "name",
    "fields"
  ],
  "patternProperties": {
    "^x-": true
  },
  "$defs": {
    "fieldPath": {
      "description": "Field path. ASCII letter/underscore start; alphanumeric, underscore, dot, hyphen.",
      "type": "string",
      "pattern": "^[a-zA-Z_][a-zA-Z0-9_.-]*$"
    },
    "field": {
      "type": "object",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "integer",
            "number",
            "string",
            "bool",
            "time",
            "duration",
            "url",
            "json"
          ]
        },
        "description": {
          "type": "string"
        },
        "default": {
          "type": "string"
        },
        "nullable": {
          "type": "boolean"
        },
        "deprecated": {
          "type": "boolean"
        },
        "redirect_to": {
          "description": "Target field path for deprecated-field reads. Existence checked Go-side.",
          "type": "string",
          "pattern": "^[a-zA-Z_][a-zA-Z0-9_.-]*$"
        },
        "title": {
          "type": "string"
        },
        "example": {
          "type": "string"
        },
        "examples": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/example"
          }
        },
        "externalDocs": {
          "$ref": "#/$defs/externalDocs"
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "format": {
          "description": "Free-form semantic format hint (e.g. \"email\", \"semver\", \"percentage\"). Informational only — not enforced by validation.",
          "type": "string"
        },
        "readOnly": {
          "type": "boolean"
        },
        "writeOnce": {
          "type": "boolean"
        },
        "sensitive": {
          "type": "boolean"
        },
        "constraints": {
          "type": "object"
        }
      },
      "unevaluatedProperties": false,
      "allOf": [
        {
          "if": {
            "properties": {
              "type": {
                "enum": [
                  "integer",
                  "number",
                  "duration"
                ]
              }
            },
            "required": [
              "type"
            ],
            "type": "object"
          },
          "then": {
            "properties": {
              "constraints": {
                "$ref": "#/$defs/constraintsNumeric"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "string"
              }
            },
            "required": [
              "type"
            ],
            "type": "object"
          },
          "then": {
            "properties": {
              "constraints": {
                "$ref": "#/$defs/constraintsString"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "json"
              }
            },
            "required": [
              "type"
            ],
            "type": "object"
          },
          "then": {
            "properties": {
              "constraints": {
                "$ref": "#/$defs/constraintsJSON"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "enum": [
                  "bool",
                  "time",
                  "url"
                ]
              }
            },
            "required": [
              "type"
            ],
            "type": "object"
          },
          "then": {
            "properties": {
              "constraints": {
                "$ref": "#/$defs/constraintsOther"
              }
            }
          }
        }
      ],
      "patternProperties": {
        "^x-": true
      }
    },
    "constraintsNumeric": {
      "description": "Constraints valid for integer / number / duration fields.",
      "type": "object",
      "properties": {
        "minimum": {
          "type": "number"
        },
        "maximum": {
          "type": "number"
        },
        "exclusiveMinimum": {
          "type": "number"
        },
        "exclusiveMaximum": {
          "type": "number"
        },
        "enum": {
          "type": "array",
          "items": true
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    },
    "constraintsString": {
      "description": "Constraints valid for string fields.",
      "type": "object",
      "properties": {
        "minLength": {
          "type": "integer",
          "minimum": 0
        },
        "maxLength": {
          "type": "integer",
          "minimum": 0
        },
        "pattern": {
          "description": "RE2 regex the value must match.",
          "type": "string"
        },
        "enum": {
          "type": "array",
          "items": true
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    },
    "constraintsJSON": {
      "description": "Constraints valid for json fields.",
      "type": "object",
      "properties": {
        "json_schema": {
          "description": "Embedded JSON Schema (as a JSON-encoded string) for structural validation.",
          "type": "string"
        },
        "enum": {
          "type": "array",
          "items": true
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    },
    "constraintsOther": {
      "description": "Constraints valid for bool / time / url fields.",
      "type": "object",
      "properties": {
        "enum": {
          "type": "array",
          "items": true
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    },
    "info": {
      "description": "Optional schema-level metadata. OAS Info Object.",
      "type": "object",
      "properties": {
        "title": {
          "type": "string"
        },
        "author": {
          "type": "string"
        },
        "contact": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "email": {
              "type": "string",
              "format": "email"
            },
            "url": {
              "type": "string",
              "format": "uri"
            }
          },
          "unevaluatedProperties": false,
          "patternProperties": {
            "^x-": true
          }
        },
        "labels": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          }
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    },
    "example": {
      "type": "object",
      "required": [
        "value"
      ],
      "properties": {
        "value": {
          "type": "string"
        },
        "summary": {
          "type": "string"
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    },
    "externalDocs": {
      "type": "object",
      "required": [
        "url"
      ],
      "properties": {
        "url": {
          "type": "string",
          "format": "uri"
        },
        "description": {
          "type": "string"
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    },
    "validation": {
      "description": "One CEL validation rule. See cel-validation.md.",
      "type": "object",
      "required": [
        "rule",
        "message"
      ],
      "properties": {
        "path": {
          "description": "Optional path prefix scoping the rule. Empty == schema-wide.",
          "type": "string"
        },
        "rule": {
          "description": "CEL expression source. Compilation deferred to Phase 2.",
          "type": "string",
          "minLength": 1
        },
        "message": {
          "description": "Human-readable failure message shown to clients.",
          "type": "string",
          "minLength": 1
        },
        "severity": {
          "description": "error (default) rejects writes; warning is non-blocking (reserved for Phase 2). Empty string permitted to match the Go parser's default-to-error behavior.",
          "type": "string",
          "enum": [
            "",
            "error",
            "warning"
          ]
        },
        "reason": {
          "description": "Optional machine-readable failure code.",
          "type": "string"
        }
      },
      "unevaluatedProperties": false,
      "patternProperties": {
        "^x-": true
      }
    }
  },
  "unevaluatedProperties": false
}
