{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://gxplex.com/api/v1/schema/observation-bundle.json",
  "title": "Observation bundle",
  "description": "The document served at /api/v1/observation-bundle/<id>.json: one tracked row's observations, each under its citation key, with the path from each digest to the daily root, the root file, the proofs that cover it, the row's rights fields and the bundle's own signature state. It carries the envelope's keys except `count`; its counts are under `counts`.",
  "type": "object",
  "properties": {
    "schema_version": {
      "type": "integer",
      "description": "Always 1 under this contract. It increments only when a field is removed or re-typed, which the published contract forbids."
    },
    "generated_at": {
      "type": "string",
      "format": "date",
      "description": "The day this record calls today, at day granularity. Not a build clock: the unit of this archive is the day."
    },
    "source": {
      "type": "string",
      "description": "The origin this document was built for."
    },
    "notice": {
      "type": "string",
      "description": "What this record reports, and what it does not."
    },
    "source_terms": {
      "type": "string",
      "description": "A statement of fact about the compiled content. It is not a licence and grants nothing."
    },
    "schema": {
      "type": [
        "string",
        "null"
      ],
      "description": "The address of this document schema, or null where none is published for the collection. Null with the key present, so an absent schema is distinguishable from a build that did not look."
    },
    "licence_class": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "open",
        "restricted",
        "unknown"
      ],
      "description": "What this archive recorded of the terms the source states. Null where no reading exists for this object. See `rights` on the envelope."
    },
    "text_retained": {
      "type": [
        "boolean",
        "null"
      ],
      "description": "Whether normalised prose of the document is held here for a quotation to be checked against. Held, never served. Null where no reading exists."
    },
    "quote_allowed": {
      "type": [
        "boolean",
        "null"
      ],
      "description": "Whether a quotation from the document appears in this record's own published output. A fact about this record's handling, not a reading of what the publisher permits, and not a grant. Null where no reading exists."
    },
    "snapshot_available": {
      "type": [
        "boolean",
        "null"
      ],
      "description": "Whether a retained snapshot of an observed retrieval is still held here for a digest to be re-checked against. No snapshot is served. Null where no reading exists."
    },
    "rights_of": {
      "type": [
        "string",
        "null"
      ],
      "description": "The tracked entry id the four fields above are the rights OF. Null where the object names no entry."
    },
    "rights_unresolved": {
      "type": [
        "string",
        "null"
      ],
      "description": "Present only where the four fields are null, naming which absence it is: an id this record does not hold, or an object that names no entry."
    },
    "bundle_of": {
      "type": "string",
      "description": "The tracked row the bundle is of."
    },
    "document": {
      "type": "string",
      "description": "The row's title, as the row holds it."
    },
    "citation": {
      "type": "object",
      "description": "`key_rule`, `permalink_pattern` and `bundle_url`: how an observation in the bundle is named and where the bundle is served."
    },
    "signature": {
      "type": "object",
      "description": "`state`, `signed_by` and `why`: the bundle's own signature state, stated rather than implied."
    },
    "covers": {
      "type": "object",
      "description": "What the root fixes and what it does not."
    },
    "root": {
      "type": "object",
      "description": "The root value, the root file's text and sha256, where the root and leaves are served, the leaf count, the day built, and the hashing rules."
    },
    "proofs": {
      "type": "object",
      "description": "The RFC 3161 and OpenTimestamps proofs over the root, each with its own state."
    },
    "counts": {
      "type": "object",
      "description": "Observations in the bundle, with a leaf, without a digest, with a digest that is not a leaf, distinct leaves, and records without an address."
    },
    "records_without_address": {
      "type": "array",
      "description": "Records of the row that carry no address, named rather than dropped."
    },
    "verify": {
      "type": "object",
      "description": "Where the offline check is published, what it checks, its exit statuses, and what it cannot tell."
    },
    "leaves": {
      "type": "object",
      "description": "The path from each leaf to the root."
    },
    "observations": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/observation"
      },
      "description": "Every observation of the row, in day and sequence order."
    },
    "collection": {
      "const": "observation-bundle"
    }
  },
  "required": [
    "schema_version",
    "collection",
    "generated_at",
    "source",
    "notice",
    "source_terms",
    "bundle_of",
    "document",
    "citation",
    "signature",
    "covers",
    "root",
    "proofs",
    "counts",
    "records_without_address",
    "verify",
    "leaves",
    "observations",
    "licence_class",
    "text_retained",
    "quote_allowed",
    "snapshot_available",
    "rights_of"
  ],
  "additionalProperties": true,
  "$defs": {
    "observation": {
      "type": "object",
      "title": "Bundled observation",
      "properties": {
        "key": {
          "type": "string",
          "description": "The citation key: the day and the sequence within it."
        },
        "date": {
          "type": "string",
          "format": "date",
          "description": "The day of the observation."
        },
        "sequence": {
          "type": "integer",
          "description": "The sequence within the day."
        },
        "permalink": {
          "type": "string",
          "description": "The observation's address on its series page."
        },
        "leaf": {
          "type": [
            "string",
            "null"
          ],
          "description": "The leaf line under the root, or null where none is."
        },
        "leaf_absent_because": {
          "type": [
            "string",
            "null"
          ],
          "description": "Why no leaf is carried; null where one is."
        },
        "record": {
          "type": "object",
          "description": "The observation record as the series serves it."
        }
      },
      "required": [
        "key",
        "date",
        "sequence",
        "permalink",
        "leaf",
        "leaf_absent_because",
        "record"
      ],
      "additionalProperties": true
    }
  }
}
