{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://thehiveryiq.com/.well-known/schemas/unchanged-value-run-v1.json",
  "title": "Unchanged Value Run Receipt, v1",
  "description": "Canonical schema for the Hive unchanged value run receipt, canonical type value.unchangedrun. The instrument records a sealed history of per period value fingerprints for one series, presented as salted commitments, together with a run limit fixed beforehand, and computes from that history how many periods in a row the fingerprint stayed identical and whether any run went past the limit. The values themselves never enter the signed body, only salted fingerprints of them.",
  "type": "object",
  "required": [
    "receipt_id",
    "payload_sha256",
    "sig_b64u",
    "key_id",
    "algorithm",
    "ts",
    "signed_body"
  ],
  "additionalProperties": false,
  "properties": {
    "receipt_id": { "type": "string", "pattern": "^r_value[.]unchangedrun_[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",
        "series_id",
        "series_commitment",
        "salt_commitment",
        "run_limit",
        "periods",
        "history_digest",
        "finding",
        "recorded_at",
        "boundary"
      ],
      "additionalProperties": false,
      "properties": {
        "receipt_type": { "type": "string", "const": "value.unchangedrun" },
        "schema": { "type": "string", "const": "r1.0.0" },
        "series_id": { "type": "string", "pattern": "^ser_[0-9a-z][0-9a-z._-]{0,47}$" },
        "series_commitment": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$",
          "description": "Salted commitment over the series descriptor, for example an instrument identifier. The descriptor never enters the signed body."
        },
        "salt_commitment": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
        "run_limit": {
          "type": "object",
          "required": ["max_unchanged_periods", "rule_digest", "fixed_at"],
          "additionalProperties": false,
          "properties": {
            "max_unchanged_periods": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100000,
              "description": "The longest run of consecutive periods with an identical fingerprint that the rule allows. A run longer than this is over the limit."
            },
            "rule_digest": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "Lowercase hex SHA-256 over the rule text as fixed. The text is never carried here."
            },
            "fixed_at": {
              "type": "object",
              "required": ["utc", "drift_seconds"],
              "additionalProperties": false,
              "properties": {
                "utc": { "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$" },
                "drift_seconds": { "type": "integer", "minimum": 0, "maximum": 86400 }
              }
            }
          }
        },
        "periods": {
          "type": "array",
          "minItems": 1,
          "maxItems": 10000,
          "items": {
            "type": "object",
            "required": ["period_start", "fingerprint"],
            "additionalProperties": false,
            "properties": {
              "period_start": {
                "type": "object",
                "required": ["utc", "drift_seconds"],
                "additionalProperties": false,
                "properties": {
                  "utc": { "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$" },
                  "drift_seconds": { "type": "integer", "minimum": 0, "maximum": 86400 }
                }
              },
              "fingerprint": {
                "type": "string",
                "pattern": "^[0-9a-f]{64}$",
                "description": "Salted fingerprint of the value recorded for this period. Equal values give equal fingerprints under one salt."
              }
            }
          }
        },
        "history_digest": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$",
          "description": "Hash chain over the series commitment and every period instant and fingerprint, in order."
        },
        "finding": {
          "type": "object",
          "required": [
            "period_count",
            "current_run_length",
            "longest_run_length",
            "longest_run_start_index",
            "runs_over_limit",
            "over_limit"
          ],
          "additionalProperties": false,
          "properties": {
            "period_count": { "type": "integer", "minimum": 1, "maximum": 10000 },
            "current_run_length": { "type": "integer", "minimum": 1, "maximum": 10000 },
            "longest_run_length": { "type": "integer", "minimum": 1, "maximum": 10000 },
            "longest_run_start_index": { "type": "integer", "minimum": 0, "maximum": 9999 },
            "runs_over_limit": { "type": "integer", "minimum": 0, "maximum": 10000 },
            "over_limit": { "type": "boolean" }
          }
        },
        "recorded_at": {
          "type": "object",
          "required": ["utc", "drift_seconds"],
          "additionalProperties": false,
          "properties": {
            "utc": { "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$" },
            "drift_seconds": { "type": "integer", "minimum": 0, "maximum": 86400 }
          }
        },
        "boundary": {
          "type": "string",
          "minLength": 1,
          "const": "Hive records and checks; it does not decide, block, enforce or sit in the access path. This receipt shows what was recorded and when, not that it was correct. It attests only that a sealed history of per period value fingerprints for one series, presented as salted commitments, was recorded at the recorded instant against a run limit fixed at the recorded earlier instant, and that the run length and over limit flag were computed from that history under that limit. It does not establish that any value was accurate, fair, stale, or wrong, that any period was missing from the history, that the limit is adequate for any purpose, or that any party acted on the result. The values and the rule text never enter this receipt, and the recorded instants are presented as reported by the recording party."
        }
      }
    }
  }
}
