{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "tiba-receipt-v0.1.schema.json",
  "title": "Tiba Execution Receipt v0.1",
  "description": "A portable signed statement of an attempted or completed action under a Tiba mandate chain.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "type",
    "version",
    "id",
    "mandate_id",
    "mandate_hash",
    "mandate_chain",
    "action",
    "input_hash",
    "output_hash",
    "result",
    "executed_at",
    "actor",
    "signature"
  ],
  "properties": {
    "type": { "const": "tiba.receipt" },
    "version": { "const": "0.1" },
    "id": { "$ref": "#/$defs/id" },
    "mandate_id": { "$ref": "#/$defs/id" },
    "mandate_hash": { "$ref": "#/$defs/hash" },
    "mandate_chain": {
      "type": "array",
      "description": "Full signed mandates, ordered from root to the active (leaf) mandate. This makes a receipt independently verifiable offline.",
      "minItems": 1,
      "maxItems": 9,
      "items": { "$ref": "tiba-mandate-v0.1.schema.json" }
    },
    "action": { "$ref": "#/$defs/action" },
    "input_hash": { "$ref": "#/$defs/hash" },
    "output_hash": { "$ref": "#/$defs/hash" },
    "result": { "enum": ["success", "failure", "denied"] },
    "reason": {
      "type": "string",
      "description": "A Tiba error code. It is REQUIRED for result=denied and RECOMMENDED for result=failure.",
      "pattern": "^TIBA_[A-Z0-9_]+$",
      "maxLength": 80
    },
    "executed_at": { "$ref": "#/$defs/timestamp" },
    "actor": { "$ref": "#/$defs/did_key" },
    "evidence": {
      "type": "array",
      "description": "Opaque external protocol references, not secret payloads. For a Solana payment include a solana_transaction reference and solana-devnet network.",
      "items": { "$ref": "#/$defs/evidence" }
    },
    "extensions": {
      "type": "object",
      "description": "Namespaced extension data. Verifiers MUST fail closed for a security-relevant extension they do not understand.",
      "additionalProperties": true
    },
    "signature": { "$ref": "#/$defs/signature" }
  },
  "allOf": [
    {
      "if": { "required": ["result"], "properties": { "result": { "const": "denied" } } },
      "then": { "required": ["reason"] }
    }
  ],
  "$defs": {
    "id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "pattern": "^[A-Za-z0-9._:-]+$"
    },
    "did_key": {
      "type": "string",
      "pattern": "^did:key:z[1-9A-HJ-NP-Za-km-z]+$",
      "maxLength": 128
    },
    "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}\\.[0-9]{3}Z$",
      "maxLength": 24
    },
    "hash": {
      "type": "string",
      "pattern": "^sha256-[A-Za-z0-9_-]{43}$"
    },
    "selector": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2048,
      "pattern": "^(\\*|[^*\\s]+)$"
    },
    "amount": {
      "type": "string",
      "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,18})?$",
      "maxLength": 64
    },
    "currency": {
      "type": "string",
      "pattern": "^[A-Z][A-Z0-9._-]{1,15}$",
      "maxLength": 16
    },
    "action": {
      "type": "object",
      "additionalProperties": false,
      "required": ["protocol", "action", "resource", "tool", "counterparty", "data_access"],
      "properties": {
        "protocol": { "$ref": "#/$defs/selector" },
        "action": { "$ref": "#/$defs/selector" },
        "resource": { "$ref": "#/$defs/selector" },
        "tool": { "$ref": "#/$defs/selector" },
        "counterparty": { "$ref": "#/$defs/selector" },
        "amount": { "$ref": "#/$defs/amount" },
        "currency": { "$ref": "#/$defs/currency" },
        "data_access": {
          "type": "object",
          "additionalProperties": false,
          "required": ["read", "write"],
          "properties": {
            "read": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/selector" } },
            "write": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/selector" } }
          }
        }
      },
      "allOf": [
        {
          "if": { "required": ["amount"] },
          "then": { "required": ["currency"] }
        },
        {
          "if": { "required": ["currency"] },
          "then": { "required": ["amount"] }
        }
      ]
    },
    "evidence": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "reference"],
      "properties": {
        "type": { "type": "string", "minLength": 1, "maxLength": 100 },
        "reference": { "type": "string", "minLength": 1, "maxLength": 2048 },
        "network": { "type": "string", "minLength": 1, "maxLength": 100 },
        "url": { "type": "string", "format": "uri", "maxLength": 2048 },
        "hash": { "$ref": "#/$defs/hash" }
      }
    },
    "signature": {
      "type": "object",
      "additionalProperties": false,
      "required": ["alg", "kid", "value"],
      "properties": {
        "alg": { "const": "Ed25519" },
        "kid": { "$ref": "#/$defs/did_key" },
        "value": { "type": "string", "pattern": "^[A-Za-z0-9_-]{86}$" }
      }
    }
  }
}
