{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://vibe-qc.org/spec/qvf/1/manifest.schema.json",
  "title": "QVF Manifest",
  "description": "Canonical JSON Schema for manifest.json inside a .qvf archive (v1). This file is the single source of truth for the QVF v1 contract; the vibe-view consumer loads it from a symlink so producer and consumer cannot diverge.",
  "type": "object",
  "additionalProperties": false,
  "required": ["qvf_version", "source", "sections"],
  "properties": {
    "qvf_version": {
      "type": "integer",
      "const": 1,
      "description": "QVF format version. v1 is the only released version."
    },
    "schema_uri": {
      "type": "string",
      "format": "uri",
      "description": "Canonical URI of this JSON Schema. Informational; not validated against."
    },
    "source": {
      "type": "object",
      "additionalProperties": false,
      "required": ["program", "version", "calculation"],
      "properties": {
        "program": { "type": "string", "minLength": 1 },
        "version": { "type": "string", "minLength": 1 },
        "calculation": { "type": "string" }
      }
    },
    "provenance": {
      "type": "object",
      "additionalProperties": true,
      "description": "Optional calculation provenance carried at manifest root.",
      "properties": {
        "method": { "type": "string" },
        "functional": { "type": "string" },
        "basis": { "type": "string" },
        "charge": { "type": "integer" },
        "multiplicity": { "type": "integer" },
        "n_electrons": { "type": "integer", "minimum": 0 },
        "scf_converged": { "type": "boolean" },
        "scf_energy": { "$ref": "#/$defs/ValueWithUnits" },
        "fermi_energy": { "$ref": "#/$defs/ValueWithUnits" },
        "wall_seconds": { "type": "number", "minimum": 0 },
        "hostname": { "type": "string" },
        "dimensionality": { "type": "integer", "minimum": 0, "maximum": 3 }
      }
    },
    "viewer_defaults": {
      "type": "object",
      "additionalProperties": { "$ref": "#/$defs/ViewerHint" },
      "properties": {
        "auto_open": {
          "type": "array",
          "items": { "type": "string" }
        },
        "bookmarks": {
          "type": "array",
          "description": "Ordered camera bookmarks for consistent framing across viewers and movie export. The list order is the playback order.",
          "items": { "$ref": "#/$defs/Bookmark" }
        }
      }
    },
    "sections": {
      "type": "array",
      "items": { "$ref": "#/$defs/Section" }
    }
  },
  "$defs": {
    "ValueWithUnits": {
      "type": "object",
      "additionalProperties": false,
      "required": ["value", "units"],
      "properties": {
        "value": { "type": "number" },
        "units": { "type": "string", "minLength": 1 }
      }
    },
    "ViewerHint": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "isovalue": { "type": "number" },
        "colormap": { "type": "string" },
        "opacity": { "type": "number", "minimum": 0, "maximum": 1 },
        "replication": {
          "type": "array",
          "items": { "type": "integer", "minimum": 1 },
          "minItems": 3,
          "maxItems": 3
        }
      }
    },
    "Vec3": {
      "type": "array",
      "items": { "type": "number" },
      "minItems": 3,
      "maxItems": 3
    },
    "Camera": {
      "type": "object",
      "additionalProperties": false,
      "required": ["position", "focal_point", "view_up"],
      "description": "VTK-flavoured camera. Position, focal point, and view-up are world-coordinate Cartesian (Å); the focal point is what the camera looks at, view_up is its roll axis. Projection is set by exactly one of view_angle (perspective, degrees) or parallel_scale (orthographic, world units).",
      "properties": {
        "position": { "$ref": "#/$defs/Vec3" },
        "focal_point": { "$ref": "#/$defs/Vec3" },
        "view_up": { "$ref": "#/$defs/Vec3" },
        "view_angle": {
          "type": "number",
          "exclusiveMinimum": 0,
          "exclusiveMaximum": 180
        },
        "parallel_scale": { "type": "number", "exclusiveMinimum": 0 }
      },
      "oneOf": [
        {
          "required": ["view_angle"],
          "not": { "required": ["parallel_scale"] }
        },
        {
          "required": ["parallel_scale"],
          "not": { "required": ["view_angle"] }
        }
      ]
    },
    "Bookmark": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "camera"],
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "description": { "type": "string" },
        "camera": { "$ref": "#/$defs/Camera" }
      }
    },
    "Sha256Hex": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$"
    },
    "ZipPath": {
      "type": "string",
      "minLength": 1,
      "description": "Path of the member inside the zip archive. Forward slashes; no leading slash; no '..' segments.",
      "pattern": "^[^/][^\\0]*$",
      "not": { "pattern": "(^|/)\\.\\.(/|$)" }
    },
    "NumpyDtype": {
      "type": "string",
      "enum": [
        "int8",
        "int16",
        "int32",
        "int64",
        "uint8",
        "uint16",
        "uint32",
        "uint64",
        "float32",
        "float64"
      ]
    },
    "BinaryMember": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "format", "dtype", "shape", "sha256"],
      "properties": {
        "path": { "$ref": "#/$defs/ZipPath" },
        "format": { "const": "binary" },
        "dtype": { "$ref": "#/$defs/NumpyDtype" },
        "shape": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "minItems": 1
        },
        "sha256": { "$ref": "#/$defs/Sha256Hex" }
      }
    },
    "JsonMember": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "format", "sha256"],
      "properties": {
        "path": { "$ref": "#/$defs/ZipPath" },
        "format": { "const": "json" },
        "sha256": { "$ref": "#/$defs/Sha256Hex" }
      }
    },
    "Section": {
      "type": "object",
      "required": ["id", "kind", "members"],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "pattern": "^[A-Za-z0-9_.-]+$",
          "description": "Unique identifier for this section within the file."
        },
        "kind": {
          "type": "string",
          "description": "Kind string from the QVF v1 registry or x_<vendor>.* namespace."
        },
        "label": { "type": "string" },
        "component": { "type": "string" },
        "members": { "type": "object" }
      },
      "oneOf": [
        { "$ref": "#/$defs/SectionStructure" },
        { "$ref": "#/$defs/SectionVolumeDensity" },
        { "$ref": "#/$defs/SectionVolumeOrbital" },
        { "$ref": "#/$defs/SectionVolumeSpin" },
        { "$ref": "#/$defs/SectionVolumeELF" },
        { "$ref": "#/$defs/SectionVolumeDifference" },
        { "$ref": "#/$defs/SectionVolumeGeneric" },
        { "$ref": "#/$defs/SectionWavefunctionGTO" },
        { "$ref": "#/$defs/SectionAtomProperties" },
        { "$ref": "#/$defs/SectionTrajectory" },
        { "$ref": "#/$defs/SectionReactionPath" },
        { "$ref": "#/$defs/SectionReactionWaypoints" },
        { "$ref": "#/$defs/SectionVibrations" },
        { "$ref": "#/$defs/SectionSpectraIR" },
        { "$ref": "#/$defs/SectionSpectraRaman" },
        { "$ref": "#/$defs/SectionSpectraUVVis" },
        { "$ref": "#/$defs/SectionSpectraECD" },
        { "$ref": "#/$defs/SectionSpectraVCD" },
        { "$ref": "#/$defs/SectionSpectraNMR" },
        { "$ref": "#/$defs/SectionSpectraGeneric" },
        { "$ref": "#/$defs/SectionBands" },
        { "$ref": "#/$defs/SectionDOSTotal" },
        { "$ref": "#/$defs/SectionDOSProjected" },
        { "$ref": "#/$defs/SectionStructureSymmetry" },
        { "$ref": "#/$defs/SectionBonds" },
        { "$ref": "#/$defs/SectionSCFHistory" },
        { "$ref": "#/$defs/SectionCitations" },
        { "$ref": "#/$defs/SectionVendor" }
      ]
    },
    "Volume3DBinary": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "enum": ["float32", "float64"] },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "SectionStructure": {
      "properties": {
        "kind": { "const": "structure" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["structure"],
          "properties": {
            "structure": { "$ref": "#/$defs/JsonMember" },
            "bonds": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionVolumeDensity": {
      "properties": {
        "kind": { "const": "volume.density" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeOrbital": {
      "properties": {
        "kind": { "const": "volume.orbital" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeSpin": {
      "properties": {
        "kind": { "const": "volume.spin" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeELF": {
      "properties": {
        "kind": { "const": "volume.elf" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeGeneric": {
      "description": "Generic scalar field — escape hatch for any volumetric kind that doesn't map onto density/orbital/spin/elf/difference. Structurally identical: grid + data. Producers should prefer a more specific kind when one fits.",
      "properties": {
        "kind": { "const": "volume.generic" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeDifference": {
      "description": "Difference density (or any difference scalar field). Structurally identical to volume.density; carries optional references to the two operand sections used to compute it. Sign convention: data = a - b.",
      "properties": {
        "kind": { "const": "volume.difference" },
        "operand_a": {
          "type": "string",
          "description": "Section id of the minuend (the 'a' in a - b). Must reference a section that exists in this archive."
        },
        "operand_b": {
          "type": "string",
          "description": "Section id of the subtrahend (the 'b' in a - b). Must reference a section that exists in this archive."
        },
        "description": {
          "type": "string",
          "description": "Optional human-readable description, e.g. 'ρ(product) - ρ(reactant)'."
        },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      },
      "dependentRequired": {
        "operand_a": ["operand_b"],
        "operand_b": ["operand_a"]
      }
    },
    "AtomChargeBinary": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 1, "maxItems": 1 }
          }
        }
      ]
    },
    "SectionAtomProperties": {
      "properties": {
        "kind": { "const": "atom_properties" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "minProperties": 1,
          "properties": {
            "mulliken_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "loewdin_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "spin_population": { "$ref": "#/$defs/AtomChargeBinary" }
          }
        }
      }
    },
    "TrajectoryCoords": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "SectionTrajectory": {
      "properties": {
        "kind": { "const": "trajectory" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["metadata", "coords"],
          "properties": {
            "metadata": { "$ref": "#/$defs/JsonMember" },
            "coords": { "$ref": "#/$defs/TrajectoryCoords" }
          }
        }
      }
    },
    "SectionReactionPath": {
      "description": "Self-contained reaction path: frames + per-frame energies + waypoint annotations identifying reactant / transition state / intermediate / product frames. Binary layout matches `trajectory` so the same readers can decode coords.",
      "properties": {
        "kind": { "const": "reaction.path" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["metadata", "coords"],
          "properties": {
            "metadata": { "$ref": "#/$defs/JsonMember" },
            "coords": { "$ref": "#/$defs/TrajectoryCoords" }
          }
        }
      }
    },
    "SectionReactionWaypoints": {
      "description": "Lightweight waypoint annotations layered onto an existing `trajectory` section. Use this when the frames are already carried by a trajectory and you only want to label reactant/TS/intermediate/product frames without duplicating coords.",
      "properties": {
        "kind": { "const": "reaction.waypoints" },
        "trajectory_ref": {
          "type": "string",
          "description": "Section id of the trajectory section this annotation refers to. Must reference an existing section with kind 'trajectory' in this archive."
        },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["waypoints"],
          "properties": {
            "waypoints": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members", "trajectory_ref"]
    },
    "VibrationsDisplacements": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "SectionVibrations": {
      "properties": {
        "kind": { "const": "vibrations" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["metadata", "displacements"],
          "properties": {
            "metadata": { "$ref": "#/$defs/JsonMember" },
            "displacements": { "$ref": "#/$defs/VibrationsDisplacements" }
          }
        }
      }
    },
    "SectionSpectraIR": {
      "properties": {
        "kind": { "const": "spectra.ir" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraRaman": {
      "properties": {
        "kind": { "const": "spectra.raman" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "BandsEigenvalues": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "SectionSpectraUVVis": {
      "properties": {
        "kind": { "const": "spectra.uvvis" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraECD": {
      "properties": {
        "kind": { "const": "spectra.ecd" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraVCD": {
      "properties": {
        "kind": { "const": "spectra.vcd" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraNMR": {
      "properties": {
        "kind": { "const": "spectra.nmr" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraGeneric": {
      "properties": {
        "kind": { "const": "spectra.generic" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "MoCoefficientsBinary": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 2, "maxItems": 2 }
          }
        }
      ]
    },
    "SectionWavefunctionGTO": {
      "description": "Atom-centered Gaussian basis + MO coefficients, molecular only. Renderer-friendly: a re-sampling viewer can evaluate any orbital on its own grid (Molden-style). Periodic (Bloch) wavefunctions are out of scope for v1.",
      "properties": {
        "kind": { "const": "wavefunction.gto" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["basis", "mo_metadata"],
          "properties": {
            "basis": { "$ref": "#/$defs/JsonMember" },
            "mo_metadata": { "$ref": "#/$defs/JsonMember" },
            "mo_coefficients": { "$ref": "#/$defs/MoCoefficientsBinary" },
            "mo_coefficients_alpha": { "$ref": "#/$defs/MoCoefficientsBinary" },
            "mo_coefficients_beta": { "$ref": "#/$defs/MoCoefficientsBinary" }
          },
          "oneOf": [
            {
              "required": ["mo_coefficients"],
              "not": {
                "anyOf": [
                  { "required": ["mo_coefficients_alpha"] },
                  { "required": ["mo_coefficients_beta"] }
                ]
              }
            },
            {
              "required": ["mo_coefficients_alpha", "mo_coefficients_beta"],
              "not": { "required": ["mo_coefficients"] }
            }
          ]
        }
      }
    },
    "SectionBands": {
      "properties": {
        "kind": { "const": "bands" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["kpath", "eigenvalues"],
          "properties": {
            "kpath": { "$ref": "#/$defs/JsonMember" },
            "eigenvalues": { "$ref": "#/$defs/BandsEigenvalues" }
          }
        }
      }
    },
    "SectionDOSTotal": {
      "properties": {
        "kind": { "const": "dos.total" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["energies", "dos"],
          "properties": {
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "dos": { "$ref": "#/$defs/BinaryMember" }
          }
        }
      }
    },
    "SectionDOSProjected": {
      "properties": {
        "kind": { "const": "dos.projected" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["energies", "projections"],
          "properties": {
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "projections": { "$ref": "#/$defs/BinaryMember" }
          }
        }
      }
    },
    "SectionStructureSymmetry": {
      "properties": {
        "kind": { "const": "structure.symmetry" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["data"],
          "properties": {
            "data": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionBonds": {
      "properties": {
        "kind": { "const": "bonds" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["bonds"],
          "properties": {
            "bonds": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSCFHistory": {
      "properties": {
        "kind": { "const": "scf_history" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["iterations"],
          "properties": {
            "iterations": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "CitationsReferences": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "format", "sha256"],
      "description": "BibTeX bytes are carried as a binary member; consumers decode as UTF-8.",
      "properties": {
        "path": { "$ref": "#/$defs/ZipPath" },
        "format": { "const": "binary" },
        "sha256": { "$ref": "#/$defs/Sha256Hex" }
      }
    },
    "SectionCitations": {
      "properties": {
        "kind": { "const": "citations" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["references"],
          "properties": {
            "references": { "$ref": "#/$defs/CitationsReferences" }
          }
        }
      }
    },
    "SectionVendor": {
      "description": "Vendor-namespace section. The `kind` must start with `x_<vendor>`; member shape is unconstrained except that every member is a valid JsonMember or BinaryMember.",
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^x_[A-Za-z0-9_]+(\\.[A-Za-z0-9_.-]+)?$"
        },
        "members": {
          "type": "object",
          "additionalProperties": {
            "oneOf": [
              { "$ref": "#/$defs/JsonMember" },
              { "$ref": "#/$defs/BinaryMember" }
            ]
          }
        }
      }
    }
  }
}
