{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://thehiveryiq.com/.well-known/schemas/assembly-receipt-v1.json",
  "title": "Assembly Receipt v1, multi-provider assembly receipt",
  "description": "Canonical schema for the Hive multi-provider assembly receipt, canonical type assembly.receipt. Binds ordered or explicitly unordered contributions from multiple providers, models, tools, or sources into one Ed25519 signature over a recomputable payload_sha256. Names the contributor identity, the leaf digest, and the assembly policy for each contribution, commits to the whole contribution set with a Merkle root, and binds a final output digest. The receipt attests that the recorded contribution set, in the order stated when order is material, produces the committed Merkle root and the named final output digest. It does not attest that any individual contribution is correct or that any provider performed the work claimed.",
  "type": "object",
  "required": [
    "receipt_id",
    "payload_sha256",
    "sig_b64u",
    "key_id",
    "algorithm",
    "ts",
    "signed_body"
  ],
  "additionalProperties": false,
  "properties": {
    "receipt_id": {
      "type": "string",
      "pattern": "^r_assembly\\.receipt_[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",
        "assembly_id",
        "tenant_id",
        "assembly_policy",
        "contributions",
        "commitment",
        "final_output_sha256",
        "boundary"
      ],
      "additionalProperties": false,
      "properties": {
        "receipt_type": { "type": "string", "const": "assembly.receipt" },
        "schema": { "type": "string", "const": "r1.0.0" },
        "assembly_id": { "type": "string", "minLength": 1, "maxLength": 256 },
        "tenant_id": { "type": "string", "minLength": 1, "maxLength": 256 },
        "assembly_policy": {
          "type": "object",
          "description": "Declares whether contribution order is material and how the commitment is computed.",
          "required": ["order_matters", "commitment_scheme"],
          "additionalProperties": false,
          "properties": {
            "order_matters": {
              "type": "boolean",
              "description": "true means contributions.[] order is part of what is being attested and a reordering is a tamper. false means contributions are an unordered set and are sorted by contribution_id before the commitment is computed."
            },
            "commitment_scheme": {
              "type": "string",
              "enum": ["merkle_sha256", "sorted_concat_sha256"],
              "description": "merkle_sha256 builds a binary Merkle tree of leaf digests, hashing pairs left to right and duplicating a lone final node. sorted_concat_sha256 is a single SHA-256 over the leaf digests concatenated in commitment order, for a small or trivial contribution set."
            },
            "min_contributors": { "type": "integer", "minimum": 1 },
            "allow_duplicate_provider": { "type": "boolean" },
            "expected_contributors": {
              "type": "array",
              "minItems": 1,
              "maxItems": 4096,
              "description": "When present, the exact set of contributor_id values the assembly must contain, no more and no fewer. Every entry must appear exactly once among contributions[].contributor.contributor_id, so an omitted expected contributor, an unexpected contributor not on this list, or a duplicate contributor_id is detected directly, rather than only checked against a minimum count.",
              "items": { "type": "string", "minLength": 1, "maxLength": 256 }
            }
          }
        },
        "contributions": {
          "type": "array",
          "minItems": 1,
          "maxItems": 4096,
          "description": "One entry per contribution, in the order they were assembled. If assembly_policy.order_matters is false this order is administrative only, and the commitment is computed after sorting by contribution_id.",
          "items": {
            "type": "object",
            "required": ["contribution_id", "contributor", "leaf_sha256"],
            "additionalProperties": false,
            "properties": {
              "contribution_id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 256,
                "description": "Unique identifier for this contribution within the assembly. Two contributions sharing a contribution_id is a tamper, not a legitimate resubmission."
              },
              "contributor": {
                "type": "object",
                "required": ["contributor_id", "role"],
                "additionalProperties": false,
                "properties": {
                  "contributor_id": { "type": "string", "minLength": 1, "maxLength": 256 },
                  "role": {
                    "type": "string",
                    "enum": ["provider", "model", "tool", "source"]
                  },
                  "provider": { "type": "string", "minLength": 1, "maxLength": 128 },
                  "model_id": { "type": "string", "minLength": 1, "maxLength": 256 }
                }
              },
              "leaf_sha256": {
                "type": "string",
                "pattern": "^[0-9a-f]{64}$",
                "description": "Digest committing to this contribution's content. The commitment is built from these leaves, never from raw content, so the raw content need not be disclosed to verify the assembly."
              },
              "byte_length": { "type": "integer", "minimum": 0 }
            }
          }
        },
        "commitment": {
          "type": "object",
          "required": ["scheme", "root_sha256"],
          "additionalProperties": false,
          "properties": {
            "scheme": { "type": "string", "enum": ["merkle_sha256", "sorted_concat_sha256"] },
            "root_sha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "The recomputable commitment over every contribution leaf, per assembly_policy.commitment_scheme."
            }
          }
        },
        "final_output_sha256": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$",
          "description": "Digest of the assembled final output produced from the contributions."
        },
        "boundary": {
          "type": "string",
          "const": "This receipt attests that the recorded contribution set in signed_body, applied in the stated order when assembly_policy.order_matters is true, recomputes to the committed Merkle root or equivalent commitment and to final_output_sha256, and, when assembly_policy.expected_contributors is present, that the contribution set contains exactly that set of contributors with no omission, duplication, or unexpected contributor. It does not attest that any individual contribution is correct, that any named provider or model actually performed the work claimed, or that the final output is fit for any purpose."
        }
      }
    }
  }
}
