{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://schemas.sbo3l.dev/policy/v1.json",
  "title": "SBO3L Policy YAML Model v1",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "version",
    "policy_id",
    "default_decision",
    "agents",
    "budgets",
    "providers",
    "recipients",
    "rules"
  ],
  "properties": {
    "version": {
      "type": "integer",
      "const": 1
    },
    "policy_id": {
      "type": "string",
      "minLength": 3,
      "maxLength": 64,
      "pattern": "^[a-z0-9][a-z0-9_-]{2,63}$"
    },
    "description": {
      "type": "string",
      "maxLength": 512
    },
    "default_decision": {
      "type": "string",
      "enum": [
        "deny",
        "requires_human"
      ]
    },
    "agents": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/agent_selector"
      }
    },
    "budgets": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/budget"
      }
    },
    "providers": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/provider"
      }
    },
    "recipients": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/recipient"
      }
    },
    "rules": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/rule"
      }
    },
    "emergency": {
      "$ref": "#/$defs/emergency"
    }
  },
  "$defs": {
    "agent_id": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9_-]{2,63}$"
    },
    "agent_selector": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "agent_id",
        "status"
      ],
      "properties": {
        "agent_id": {
          "$ref": "#/$defs/agent_id"
        },
        "status": {
          "type": "string",
          "enum": [
            "active",
            "paused",
            "revoked"
          ]
        },
        "policy_role": {
          "type": "string",
          "maxLength": 64
        }
      }
    },
    "budget": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "agent_id",
        "scope",
        "cap_usd"
      ],
      "properties": {
        "agent_id": {
          "$ref": "#/$defs/agent_id"
        },
        "scope": {
          "type": "string",
          "enum": [
            "per_tx",
            "daily",
            "monthly",
            "per_provider"
          ]
        },
        "scope_key": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 128,
          "default": null
        },
        "cap_usd": {
          "$ref": "#/$defs/money"
        },
        "soft_cap_usd": {
          "anyOf": [
            {
              "$ref": "#/$defs/money"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        }
      }
    },
    "provider": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "url",
        "status"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 3,
          "maxLength": 128
        },
        "url": {
          "type": "string",
          "format": "uri",
          "maxLength": 2048
        },
        "status": {
          "type": "string",
          "enum": [
            "trusted",
            "allowed",
            "denied",
            "observation"
          ]
        },
        "cert_pin_sha256": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^[A-Fa-f0-9]{64}$",
          "default": null
        }
      }
    },
    "recipient": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "address",
        "chain",
        "status"
      ],
      "properties": {
        "address": {
          "type": "string",
          "pattern": "^0x[a-fA-F0-9]{40}$"
        },
        "chain": {
          "type": "string",
          "minLength": 2,
          "maxLength": 32
        },
        "status": {
          "type": "string",
          "enum": [
            "allowed",
            "denied"
          ]
        },
        "label": {
          "type": "string",
          "maxLength": 128
        }
      }
    },
    "rule": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "effect",
        "when"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 3,
          "maxLength": 64,
          "pattern": "^[a-z0-9][a-z0-9_-]{2,63}$"
        },
        "effect": {
          "type": "string",
          "enum": [
            "allow",
            "deny",
            "requires_human"
          ]
        },
        "deny_code": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^policy\\.[a-z0-9_]+$",
          "default": null
        },
        "when": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2048,
          "description": "Rego expression fragment evaluated against the normalized payment request context."
        }
      }
    },
    "emergency": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "freeze_all": {
          "type": "boolean",
          "default": false
        },
        "paused_agents": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/agent_id"
          },
          "default": []
        }
      }
    },
    "money": {
      "type": "string",
      "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,2})?$"
    }
  }
}
