{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://odexa.io/schemas/1.2.0-draft.1/policy.schema.json",
  "title": "Odexa native policy 1.2.0-draft.1",
  "description": "Draft local contract. Publication at the $id is not claimed. Semantic validation remains required.",
  "$comment": "Structural schema only. The native draft additionally requires integer-token-only JSON syntax (no decimal/exponent tokens), duplicate-key rejection, canonical URL rules, origin/resource-reference integrity, timestamp ordering and history immutability. JSON Schema validators do not enforce all these; run the reference validator.",
  "type": "object",
  "properties": {
    "protocol_version": {
      "const": "1.2.0-draft.1"
    },
    "policy_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 4096,
      "format": "uri",
      "pattern": "^https://"
    },
    "revision": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "origin": {
      "type": "string",
      "minLength": 1,
      "maxLength": 4096,
      "format": "uri",
      "pattern": "^https://"
    },
    "issued_at": {
      "$ref": "#/$defs/timestamp"
    },
    "expires_at": {
      "$ref": "#/$defs/timestamp"
    },
    "default": {
      "const": "no_grant"
    },
    "resources": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/resource"
      },
      "minItems": 1,
      "maxItems": 256,
      "uniqueItems": true
    },
    "rules": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/rule"
      },
      "minItems": 1,
      "maxItems": 512,
      "uniqueItems": true
    }
  },
  "required": [
    "protocol_version",
    "policy_id",
    "revision",
    "origin",
    "issued_at",
    "expires_at",
    "default",
    "resources",
    "rules"
  ],
  "additionalProperties": false,
  "$defs": {
    "timestamp": {
      "type": "string",
      "format": "date-time",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$",
      "minLength": 20,
      "maxLength": 20
    },
    "selector": {
      "type": "object",
      "properties": {
        "type": {
          "enum": [
            "exact",
            "directory_prefix"
          ]
        },
        "path": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^/"
        },
        "query": {
          "enum": [
            "absent",
            "any"
          ]
        }
      },
      "required": [
        "type",
        "path",
        "query"
      ],
      "additionalProperties": false,
      "allOf": [
        {
          "if": {
            "properties": {
              "type": {
                "const": "directory_prefix"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "properties": {
              "path": {
                "pattern": "/$",
                "type": "string"
              }
            }
          }
        }
      ]
    },
    "resource": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
        },
        "selectors": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/selector"
          },
          "minItems": 1,
          "maxItems": 32,
          "uniqueItems": true
        }
      },
      "required": [
        "id",
        "selectors"
      ],
      "additionalProperties": false
    },
    "obligation": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "const": "attribution"
            },
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "url": {
              "type": "string",
              "minLength": 1,
              "maxLength": 4096,
              "format": "uri",
              "pattern": "^https://"
            }
          },
          "required": [
            "type",
            "name",
            "url"
          ],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "type": {
              "const": "retention"
            },
            "max_seconds": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          },
          "required": [
            "type",
            "max_seconds"
          ],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "type": {
              "const": "report_usage"
            },
            "endpoint": {
              "type": "string",
              "minLength": 1,
              "maxLength": 4096,
              "format": "uri",
              "pattern": "^https://"
            },
            "deadline_seconds": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          "required": [
            "type",
            "endpoint",
            "deadline_seconds"
          ],
          "additionalProperties": false
        }
      ]
    },
    "rule": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
        },
        "resource_ids": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
          },
          "minItems": 1,
          "maxItems": 256,
          "uniqueItems": true
        },
        "actions": {
          "type": "array",
          "items": {
            "enum": [
              "retrieve",
              "store",
              "transform",
              "redistribute"
            ]
          },
          "minItems": 1,
          "maxItems": 4,
          "uniqueItems": true
        },
        "purposes": {
          "type": "array",
          "items": {
            "enum": [
              "search_indexing",
              "public_retrieval",
              "internal_knowledge",
              "model_training",
              "model_fine_tuning",
              "redistribution"
            ]
          },
          "minItems": 1,
          "maxItems": 6,
          "uniqueItems": true
        },
        "effect": {
          "enum": [
            "permit",
            "prohibit",
            "require_agreement"
          ]
        },
        "obligations": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/obligation"
          },
          "minItems": 0,
          "maxItems": 64
        }
      },
      "required": [
        "id",
        "resource_ids",
        "actions",
        "purposes",
        "effect",
        "obligations"
      ],
      "additionalProperties": false,
      "allOf": [
        {
          "if": {
            "properties": {
              "effect": {
                "const": "prohibit"
              }
            },
            "required": [
              "effect"
            ]
          },
          "then": {
            "properties": {
              "obligations": {
                "maxItems": 0,
                "type": "array"
              }
            }
          }
        }
      ]
    }
  }
}
