{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://getzero.dev/contracts/zero.proof_packet.v1.schema.json",
  "title": "ZERO ProofPacket v1",
  "description": "The exportable, third-party-verifiable record of ONE capital operation: the redacted latest zero.capital_operation.v1 envelope snapshot, an ordered sha256 chain over every journal snapshot of that operation, the authority it ran under, and the Ed25519 material needed to verify its authorization signatures offline — no secrets required, none included. Not zero.proof_pack.v1 (the per-root daily journal proof); this contract is per-operation. The runtime validator (zero.protocol.proof_packet) and the offline verifier (python3 -m zero.proof_packet_verify <packet.json>) additionally enforce cross-field laws this schema cannot express: packet_id must equal pp_<op_id> of the packaged operation; receipts and signature.entries must be verbatim mirrors of the operation's receipts and signatures; each snapshot_chain seq must equal its array position and the chain head status must match the operation; every status change in the chain must be a legal lifecycle transition; each signature challenge must bind this operation's op_id, policy_hash, simulation_hash, quote_hash, scope_id, and scope_epoch, be signed before quote expiry, and verify against the embedded public key; and proof_hash must reproduce as sha256 over the canonical packet bytes (JSON with sorted keys, compact separators, non-ASCII preserved, UTF-8) with proof_hash itself excluded.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema",
    "packet_id",
    "generated_at",
    "operation",
    "snapshot_chain",
    "receipts",
    "authority",
    "signature",
    "journal_anchor",
    "redaction",
    "proof_hash"
  ],
  "properties": {
    "schema": { "const": "zero.proof_packet.v1" },
    "packet_id": { "type": "string", "pattern": "^pp_op_[A-Za-z0-9_-]+$" },
    "generated_at": { "type": "string", "format": "date-time" },
    "operation": {
      "type": "object",
      "required": ["schema", "op_id", "status", "consequence_class", "authority", "receipts", "signatures"],
      "properties": {
        "schema": { "const": "zero.capital_operation.v1" },
        "op_id": { "type": "string", "pattern": "^op_[A-Za-z0-9_-]+$" },
        "status": {
          "enum": [
            "SIMULATED",
            "AUTHORIZED",
            "SUBMITTED",
            "SETTLED",
            "CONFIRMED",
            "RECONCILED",
            "REFUSED",
            "EXPIRED",
            "DISPUTED",
            "CANCELLED",
            "COMPENSATED"
          ]
        }
      },
      "description": "The packaged operation's latest journal snapshot, redacted for export (free text sanitized). A full zero.capital_operation.v1 envelope — see the sibling contract for its shape; the runtime re-validates it in full. DRAFT and QUOTED are excluded: pre-simulation there are no bound hashes, so there is nothing a third party could verify. Every other status — including the terminals REFUSED/EXPIRED/CANCELLED — is packet-legal, because refusals and expiries are exactly the histories that need proving."
    },
    "snapshot_chain": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["seq", "status", "sha256"],
        "properties": {
          "seq": { "type": "integer", "minimum": 0 },
          "status": { "$ref": "#/$defs/operationStatus" },
          "sha256": { "$ref": "#/$defs/sha256Hex" }
        }
      },
      "description": "Ordered hash chain over every journal snapshot of the operation, in append order, excluding snapshots whose newest receipt is a proof_packet receipt (proof emission is observational and excluded from the chain it attests). Each sha256 is over the canonical bytes of the full snapshot. Hashes must be distinct — every journal append changes state."
    },
    "receipts": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": true,
        "required": ["receipt_id", "kind"],
        "properties": {
          "receipt_id": { "type": "string", "minLength": 1 },
          "kind": { "$ref": "#/$defs/receiptKind" }
        }
      },
      "description": "Verbatim mirror of the packaged operation's receipts — the runtime validator rejects any divergence between the two."
    },
    "authority": {
      "type": "object",
      "additionalProperties": false,
      "required": ["scope_id", "scope_epoch", "class"],
      "properties": {
        "scope_id": { "type": "string", "minLength": 1 },
        "scope_epoch": { "type": "integer", "minimum": 0 },
        "class": {
          "type": "integer",
          "minimum": 0,
          "maximum": 5,
          "description": "The operation's consequence class (0 read-only … 5 irreversible). Must match the packaged operation."
        }
      },
      "description": "The authority the operation ran under. Must match the packaged operation's authority block and consequence class — the offline verifier rejects any drift."
    },
    "signature": {
      "type": "object",
      "additionalProperties": false,
      "required": ["algorithm", "entries"],
      "properties": {
        "algorithm": { "const": "ed25519" },
        "public_key_pem": {
          "type": ["string", "null"],
          "description": "The runtime signer's PUBLIC key PEM — everything a third party needs to verify the authorization signatures offline. Null exactly when there are no signatures (e.g. an operation refused before authorization)."
        },
        "entries": {
          "type": "array",
          "items": { "type": "object" },
          "description": "Verbatim mirror of the operation's signatures. Each entry carries the signed challenge and its Ed25519 signature."
        }
      }
    },
    "journal_anchor": {
      "oneOf": [
        { "type": "null" },
        {
          "type": "object",
          "required": ["root_hash"],
          "properties": {
            "root_hash": { "type": "string", "minLength": 1 }
          },
          "description": "Reference to a signed daily journal root committing to the capital-operations journal. The offline verifier requires root_hash to be 64-character sha256 hex when present."
        }
      ],
      "description": "Explicit null while the capital-operations journal is not yet committed to daily journal roots — absence of anchoring is stated, never implied."
    },
    "redaction": {
      "type": "object",
      "additionalProperties": true,
      "required": ["secret_material_included", "free_text_sanitized"],
      "properties": {
        "secret_material_included": { "const": false },
        "free_text_sanitized": { "const": true }
      }
    },
    "proof_hash": {
      "$ref": "#/$defs/sha256Hex",
      "description": "sha256 over the canonical packet bytes with proof_hash itself excluded — any un-rehashed edit anywhere in the packet breaks it."
    }
  },
  "allOf": [
    {
      "if": {
        "properties": { "signature": { "properties": { "entries": { "minItems": 1 } }, "required": ["entries"] } },
        "required": ["signature"]
      },
      "then": {
        "properties": {
          "signature": {
            "properties": { "public_key_pem": { "type": "string", "pattern": "BEGIN PUBLIC KEY" } },
            "required": ["public_key_pem"]
          }
        }
      }
    }
  ],
  "$defs": {
    "sha256Hex": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
    "operationStatus": {
      "enum": [
        "DRAFT",
        "QUOTED",
        "SIMULATED",
        "AUTHORIZED",
        "SUBMITTED",
        "SETTLED",
        "CONFIRMED",
        "RECONCILED",
        "REFUSED",
        "EXPIRED",
        "DISPUTED",
        "CANCELLED",
        "COMPENSATED"
      ]
    },
    "receiptKind": {
      "enum": [
        "intent",
        "policy",
        "simulation",
        "authorization",
        "execution",
        "settlement",
        "service",
        "work",
        "dispute",
        "refusal",
        "revocation",
        "reconciliation",
        "proof_packet"
      ]
    }
  }
}
