{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://cbfpspec.org/schemas/main.schema.json",
  "title": "CBFP MAIN \u2014 draft strict-v0.1 structural profile",
  "description": "Derived from private SDK review c3a69c1. Not an approved universal reader contract. Cross-field, byte-level and admission checks are separate.",
  "type": "object",
  "required": [
    "format",
    "sha256",
    "song",
    "source",
    "revision",
    "spans"
  ],
  "properties": {
    "format": {
      "const": "choirboy.sidecar/2"
    },
    "sha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$",
      "minLength": 64,
      "maxLength": 64
    },
    "song": {
      "type": "object",
      "required": [
        "title",
        "artist",
        "durationMs"
      ],
      "properties": {
        "title": {
          "type": "string",
          "maxLength": 256
        },
        "artist": {
          "type": "string",
          "maxLength": 256
        },
        "durationMs": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9223372036854775807
        }
      },
      "additionalProperties": true
    },
    "source": {
      "type": "string",
      "maxLength": 256
    },
    "revision": {
      "type": "integer",
      "minimum": 0,
      "maximum": 4294967295
    },
    "spans": {
      "type": "array",
      "maxItems": 20000,
      "items": {
        "type": "object",
        "required": [
          "id",
          "word",
          "category",
          "startMs",
          "endMs"
        ],
        "properties": {
          "id": {
            "type": "string",
            "maxLength": 256,
            "minLength": 1
          },
          "word": {
            "type": "string",
            "maxLength": 256
          },
          "category": {
            "type": "string",
            "maxLength": 256
          },
          "startMs": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9223372036854775807
          },
          "endMs": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9223372036854775807
          },
          "action": {
            "type": "string",
            "maxLength": 256,
            "default": "mute"
          },
          "origin": {
            "type": "string",
            "maxLength": 256,
            "default": "auto"
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "default": 0.9
          },
          "label": {
            "type": "string",
            "maxLength": 140,
            "not": {
              "pattern": "[^ -~]"
            }
          }
        },
        "additionalProperties": true
      }
    },
    "completeScan": {
      "type": "boolean",
      "default": false
    },
    "analysisRan": {
      "type": "boolean",
      "default": false
    },
    "editsRef": {
      "type": "string",
      "minLength": 75,
      "maxLength": 75,
      "pattern": "^[0-9a-f]{64}\\.edits\\.json$"
    },
    "landmark": {
      "anyOf": [
        {
          "type": "null"
        },
        {
          "type": "object",
          "required": [
            "algo",
            "count",
            "records"
          ],
          "properties": {
            "algo": {
              "const": "landmark-1"
            },
            "count": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8000
            },
            "records": {
              "type": "string",
              "minLength": 12,
              "maxLength": 85336,
              "contentEncoding": "base64",
              "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$",
              "not": {
                "pattern": "[^A-Za-z0-9+/=]"
              },
              "description": "Standard padded base64. Decode separately to check canonical encoding, eight-byte records, count, ordering and signed-safe frames."
            }
          },
          "additionalProperties": true
        }
      ]
    }
  },
  "additionalProperties": true
}
