{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://standards.rootblocks.com/schemas/attestation/in-toto-statement.v1.schema.json",
  "title": "in-toto Statement v1 (envelope)",
  "$comment": "A faithful, product-neutral mirror of the in-toto Attestation Framework Statement layer v1 (spec: https://in-toto.io/Statement/v1, ITE-6 ResourceDescriptor). It is the generic envelope: `_type` and `subject` describe WHAT is attested; `predicateType` names the claim's vocabulary and `predicate` carries the claim itself, left opaque here (`type: object`). RootBlocks specializes this envelope in schemas/attestation/rootblocks-decision-provenance.statement.v1.schema.json, which pins `predicateType` and binds `predicate` to the decision-provenance predicate. Keeping the generic envelope as its own contract means a RootBlocks statement IS a valid in-toto Statement, so if an ecosystem (e.g. GitHub artifact attestations / a sigstore bundle) carries in-toto Statements, a RootBlocks decision-provenance attestation slots in as its payload. DRAFT / experimental.",
  "type": "object",
  "additionalProperties": false,
  "required": ["_type", "subject", "predicateType"],
  "properties": {
    "_type": {
      "description": "The in-toto Statement version identifier. Const-pinned to the v1 URI.",
      "const": "https://in-toto.io/Statement/v1"
    },
    "subject": {
      "description": "The software artifacts the attestation applies to. Non-empty; each entry is a ResourceDescriptor identifying one artifact (typically by digest).",
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/resourceDescriptor"
      }
    },
    "predicateType": {
      "description": "URI naming the meaning and schema of `predicate` (the claim vocabulary).",
      "type": "string",
      "format": "uri",
      "minLength": 1
    },
    "predicate": {
      "description": "The claim about the subject. Opaque in the generic envelope; a specialization binds it to a concrete predicate schema.",
      "type": "object"
    }
  },
  "$defs": {
    "resourceDescriptor": {
      "description": "in-toto v1 ResourceDescriptor (ITE-6). Identifies an artifact; at least one of `digest`, `uri`, or `content` must be present.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "uri": {
          "type": "string",
          "minLength": 1
        },
        "digest": {
          "$ref": "#/$defs/digestSet"
        },
        "content": {
          "description": "Base64-encoded bytes of the resource, when carried inline.",
          "type": "string"
        },
        "mediaType": {
          "type": "string",
          "minLength": 1
        },
        "annotations": {
          "description": "Producer-defined metadata. Keys SHOULD be reverse-DNS namespaced.",
          "type": "object"
        }
      },
      "anyOf": [
        { "required": ["digest"] },
        { "required": ["uri"] },
        { "required": ["content"] }
      ]
    },
    "digestSet": {
      "description": "Map of algorithm name -> lowercase hex-encoded digest. At least one entry.",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "pattern": "^[A-Za-z0-9_-]+$"
      },
      "additionalProperties": {
        "type": "string",
        "pattern": "^[a-f0-9]+$"
      }
    }
  }
}
