{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://audiobottle.app/schemas/audbot-manifest-split-v1.json",
  "title": "Audbot Manifest (split-v1)",
  "description": "Manifest written by Story 8-3 audbot_packager into the FIRST member of the outer .audiobottle tar. The audbot_format const lock at 'split-v1' is the load-bearing forward-compatibility check; future format versions extend this schema with new format strings.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "audbot_format",
    "audbot_version",
    "audbot_schema_version",
    "source_session_name",
    "created_at",
    "audbot_creator",
    "wavpack_compression_power",
    "incompressible_tar",
    "compressible_tar_zst",
    "audio_files",
    "audio_summary",
    "data_summary"
  ],
  "properties": {
    "audbot_format": {
      "const": "split-v1",
      "description": "Forward-compatibility lock. Story 8-4 rejects any other value."
    },
    "audbot_version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+(\\.[0-9]+)?$",
      "description": "Semver string. Minor revisions are forward-compatible."
    },
    "audbot_schema_version": {
      "type": "integer",
      "minimum": 1,
      "description": "Structural schema version. Extractor checks this BEFORE jsonschema validation so out-of-window builds give a friendly message instead of an opaque additionalProperties rejection. Bump on every field addition or interpretation change. v3 (Story 12.101): compressed_wavpack restores to the entry's ORIGINAL extension (WavPack-native containers) and audbot_path appends .wv to the full filename; pre-v3 readers must refuse. (Code review P7 / decision D2.)"
    },
    "source_session_name": {
      "type": "string",
      "minLength": 1
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
      "description": "UTC ISO 8601 with trailing Z."
    },
    "audbot_creator": {
      "type": "string",
      "minLength": 1,
      "description": "Caller-supplied app/version string (stored verbatim, displayed by restore tools)."
    },
    "wavpack_compression_power": {
      "enum": [
        "fast",
        "normal",
        "high",
        "very_high",
        "extra_high"
      ],
      "description": "Locked against archive.audbot_compressor.WavpackPower."
    },
    "incompressible_tar": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "filename",
        "sha256",
        "file_count",
        "uncompressed_total_bytes",
        "by_category"
      ],
      "properties": {
        "filename": {
          "const": "incompressible.tar"
        },
        "sha256": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "file_count": {
          "type": "integer",
          "minimum": 0
        },
        "uncompressed_total_bytes": {
          "type": "integer",
          "minimum": 0
        },
        "by_category": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "audio_compressed_wavpack",
            "audio_passthrough_already_compressed",
            "audio_passthrough_non_pcm",
            "video",
            "image",
            "archive",
            "document",
            "adobe_disk",
            "other_incompressible"
          ],
          "properties": {
            "audio_compressed_wavpack": {
              "type": "integer",
              "minimum": 0
            },
            "audio_passthrough_already_compressed": {
              "type": "integer",
              "minimum": 0
            },
            "audio_passthrough_non_pcm": {
              "type": "integer",
              "minimum": 0
            },
            "video": {
              "type": "integer",
              "minimum": 0
            },
            "image": {
              "type": "integer",
              "minimum": 0
            },
            "archive": {
              "type": "integer",
              "minimum": 0
            },
            "document": {
              "type": "integer",
              "minimum": 0
            },
            "adobe_disk": {
              "type": "integer",
              "minimum": 0
            },
            "other_incompressible": {
              "type": "integer",
              "minimum": 0
            }
          }
        }
      }
    },
    "compressible_tar_zst": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "filename",
        "sha256",
        "file_count",
        "stored_size_bytes",
        "uncompressed_total_bytes",
        "zstd_level",
        "by_top_level_dir"
      ],
      "properties": {
        "filename": {
          "const": "compressible.tar.zst"
        },
        "sha256": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "file_count": {
          "type": "integer",
          "minimum": 0
        },
        "stored_size_bytes": {
          "type": "integer",
          "minimum": 0,
          "description": "Post-zstd size of compressible.tar.zst."
        },
        "uncompressed_total_bytes": {
          "type": "integer",
          "minimum": 0,
          "description": "Sum of source bytes BEFORE zstd."
        },
        "zstd_level": {
          "const": 3
        },
        "by_top_level_dir": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "file_count",
              "uncompressed_bytes"
            ],
            "properties": {
              "file_count": {
                "type": "integer",
                "minimum": 0
              },
              "uncompressed_bytes": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      }
    },
    "audio_files": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "relative_path",
          "treatment",
          "audbot_path"
        ],
        "properties": {
          "relative_path": {
            "type": "string",
            "minLength": 1
          },
          "treatment": {
            "enum": [
              "compressed_wavpack",
              "passthrough_already_compressed",
              "passthrough_non_pcm"
            ]
          },
          "audbot_path": {
            "type": "string",
            "minLength": 1,
            "description": "Path of this file inside incompressible.tar (relative_path + '.wv' appended for compressed audio, original path otherwise)."
          },
          "original_format": {
            "type": [
              "string",
              "null"
            ]
          },
          "audio_codec": {
            "type": [
              "string",
              "null"
            ]
          },
          "sample_rate_hz": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "channels": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "duration_seconds": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "original_size_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "wav_chunks_preserved": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "passthrough_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "aiff_compression_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "caf_format_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "stored_size_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          }
        }
      }
    },
    "audio_summary": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "total_audio_files",
        "by_treatment",
        "by_format"
      ],
      "properties": {
        "total_audio_files": {
          "type": "integer",
          "minimum": 0
        },
        "by_treatment": {
          "type": "object",
          "additionalProperties": {
            "type": "integer",
            "minimum": 0
          }
        },
        "by_format": {
          "type": "object",
          "additionalProperties": {
            "type": "integer",
            "minimum": 0
          }
        }
      }
    },
    "data_summary": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "incompressible_file_count",
        "compressible_file_count",
        "incompressible_uncompressed_total_bytes",
        "compressible_uncompressed_total_bytes"
      ],
      "properties": {
        "incompressible_file_count": {
          "type": "integer",
          "minimum": 0
        },
        "compressible_file_count": {
          "type": "integer",
          "minimum": 0
        },
        "incompressible_uncompressed_total_bytes": {
          "type": "integer",
          "minimum": 0
        },
        "compressible_uncompressed_total_bytes": {
          "type": "integer",
          "minimum": 0
        }
      }
    }
  }
}
