{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://thehiveryiq.com/.well-known/schemas/effect-closure-v1.json",
  "title": "Effect Closure v1, effect closure receipt",
  "description": "Canonical schema for the Hive effect closure receipt, canonical type effect.closure. Binds an authorized action or effect digest and an idempotency key to an observed outcome, a completion status, timestamps, external evidence digests, and an optional reversal reference into one Ed25519 signature over a recomputable payload_sha256. The receipt attests that the named authorization was closed with the stated outcome at the stated time, under the stated idempotency key. It does not attest that the external evidence it names is itself accurate, and a completed status without a required evidence digest is a schema violation rather than a completed effect.",
  "type": "object",
  "required": [
    "receipt_id",
    "payload_sha256",
    "sig_b64u",
    "key_id",
    "algorithm",
    "ts",
    "signed_body"
  ],
  "additionalProperties": false,
  "properties": {
    "receipt_id": {
      "type": "string",
      "pattern": "^r_effect\\.closure_[0-9]{10,}_[0-9a-f]{12}$"
    },
    "payload_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
    "sig_b64u": { "type": "string", "pattern": "^[A-Za-z0-9_-]{86}$" },
    "key_id": { "type": "string", "pattern": "^did:(hive|web|key):[A-Za-z0-9._:%-]+$" },
    "algorithm": { "type": "string", "const": "Ed25519" },
    "ts": { "type": "integer", "minimum": 1000000000 },
    "signed_body": {
      "type": "object",
      "required": [
        "receipt_type",
        "schema",
        "closure_id",
        "tenant_id",
        "authorization",
        "idempotency_key",
        "status",
        "opened_at",
        "closed_at",
        "boundary"
      ],
      "additionalProperties": false,
      "properties": {
        "receipt_type": { "type": "string", "const": "effect.closure" },
        "schema": { "type": "string", "const": "r1.0.0" },
        "closure_id": { "type": "string", "minLength": 1, "maxLength": 256 },
        "tenant_id": { "type": "string", "minLength": 1, "maxLength": 256 },
        "authorization": {
          "type": "object",
          "description": "The action or effect this closure claims to close. effect_sha256 must match the digest of the effect actually observed.",
          "required": ["authorization_id", "effect_sha256"],
          "additionalProperties": false,
          "properties": {
            "authorization_id": { "type": "string", "minLength": 1, "maxLength": 256 },
            "effect_sha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "Digest of the authorized action or effect definition. A closure whose effect_sha256 does not match the authorization it names is a mismatched authorization."
            }
          }
        },
        "idempotency_key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "description": "Caller supplied key. Two closures with the same idempotency_key and the same closure_id are a replay. Two closures with the same idempotency_key naming different authorization_id values are a duplicate closure attempt against a key that should be unique per authorization."
        },
        "status": {
          "type": "string",
          "enum": ["completed", "failed", "reversed"],
          "description": "completed requires evidence. failed records a closed but unsuccessful attempt. reversed requires reversal_ref."
        },
        "opened_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}([.][0-9]{1,9})?Z$"
        },
        "closed_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}([.][0-9]{1,9})?Z$",
          "description": "Must not precede opened_at."
        },
        "evidence": {
          "type": "array",
          "minItems": 0,
          "maxItems": 64,
          "description": "External evidence digests supporting the stated outcome. status completed requires at least one entry here.",
          "items": {
            "type": "object",
            "required": ["evidence_id", "evidence_sha256"],
            "additionalProperties": false,
            "properties": {
              "evidence_id": { "type": "string", "minLength": 1, "maxLength": 256 },
              "evidence_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
            }
          }
        },
        "reversal_ref": {
          "type": "object",
          "description": "Required when status is reversed. Names the closure receipt being reversed, which must itself have status completed and must not already carry its own reversal_ref.",
          "required": ["receipt_id", "payload_sha256"],
          "additionalProperties": false,
          "properties": {
            "receipt_id": { "type": "string", "minLength": 1, "maxLength": 300 },
            "payload_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
          }
        },
        "boundary": {
          "type": "string",
          "const": "This receipt attests that the closure named in signed_body closes the named authorization under the stated idempotency_key with the stated status, opened_at, and closed_at. It does not attest that the evidence digests it names are themselves accurate, and it does not attest that the underlying effect was fit for any purpose."
        }
      }
    }
  }
}
