{
  "$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 (QVF format version 1). This file is the single source of truth for the QVF contract: where the specification prose and this schema disagree, the schema wins. The root thermochemistry, dipole_moment and constraints metadata blocks, the extensions governance block, and the per-section critical flag are optional additions within v1; archives that omit them remain valid. It also carries the payload definitions, the $defs entries whose names end in `Payload` (StructurePayload, JobSpecPayload, VolumeGridPayload, …), which specify the JSON payloads of archive members by section kind and role. Those payloads are separate archive members, so nothing in the manifest $refs them; a validator loads each member's bytes and checks them against the definition. See QVF spec § 5 (Canonical section kinds) and § 6 (Validation semantics).",
  "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."
    },
    "byte_order": {
      "const": "little",
      "description": "Byte order of every binary member of the archive. The only valid value is 'little', which every v1 archive is whether or not it declares it; any other value is invalid. A later major version moves the byte order into the dtype names. See QVF spec § 2.2 (Endianness)."
    },
    "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. Open: a key not listed here is allowed. See QVF spec § 3.2 (provenance).",
      "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" },
        "n_scf_iterations": { "type": "integer", "minimum": 0 },
        "scf_energy": { "$ref": "#/$defs/ValueWithUnits" },
        "fermi_energy": { "$ref": "#/$defs/ValueWithUnits" },
        "wall_seconds": { "type": "number", "minimum": 0 },
        "hostname": {
          "type": "string",
          "deprecated": true,
          "description": "Deprecated; see QVF spec § 3.2 (provenance). The name of the machine the calculation ran on. Producers SHOULD NOT emit it; consumers MUST ignore it for any purpose other than display and MUST NOT rely on it. Kept so that archives which already carry it remain valid; it may be removed in a future major version."
        },
        "dimensionality": { "type": "integer", "minimum": 0, "maximum": 3 },
        "run_status": {
          "enum": ["pending", "running", "converged", "failed"],
          "description": "The archive's place in a calculation's lifecycle, as defined in QVF spec § 3.2 (provenance): 'pending' = a job described (structure + job.spec) but not yet run; 'running' = a live mid-run checkpoint snapshot; 'converged' / 'failed' = a settled terminal archive. Absent means 'not stated' — a consumer MUST NOT infer a status."
        },
        "software": {
          "type": "array",
          "items": { "$ref": "#/$defs/ProvenanceSoftware" },
          "description": "The programs and libraries that produced the results, one object per component: the program itself, the integral library it called, and so on. Each names the component and may give its version and its home page; see QVF spec § 3.2 (provenance). The root `source` names the QVF producer, and this list names every component that shaped the numbers."
        },
        "git_commit": {
          "type": "string",
          "pattern": "^[0-9a-fA-F]{7,64}$",
          "description": "The producer's own source revision: a git commit hash of 7 to 64 hexadecimal characters, so an abbreviated hash, a 40-character SHA-1 or a 64-character SHA-256 hash. Git prints lowercase; see QVF spec § 3.2 (provenance)."
        },
        "n_threads": {
          "type": "integer",
          "minimum": 1,
          "description": "Number of threads the calculation ran with, per process; see QVF spec § 3.2 (provenance)."
        },
        "n_mpi_ranks": {
          "type": "integer",
          "minimum": 1,
          "description": "Number of MPI ranks (processes) the calculation ran with; 1 for a serial run. See QVF spec § 3.2 (provenance)."
        },
        "n_gpus": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of GPUs the calculation used; 0 for a run that used none. See QVF spec § 3.2 (provenance)."
        },
        "started_utc": {
          "type": "string",
          "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?Z$",
          "description": "When the calculation started: an ISO 8601 date and time in UTC, YYYY-MM-DDThh:mm:ssZ with an optional fractional second, e.g. '2026-10-07T12:00:00Z'; see QVF spec § 3.2 (provenance)."
        },
        "finished_utc": {
          "type": "string",
          "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?Z$",
          "description": "When the calculation finished, in the form of `started_utc`; see QVF spec § 3.2 (provenance)."
        }
      }
    },
    "metadata": {
      "$ref": "#/$defs/Metadata",
      "description": "Optional descriptive metadata of the archive as a whole: title, authors, licence, identifiers and time stamps; see QVF spec § 3.5 (Root metadata)."
    },
    "viewer_defaults": {
      "type": "object",
      "description": "Hints for consumers that render the archive; see QVF spec § 3.4 (viewer_defaults). The members auto_open, bookmarks, camera and crossfade are reserved and no section may use one as its id; every other key is a section id whose value is that section's hint 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" }
        },
        "camera": {
          "description": "The camera a consumer starts with, an object in the shape of #/$defs/Camera. Specified in QVF spec § 3.4 (viewer_defaults) only: the schema does not check the value, so a malformed camera never makes an archive invalid, and a consumer ignores one it cannot use."
        },
        "crossfade": {
          "description": "Two scalar-field sections to cross-fade between and the initial position of the blend: {a, b, blend?}, where a and b are section ids and blend is a number from 0 to 1, default 0.5. Specified in QVF spec § 3.4 (viewer_defaults) only: the schema does not check the value, so a malformed cross-fade never makes an archive invalid, and a consumer ignores one it cannot use."
        }
      }
    },
    "thermochemistry": {
      "$ref": "#/$defs/Thermochemistry",
      "description": "Optional thermochemical corrections at manifest root; see QVF spec § 3.3 (Root metadata blocks)."
    },
    "dipole_moment": {
      "$ref": "#/$defs/DipoleMoment",
      "description": "Optional dipole moment at manifest root; see QVF spec § 3.3 (Root metadata blocks)."
    },
    "constraints": {
      "$ref": "#/$defs/Constraints",
      "description": "Optional geometry optimisation constraints at manifest root; see QVF spec § 3.3 (Root metadata blocks)."
    },
    "energies": {
      "$ref": "#/$defs/Energies",
      "description": "Optional energies of the calculation at manifest root: the energy of the primary result, its components, and energies by further methods; see QVF spec § 3.6 (Root energies)."
    },
    "extensions": {
      "$ref": "#/$defs/Extensions",
      "description": "Optional extension governance block declaring vendor extensions in use; see QVF spec § 7.4 (Root extensions block and per-section critical)."
    },
    "sections": {
      "type": "array",
      "items": { "$ref": "#/$defs/Section" }
    }
  },
  "$defs": {
    "ValueWithUnits": {
      "type": "object",
      "additionalProperties": false,
      "required": ["value", "units"],
      "properties": {
        "value": { "type": "number" },
        "units": {
          "oneOf": [
            { "$ref": "#/$defs/UnitName" },
            { "$ref": "#/$defs/LegacyUnitName" }
          ],
          "description": "Unit of `value`: a unit name, or one of the legacy spellings that archives written before the vocabulary carry. Producers write the unit name; see QVF spec § 4.3 (Units and numeric conventions)."
        }
      }
    },
    "UnitName": {
      "enum": [
        "angstrom", "bohr", "hartree", "ev", "kcal_per_mol", "kj_per_mol",
        "cm-1", "nm", "debye", "mhz", "hz", "ppm", "km_per_mol", "a3", "bohr3",
        "gpa", "fs", "ps", "kelvin", "atm", "e", "amu", "radian", "degree",
        "dimensionless"
      ],
      "description": "A unit name of the QVF unit vocabulary, the controlled list of unit strings in QVF spec § 4.3 (Units and numeric conventions), which lists the same names in the same order with the quantity and definition of each. Names are case-sensitive. Every `units` object, `x_units`, `y_units` and `broadening.units` of a member payload, and the `units` of a {value, units} object, names its unit with one of these."
    },
    "LegacyUnitName": {
      "enum": ["Eh", "eV", "Hartree"],
      "deprecated": true,
      "description": "Deprecated spellings that a {value, units} object (ValueWithUnits) still accepts, because archives written before the unit vocabulary carry them: `Eh` and `Hartree` mean `hartree`, `eV` means `ev`. Producers write the unit name instead; consumers read a legacy spelling as the unit it names. Nowhere else is a legacy spelling a unit name; see QVF spec § 4.3 (Units and numeric conventions)."
    },
    "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"
      ]
    },
    "MemberSize": {
      "type": "integer",
      "minimum": 0,
      "description": "Uncompressed byte count of the stored member: it must equal the uncompressed size the ZIP central directory records for the member's entry, which a validator checks before reading the member. Optional on every member spec. See QVF spec § 4.2 (Member specs)."
    },
    "MediaType": {
      "type": "string",
      "pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*$",
      "description": "IANA media type of the member's bytes, a type and a subtype without parameters (RFC 6838), e.g. 'image/png' or 'text/plain'. Optional on every member spec; it describes the bytes and changes nothing in how they are read. A kind may require it, as `preview` does. See QVF spec § 4.2 (Member specs)."
    },
    "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" },
        "size": { "$ref": "#/$defs/MemberSize" },
        "media_type": { "$ref": "#/$defs/MediaType" }
      }
    },
    "JsonMember": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "format", "sha256"],
      "properties": {
        "path": { "$ref": "#/$defs/ZipPath" },
        "format": { "const": "json" },
        "sha256": { "$ref": "#/$defs/Sha256Hex" },
        "size": { "$ref": "#/$defs/MemberSize" },
        "media_type": { "$ref": "#/$defs/MediaType" }
      }
    },
    "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 registry or x_<vendor>.* namespace."
        },
        "label": { "type": "string" },
        "component": { "type": "string" },
        "critical": {
          "type": "boolean",
          "default": false,
          "description": "If true, a consumer that does not support this kind MUST refuse to open the archive; see QVF spec § 7.4 (Root extensions block and per-section critical)."
        },
        "structure_ref": {
          "type": "string",
          "description": "Id of the `structure` section this section describes. It must name a section of kind `structure` in this archive. When one of the section's payloads also carries a `structure_ref` (the `basis` of a `wavefunction.gto`), this one takes precedence; see QVF spec § 4.1 (Section object)."
        },
        "run_ref": {
          "type": "string",
          "description": "Id of the `run.record` section of the program run that produced this section. It must name a section of kind `run.record` in this archive; see QVF spec § 4.1 (Section object)."
        },
        "group": {
          "type": "string",
          "description": "Free-text label that groups related sections for display, e.g. 'step 2: frequencies'. Sections with equal `group` values belong together; the value carries no other meaning; see QVF spec § 4.1 (Section object)."
        },
        "members": { "type": "object" }
      },
      "oneOf": [
        { "$ref": "#/$defs/SectionStructure" },
        { "$ref": "#/$defs/SectionVolumeDensity" },
        { "$ref": "#/$defs/SectionVolumeOrbital" },
        { "$ref": "#/$defs/SectionVolumeSpin" },
        { "$ref": "#/$defs/SectionVolumeELF" },
        { "$ref": "#/$defs/SectionVolumeDifference" },
        { "$ref": "#/$defs/SectionVolumePotential" },
        { "$ref": "#/$defs/SectionVolumeRDG" },
        { "$ref": "#/$defs/SectionVolumeGeneric" },
        { "$ref": "#/$defs/SectionVolumeLaplacian" },
        { "$ref": "#/$defs/SectionVolumeVector" },
        { "$ref": "#/$defs/SectionVolumeComplex" },
        { "$ref": "#/$defs/SectionVolumeSeries" },
        { "$ref": "#/$defs/SectionWavefunctionGTO" },
        { "$ref": "#/$defs/SectionWavefunctionBloch" },
        { "$ref": "#/$defs/SectionAtomProperties" },
        { "$ref": "#/$defs/SectionTrajectory" },
        { "$ref": "#/$defs/SectionReactionPath" },
        { "$ref": "#/$defs/SectionReactionWaypoints" },
        { "$ref": "#/$defs/SectionReactionScheme" },
        { "$ref": "#/$defs/SectionScanSurface" },
        { "$ref": "#/$defs/SectionVibrations" },
        { "$ref": "#/$defs/SectionSpectraIR" },
        { "$ref": "#/$defs/SectionSpectraRaman" },
        { "$ref": "#/$defs/SectionSpectraUVVis" },
        { "$ref": "#/$defs/SectionSpectraECD" },
        { "$ref": "#/$defs/SectionSpectraVCD" },
        { "$ref": "#/$defs/SectionSpectraNMR" },
        { "$ref": "#/$defs/SectionSpectraEPR" },
        { "$ref": "#/$defs/SectionSpectraGeneric" },
        { "$ref": "#/$defs/SectionBands" },
        { "$ref": "#/$defs/SectionDOSTotal" },
        { "$ref": "#/$defs/SectionDOSProjected" },
        { "$ref": "#/$defs/SectionDOSCOOP" },
        { "$ref": "#/$defs/SectionDOSCOHP" },
        { "$ref": "#/$defs/SectionStructureSymmetry" },
        { "$ref": "#/$defs/SectionBonds" },
        { "$ref": "#/$defs/SectionBondOrders" },
        { "$ref": "#/$defs/SectionSCFHistory" },
        { "$ref": "#/$defs/SectionCitations" },
        { "$ref": "#/$defs/SectionRunRecord" },
        { "$ref": "#/$defs/SectionJobSpec" },
        { "$ref": "#/$defs/SectionBasisAO" },
        { "$ref": "#/$defs/SectionEquationOfState" },
        { "$ref": "#/$defs/SectionFermiSurface" },
        { "$ref": "#/$defs/SectionPhononBands" },
        { "$ref": "#/$defs/SectionPhononDOS" },
        { "$ref": "#/$defs/SectionTopologyQTAIM" },
        { "$ref": "#/$defs/SectionForces" },
        { "$ref": "#/$defs/SectionHessian" },
        { "$ref": "#/$defs/SectionExcitedStates" },
        { "$ref": "#/$defs/SectionVolumeTransitionDensity" },
        { "$ref": "#/$defs/SectionPreview" },
        { "$ref": "#/$defs/SectionPropertiesElectric" },
        { "$ref": "#/$defs/SectionPropertiesElastic" },
        { "$ref": "#/$defs/SectionPropertiesDielectric" },
        { "$ref": "#/$defs/SectionVendor" }
      ]
    },
    "Volume3DBinary": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "enum": ["float32", "float64"] },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "Volume4DBinary": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "enum": ["float32", "float64"] },
            "shape": { "minItems": 4, "maxItems": 4 }
          }
        }
      ]
    },
    "Volume4DVectorBinary": {
      "description": "The `data` member of a `volume.vector` section: float32 or float64 [nx, ny, nz, 3], one Cartesian vector per grid point, the last axis holding its x, y and z components. That the leading three extents equal the grid `shape` is not checked by this schema. See QVF spec § 5.2 (volume.*).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "enum": ["float32", "float64"] },
            "shape": {
              "minItems": 4,
              "maxItems": 4,
              "prefixItems": [{}, {}, {}, { "const": 3 }]
            }
          }
        }
      ]
    },
    "Volume4DComplexBinary": {
      "description": "The `data` member of a `volume.complex` section: float32 or float64 [nx, ny, nz, 2], one complex value per grid point, the last axis holding [re, im] as for complex phonon eigenvectors. See QVF spec § 5.2 (volume.*).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "enum": ["float32", "float64"] },
            "shape": {
              "minItems": 4,
              "maxItems": 4,
              "prefixItems": [{}, {}, {}, { "const": 2 }]
            }
          }
        }
      ]
    },
    "StructureAtom": {
      "type": "object",
      "additionalProperties": true,
      "required": ["symbol", "position", "atomic_number"],
      "description": "One atom of a `structure` payload. `position` is Cartesian, in Ångström — real coordinates, never fractional. Producers may add further per-atom fields; consumers ignore what they don't understand. Biomolecular producers conventionally add `atom_name` (PDB cols 13-16, e.g. \"CA\"), `residue_name` (cols 18-20), `residue_seq` (cols 23-26), `chain_id` (col 22) and `b_factor` (cols 61-66); of these only `b_factor` is typed here, because the other four predate this schema and archives in the wild carry `residue_seq` both as an integer and as a string.",
      "properties": {
        "symbol": { "type": "string", "minLength": 1, "maxLength": 3 },
        "position": { "$ref": "#/$defs/Vec3" },
        "atomic_number": { "type": "integer", "minimum": 0 },
        "b_factor": { "type": "number", "description": "Per-atom temperature factor / pLDDT-style confidence (PDB cols 61-66). The per-atom carrier is authoritative over the section-level `b_factors` array, because it cannot desynchronize from its own atom; see QVF spec § 5.1 (structure and bonds)." }
      }
    },
    "Lattice3x3": {
      "type": "array",
      "minItems": 3,
      "maxItems": 3,
      "items": { "$ref": "#/$defs/Vec3" },
      "description": "Lattice as three ROW vectors in Ångström: row i is the lattice vector of axis i, paired with pbc[i]."
    },
    "StructurePayload": {
      "type": "object",
      "additionalProperties": true,
      "required": ["atoms"],
      "description": "The JSON payload named by a `structure` section's `structure` member (conventionally `structure/structure.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. `pbc` is the normative carrier of per-axis periodicity; `dimensionality` is a derived convenience. See QVF spec § 5.1 (structure and bonds).",
      "properties": {
        "atoms": {
          "type": "array",
          "items": { "$ref": "#/$defs/StructureAtom" }
        },
        "pbc": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "type": "boolean" },
          "description": "Per-axis periodicity: axis i is periodic iff pbc[i]. REQUIRED when `lattice_vectors` is a non-null array; absent means a molecule ([false, false, false]). All eight patterns are legal — the periodic axes need NOT be the leading ones.",
          "default": [false, false, false]
        },
        "lattice_vectors": {
          "oneOf": [{ "$ref": "#/$defs/Lattice3x3" }, { "type": "null" }],
          "description": "REQUIRED (non-null) when any pbc[i] is true; null or absent for a molecule. For every axis i with pbc[i] false, row i is non-physical bookkeeping — producers keep the matrix full-rank 3x3 so integrals and symmetry finders always see a 3-D lattice. Such a row is not a cell edge: a consumer MUST NOT draw it, replicate along it, or read it as a vacuum extent."
        },
        "dimensionality": {
          "type": "integer",
          "minimum": 0,
          "maximum": 3,
          "description": "Derived count of periodic axes: equal to the number of true entries in `pbc`. Optional, and MUST agree when present. It carries no axis identity — a consumer MUST NOT infer WHICH axes are periodic from it."
        }
      },
      "allOf": [
        {
          "$comment": "A non-null lattice means the producer is describing a cell, so `pbc` must say which of its axes are periodic.",
          "if": {
            "required": ["lattice_vectors"],
            "properties": { "lattice_vectors": { "type": "array" } }
          },
          "then": { "required": ["pbc"] }
        },
        {
          "$comment": "Conversely, a periodic axis needs the lattice vector that spans it.",
          "if": {
            "required": ["pbc"],
            "properties": { "pbc": { "contains": { "const": true } } }
          },
          "then": {
            "required": ["lattice_vectors"],
            "properties": { "lattice_vectors": { "type": "array" } }
          }
        },
        {
          "$comment": "dimensionality == sum(pbc), enumerated over 0..3 because JSON Schema counts matching items with minContains/maxContains rather than summing them.",
          "if": {
            "required": ["dimensionality"],
            "properties": { "dimensionality": { "const": 0 } }
          },
          "then": {
            "properties": { "pbc": { "not": { "contains": { "const": true } } } }
          }
        },
        {
          "if": {
            "required": ["dimensionality"],
            "properties": { "dimensionality": { "const": 1 } }
          },
          "then": {
            "required": ["pbc"],
            "properties": {
              "pbc": {
                "contains": { "const": true },
                "minContains": 1,
                "maxContains": 1
              }
            }
          }
        },
        {
          "if": {
            "required": ["dimensionality"],
            "properties": { "dimensionality": { "const": 2 } }
          },
          "then": {
            "required": ["pbc"],
            "properties": {
              "pbc": {
                "contains": { "const": true },
                "minContains": 2,
                "maxContains": 2
              }
            }
          }
        },
        {
          "if": {
            "required": ["dimensionality"],
            "properties": { "dimensionality": { "const": 3 } }
          },
          "then": {
            "required": ["pbc"],
            "properties": {
              "pbc": {
                "contains": { "const": true },
                "minContains": 3,
                "maxContains": 3
              }
            }
          }
        }
      ]
    },
    "BiomoleculeResidue": {
      "type": "object",
      "additionalProperties": true,
      "required": ["name", "seq", "chain", "atom_indices"],
      "description": "One residue of a biomolecular `structure` section. `atom_indices` are 0-based indices into the `structure` member payload's `atoms` array. Residues are listed in chain order — the order a consumer draws a ribbon in — not sorted by `seq`, because insertion codes and non-monotonic numbering are both legal and sorting would silently reorder them. See QVF spec § 5.1 (structure and bonds).",
      "properties": {
        "name": { "type": "string", "description": "Residue name, e.g. \"GLY\"." },
        "seq": { "type": "integer", "description": "Residue sequence number (PDB cols 23-26). Not unique across a solvated system: PDB numbering is four columns wide and wraps at 9999, so a consumer MUST NOT use it as a global key." },
        "chain": { "type": "string", "description": "Chain id this residue belongs to; matches an entry of the section's `chains` when that is present." },
        "atom_indices": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "0-based indices into the structure payload's `atoms` array."
        }
      }
    },
    "BiomoleculeSecondaryStructure": {
      "type": "object",
      "additionalProperties": true,
      "required": ["type", "chain", "start_seq", "end_seq"],
      "description": "One inclusive secondary-structure range on one chain. A producer knows things a consumer cannot infer from CA geometry alone (alpha vs pi vs 3-10 helix, beta bridge vs sheet), so a consumer that also has its own geometric assignment MUST prefer these ranges where they are supplied; see QVF spec § 5.1 (structure and bonds).",
      "properties": {
        "type": { "enum": ["helix", "sheet", "coil"] },
        "chain": { "type": "string" },
        "start_seq": { "type": "integer", "description": "First residue `seq` of the range, inclusive." },
        "end_seq": { "type": "integer", "description": "Last residue `seq` of the range, inclusive." }
      }
    },
    "SectionStructure": {
      "description": "Atoms plus an optional cell. The `structure` member's JSON payload is specified by `#/$defs/StructurePayload` and the optional `bonds` member's by `#/$defs/BondsPayload`; because they are archive members rather than manifest content, a validator checks them separately from manifest.json; see QVF spec § 5.1 (structure and bonds) and § 6 (Validation semantics). The optional biomolecule fields (`chains`, `residues`, `secondary_structure`, `b_factors`) sit on this section object rather than in the payload, and are independently optional: a structure carrying none of them is a valid plain structure, and a consumer that does not understand them ignores them. So do the optional fields of the species' chemical identity (`charge`, `multiplicity`, `name`, `smiles`, `inchi`, `inchikey`; the generic `label` is its compound label); see QVF spec § 5.1 (structure and bonds), under Chemical identity.",
      "properties": {
        "kind": { "const": "structure" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["structure"],
          "properties": {
            "structure": { "$ref": "#/$defs/JsonMember" },
            "bonds": { "$ref": "#/$defs/JsonMember" }
          }
        },
        "chains": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Chain ids present in this structure, in the order a consumer should present them. OPTIONAL and additive."
        },
        "residues": {
          "type": "array",
          "items": { "$ref": "#/$defs/BiomoleculeResidue" },
          "description": "Residue decomposition of the structure, in chain order. OPTIONAL and additive. A consumer that can also derive residues from per-atom fields MUST prefer these when present."
        },
        "secondary_structure": {
          "type": "array",
          "items": { "$ref": "#/$defs/BiomoleculeSecondaryStructure" },
          "description": "Per-chain secondary-structure ranges. OPTIONAL and additive; takes precedence over a consumer's own geometric assignment."
        },
        "b_factors": {
          "type": "array",
          "items": { "type": "number" },
          "description": "One temperature factor per atom, parallel to the `structure` payload's `atoms` order. OPTIONAL and additive. A consumer MUST ignore the array entirely when its length differs from the atom count, rather than assigning a partial mapping; and per-atom `StructureAtom.b_factor`, where present, wins over this array."
        },
        "charge": {
          "type": "integer",
          "description": "Net charge of the species whose atoms the `structure` payload holds, in units of the elementary charge. Absent states nothing (not neutral). With the payload's atomic numbers it gives the electron count, which must not be negative; in an archive with one `structure` section it must equal `provenance.charge` when both are present. See QVF spec § 5.1 (structure and bonds), under Chemical identity."
        },
        "multiplicity": {
          "type": "integer",
          "minimum": 1,
          "description": "Spin multiplicity 2S+1 of the species. With `charge`, multiplicity − 1 must not exceed the electron count and must have its parity; in an archive with one `structure` section it must equal `provenance.multiplicity` when both are present. See QVF spec § 5.1 (structure and bonds), under Chemical identity."
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "Name of the species, e.g. 'ethanol'. The generic `label` is the short label a scheme shows, such as a compound number. See QVF spec § 5.1 (structure and bonds), under Chemical identity."
        },
        "smiles": {
          "type": "string",
          "pattern": "^\\S+$",
          "description": "SMILES of the species, hydrogens implied or explicit. It names the species as a whole and implies no atom order. See QVF spec § 5.1 (structure and bonds), under Chemical identity."
        },
        "inchi": {
          "type": "string",
          "pattern": "^InChI=\\S+$",
          "description": "InChI of the species, standard ('InChI=1S/…') or not. See QVF spec § 5.1 (structure and bonds), under Chemical identity."
        },
        "inchikey": {
          "type": "string",
          "pattern": "^[A-Z]{14}-[A-Z]{10}-[A-Z]$",
          "description": "InChIKey of the species. See QVF spec § 5.1 (structure and bonds), under Chemical identity."
        }
      }
    },
    "SectionVolumeDensity": {
      "properties": {
        "kind": { "const": "volume.density" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "VolumeGridPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["origin", "voxel_vectors", "shape"],
      "description": "The JSON payload named by the `grid` member of every volume.* section and of a `basis.ao` section, and by the `volume_grid` member of a `reaction.path` section (conventionally `volumes/<section id>_grid.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. The grid is point-centred: data index (i, j, k) lies at origin + i·v_i + j·v_j + k·v_k, so the data holds exactly `shape` points. Along an axis a that `periodic` marks, the grid samples one period of the cell of its structure: voxel_vectors[a] × (shape[a] − 1) spans lattice vector a when `includes_endpoint` is true (the default, cube style: the last plane repeats the first), and voxel_vectors[a] × shape[a] spans it when `includes_endpoint` is false (CHGCAR style); validators check the span. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.2 (volume.*).",
      "properties": {
        "origin": {
          "$ref": "#/$defs/Vec3",
          "description": "Cartesian position of grid point (0, 0, 0), in bohr."
        },
        "voxel_vectors": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "$ref": "#/$defs/Vec3" },
          "description": "The step vectors v_i, v_j, v_k, in bohr: row n is the displacement between neighbouring points along data axis n. Non-zero off-diagonal components describe a non-orthogonal grid."
        },
        "shape": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "type": "integer", "minimum": 1 },
          "description": "Number of points [nx, ny, nz] along the three spatial data axes. It equals the shape of the section's 3-D `data` member, the leading three dimensions of a `volume.vector` or `volume.complex` `data` member, or the trailing three dimensions of a `volume.series` `data` member or of a `reaction.path` section's `frame_volumes` member."
        },
        "periodic": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "type": "boolean" },
          "default": [false, false, false],
          "description": "Per-axis periodicity of the sampled field: periodic[a] true means the field repeats with lattice vector a of the grid's structure along data axis a, so a consumer may tile or wrap the grid along it. Absent means [false, false, false], a finite box. An axis may be periodic only where the structure's `pbc` is true, and voxel_vectors[a] must then span lattice vector a as `includes_endpoint` says; see QVF spec § 5.2 (volume.*)."
        },
        "includes_endpoint": {
          "type": "boolean",
          "default": true,
          "description": "Whether the points along a periodic axis include the endpoint of the period. true (the default, cube-file style): the last plane is the image of the first, shape[a] − 1 steps span one period, and a consumer that tiles or wraps the grid MUST drop the duplicated plane. false (CHGCAR style): shape[a] distinct planes span one period, exclusive of the endpoint. It matters only on periodic axes; see QVF spec § 5.2 (volume.*)."
        },
        "structure_ref": {
          "type": "string",
          "description": "Id of the `structure` section whose cell the grid samples. It must name a section of kind `structure` in the archive. The section-level `structure_ref` takes precedence when both are present; with neither, the archive's only `structure` section is the grid's structure. See QVF spec § 5.2 (volume.*)."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional declaration of units: each key names a field of this payload or the role of a member of the section, each value a unit name. `origin` and `voxel_vectors` are fixed to `bohr`, and a declaration restates that; see QVF spec § 4.3 (Units and numeric conventions).",
          "properties": {
            "origin": { "const": "bohr" },
            "voxel_vectors": { "const": "bohr" }
          }
        }
      }
    },
    "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"]
      }
    },
    "SectionVolumePotential": {
      "description": "Electrostatic potential grid — identical member structure to volume.density (grid + data). Data is in hartree/e (atomic units of potential). Specified in QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": { "const": "volume.potential" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeRDG": {
      "description": "Reduced density gradient for NCI analysis — identical member structure to volume.density (grid + data). Data is dimensionless. Specified in QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": { "const": "volume.rdg" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeLaplacian": {
      "description": "Laplacian of the electron density, ∇²ρ, in e/bohr⁵: negative where charge concentrates, positive where it is depleted. Identical member structure to volume.density (grid + 3-D data). The vocabulary has no unit name for e/bohr⁵, so the grid does not declare `units.data` for it. See QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": { "const": "volume.laplacian" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionVolumeVector": {
      "description": "A Cartesian vector field on a grid, such as a density gradient, an electric field or a current density: `data` is [nx, ny, nz, 3] with the x, y and z components on the last axis, in the Cartesian frame of the grid `origin`. Its unit is that of the field, which the grid declares as `units.data` when the vocabulary names it. The section field `component` is not used. See QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": { "const": "volume.vector" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume4DVectorBinary" }
          }
        }
      }
    },
    "SectionVolumeComplex": {
      "description": "A complex scalar field on a grid, such as a complex orbital or a Bloch function at one k-point: `data` is [nx, ny, nz, 2] with the last axis [re, im]. See QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": { "const": "volume.complex" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume4DComplexBinary" }
          }
        }
      }
    },
    "SectionVolumeSeries": {
      "description": "A series of n scalar fields on one grid, indexed by time, trajectory frame, electronic state or another quantity: `data` is [n, nx, ny, nz], slab s holding the field at the axis value `axis.values[s]`, and the required `axis` member says what the leading axis is. It supersedes, without deprecating, the `frame_volumes` + `volume_grid` members of a `reaction.path` section. See QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": { "const": "volume.series" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data", "axis"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume4DBinary" },
            "axis": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "VolumeSeriesAxisPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["kind", "values"],
      "description": "The JSON payload named by the `axis` member of a `volume.series` section (conventionally `volumes/<section id>_axis.json`): what indexes the leading axis of the section's `data` member, one entry per slab. It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": {
          "enum": ["time", "frame", "state", "custom"],
          "description": "What indexes the slabs: `time` (the values are times), `frame` (0-based frame indices of the trajectory or reaction path named by `trajectory_ref`), `state` (electronic states, the values being state indices or energies) or `custom` (anything else, which `labels` describe)."
        },
        "values": {
          "type": "array",
          "items": { "type": "number" },
          "description": "The axis value of each slab, in slab order. It has n entries, n being the leading extent of `data`, which validators check."
        },
        "units": {
          "$ref": "#/$defs/UnitName",
          "description": "Unit of `values`, a unit name. Absent means the values are pure numbers (`dimensionless`), as frame and state indices are; a time axis should declare its unit (`fs` or `ps`)."
        },
        "labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Display label of each slab, n entries, e.g. \"S1\" for an excited state."
        },
        "trajectory_ref": {
          "type": "string",
          "description": "Id of the `trajectory` or `reaction.path` section whose frames the slabs belong to; the frame indices of a `frame` axis index its `coords`. It must name a section of one of those two kinds."
        }
      },
      "allOf": [
        {
          "$comment": "A frame axis counts frames, so its values are 0-based frame indices.",
          "if": {
            "required": ["kind"],
            "properties": { "kind": { "const": "frame" } }
          },
          "then": {
            "properties": { "values": { "items": { "type": "integer", "minimum": 0 } } }
          }
        }
      ]
    },
    "AtomChargeBinary": {
      "description": "A per-atom scalar array: float64, shape [n_atoms]. Used by the scalar roles of an `atom_properties` section and by a scalar `custom.<name>` role. Specified in QVF spec § 5.7 (Analysis kinds).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 1, "maxItems": 1 }
          }
        }
      ]
    },
    "AtomVectorBinary": {
      "description": "A per-atom Cartesian vector array: float64, shape [n_atoms, 3]. Used by the vector roles `magnetic_moment` and `force_eh_bohr` of an `atom_properties` section and by a vector `custom.<name>` role. Specified in QVF spec § 5.7 (Analysis kinds).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": {
              "minItems": 2,
              "maxItems": 2,
              "prefixItems": [ true, { "const": 3 } ]
            }
          }
        }
      ]
    },
    "AtomPropertyMetaEntry": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["units", "description", "kind"],
      "description": "The description of one `custom.<name>` role in the `meta` member of an `atom_properties` section. Strict: only the fields below and keys beginning with x_ are allowed. See QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "units": {
          "$ref": "#/$defs/UnitName",
          "minLength": 1,
          "description": "The unit of the role's values, spelled as in QVF spec § 4.3 (Units and numeric conventions) where that gives a spelling; `dimensionless` for a pure number."
        },
        "description": {
          "type": "string",
          "minLength": 1,
          "description": "What the quantity is, including any sign convention."
        },
        "kind": {
          "enum": ["scalar", "vector"],
          "description": "`scalar` for a float64 [n_atoms] member, `vector` for a float64 [n_atoms, 3] member."
        }
      }
    },
    "AtomPropertiesMetaPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^custom\\.[A-Za-z0-9_]+$": { "$ref": "#/$defs/AtomPropertyMetaEntry" },
        "^x_": {}
      },
      "description": "The JSON payload of the `meta` member of an `atom_properties` section: a map from the name of a `custom.<name>` role to its description. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only entries named by a `custom.<name>` role and keys beginning with x_ are allowed. See QVF spec § 5.7 (Analysis kinds)."
    },
    "SectionAtomProperties": {
      "description": "Per-atom analysis results. The member roles are the one canonical role list: the scalar roles `mulliken_charge`, `loewdin_charge`, `hirshfeld_charge`, `iao_charge`, `spin_population`, `cm5_charge`, `chelpg_charge`, `resp_charge`, `esp_charge`, `nbo_charge`, `mbis_charge`, `bader_charge`, `ddec_charge`, `valence`, `bonded_valence`, `fukui_plus`, `fukui_minus`, `fukui_zero`, `dual_descriptor`, `atomic_energy_eh`, `atomic_volume_bohr3`, `nmr_shielding_iso_ppm`, each float64 [n_atoms], and the vector roles `magnetic_moment` and `force_eh_bohr`, each float64 [n_atoms, 3]. A section carries one or more of them, plus any number of `custom.<name>` roles (scalar or vector), which are allowed only together with a `meta` member that describes each of them. Specified in QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "kind": { "const": "atom_properties" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "minProperties": 1,
          "not": { "required": ["meta"], "maxProperties": 1 },
          "if": { "not": { "patternProperties": { "^custom\\.": false } } },
          "then": { "required": ["meta"] },
          "properties": {
            "mulliken_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "loewdin_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "hirshfeld_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "iao_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "spin_population": { "$ref": "#/$defs/AtomChargeBinary" },
            "cm5_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "chelpg_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "resp_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "esp_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "nbo_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "mbis_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "bader_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "ddec_charge": { "$ref": "#/$defs/AtomChargeBinary" },
            "valence": { "$ref": "#/$defs/AtomChargeBinary" },
            "bonded_valence": { "$ref": "#/$defs/AtomChargeBinary" },
            "fukui_plus": { "$ref": "#/$defs/AtomChargeBinary" },
            "fukui_minus": { "$ref": "#/$defs/AtomChargeBinary" },
            "fukui_zero": { "$ref": "#/$defs/AtomChargeBinary" },
            "dual_descriptor": { "$ref": "#/$defs/AtomChargeBinary" },
            "atomic_energy_eh": { "$ref": "#/$defs/AtomChargeBinary" },
            "atomic_volume_bohr3": { "$ref": "#/$defs/AtomChargeBinary" },
            "nmr_shielding_iso_ppm": { "$ref": "#/$defs/AtomChargeBinary" },
            "magnetic_moment": { "$ref": "#/$defs/AtomVectorBinary" },
            "force_eh_bohr": { "$ref": "#/$defs/AtomVectorBinary" },
            "meta": { "$ref": "#/$defs/JsonMember" }
          },
          "patternProperties": {
            "^custom\\.[A-Za-z0-9_]+$": {
              "anyOf": [
                { "$ref": "#/$defs/AtomChargeBinary" },
                { "$ref": "#/$defs/AtomVectorBinary" }
              ]
            }
          }
        }
      }
    },
    "TrajectoryCoords": {
      "description": "Cartesian positions of every atom in every frame, [n_frames, n_atoms, 3], in Angstrom. float64, or float32 when the section's metadata sets `precision` to \"float32\"; that the dtype agrees with `precision` is checked by validators, not by this schema. See QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "enum": ["float64", "float32"] },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "TrajectoryFrameVectors": {
      "description": "One 3-vector per atom per frame, float64 [n_frames, n_atoms, 3], in the atom and frame order of `coords`: the `velocities` (Angstrom/fs) and `gradient` (hartree/bohr) members of a trajectory or reaction path. That n_frames and n_atoms equal the extents of `coords` is checked by validators, not by this schema. See QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3, "prefixItems": [{}, {}, { "const": 3 }] }
          }
        }
      ]
    },
    "TrajectoryFrameScalars": {
      "description": "One number per frame, float64 [n_frames], in the frame order of `coords`: the `times` (fs), `energies` (hartree), `cell_volumes` (Angstrom^3) and `temperatures` (kelvin) members of a trajectory, and the `times` and `energies` of a reaction path. That n_frames equals the leading extent of `coords` is checked by validators, not by this schema. See QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 1, "maxItems": 1 }
          }
        }
      ]
    },
    "TrajectoryLattice": {
      "description": "The cell of a periodic trajectory, float64, in the structure convention: each [3, 3] matrix holds the lattice vectors as ROWS (row i is the lattice vector of axis i, paired with metadata.pbc[i]), in Angstrom, exactly as `structure.lattice_vectors`. Shape [3, 3] when every frame shares one cell, or [n_frames, 3, 3] with one cell per frame (variable-cell and NPT runs). This is NOT the convention of the `lattice` member of a reaction path (columns, bohr); QVF spec § 4.3 (Units and numeric conventions) states both. A trajectory that carries this member MUST carry metadata.pbc. That n_frames equals the leading extent of `coords` is checked by validators. See QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": {
              "oneOf": [
                {
                  "type": "array",
                  "minItems": 2,
                  "maxItems": 2,
                  "prefixItems": [{ "const": 3 }, { "const": 3 }]
                },
                {
                  "type": "array",
                  "minItems": 3,
                  "maxItems": 3,
                  "prefixItems": [
                    { "type": "integer", "minimum": 1 },
                    { "const": 3 },
                    { "const": 3 }
                  ]
                }
              ]
            }
          }
        }
      ]
    },
    "SectionTrajectory": {
      "description": "A sequence of frames of one set of atoms: an optimization, an IRC, a scan, a NEB or a molecular-dynamics run. `metadata` names the atoms and `coords` holds the positions; the optional members add per-frame data: the cell (`lattice`, rows in Angstrom), `velocities`, the energy `gradient` (the forces are its negative), `times`, `energies`, `cell_volumes` and `temperatures`. Every per-frame member has the leading extent of `coords`. See QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "kind": { "const": "trajectory" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["metadata", "coords"],
          "properties": {
            "metadata": { "$ref": "#/$defs/JsonMember" },
            "coords": { "$ref": "#/$defs/TrajectoryCoords" },
            "lattice": { "$ref": "#/$defs/TrajectoryLattice" },
            "velocities": {
              "$ref": "#/$defs/TrajectoryFrameVectors",
              "description": "Velocity of every atom in every frame, [n_frames, n_atoms, 3], in Angstrom/fs."
            },
            "gradient": {
              "$ref": "#/$defs/TrajectoryFrameVectors",
              "description": "Energy gradient dE/dR of every atom in every frame, [n_frames, n_atoms, 3], in hartree/bohr, as the gradient member of a forces section: the forces are its negative."
            },
            "times": {
              "$ref": "#/$defs/TrajectoryFrameScalars",
              "description": "Simulation time of each frame, in fs. When absent and metadata.timestep_fs is present, frame k is at k * timestep_fs."
            },
            "energies": {
              "$ref": "#/$defs/TrajectoryFrameScalars",
              "description": "Energy of each frame, in hartree; the binary form of metadata.energies, preferred for long runs. When both are present they MUST agree within 1e-10 hartree."
            },
            "cell_volumes": {
              "$ref": "#/$defs/TrajectoryFrameScalars",
              "description": "Cell volume of each frame, in Angstrom^3."
            },
            "temperatures": {
              "$ref": "#/$defs/TrajectoryFrameScalars",
              "description": "Instantaneous temperature of each frame, in kelvin."
            }
          }
        }
      }
    },
    "TrajectoryAtom": {
      "type": "object",
      "additionalProperties": true,
      "required": ["symbol", "atomic_number"],
      "description": "Identity of one atom in the `atoms` list of a trajectory-family metadata payload. Positions live in the section's binary members, not here; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "symbol": { "type": "string", "minLength": 1, "maxLength": 3 },
        "atomic_number": { "type": "integer", "minimum": 0 }
      }
    },
    "TrajectoryMetadataCommon": {
      "type": "object",
      "additionalProperties": true,
      "description": "The keys that the metadata payloads of a `trajectory` (TrajectoryMetadataPayload) and of a `reaction.path` (ReactionPathMetadataPayload) share; each of those definitions extends this one. It names the atoms, in the atom order of `coords`, through at least one of `symbols`, `atomic_numbers` and `atoms`; per-frame arrays are in frame order. Typed-open: the keys named here are typed, and any other key is accepted and ignored by a consumer that does not understand it; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "anyOf": [
        { "required": ["symbols"] },
        { "required": ["atomic_numbers"] },
        { "required": ["atoms"] }
      ],
      "properties": {
        "symbols": {
          "type": "array",
          "items": { "type": "string", "minLength": 1, "maxLength": 3 },
          "description": "Element symbol of each atom."
        },
        "atomic_numbers": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "Atomic number of each atom."
        },
        "atoms": {
          "type": "array",
          "items": { "$ref": "#/$defs/TrajectoryAtom" },
          "description": "Atom identities as objects, an alternative to `symbols` and `atomic_numbers`. When more than one of the three is present they MUST describe the same atoms."
        },
        "n_frames": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of frames; equals the leading dimension of `coords`."
        },
        "energies": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Energy of each frame, in Hartree. When the section also carries the binary `energies` member, the two MUST agree within 1e-10 hartree."
        },
        "kind": {
          "enum": ["optimization", "irc", "md", "neb", "scan", "custom"],
          "description": "What produced the frames: a geometry optimization, an intrinsic reaction coordinate, molecular dynamics, a nudged elastic band, a coordinate scan (relaxed or rigid), or something else."
        },
        "pbc": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "type": "boolean" },
          "description": "Per-axis periodicity of the frames: axis i is periodic iff pbc[i], as in the `structure` payload. Absent means the frames are molecular. For a `trajectory` it is REQUIRED when the section carries a `lattice` member, and a true entry requires that member."
        },
        "ensemble": {
          "enum": ["nve", "nvt", "npt", "nph", "custom"],
          "description": "Thermodynamic ensemble of a molecular-dynamics run: constant N, V, E; N, V, T; N, p, T; N, p, H; or another."
        },
        "timestep_fs": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Time between consecutive frames, in fs. When the section has no `times` member, frame k is at k * timestep_fs."
        },
        "precision": {
          "enum": ["float64", "float32"],
          "description": "Floating-point precision of the `coords` member; absent means float64. It MUST agree with that member's dtype: float32 coords require \"float32\" here."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional declaration of units: each key names a field of this payload or the role of a member of the section, each value a unit name. The units are fixed, and a declaration restates them: `energies` is `hartree`, `coords` is `angstrom`, and `times` and `timestep_fs` are `fs`; the `velocities` (Angstrom/fs) and `gradient` (hartree/bohr) members have no unit name and are not declared. See QVF spec § 4.3 (Units and numeric conventions).",
          "properties": {
            "energies": { "const": "hartree" },
            "coords": { "const": "angstrom" },
            "times": { "const": "fs" },
            "timestep_fs": { "const": "fs" }
          }
        }
      }
    },
    "TrajectoryMetadataPayload": {
      "type": "object",
      "additionalProperties": true,
      "allOf": [{ "$ref": "#/$defs/TrajectoryMetadataCommon" }],
      "description": "The JSON payload named by a `trajectory` section's `metadata` member (conventionally `<section id>/metadata.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. It carries the keys of TrajectoryMetadataCommon, which a `reaction.path` metadata payload shares (ReactionPathMetadataPayload), and fixes the units of the members only a trajectory has. Typed-open: the keys named here are typed, and any other key is accepted and ignored by a consumer that does not understand it; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "The `units` declaration of TrajectoryMetadataCommon, which also fixes the trajectory-only members: `lattice` is `angstrom` (rows, the structure convention), `cell_volumes` is `a3` and `temperatures` is `kelvin`; see QVF spec § 4.3 (Units and numeric conventions).",
          "properties": {
            "lattice": { "const": "angstrom" },
            "cell_volumes": { "const": "a3" },
            "temperatures": { "const": "kelvin" }
          }
        }
      }
    },
    "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. Optional per-frame volumetric data (electron density / an orbital morphing along the path) may be attached via the `frame_volumes` (4D: [n_emitted_frames, nx, ny, nz]) + `volume_grid` members; the metadata then carries `volume_frame_index` (which path frame each emitted slab belongs to, for decimation), `volume_label`, and optional `volume_isovalue`. Readers that don't understand these members ignore them. These two members are the older form of a `volume.series` section whose `axis` has kind `frame` and names the path, which producers should prefer; both stay valid. The optional `velocities`, `gradient`, `times` and `energies` members carry per-frame data with the shapes and units they have in a trajectory, and the optional `lattice` member (columns, bohr) marks the path periodic; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "kind": { "const": "reaction.path" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["metadata", "coords"],
          "properties": {
            "metadata": { "$ref": "#/$defs/JsonMember" },
            "coords": { "$ref": "#/$defs/TrajectoryCoords" },
            "frame_volumes": { "$ref": "#/$defs/Volume4DBinary" },
            "volume_grid": { "$ref": "#/$defs/JsonMember" },
            "lattice": { "$ref": "#/$defs/ReactionPathLattice" },
            "velocities": {
              "$ref": "#/$defs/TrajectoryFrameVectors",
              "description": "Velocity of every atom in every frame, [n_frames, n_atoms, 3], in Angstrom/fs, as for a trajectory."
            },
            "gradient": {
              "$ref": "#/$defs/TrajectoryFrameVectors",
              "description": "Energy gradient dE/dR of every atom in every frame, [n_frames, n_atoms, 3], in hartree/bohr; the forces are its negative."
            },
            "times": {
              "$ref": "#/$defs/TrajectoryFrameScalars",
              "description": "Time of each frame, in fs, as for a trajectory."
            },
            "energies": {
              "$ref": "#/$defs/TrajectoryFrameScalars",
              "description": "Energy of each frame, in hartree; the binary form of metadata.energies. When both are present they MUST agree within 1e-10 hartree."
            }
          }
        }
      }
    },
    "ReactionWaypoint": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["frame_index", "label", "kind"],
      "description": "One annotated frame of a reaction path, an item of the `waypoints` list of a `reaction.path` metadata payload or of a `reaction.waypoints` payload. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "frame_index": {
          "type": "integer",
          "minimum": 0,
          "description": "0-based index of the annotated frame: into the section's own `coords` for `reaction.path`, into the `coords` of the trajectory named by `trajectory_ref` for `reaction.waypoints`."
        },
        "label": { "type": "string", "description": "Display label, e.g. \"TS1\"." },
        "kind": {
          "enum": ["reactant", "transition_state", "intermediate", "product", "point"],
          "description": "Role of the frame on the path; `point` marks any other annotated frame."
        },
        "energy_eh": { "type": "number", "description": "Energy of the frame, in Hartree." }
      }
    },
    "ReactionPathMetadataPayload": {
      "type": "object",
      "additionalProperties": true,
      "allOf": [{ "$ref": "#/$defs/TrajectoryMetadataCommon" }],
      "description": "The JSON payload named by a `reaction.path` section's `metadata` member (conventionally `<section id>/metadata.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. It carries every key of TrajectoryMetadataCommon, the keys it shares with a `trajectory` metadata payload, plus waypoint annotations, an optional reaction coordinate, and the keys that describe the optional per-frame volumes (the `frame_volumes` and `volume_grid` members). Typed-open: the keys named here are typed, and any other key is accepted and ignored by a consumer that does not understand it; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "waypoints": {
          "type": "array",
          "items": { "$ref": "#/$defs/ReactionWaypoint" },
          "description": "Annotated frames of the path."
        },
        "reaction_coordinate": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Value of the reaction coordinate at each frame, in frame order: the abscissa of an energy profile."
        },
        "reaction_coordinate_label": { "type": "string", "description": "Display label of the reaction coordinate." },
        "reaction_coordinate_unit": { "type": "string", "description": "Unit of `reaction_coordinate`, e.g. \"bohr\" or \"rad\"." },
        "dim": {
          "type": "integer",
          "minimum": 0,
          "maximum": 3,
          "description": "Number of periodic dimensions, shared by every frame of a periodic path."
        },
        "dim_per_frame": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0, "maximum": 3 },
          "description": "Number of periodic dimensions of each frame, for a path whose frames differ; used instead of `dim`."
        },
        "volume_frame_index": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "For each slab of the `frame_volumes` member, in order, the 0-based path frame it belongs to, so that volumes can be emitted for a subset of the frames. One entry per slab."
        },
        "volume_label": { "type": "string", "description": "Display label of the per-frame volumes, e.g. \"density\"." },
        "volume_isovalue": { "type": "number", "description": "Suggested isovalue for the per-frame volumes, in the unit of their data." },
        "units": {
          "type": "object",
          "description": "The `units` declaration of TrajectoryMetadataCommon, which also fixes the `lattice` member of a periodic path to `bohr` (columns, unlike the `lattice` of a trajectory); see QVF spec § 4.3 (Units and numeric conventions).",
          "properties": {
            "lattice": { "const": "bohr" }
          }
        }
      }
    },
    "ReactionPathLattice": {
      "description": "Per-frame lattice vectors as a binary member, specified in QVF spec § 5.5 (Trajectories, reactions, vibrations). Each lattice is a 3x3 matrix with columns = a, b, c, in bohr. Shape is either [3, 3] when every frame shares the same lattice (the fixed-cell common case — recommended) or [n_frames, 3, 3] when frames carry per-frame lattices (forward-compat with variable-cell scans). When this member is absent the reaction.path is a molecular trajectory and renderers must draw no cell. Presence of this member — not the manifest version — is how a consumer detects a periodic reaction path.",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": {
              "oneOf": [
                {
                  "type": "array",
                  "minItems": 2,
                  "maxItems": 2,
                  "prefixItems": [{ "const": 3 }, { "const": 3 }]
                },
                {
                  "type": "array",
                  "minItems": 3,
                  "maxItems": 3,
                  "prefixItems": [
                    { "type": "integer", "minimum": 1 },
                    { "const": 3 },
                    { "const": 3 }
                  ]
                }
              ]
            }
          }
        }
      ]
    },
    "SectionScanSurface": {
      "description": "2D relaxed-scan energy surface: two driven internal coordinates (axis_a x axis_b) with the relaxed energy at each grid node. `energies` is a 2D binary array [nA, nB]; `axis_a` / `axis_b` are the 1D coordinate values (bohr for bonds, radians for angles/dihedrals). The metadata carries per-axis label + unit. Optional `geometries` (4D-flattened [nA*nB, n_atoms, 3] in angstrom, row-major over (a, b)) lets a viewer show the relaxed structure at a clicked node.",
      "properties": {
        "kind": { "const": "scan.surface" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["metadata", "axis_a", "axis_b", "energies"],
          "properties": {
            "metadata": { "$ref": "#/$defs/JsonMember" },
            "axis_a": { "$ref": "#/$defs/BinaryMember" },
            "axis_b": { "$ref": "#/$defs/BinaryMember" },
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "geometries": { "$ref": "#/$defs/BinaryMember" }
          }
        }
      }
    },
    "ScanSurfaceAxis": {
      "type": "object",
      "additionalProperties": true,
      "required": ["label"],
      "description": "One driven coordinate of a `scan.surface` section; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "label": { "type": "string", "description": "Display label of the coordinate." },
        "unit": {
          "type": "string",
          "description": "Unit of the coordinate values in the matching `axis_a` / `axis_b` binary member, e.g. \"bohr\" or \"rad\"."
        },
        "atoms": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "0-based indices of the atoms that define the coordinate: two for a distance, three for an angle, four for a dihedral."
        }
      }
    },
    "ScanSurfaceMetadataPayload": {
      "type": "object",
      "additionalProperties": true,
      "description": "The JSON payload named by a `scan.surface` section's `metadata` member (conventionally `<section id>/metadata.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. The structured axis descriptions `axis_a` and `axis_b` are preferred; the flat label keys are recognised alternatives, and when both forms are present the objects take precedence. Typed-open: the keys named here are typed, and any other key is accepted and ignored by a consumer that does not understand it; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "axis_a": { "$ref": "#/$defs/ScanSurfaceAxis", "description": "The first driven coordinate, along the rows of `energies`." },
        "axis_b": { "$ref": "#/$defs/ScanSurfaceAxis", "description": "The second driven coordinate, along the columns of `energies`." },
        "axis_a_label": { "type": "string", "description": "Flat alternative to `axis_a.label`." },
        "axis_b_label": { "type": "string", "description": "Flat alternative to `axis_b.label`." },
        "coordinate_a_label": { "type": "string", "description": "Flat alternative to `axis_a.label`." },
        "coordinate_a_unit": { "type": "string", "description": "Flat alternative to `axis_a.unit`." },
        "coordinate_b_label": { "type": "string", "description": "Flat alternative to `axis_b.label`." },
        "coordinate_b_unit": { "type": "string", "description": "Flat alternative to `axis_b.unit`." },
        "atoms": {
          "type": "array",
          "items": { "$ref": "#/$defs/TrajectoryAtom" },
          "description": "Atom identities, in the atom order of the `geometries` member."
        },
        "energy_unit": { "type": "string", "description": "Unit of the `energies` member values; absent means Hartree." },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional declaration of units: each key names a field of this payload or the role of a member of the section (`axis_a`, `axis_b`, `energies`, `geometries`), each value a unit name. A declared unit is the unit the values are stored in. When `units.energies` and `energy_unit`, or a `units` entry and an axis `unit`, are both present they MUST name the same unit; see QVF spec § 4.3 (Units and numeric conventions)."
        }
      }
    },
    "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"]
    },
    "ReactionWaypointsPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["waypoints"],
      "description": "The JSON payload named by a `reaction.waypoints` section's `waypoints` member (conventionally `<section id>/waypoints.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "waypoints": {
          "type": "array",
          "items": { "$ref": "#/$defs/ReactionWaypoint" },
          "description": "Annotated frames of the trajectory named by the section's `trajectory_ref`."
        },
        "reaction_coordinate": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Value of the reaction coordinate at each frame of that trajectory, in frame order."
        }
      }
    },
    "SectionReactionScheme": {
      "description": "A reaction scheme: steps that relate `structure` sections as reactants, reagents and products, with the kind of arrow, the conditions and the yield. The `scheme` member's JSON payload is `#/$defs/ReactionSchemePayload`; see QVF spec § 5.14 (reaction.scheme — reaction schemes).",
      "properties": {
        "kind": { "const": "reaction.scheme" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["scheme"],
          "properties": {
            "scheme": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "ReactionSchemePayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x_": {}
      },
      "required": ["steps"],
      "description": "The JSON payload named by a `reaction.scheme` section's `scheme` member (conventionally `<section id>/scheme.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition; a validator loads the member's bytes and checks them against it, and also checks that every participant names a `structure` section, that step ids are unique and that no structure occurs twice within one role of a step. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.14 (reaction.scheme — reaction schemes).",
      "properties": {
        "steps": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/ReactionStep" },
          "description": "The steps of the scheme, in reading order."
        }
      }
    },
    "ReactionStep": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x_": {}
      },
      "required": ["id", "reactants", "products"],
      "description": "One step of a reaction scheme. Roles are chemical: `reactants` are consumed and `products` formed in the step's forward direction whatever the `arrow`, so for a retrosynthetic arrow the target is among the `products`. The key `energies` is reserved for a later revision. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.14 (reaction.scheme — reaction schemes).",
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_.-]+$",
          "description": "Identifier of the step, unique within the payload."
        },
        "label": {
          "type": "string",
          "description": "Display label of the step, e.g. 'a' or 'step 2'."
        },
        "reactants": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/ReactionParticipant" },
          "description": "The species the step consumes."
        },
        "products": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/ReactionParticipant" },
          "description": "The species the step forms."
        },
        "reagents": {
          "type": "array",
          "items": { "$ref": "#/$defs/ReactionParticipant" },
          "description": "Species drawn at the arrow: reagents, catalysts, solvents drawn as structures."
        },
        "arrow": {
          "enum": ["forward", "equilibrium", "retrosynthetic", "resonance"],
          "default": "forward",
          "description": "The kind of arrow: 'forward' (reactants → products), 'equilibrium' (⇌), 'retrosynthetic' (products ⇒ reactants: target at the tail, precursors at the head) or 'resonance' (two resonance structures of one species, no reaction). Absent means 'forward'."
        },
        "conditions": {
          "type": "array",
          "items": { "type": "string" },
          "description": "The text written at the arrow, one entry per line, in reading order."
        },
        "yield_percent": {
          "type": "number",
          "minimum": 0,
          "maximum": 100,
          "description": "Yield of the step's products, in percent."
        },
        "yield_text": {
          "type": "string",
          "description": "The yield as printed, e.g. '87%', '>95%' or 'quant.'."
        }
      }
    },
    "ReactionParticipant": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x_": {}
      },
      "required": ["structure_ref"],
      "description": "A species of a reaction step: the `structure` section that holds it and its stoichiometric coefficient. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.14 (reaction.scheme — reaction schemes).",
      "properties": {
        "structure_ref": {
          "type": "string",
          "minLength": 1,
          "description": "Id of the `structure` section of the species. It must name a section of kind `structure` in this archive."
        },
        "coefficient": {
          "type": "number",
          "exclusiveMinimum": 0,
          "default": 1,
          "description": "Stoichiometric coefficient of the species in the step; absent means 1."
        }
      }
    },
    "VibrationsDisplacements": {
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "SectionVibrations": {
      "properties": {
        "kind": { "const": "vibrations" },
        "hessian_ref": {
          "type": "string",
          "minLength": 1,
          "description": "Optional id of the hessian section the modes were derived from; a validator checks that it names a hessian section. See QVF spec § 5.5 (Trajectories, reactions, vibrations)."
        },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["metadata", "displacements"],
          "properties": {
            "metadata": { "$ref": "#/$defs/JsonMember" },
            "displacements": { "$ref": "#/$defs/VibrationsDisplacements" }
          }
        }
      }
    },
    "VibrationsMetadataPayload": {
      "type": "object",
      "additionalProperties": true,
      "required": ["frequencies"],
      "description": "The JSON payload named by a `vibrations` section's `metadata` member (conventionally `<section id>/metadata.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. Per-mode arrays hold one entry per mode, in the mode order of `displacements`. An imaginary mode is written as a negative frequency whose magnitude is the imaginary wavenumber. Typed-open: the keys named here are typed, and any other key is accepted and ignored by a consumer that does not understand it; see QVF spec § 5.5 (Trajectories, reactions, vibrations).",
      "properties": {
        "frequencies": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Harmonic wavenumber of each mode, in cm⁻¹; negative for an imaginary mode."
        },
        "ir_intensities": {
          "type": "array",
          "items": { "type": "number" },
          "description": "IR intensity of each mode, in km·mol⁻¹."
        },
        "raman_activities": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Raman scattering activity of each mode, in Å⁴·amu⁻¹."
        },
        "reduced_masses": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Reduced mass of each mode, in amu."
        },
        "force_constants": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Force constant of each mode, in mdyn·Å⁻¹."
        },
        "symmetry_labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Irreducible-representation label of each mode."
        },
        "imaginary": {
          "type": "array",
          "items": { "type": "boolean" },
          "description": "Per-mode flag, true for an imaginary mode. When present it MUST agree with the sign of `frequencies`."
        },
        "n_modes": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of modes; equals the leading dimension of `displacements`."
        },
        "symbols": {
          "type": "array",
          "items": { "type": "string", "minLength": 1, "maxLength": 3 },
          "description": "Element symbol of each atom, in the atom order of `displacements`."
        },
        "atoms": {
          "type": "array",
          "items": { "$ref": "#/$defs/StructureAtom" },
          "description": "The reference geometry: one atom per atom of `displacements`, in the same order, with Cartesian positions in Ångström."
        }
      }
    },
    "SectionSpectraIR": {
      "description": "One-dimensional infrared spectrum. The `spectrum` member's JSON payload is specified by `#/$defs/SpectrumPayload`; see QVF spec § 5.4 (Spectra).",
      "properties": {
        "kind": { "const": "spectra.ir" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SpectrumPayload": {
      "type": "object",
      "additionalProperties": true,
      "required": ["frequencies", "intensities"],
      "description": "The JSON payload named by the `spectrum` member of a one-dimensional spectrum section: `spectra.ir`, `spectra.raman`, `spectra.uvvis`, `spectra.ecd`, `spectra.vcd` or `spectra.generic`. It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition; a validator loads the member's bytes and checks them against it. Typed-open: the fields below are typed and the root stays open. `frequencies` carries the x axis in the unit QVF spec § 4.3 (Units and numeric conventions) gives the kind, unless `x_units` declares another; the name is kept for every kind, including those whose x values are energies. `frequencies`, `intensities` and, when present, `x` MUST have the same length. JSON Schema cannot express that rule, so a validator checks it separately; see QVF spec § 5.4 (Spectra) and § 6 (Validation semantics).",
      "properties": {
        "frequencies": {
          "type": "array",
          "items": { "type": "number" },
          "description": "The x value of every point or line. Unit: the kind's unit from QVF spec § 4.3 (Units and numeric conventions), or `x_units` when present."
        },
        "intensities": {
          "type": "array",
          "items": { "type": "number" },
          "description": "The y value of each entry of `frequencies`, in the same order. Unit: the kind's unit from QVF spec § 4.3 (Units and numeric conventions), or `y_units` when present."
        },
        "x": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Optional alias of `frequencies` under a quantity-neutral name: the same values in the same order. `frequencies` stays REQUIRED; a consumer may read either."
        },
        "x_units": {
          "$ref": "#/$defs/UnitName",
          "description": "Unit name of `frequencies` and `x`. Absent means the kind's unit from QVF spec § 4.3 (Units and numeric conventions)."
        },
        "y_units": {
          "$ref": "#/$defs/UnitName",
          "description": "Unit name of `intensities`. Absent means the kind's unit from QVF spec § 4.3 (Units and numeric conventions)."
        },
        "peaks": {
          "type": "array",
          "items": { "$ref": "#/$defs/SpectrumPeak" },
          "description": "Annotated peaks, in the units of `frequencies` and `intensities`."
        },
        "broadening": {
          "type": "object",
          "required": ["type"],
          "description": "The line shape the producer applied to turn discrete lines into an envelope, or recommends a consumer to apply.",
          "properties": {
            "type": { "enum": ["none", "gaussian", "lorentzian"] },
            "fwhm": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Full width at half maximum of the line shape."
            },
            "units": {
              "$ref": "#/$defs/UnitName",
              "description": "Unit name of `fwhm`. Absent means the unit of the x axis."
            }
          }
        },
        "temperature_k": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Temperature the spectrum refers to, in kelvin."
        },
        "raman": {
          "type": "object",
          "description": "Raman-specific data, meaningful in a `spectra.raman` payload.",
          "properties": {
            "laser_nm": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Excitation wavelength, in nm."
            },
            "depolarization_ratios": {
              "type": "array",
              "items": { "type": "number" },
              "description": "Depolarization ratio of each line, in the order of `frequencies`."
            }
          }
        },
        "uvvis": {
          "type": "object",
          "description": "UV-Vis-specific data, meaningful in a `spectra.uvvis` payload.",
          "properties": {
            "x_axis": {
              "enum": ["energy_ev", "wavelength_nm"],
              "description": "The x quantity the producer recommends for display: excitation energy in eV or wavelength in nm. It does not change the stored values, whose unit `frequencies` and `x_units` define."
            }
          }
        },
        "states_ref": {
          "type": "string",
          "description": "Id of the `excited_states` section whose states the peaks name: every `peaks[].assignment.state_index` is then the `index` of a state of that section. It must name a section of kind `excited_states` in this archive; see QVF spec § 5.4 (Spectra)."
        }
      }
    },
    "SpectrumPeak": {
      "type": "object",
      "additionalProperties": true,
      "required": ["x"],
      "description": "One annotated peak of a `SpectrumPayload`. `x` and `width` are in the unit of the payload's `frequencies`, `y` in the unit of its `intensities`; see QVF spec § 5.4 (Spectra).",
      "properties": {
        "x": { "type": "number", "description": "Peak position." },
        "y": { "type": "number", "description": "Peak intensity." },
        "width": {
          "type": "number",
          "minimum": 0,
          "description": "Full width at half maximum of the peak."
        },
        "label": { "type": "string" },
        "assignment": {
          "type": "object",
          "description": "What the peak arises from. `mode_index` is a 0-based index into the modes of the archive's `vibrations` section; `state_index` identifies the electronic state the transition reaches: the `index` of a state of the `excited_states` section that the payload's `states_ref` names, or, without `states_ref`, as the producer numbers its states.",
          "properties": {
            "mode_index": { "type": "integer", "minimum": 0 },
            "state_index": { "type": "integer", "minimum": 0 }
          }
        }
      }
    },
    "SectionSpectraRaman": {
      "description": "One-dimensional Raman spectrum. The `spectrum` member's JSON payload is specified by `#/$defs/SpectrumPayload`; see QVF spec § 5.4 (Spectra).",
      "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": {
      "description": "One-dimensional UV-Vis absorption spectrum. The `spectrum` member's JSON payload is specified by `#/$defs/SpectrumPayload`; see QVF spec § 5.4 (Spectra).",
      "properties": {
        "kind": { "const": "spectra.uvvis" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraECD": {
      "description": "One-dimensional electronic circular dichroism spectrum. The `spectrum` member's JSON payload is specified by `#/$defs/SpectrumPayload`; see QVF spec § 5.4 (Spectra).",
      "properties": {
        "kind": { "const": "spectra.ecd" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraVCD": {
      "description": "One-dimensional vibrational circular dichroism spectrum. The `spectrum` member's JSON payload is specified by `#/$defs/SpectrumPayload`; see QVF spec § 5.4 (Spectra).",
      "properties": {
        "kind": { "const": "spectra.vcd" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionSpectraNMR": {
      "description": "Nuclear magnetic resonance parameters. The payload is a single object-shaped `spectrum` JSON member rather than a frequency/intensity pair, specified by `#/$defs/NmrSpectrumPayload`; see QVF spec § 5.4 (Spectra).",
      "properties": {
        "kind": { "const": "spectra.nmr" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "NmrSpectrumPayload": {
      "type": "object",
      "additionalProperties": true,
      "description": "The JSON payload named by a `spectra.nmr` section's `spectrum` member: per-nucleus chemical shifts, shielding tensors and spin-spin couplings rather than a frequency/intensity pair. Permissive: the known fields are typed, every object stays open, and a later revision may tighten the definition. Shifts and shieldings are in ppm, couplings in Hz. See QVF spec § 5.4 (Spectra).",
      "properties": {
        "isotope": { "type": "string", "description": "Observed nucleus, e.g. '1H' or '13C'." },
        "reference": { "type": "string", "description": "Shift reference, e.g. 'TMS'." },
        "solvent": { "type": "string", "description": "Solvent or solvation model, when one was used." },
        "chemical_shifts": {
          "type": "array",
          "description": "One entry per nucleus.",
          "items": {
            "type": "object",
            "required": ["atom_index", "isotropic_shift_ppm"],
            "properties": {
              "atom_index": {
                "type": "integer",
                "minimum": 0,
                "description": "0-based index into the structure's atoms."
              },
              "symbol": { "type": "string" },
              "isotropic_shift_ppm": {
                "type": "number",
                "description": "Isotropic chemical shift relative to `reference`, in ppm."
              },
              "anisotropy_ppm": { "type": "number", "description": "Shielding anisotropy, in ppm." },
              "asymmetry": { "type": "number", "description": "Shielding asymmetry parameter, dimensionless." }
            }
          }
        },
        "shielding_tensors": {
          "type": "array",
          "description": "Full shielding tensors, one entry per nucleus.",
          "items": {
            "type": "object",
            "properties": {
              "atom_index": { "type": "integer", "minimum": 0 },
              "tensor": {
                "type": "array",
                "minItems": 3,
                "maxItems": 3,
                "items": { "$ref": "#/$defs/Vec3" },
                "description": "Shielding tensor in ppm: three rows in the Cartesian frame of the structure."
              },
              "isotropic_ppm": {
                "type": "number",
                "description": "Isotropic shielding, one third of the trace, in ppm."
              }
            }
          }
        },
        "j_couplings": {
          "type": "array",
          "description": "Indirect spin-spin couplings, one entry per atom pair.",
          "items": {
            "type": "object",
            "required": ["i", "j", "value_hz"],
            "properties": {
              "i": { "type": "integer", "minimum": 0 },
              "j": { "type": "integer", "minimum": 0 },
              "value_hz": { "type": "number", "description": "Coupling constant J, in Hz." },
              "isotope_i": { "type": "string" },
              "isotope_j": { "type": "string" }
            }
          }
        }
      }
    },
    "SectionSpectraEPR": {
      "description": "Electron paramagnetic resonance (EPR / ESR) parameters. Like spectra.nmr, the payload is a single object-shaped `spectrum` JSON member rather than a frequency/intensity pair; it carries the g-tensor, per-nucleus hyperfine (A) tensors, and the zero-field-splitting (D) tensor. The `spectrum` member's JSON payload is specified by `#/$defs/EprSpectrumPayload`; see QVF spec § 5.4 (Spectra).",
      "properties": {
        "kind": { "const": "spectra.epr" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "EprSpectrumPayload": {
      "type": "object",
      "additionalProperties": true,
      "description": "The JSON payload named by a `spectra.epr` section's `spectrum` member: the g-tensor, per-nucleus hyperfine (A) tensors and the zero-field-splitting (D) tensor. Permissive: the known fields are typed, every object stays open, and a later revision may tighten the definition. Units are fixed: g-values are dimensionless, hyperfine and zero-field-splitting parameters are in MHz. See QVF spec § 5.4 (Spectra).",
      "properties": {
        "g_tensor": {
          "type": "object",
          "properties": {
            "matrix": {
              "type": "array",
              "minItems": 3,
              "maxItems": 3,
              "items": { "$ref": "#/$defs/Vec3" },
              "description": "Full g-tensor, dimensionless: three rows in the Cartesian frame of the structure."
            },
            "isotropic": { "type": "number", "description": "Isotropic g-value, one third of the trace." },
            "principal": { "$ref": "#/$defs/Vec3", "description": "Principal g-values." }
          }
        },
        "hyperfine": {
          "type": "array",
          "description": "Hyperfine couplings, one entry per magnetic nucleus.",
          "items": {
            "type": "object",
            "required": ["atom_index"],
            "properties": {
              "atom_index": {
                "type": "integer",
                "minimum": 0,
                "description": "0-based index into the structure's atoms."
              },
              "symbol": { "type": "string" },
              "isotope": { "type": "string", "description": "Nucleus, e.g. '14N'." },
              "a_iso_mhz": { "type": "number", "description": "Isotropic hyperfine coupling, in MHz." },
              "a_tensor_mhz": {
                "type": "array",
                "minItems": 3,
                "maxItems": 3,
                "items": { "$ref": "#/$defs/Vec3" },
                "description": "Full hyperfine tensor in MHz: three rows in the Cartesian frame of the structure."
              },
              "a_principal_mhz": { "$ref": "#/$defs/Vec3", "description": "Principal hyperfine values, in MHz." }
            }
          }
        },
        "zero_field_splitting": {
          "type": "object",
          "properties": {
            "d_mhz": { "type": "number", "description": "Axial zero-field-splitting parameter D, in MHz." },
            "e_mhz": { "type": "number", "description": "Rhombic zero-field-splitting parameter E, in MHz." },
            "tensor_mhz": {
              "type": "array",
              "minItems": 3,
              "maxItems": 3,
              "items": { "$ref": "#/$defs/Vec3" },
              "description": "Full zero-field-splitting tensor in MHz: three rows in the Cartesian frame of the structure."
            }
          }
        }
      }
    },
    "SectionSpectraGeneric": {
      "description": "One-dimensional spectrum of a kind QVF does not name. The `spectrum` member's JSON payload is specified by `#/$defs/SpectrumPayload`; producers SHOULD declare its `x_units` and `y_units`. See QVF spec § 5.4 (Spectra).",
      "properties": {
        "kind": { "const": "spectra.generic" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spectrum"],
          "properties": {
            "spectrum": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "MoCoefficientsBinary": {
      "description": "MO coefficients of a `wavefunction.gto` section, float64, one row per MO: [n_mo, n_ao] when real, [n_mo, n_ao, 2] with the last axis (real, imaginary) when the `mo_metadata` payload says `complex: true`. A `generalized` wavefunction doubles the AO axis to 2 n_ao, all α components first. That the rank matches `complex` is checked by validators, not by this schema. See QVF spec § 5.3 (wavefunction.gto).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 2, "maxItems": 3 }
          }
        }
      ]
    },
    "SectionWavefunctionGTO": {
      "description": "Atom-centered Gaussian basis + MO coefficients. Renderer-friendly: a re-sampling viewer can evaluate any orbital on its own grid (Molden-style). Complex coefficients are stored as float64 [n_mo, n_ao, 2] with last axis [real, imag]. Optional AO-basis matrices: the `overlap` matrix, with which a consumer verifies the normalization contract of QVF spec Appendix A.1, and the one-particle density matrices `density_matrix` (with `mo_coefficients`) or `density_matrix_alpha` + `density_matrix_beta` (with the α and β coefficients). See QVF spec § 5.3 (wavefunction.gto).",
      "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" },
            "overlap": { "$ref": "#/$defs/WavefunctionAoMatrix" },
            "density_matrix": { "$ref": "#/$defs/WavefunctionAoMatrix" },
            "density_matrix_alpha": { "$ref": "#/$defs/WavefunctionAoMatrix" },
            "density_matrix_beta": { "$ref": "#/$defs/WavefunctionAoMatrix" }
          },
          "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"] }
            }
          ]
        }
      }
    },
    "WavefunctionAoMatrix": {
      "description": "An optional AO-basis matrix of a `wavefunction.gto` section, float64 [n_ao, n_ao], rows and columns in the AO order of the `basis` payload (QVF spec Appendix A.2): the `overlap` matrix of the contracted AOs as QVF spec Appendix A.1 defines them (dimensionless), or a one-particle density matrix in the AO basis (`density_matrix` the spin-summed total, `density_matrix_alpha` and `density_matrix_beta` one spin each), so that the trace of a density matrix times the overlap is the number of electrons it describes. That n_ao matches the basis, and that the density members pair with the coefficient members, are checked by validators, not by this schema. See QVF spec § 5.3 (wavefunction.gto).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 2, "maxItems": 2 }
          }
        }
      ]
    },
    "BasisShell": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["center", "l", "exponents", "coefficients"],
      "description": "One contracted shell of a `basis` payload. It contributes 2l+1 (spherical) or (l+1)(l+2)/2 (Cartesian) AOs, ordered as in QVF spec Appendix A.2. `exponents` and `coefficients` are parallel, one entry per primitive, and MUST have the same length; JSON Schema cannot express that rule, so this definition does not check it. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.3 (wavefunction.gto).",
      "properties": {
        "center": {
          "type": "integer",
          "minimum": 0,
          "description": "0-based index of the atom the shell sits on, in the `atoms` of the `structure` section named by the payload's `structure_ref`."
        },
        "l": {
          "type": "integer",
          "minimum": 0,
          "maximum": 7,
          "description": "Angular momentum of the shell (0 = s, 1 = p, 2 = d, …)."
        },
        "exponents": {
          "type": "array",
          "minItems": 1,
          "items": { "type": "number", "exclusiveMinimum": 0 },
          "description": "Primitive exponents, in bohr⁻²."
        },
        "coefficients": {
          "type": "array",
          "minItems": 1,
          "items": { "type": "number" },
          "description": "Contraction coefficients, one per exponent, applying to primitives normalized as QVF spec Appendix A.1 prescribes."
        },
        "pure": {
          "type": "boolean",
          "description": "true = spherical harmonics, false = Cartesian. Overrides the payload-level `pure` for this shell."
        }
      }
    },
    "BasisEcpProjector": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["l", "exponents", "coefficients", "powers"],
      "description": "One radial function of an effective core potential, in the conventional semi-local form U(r) = Σ_i c_i r^(n_i − 2) exp(−α_i r²), with r in bohr and U in hartree: parallel arrays with one entry per term i, which MUST have the same length (JSON Schema cannot express that rule, so this definition does not check it). With `local: true` it is the local part of the centre's potential, which acts on every angular momentum; otherwise it is the semi-local channel of angular momentum `l`, which acts through the projector onto `l`. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.3 (wavefunction.gto).",
      "properties": {
        "l": {
          "type": "integer",
          "minimum": 0,
          "description": "Angular momentum of the channel. For the local part (`local: true`) it is the conventional label L of that part, which is greater than the `l` of every semi-local channel of the centre."
        },
        "exponents": {
          "type": "array",
          "minItems": 1,
          "items": { "type": "number", "exclusiveMinimum": 0 },
          "description": "Gaussian exponents α_i of the terms, in bohr⁻²."
        },
        "coefficients": {
          "type": "array",
          "minItems": 1,
          "items": { "type": "number" },
          "description": "Coefficients c_i of the terms, in hartree · bohr^(2 − n_i), so that every term is an energy in hartree."
        },
        "powers": {
          "type": "array",
          "minItems": 1,
          "items": { "type": "integer" },
          "description": "Radial powers n_i of the terms: term i is c_i r^(n_i − 2) exp(−α_i r²), so n_i = 2 is a plain Gaussian and n_i = 0 carries r^(−2)."
        },
        "local": {
          "type": "boolean",
          "default": false,
          "description": "true: this radial function is the local part U_L(r) of the centre's potential, which acts on every angular momentum; a centre has at most one, and its `l` is the highest on the centre. false or absent: a semi-local channel, which multiplies the projector onto angular momentum `l`. As in the usual tabulations, a semi-local channel of a centre with a local part holds the difference U_l(r) − U_L(r)."
        }
      }
    },
    "BasisEcpCentre": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["center", "n_core_electrons"],
      "description": "The effective core potential on one atom of a `basis` payload: it replaces the `n_core_electrons` innermost electrons of that atom, which the wavefunction therefore does not describe. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.3 (wavefunction.gto).",
      "properties": {
        "center": {
          "type": "integer",
          "minimum": 0,
          "description": "0-based index of the atom, as for a shell's `center`."
        },
        "n_core_electrons": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of electrons the potential replaces on this atom: the wavefunction describes the remaining Z − n_core_electrons of the atom's electrons."
        },
        "label": { "type": "string", "description": "Name of the potential, e.g. \"def2-ECP\"." },
        "projectors": {
          "type": "array",
          "items": { "$ref": "#/$defs/BasisEcpProjector" },
          "description": "The radial functions of the potential: at most one local part and the semi-local channels. Absent: the potential is named by `label` and its core count only, and a consumer that needs the potential itself cannot evaluate it."
        }
      }
    },
    "BasisPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["structure_ref", "shells"],
      "description": "The JSON payload named by a `wavefunction.gto` section's `basis` member (conventionally `<section id>/basis.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. The AO order is the concatenation of the shells in array order, each in the in-shell order of QVF spec Appendix A.2. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.3 (wavefunction.gto).",
      "properties": {
        "structure_ref": {
          "type": "string",
          "minLength": 1,
          "description": "Id of the `structure` section whose atoms the shell `center` indices refer to."
        },
        "pure": {
          "type": "boolean",
          "description": "Angular type of every shell without its own `pure`: true = spherical harmonics, false = Cartesian. Absent means true."
        },
        "n_ao": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of AOs: the sum over the shells of 2l+1 (spherical) or (l+1)(l+2)/2 (Cartesian). It equals the AO dimension of the MO coefficient members."
        },
        "shells": {
          "type": "array",
          "items": { "$ref": "#/$defs/BasisShell" },
          "description": "The contracted shells, in AO order."
        },
        "ecp": {
          "type": "array",
          "items": { "$ref": "#/$defs/BasisEcpCentre" },
          "description": "Effective core potentials, at most one per atom (no two entries share a `center`); see QVF spec § 5.3 (wavefunction.gto)."
        },
        "n_electrons": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of electrons the wavefunction describes: the sum of the atomic numbers, minus the `n_core_electrons` of every `ecp` entry, minus the charge. When present it equals the sum of the `mo_metadata` occupations over both spin channels (within 1e-6) and `provenance.n_electrons` when that is present; validators check both, which JSON Schema cannot express."
        }
      }
    },
    "MoSpinChannel": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["energies", "occupations"],
      "description": "The orbitals of one spin channel of an unrestricted `mo_metadata` payload: per-MO arrays in the row order of the matching `mo_coefficients_alpha` or `mo_coefficients_beta` member. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.3 (wavefunction.gto).",
      "properties": {
        "n_mo": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of MOs in the channel; equals the row count of its coefficient member."
        },
        "energies": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Orbital energy of each MO, in Hartree."
        },
        "occupations": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Occupation of each MO, in electrons (0 to 1 in a spin channel), or a squared singular-value transition weight when occupation_semantics is transition_weight. For unrestricted NTOs, the nonnegative weights are in non-increasing order, match the paired section per spin, and both spins together sum to 1 for a normalized state; see QVF spec § 5.3 (wavefunction.gto)."
        },
        "symmetry_labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Irreducible-representation label of each MO of the channel, parallel to its `energies`; validators check the length."
        }
      }
    },
    "MoMetadataPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["spin"],
      "description": "The JSON payload named by a `wavefunction.gto` section's `mo_metadata` member (conventionally `<section id>/mo_metadata.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. `spin` selects one of two shapes. `unrestricted` carries an `alpha` and a `beta` object, matching the `mo_coefficients_alpha` and `mo_coefficients_beta` members, and no top-level per-MO arrays. Every other `spin` value carries one set of orbitals, matching `mo_coefficients`, with `energies` and `occupations` at the top level and no `alpha` or `beta`. Per-MO arrays are in the row order of the coefficient member. Strict: any other key is an error unless it begins with `x_`. The deprecated keys `iao_charges`, `excitation_index` and `excitation_energy_ev` remain valid so that archives which carry them keep validating; producers write their canonical carriers instead; see QVF spec § 5.3 (wavefunction.gto).",
      "properties": {
        "spin": {
          "enum": ["restricted", "unrestricted", "restricted_open", "generalized"],
          "description": "`restricted`: one set of spatial orbitals shared by both spins. `unrestricted`: separate α and β sets. `restricted_open`: one set of spatial orbitals, singly or doubly occupied, in the restricted shape. `generalized`: one set of two-component spin orbitals that mix α and β, in the restricted shape with the AO axis of `mo_coefficients` doubled to 2 n_ao (the α components of the n_ao AOs, then their β components); it requires `complex: true`. See QVF spec § 5.3 (wavefunction.gto)."
        },
        "orbital_kind": {
          "enum": ["canonical", "natural", "localized", "nto", "nbo", "iao", "ibo", "boys", "pipek_mezey", "custom"],
          "description": "What the orbitals are; absent means `canonical`. `canonical`: eigenfunctions of the converged Fock or Kohn-Sham operator. `natural`: natural orbitals. `localized`: localized orbitals of an unnamed method. `nto`: natural transition orbitals. `nbo`: natural bond orbitals. `iao`, `ibo`: intrinsic atomic and bond orbitals. `boys`, `pipek_mezey`: Foster-Boys and Pipek-Mezey localized orbitals. `custom`: anything else."
        },
        "n_ao": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of AOs; equals the `basis` payload's `n_ao`."
        },
        "n_mo": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of MOs; equals the row count of `mo_coefficients`."
        },
        "energies": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Orbital energy of each MO, in Hartree."
        },
        "occupations": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Occupation of each MO: electrons per orbital, or a transition weight when `occupation_semantics` says so."
        },
        "symmetry_labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Irreducible-representation label of each MO, parallel to `energies`; validators check the length."
        },
        "alpha": { "$ref": "#/$defs/MoSpinChannel", "description": "The α orbitals of an unrestricted wavefunction; for NTOs they pair by row with the α channel of the other section, independently of β (QVF spec § 5.3 (wavefunction.gto))." },
        "beta": { "$ref": "#/$defs/MoSpinChannel", "description": "The β orbitals of an unrestricted wavefunction; for NTOs they pair by row with the β channel of the other section, independently of α (QVF spec § 5.3 (wavefunction.gto))." },
        "occupation_semantics": {
          "enum": ["electron_occupation", "transition_weight"],
          "description": "Meaning of the `occupations` numbers: electrons per orbital (`electron_occupation`, the meaning when absent) or the weights of natural transition orbitals (`transition_weight`)."
        },
        "k_point": {
          "$ref": "#/$defs/Vec3",
          "description": "Crystal momentum of the orbitals, in fractional coordinates of the reciprocal lattice; absent or [0, 0, 0] means the Γ point."
        },
        "complex": {
          "type": "boolean",
          "description": "true when every coefficient member is complex, float64 [n_mo, n_ao, 2] (2 n_ao for `generalized`) with the last axis (real, imaginary); absent or false means real [n_mo, n_ao]. Validators check the rank of the coefficient members against it."
        },
        "coefficient_encoding": {
          "enum": ["real", "complex_split_last_axis"],
          "description": "Alternative spelling of `complex`: `real` means false, `complex_split_last_axis` means true. When both are present they MUST agree."
        },
        "coefficient_components": {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "prefixItems": [{ "const": "real" }, { "const": "imag" }],
          "description": "Order of the last axis of complex coefficients; when present it is [\"real\", \"imag\"]."
        },
        "state_ref": {
          "type": "string",
          "description": "Reference to the electronic state the orbitals describe, for state-specific orbitals. For natural transition orbitals (`orbital_kind` nto) it is the id of the `excited_states` section, and `state_index` names the state; see QVF spec § 5.3 (wavefunction.gto)."
        },
        "state_index": {
          "type": "integer",
          "minimum": 1,
          "description": "The `index` of the state that the orbitals describe, in the `excited_states` section that `state_ref` names."
        },
        "nto_role": {
          "enum": ["hole", "particle"],
          "description": "Which half of a state's natural transition orbitals the section holds: `hole`, the occupied-space orbitals, or `particle`, the virtual-space orbitals. Row k of the hole section pairs with row k of the particle section of the same state; see QVF spec § 5.3 (wavefunction.gto)."
        },
        "localization_method": { "type": "string", "description": "Name of the method that localized the orbitals." },
        "localization_reference_basis": {
          "type": "string",
          "minLength": 1,
          "description": "Name of the minimal reference basis of free-atom AOs from which the intrinsic atomic orbitals were constructed, e.g. 'minao' (IAO and IBO localization; Knizia, J. Chem. Theory Comput. 2013, 9, 4834). The IAOs, and the IAO charges and IBOs derived from them, depend on this choice; see QVF spec § 5.3 (wavefunction.gto)."
        },
        "atom_populations": {
          "type": "array",
          "items": { "type": "array", "items": { "type": "number" } },
          "description": "[n_mo, n_atoms]: the fraction of each localized orbital on each atom; each row sums to 1."
        },
        "centroids_bohr": {
          "type": "array",
          "items": { "$ref": "#/$defs/Vec3" },
          "description": "[n_mo, 3]: the centroid of each localized orbital, in bohr."
        },
        "n_centres": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "Number of atoms each localized orbital is centred on."
        },
        "iao_charges": {
          "type": "array",
          "items": { "type": "number" },
          "deprecated": true,
          "description": "Deprecated; see QVF spec § 5.3 (wavefunction.gto). The IAO partial charge of each atom, in e. Producers SHOULD NOT write it: the canonical carrier is the `iao_charge` member of an `atom_properties` section. Kept so that archives which already carry it remain valid."
        },
        "excitation_index": {
          "type": "integer",
          "minimum": 0,
          "deprecated": true,
          "description": "Deprecated; see QVF spec § 5.3 (wavefunction.gto). The excited state that natural transition orbitals describe, by the producer's own numbering. Producers SHOULD NOT write it: the canonical carrier is `state_index`, the state's `index` in the `excited_states` section that `state_ref` names. Kept so that archives which already carry it remain valid."
        },
        "excitation_energy_ev": {
          "type": "number",
          "deprecated": true,
          "description": "Deprecated; see QVF spec § 5.3 (wavefunction.gto). The excitation energy, in eV, of the state that natural transition orbitals describe. Producers SHOULD NOT write it: the canonical carrier is the `excitation_energy` of the state that `state_index` names in the `excited_states` section that `state_ref` names. Kept so that archives which already carry it remain valid."
        }
      },
      "allOf": [
        {
          "$comment": "Canonical unrestricted NTOs (nto_role present) are two sections per state, paired per spin; cross-member rules are checked by validators (QVF spec § 5.3 (wavefunction.gto)).",
          "if": {
            "required": ["spin", "orbital_kind", "nto_role"],
            "properties": { "spin": { "const": "unrestricted" }, "orbital_kind": { "const": "nto" } }
          },
          "then": {
            "required": ["occupation_semantics", "state_ref", "state_index", "nto_role"],
            "properties": { "occupation_semantics": { "const": "transition_weight" } }
          }
        },
        {
          "$comment": "The two shapes: separate alpha/beta channels for unrestricted, one top-level orbital set otherwise.",
          "if": {
            "required": ["spin"],
            "properties": { "spin": { "const": "unrestricted" } }
          },
          "then": {
            "required": ["alpha", "beta"],
            "not": {
              "anyOf": [
                { "required": ["n_mo"] },
                { "required": ["energies"] },
                { "required": ["occupations"] },
                { "required": ["symmetry_labels"] }
              ]
            }
          },
          "else": {
            "required": ["energies", "occupations"],
            "not": {
              "anyOf": [
                { "required": ["alpha"] },
                { "required": ["beta"] }
              ]
            }
          }
        },
        {
          "$comment": "A generalized (two-component) wavefunction is complex; see QVF spec § 5.3 (wavefunction.gto).",
          "if": {
            "required": ["spin"],
            "properties": { "spin": { "const": "generalized" } }
          },
          "then": {
            "required": ["complex"],
            "properties": { "complex": { "const": true } }
          }
        }
      ]
    },
    "SectionWavefunctionBloch": {
      "description": "Provisional kind. The k-resolved Bloch orbitals of a periodic system over the atom-centred Gaussian basis of its cell: complex MO coefficients at every k-point of a set, for one or two spin channels, with their energies and occupations. The Bloch functions are phi_mu,k(r) = N^(-1/2) sum_T exp(+i k.T) chi_mu(r - T) over the lattice translations T, with k in fractional reciprocal-lattice coordinates and the AO order and primitive normalization of QVF spec Appendix A. The structure named by the section-level structure_ref, else by basis.structure_ref, must have at least one periodic axis; validators check that and the agreement of the member shapes. See QVF spec § 5.3.1 (wavefunction.bloch — k-resolved Bloch orbitals, provisional).",
      "properties": {
        "kind": { "const": "wavefunction.bloch" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["basis", "kpoints", "mo_metadata", "mo_coefficients", "energies", "occupations"],
          "properties": {
            "basis": { "$ref": "#/$defs/JsonMember" },
            "kpoints": { "$ref": "#/$defs/JsonMember" },
            "mo_metadata": { "$ref": "#/$defs/JsonMember" },
            "mo_coefficients": { "$ref": "#/$defs/BlochMoCoefficients" },
            "energies": { "$ref": "#/$defs/BlochEnergies" },
            "occupations": { "$ref": "#/$defs/BlochOccupations" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "BlochMoCoefficients": {
      "description": "Complex MO coefficients, float64 [n_k, n_spin, n_mo, n_ao, 2]: element [k, s, m, mu, :] is the (real, imaginary) pair of the coefficient of Bloch function mu at k-point k in MO m of spin channel s (0 is alpha, 1 is beta). Axis 0 follows the kpoints member, axis 3 the AO order of the basis. That the extents agree with the other members is checked by validators, not by this schema. See QVF spec § 5.3.1 (wavefunction.bloch — k-resolved Bloch orbitals, provisional).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": {
              "minItems": 5,
              "maxItems": 5,
              "prefixItems": [{}, { "minimum": 1, "maximum": 2 }, {}, {}, { "const": 2 }]
            }
          }
        }
      ]
    },
    "BlochEnergies": {
      "description": "Orbital energies, float64 [n_k, n_spin, n_mo], in hartree, in the order of the first three axes of mo_coefficients. See QVF spec § 5.3.1 (wavefunction.bloch — k-resolved Bloch orbitals, provisional).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "BlochOccupations": {
      "description": "Orbital occupations, float64 [n_k, n_spin, n_mo], in electrons per orbital at each k-point, not weighted by the k-point weights: 0 to 2 when n_spin is 1, 0 to 1 when it is 2. See QVF spec § 5.3.1 (wavefunction.bloch — k-resolved Bloch orbitals, provisional).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "BlochKpointsPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["kpoints"],
      "description": "The JSON payload named by a `wavefunction.bloch` section's `kpoints` member: the k-points the orbitals are given at, in the order of axis 0 of mo_coefficients, energies and occupations. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. That the arrays have one entry per k-point and that the weights sum to 1 within 1e-6 is checked by validators, not by this schema. See QVF spec § 5.3.1 (wavefunction.bloch — k-resolved Bloch orbitals, provisional).",
      "properties": {
        "kpoints": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/Vec3" },
          "description": "Every k-point, in fractional coordinates of the reciprocal lattice (k = k1 b1 + k2 b2 + k3 b3, so k.T = 2 pi (k1 n1 + k2 n2 + k3 n3) for the translation T = n1 a1 + n2 a2 + n3 a3)."
        },
        "weights": {
          "type": "array",
          "items": { "type": "number", "minimum": 0 },
          "description": "Integration weight of each k-point, one per entry of `kpoints`, summing to 1 within 1e-6. Absent when the k-points are not an integration set, such as points along a path."
        },
        "labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "One label per k-point, parallel to `kpoints`, such as a high-symmetry name; an empty string marks an unlabelled point."
        },
        "mesh": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "type": "integer", "minimum": 1 },
          "description": "Dimensions [n1, n2, n3] of the uniform mesh the k-points were taken from, when they were; the k-points are its points, or the irreducible subset of them that the weights account for."
        },
        "shift": {
          "$ref": "#/$defs/Vec3",
          "description": "Fractional reciprocal-lattice position of mesh point (0, 0, 0). Absent means a Gamma-centred mesh."
        },
        "time_reversal": {
          "type": "boolean",
          "description": "True when the set was reduced with time-reversal symmetry: the orbitals at -k are the complex conjugates of those at k, and the weight of k includes that of -k. Absent means false."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional map from a field name of this payload to the unit name of its values. The fields are fixed by QVF spec § 4.3 (Units and numeric conventions) and the payload table; a declaration restates them and does not change them, so `kpoints`, `weights` and `shift` are `dimensionless`.",
          "properties": {
            "kpoints": { "const": "dimensionless" },
            "weights": { "const": "dimensionless" },
            "shift": { "const": "dimensionless" }
          }
        }
      }
    },
    "BlochMoMetadataPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["spin", "n_spin", "n_mo", "n_ao", "complex", "k_point_convention"],
      "description": "The JSON payload named by a `wavefunction.bloch` section's `mo_metadata` member: the orbital set the binary members carry. Per-orbital energies and occupations are the binary members `energies` and `occupations`, not fields of this payload. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. See QVF spec § 5.3.1 (wavefunction.bloch — k-resolved Bloch orbitals, provisional).",
      "properties": {
        "spin": {
          "enum": ["restricted", "unrestricted"],
          "description": "`restricted`: one set of spatial orbitals shared by both spins (n_spin 1). `unrestricted`: separate alpha and beta sets (n_spin 2)."
        },
        "n_spin": {
          "type": "integer",
          "minimum": 1,
          "maximum": 2,
          "description": "Number of spin channels; equals axis 1 of mo_coefficients, energies and occupations."
        },
        "n_mo": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of MOs at each k-point and spin; equals axis 2 of mo_coefficients, energies and occupations."
        },
        "n_ao": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of AOs; equals axis 3 of mo_coefficients and the basis payload's n_ao."
        },
        "orbital_kind": {
          "enum": ["canonical", "natural", "localized", "nto", "nbo", "iao", "ibo", "boys", "pipek_mezey", "custom"],
          "description": "What the orbitals are, with the values and meanings of the wavefunction.gto mo_metadata field of the same name; absent means `canonical`."
        },
        "complex": {
          "const": true,
          "description": "Always true: mo_coefficients carries (real, imaginary) pairs in its last axis."
        },
        "k_point_convention": {
          "enum": ["fractional"],
          "description": "How the kpoints member states k: `fractional`, in fractional coordinates of the reciprocal lattice. The only value in v1."
        },
        "n_mo_per_k": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "Number of orbitals that are defined at each k-point, one entry per k-point, each at most n_mo, for a producer whose orbital count differs between k-points (canonical orthogonalisation that removes a different number of near-linear-dependent directions at each k). Orbitals n_mo_per_k[k] to n_mo - 1 at k-point k are padding, with zero coefficients and zero occupations, and consumers ignore them. Absent means n_mo at every k-point."
        },
        "fermi_energy": {
          "$ref": "#/$defs/ValueWithUnits",
          "description": "Fermi level of the calculation, on the absolute scale of `energies`."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional map from the role of a member of the section to the unit name of its values. The units are fixed by QVF spec § 4.3 (Units and numeric conventions); a declaration restates them and does not change them, so `energies` is `hartree`.",
          "properties": {
            "energies": { "const": "hartree" }
          }
        }
      },
      "allOf": [
        {
          "$comment": "spin and n_spin agree.",
          "if": { "required": ["spin"], "properties": { "spin": { "const": "restricted" } } },
          "then": { "properties": { "n_spin": { "const": 1 } } }
        },
        {
          "if": { "required": ["spin"], "properties": { "spin": { "const": "unrestricted" } } },
          "then": { "properties": { "n_spin": { "const": 2 } } }
        }
      ]
    },
    "SectionBands": {
      "description": "Band structure — eigenvalues along a k-path, with optional Mulliken character projections (fat bands).",
      "properties": {
        "kind": { "const": "bands" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["kpath", "eigenvalues"],
          "properties": {
            "kpath": { "$ref": "#/$defs/JsonMember" },
            "eigenvalues": { "$ref": "#/$defs/BandsEigenvalues" },
            "projections": { "$ref": "#/$defs/BandsProjections" },
            "occupations": { "$ref": "#/$defs/BandsOccupations" }
          }
        }
      }
    },
    "BandsProjections": {
      "description": "Fat-band weights of a `bands` section: float64 [n_spin, n_k, n_bands, n_channels], or the legacy rank-3 form [n_k, n_bands, n_channels], which means n_spin = 1. n_spin, n_k and n_bands are those of `eigenvalues`; channel c is entry c of the kpath `channels` list. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 4 }
          }
        }
      ]
    },
    "BandsOccupations": {
      "description": "Occupation of each band state of a `bands` section: float64 [n_spin, n_k, n_bands], the shape of `eigenvalues`, in electrons per state (not weighted by k-point weights). See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 3, "maxItems": 3 }
          }
        }
      ]
    },
    "KpathSegment": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "One straight segment of a band-structure path, listed in path order. Indices count points along the path axis (axis 1 of bands `eigenvalues`, axis 0 of phonon `frequencies`) from 0. When `start` is absent it is the previous segment's `end` (0 for the first segment), so consecutive segments share their boundary point; when `end` is absent it is start + n_points - 1. A path with a jump gives the segment after the jump an explicit `start`. Keys beginning with x_ are a vendor escape. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "start": { "type": "integer", "minimum": 0, "description": "Index of the segment's first point." },
        "end": { "type": "integer", "minimum": 0, "description": "Index of the segment's last point (inclusive)." },
        "n_points": { "type": "integer", "minimum": 1, "description": "Number of points on the segment, both ends included." },
        "label_start": { "type": "string", "description": "High-symmetry label of the first point (e.g. 'G' or 'Γ'); may be empty." },
        "label_end": { "type": "string", "description": "High-symmetry label of the last point; may be empty." },
        "k_start": { "$ref": "#/$defs/Vec3", "description": "Fractional reciprocal-lattice coordinates of the first point." },
        "k_end": { "$ref": "#/$defs/Vec3", "description": "Fractional reciprocal-lattice coordinates of the last point." }
      }
    },
    "KpathPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "The JSON payload named by a `bands` section's `kpath` member: the path the eigenvalues are sampled on, the Fermi level, and the fat-band channels. It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition; a validator loads the member's bytes and checks them against it. Strict: only the fields below and keys beginning with x_ are allowed. No field is required. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kpoints": {
          "type": "array",
          "items": { "$ref": "#/$defs/Vec3" },
          "description": "Fractional reciprocal-lattice coordinates of every k-point along the path, in the order of eigenvalues axis 1 (n_kpoints entries)."
        },
        "labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "One label per k-point along the path, parallel to `kpoints` and eigenvalues axis 1; an empty string marks an unlabelled point."
        },
        "segments": {
          "type": "array",
          "items": { "$ref": "#/$defs/KpathSegment" },
          "description": "The straight segments of the path, in path order."
        },
        "fermi": {
          "type": "number",
          "description": "Fermi level in eV, on the absolute scale of `eigenvalues` (eigenvalues are not shifted by it)."
        },
        "fermi_energy_ev": {
          "type": "number",
          "description": "The Fermi level under the name the DOS kinds use. When both are present it equals `fermi`."
        },
        "spinor": {
          "type": "boolean",
          "default": false,
          "description": "True when the bands come from a two-component (spin-orbit) calculation: n_spin is then 1 and each band is one spinor state."
        },
        "n_spin": {
          "type": "integer",
          "minimum": 1,
          "maximum": 2,
          "description": "Number of spin channels; equals eigenvalues axis 0."
        },
        "n_kpoints": {
          "type": "integer",
          "minimum": 1,
          "description": "Number of k-points along the path; equals eigenvalues axis 1."
        },
        "n_bands": {
          "type": "integer",
          "minimum": 1,
          "description": "Number of bands; equals eigenvalues axis 2."
        },
        "channels": {
          "type": "array",
          "items": {
            "anyOf": [{ "$ref": "#/$defs/DosChannel" }, { "type": "string" }]
          },
          "description": "Fat-band channels, one per last-axis slice of `projections`. A string is shorthand for a channel object carrying only that `label`."
        },
        "title": { "type": "string", "description": "Display title of the band structure." },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional map from a field name of this payload, or the role of a member of the section, to the unit name of its values. The units are fixed by QVF spec § 4.3 (Units and numeric conventions); a declaration restates them and does not change them, so `fermi`, `fermi_energy_ev` and `eigenvalues` are `ev`.",
          "properties": {
            "fermi": { "const": "ev" },
            "fermi_energy_ev": { "const": "ev" },
            "eigenvalues": { "const": "ev" }
          }
        },
        "kind": { "const": "bands", "description": "Informational echo of the section kind." },
        "version": { "type": "string", "description": "Informational producer label for the payload layout; consumers do not rely on it." },
        "reciprocal_space": { "type": "boolean", "description": "Informational; k-points are always reciprocal-space coordinates." }
      }
    },
    "SectionDOSTotal": {
      "description": "Total density of states on an energy grid. Its metadata rides as optional fields on the section object (`n_spin`, `smearing`, `smearing_type`, `fermi_energy_ev`, `n_electrons`), not as members. Specified in QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kind": { "const": "dos.total" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["energies", "dos"],
          "properties": {
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "dos": { "$ref": "#/$defs/BinaryMember" }
          }
        },
        "n_spin": {
          "type": "integer",
          "enum": [1, 2],
          "description": "Number of spin channels: 1 (spin-unpolarized) or 2 (spin-polarized). OPTIONAL."
        },
        "smearing": {
          "type": "number",
          "minimum": 0,
          "description": "Width of the broadening applied to the DOS, in eV. OPTIONAL."
        },
        "smearing_type": {
          "type": "string",
          "description": "Name of the broadening function, for example \"gaussian\". OPTIONAL; free text in v1."
        },
        "fermi_energy_ev": {
          "type": "number",
          "description": "Fermi energy, in eV. OPTIONAL."
        },
        "n_electrons": {
          "type": "number",
          "minimum": 0,
          "description": "Number of electrons; may be fractional. OPTIONAL."
        }
      }
    },
    "SectionDOSProjected": {
      "description": "Projected density of states on an energy grid. Its metadata rides as optional fields on the section object, as for dos.total, plus `channels`, which labels the projection rows. Specified in QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kind": { "const": "dos.projected" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["energies", "projections"],
          "properties": {
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "projections": { "$ref": "#/$defs/DOSProjectedProjections" }
          }
        },
        "n_spin": {
          "type": "integer",
          "enum": [1, 2],
          "description": "Number of spin channels: 1 (spin-unpolarized) or 2 (spin-polarized). OPTIONAL."
        },
        "smearing": {
          "type": "number",
          "minimum": 0,
          "description": "Width of the broadening applied to the DOS, in eV. OPTIONAL."
        },
        "smearing_type": {
          "type": "string",
          "description": "Name of the broadening function, for example \"gaussian\". OPTIONAL; free text in v1."
        },
        "fermi_energy_ev": {
          "type": "number",
          "description": "Fermi energy, in eV. OPTIONAL."
        },
        "n_electrons": {
          "type": "number",
          "minimum": 0,
          "description": "Number of electrons; may be fractional. OPTIONAL."
        },
        "channels": {
          "type": "array",
          "description": "One label object per projection row, in row order. OPTIONAL. Every item field is optional, and items may carry further fields.",
          "items": {
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "atom": {
                "type": "integer",
                "minimum": 0,
                "description": "0-based index of the projected atom in the structure section."
              },
              "l": {
                "type": "integer",
                "minimum": 0,
                "description": "Angular momentum quantum number of the projection."
              },
              "m": {
                "type": "integer",
                "description": "Magnetic quantum number of the projection."
              },
              "spin": {
                "type": "integer",
                "enum": [0, 1],
                "description": "Spin channel: 0 = alpha (up), 1 = beta (down)."
              },
              "label": {
                "type": "string",
                "description": "Display label, for example \"O-2p\"."
              }
            }
          }
        }
      }
    },
    "DOSProjectedProjections": {
      "description": "Projected DOS of a `dos.projected` section: [n_spin, n_channels, n_points], or the legacy rank-2 form [n_channels, n_points], which means n_spin = 1. n_points is the length of `energies`; channel c is entry c of the section's `channels` list. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "shape": { "minItems": 2, "maxItems": 3 }
          }
        }
      ]
    },
    "SectionDOSCOOP": {
      "properties": {
        "kind": { "const": "dos.coop" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["energies", "projections", "integrated", "meta"],
          "properties": {
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "projections": { "$ref": "#/$defs/BinaryMember" },
            "integrated": { "$ref": "#/$defs/BinaryMember" },
            "meta": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SectionDOSCOHP": {
      "properties": {
        "kind": { "const": "dos.cohp" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["energies", "projections", "integrated", "meta"],
          "properties": {
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "projections": { "$ref": "#/$defs/BinaryMember" },
            "integrated": { "$ref": "#/$defs/BinaryMember" },
            "meta": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "DosChannel": {
      "type": "object",
      "additionalProperties": true,
      "required": ["label"],
      "description": "One projection channel of a DOS, fat-band or phonon projection: the atom, shell and component a slice of the projections belongs to. Typed-open: the fields below are typed and further keys are allowed. An absent field means the channel sums over that quantity (no `atom`: all atoms; no `l`: all shells; no `m`: all components of the shell). See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "atom": { "type": "integer", "minimum": 0, "description": "0-based index of the atom in the structure section." },
        "l": { "type": "integer", "minimum": 0, "description": "Angular momentum of the shell (0 = s, 1 = p, ...)." },
        "m": { "type": "integer", "description": "Component within a spherical shell, -l..l, as in QVF spec Appendix A.2." },
        "spin": { "type": "integer", "minimum": 0, "maximum": 1, "description": "0 (alpha) or 1 (beta) for a channel that is itself spin-resolved, which arises only in projections without a spin axis." },
        "label": { "type": "string", "description": "Display label, e.g. 'Fe-3d'." }
      }
    },
    "DosMetaPayload": {
      "type": "object",
      "additionalProperties": true,
      "description": "The JSON payload named by the `meta` member of a `dos.coop` or `dos.cohp` section: what the pair axis of `projections` and `integrated` means, plus broadening and Fermi level. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Typed-open: the fields below are typed and further keys are allowed. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "method": { "type": "string", "description": "The bonding analysis, conventionally 'coop' or 'cohp'." },
        "n_spin": { "type": "integer", "minimum": 1, "maximum": 2, "description": "Number of spin channels; with 2, `projections` and `integrated` carry a leading spin axis." },
        "fermi_energy_ev": { "type": "number", "description": "Absolute Fermi level in eV (`energies` are referenced to it at 0)." },
        "smearing": { "type": "number", "minimum": 0, "description": "Broadening width in eV." },
        "smearing_type": { "type": "string", "description": "Broadening function, e.g. 'gaussian'." },
        "pairs": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "array",
                "minItems": 2,
                "maxItems": 2,
                "items": { "type": "integer", "minimum": 0 }
              },
              {
                "type": "object",
                "required": ["i", "j"],
                "properties": {
                  "i": { "type": "integer", "minimum": 0 },
                  "j": { "type": "integer", "minimum": 0 },
                  "label": { "type": "string" },
                  "symbol_i": { "type": "string" },
                  "symbol_j": { "type": "string" },
                  "distance_ang": { "type": "number", "minimum": 0 }
                }
              }
            ]
          },
          "description": "The atom pairs, one per entry of the pair axis: [i, j], or an object {i, j, label?, symbol_i?, symbol_j?, distance_ang?} with 0-based atom indices and the distance in Å."
        },
        "pair_labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Display labels, one per entry of the pair axis."
        },
        "channels": {
          "type": "array",
          "items": {
            "allOf": [
              { "$ref": "#/$defs/DosChannel" },
              {
                "properties": {
                  "i": { "type": "integer", "minimum": 0 },
                  "j": { "type": "integer", "minimum": 0 }
                }
              }
            ]
          },
          "description": "Channel objects, one per entry of the pair axis; a pair channel names its two atoms as i and j."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional map from a field name of this payload, or the role of a member of the section, to the unit name of its values. The units are fixed by QVF spec § 4.3 (Units and numeric conventions); a declaration restates them and does not change them, so `fermi_energy_ev` and `energies` are `ev`.",
          "properties": {
            "fermi_energy_ev": { "const": "ev" },
            "energies": { "const": "ev" }
          }
        }
      }
    },
    "SectionStructureSymmetry": {
      "description": "Symmetry analysis of a structure. The `data` member's JSON payload is specified by `#/$defs/SymmetryPayload`; see QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "kind": { "const": "structure.symmetry" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["data"],
          "properties": {
            "data": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "SymmetryPayload": {
      "type": "object",
      "additionalProperties": true,
      "description": "The JSON payload named by a `structure.symmetry` section's `data` member: a symmetry analysis of the structure, as common symmetry finders report it. Permissive: the known fields are typed, the root stays open, and a later revision may tighten the definition. See QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "spacegroup_number": {
          "type": "integer",
          "minimum": 1,
          "maximum": 230,
          "description": "Space-group number of the International Tables for Crystallography."
        },
        "international": {
          "type": "string",
          "description": "Short international (Hermann-Mauguin) space-group symbol, e.g. 'Fm-3m'."
        },
        "hall": { "type": "string", "description": "Hall symbol of the space group." },
        "point_group": {
          "type": "string",
          "description": "Point-group symbol; Schoenflies notation is recommended, e.g. 'C2v'."
        },
        "hermann_mauguin": {
          "type": "string",
          "description": "The point group in Hermann-Mauguin notation, e.g. 'mm2'."
        },
        "space_group_number": {
          "type": "integer",
          "minimum": 1,
          "maximum": 230,
          "description": "The same quantity as `spacegroup_number`, under the name some producers write. When both are present they MUST agree."
        },
        "space_group_symbol": {
          "type": "string",
          "description": "The same quantity as `international`, under the name some producers write. When both are present they MUST agree."
        },
        "operations": {
          "type": "array",
          "description": "Symmetry operations x' = R x + t. For a periodic structure R and t act on fractional coordinates of the structure's lattice; for a molecule R acts on Cartesian coordinates and t is zero or absent.",
          "items": {
            "type": "object",
            "required": ["rotation"],
            "properties": {
              "rotation": {
                "type": "array",
                "minItems": 3,
                "maxItems": 3,
                "items": { "$ref": "#/$defs/Vec3" },
                "description": "Rotation part R: three rows."
              },
              "translation": { "$ref": "#/$defs/Vec3", "description": "Translation part t." }
            }
          }
        },
        "wyckoffs": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Wyckoff letter of each atom, in the order of the structure's atoms."
        },
        "equivalent_atoms": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "For each atom, the 0-based index of the representative atom of its symmetry-equivalence class."
        },
        "symprec": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Distance tolerance of the symmetry search, in Angstrom."
        }
      }
    },
    "SectionBonds": {
      "description": "Explicit connectivity of a structure as atom pairs. The `bonds` member's JSON payload is specified by `#/$defs/BondsPayload`, as is the optional `bonds` member of a `structure` section. The atom indices address the atoms of the structure the section's `structure_ref` names, else of the archive's first structure; an archive with several structures SHOULD set `structure_ref`. See QVF spec § 5.1 (structure and bonds).",
      "properties": {
        "kind": { "const": "bonds" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["bonds"],
          "properties": {
            "bonds": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "BondsPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["pairs"],
      "description": "The JSON payload of a `bonds` section's `bonds` member and of a `structure` section's optional `bonds` member: explicit connectivity as atom pairs. Strict: no keys other than those listed, except extension keys beginning with `x_`, here and in every pair. See QVF spec § 5.1 (structure and bonds) and § 5.7 (Analysis kinds).",
      "properties": {
        "pairs": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "patternProperties": { "^x_": {} },
            "required": ["i", "j"],
            "properties": {
              "i": {
                "type": "integer",
                "minimum": 0,
                "description": "0-based index of one atom in the structure's atoms."
              },
              "j": {
                "type": "integer",
                "minimum": 0,
                "description": "0-based index of the other atom."
              },
              "order": {
                "type": "number",
                "minimum": 0,
                "description": "Bond order. Absent means 1."
              }
            }
          }
        }
      }
    },
    "SectionBondOrders": {
      "description": "Bond-order table — Mayer / Wiberg bond orders with atom-pair labels and distances. The `bond_orders` member's JSON payload is specified by `#/$defs/BondOrdersPayload`; see QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "kind": { "const": "bond_orders" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["bond_orders"],
          "properties": {
            "bond_orders": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "BondOrdersPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["method", "pairs"],
      "description": "The JSON payload named by a `bond_orders` section's `bond_orders` member: computed bond orders per atom pair. Strict: no keys other than those listed, except extension keys beginning with `x_`, here and in every pair. See QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "method": {
          "type": "string",
          "minLength": 1,
          "description": "Bond-order definition. Lowercase names are recommended, e.g. 'mayer', 'wiberg' or 'nbo'."
        },
        "pairs": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "patternProperties": { "^x_": {} },
            "required": ["i", "j", "order"],
            "properties": {
              "i": {
                "type": "integer",
                "minimum": 0,
                "description": "0-based index of one atom in the structure's atoms."
              },
              "j": {
                "type": "integer",
                "minimum": 0,
                "description": "0-based index of the other atom."
              },
              "order": {
                "type": "number",
                "description": "Bond order under `method`. Some definitions yield small negative values, so the sign is not constrained."
              },
              "distance_ang": {
                "type": "number",
                "minimum": 0,
                "description": "Distance between the two atoms, in Angstrom."
              },
              "symbol_i": { "type": "string" },
              "symbol_j": { "type": "string" }
            }
          }
        }
      }
    },
    "SectionSCFHistory": {
      "description": "Per-iteration SCF convergence record. The `iterations` member's JSON payload is specified by `#/$defs/ScfHistoryPayload`; see QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "kind": { "const": "scf_history" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["iterations"],
          "properties": {
            "iterations": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "ScfHistoryPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["iterations"],
      "description": "The JSON payload named by a `scf_history` section's `iterations` member: one record per SCF iteration. Strict: no keys other than those listed, except extension keys beginning with `x_`, here and in every record. See QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "iterations": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "patternProperties": { "^x_": {} },
            "required": ["iter", "energy_eh"],
            "properties": {
              "iter": {
                "type": "integer",
                "minimum": 0,
                "description": "Iteration number, as the producer counts them."
              },
              "energy_eh": {
                "type": "number",
                "description": "Total energy after the iteration, in Hartree."
              },
              "delta_e": {
                "type": "number",
                "description": "Energy change from the previous iteration, in Hartree."
              },
              "diis_error": {
                "type": "number",
                "description": "DIIS error norm, in atomic units."
              },
              "rms_density_change": {
                "type": "number",
                "description": "Root-mean-square change of the density matrix from the previous iteration, in atomic units."
              }
            }
          }
        },
        "converged": {
          "type": "boolean",
          "description": "Whether the SCF met its convergence criteria. Absent means not stated."
        }
      }
    },
    "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" },
        "size": { "$ref": "#/$defs/MemberSize" },
        "media_type": { "$ref": "#/$defs/MediaType" }
      }
    },
    "SectionCitations": {
      "properties": {
        "kind": { "const": "citations" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["references"],
          "properties": {
            "references": { "$ref": "#/$defs/CitationsReferences" }
          }
        }
      }
    },
    "OpaqueBinaryMember": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "format", "sha256"],
      "description": "Opaque bytes carried as a binary member with no dtype/shape. The owning section kind defines the payload's encoding (e.g. UTF-8 text for run.record input/log).",
      "properties": {
        "path": { "$ref": "#/$defs/ZipPath" },
        "format": { "const": "binary" },
        "sha256": { "$ref": "#/$defs/Sha256Hex" },
        "size": { "$ref": "#/$defs/MemberSize" },
        "media_type": { "$ref": "#/$defs/MediaType" }
      }
    },
    "SectionRunRecord": {
      "description": "Self-contained record of one program invocation: the verbatim input handed to a quantum-chemistry code and/or the full log/output it produced, plus auxiliary attachments. `program` names the code the input/log belong to — which may differ from the root `source.program` when the archive was written by a converter. `input` and `log` are opaque binary members that MUST decode as UTF-8 text; `attachment.*` members carry arbitrary bytes described by the optional `files` index.",
      "properties": {
        "kind": { "const": "run.record" },
        "program": {
          "type": "string",
          "minLength": 1,
          "description": "The program that consumed `input` / produced `log` (e.g. 'vibe-qc', 'orca'). Lowercase identifiers recommended."
        },
        "program_version": { "type": "string" },
        "command": {
          "type": "string",
          "description": "Command line used to launch the run, as one string."
        },
        "exit_status": { "type": "integer" },
        "started_utc": {
          "type": "string",
          "description": "Run start, ISO 8601 UTC (e.g. '2026-07-24T12:00:00Z')."
        },
        "finished_utc": {
          "type": "string",
          "description": "Run end, ISO 8601 UTC."
        },
        "sequence": {
          "type": "integer",
          "minimum": 0,
          "description": "Ordering index when an archive carries multiple run records (multi-step workflows)."
        },
        "job_ref": {
          "type": "string",
          "description": "Id of the `job.spec` section this run executed. It must name a section of kind `job.spec` in this archive. In an archive with several `job.spec` sections (a job set) it is how a reader tells which job ran; see QVF spec § 5.8 (run.record — self-contained run records) and QVF spec § 5.9 (job.spec — declarative job specification), under Job sets."
        },
        "run_status": {
          "enum": ["running", "converged", "failed"],
          "description": "Outcome of this run, with the meanings of the root provenance.run_status. In a job set it is the status of the job that `job_ref` names; see QVF spec § 5.8 (run.record — self-contained run records)."
        },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "input": { "$ref": "#/$defs/OpaqueBinaryMember" },
            "log": { "$ref": "#/$defs/OpaqueBinaryMember" },
            "files": { "$ref": "#/$defs/JsonMember" }
          },
          "patternProperties": {
            "^attachment\\.[A-Za-z0-9_.-]+$": { "$ref": "#/$defs/OpaqueBinaryMember" }
          },
          "anyOf": [
            { "required": ["input"] },
            { "required": ["log"] }
          ]
        }
      },
      "required": ["id", "kind", "members", "program"]
    },
    "RunRecordFilesPayload": {
      "type": "object",
      "additionalProperties": false,
      "description": "The JSON payload named by a `run.record` section's `files` member: an index from member role to what the member was before it was embedded. Every key names a member of the same section (`input`, `log` or an `attachment.<suffix>`), so the index has no vendor escape at its top level; each entry is strict apart from keys beginning with x_. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. See QVF spec § 5.8 (run.record — self-contained run records).",
      "patternProperties": {
        "^(input|log|attachment\\.[A-Za-z0-9_.-]+)$": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "properties": {
            "filename": { "type": "string", "minLength": 1, "description": "Original file name, without directories." },
            "description": { "type": "string", "description": "What the file is, for display." },
            "media_type": { "type": "string", "minLength": 1, "description": "IANA media type of the bytes, e.g. 'text/plain' or 'chemical/x-xyz'." },
            "truncated": { "type": "boolean", "description": "True when the stored bytes are not the complete file, e.g. a log embedded before the run ended." }
          }
        }
      }
    },
    "SectionJobSpec": {
      "description": "Declarative specification of the calculation an archive requests — before, and independent of, any results it carries; see QVF spec § 5.9 (job.spec — declarative job specification). Together with a `structure` section it makes the archive an executable input: a runner reconstructs the job from the `spec` payload, executes it, and writes results plus a `run.record` back into the same container. The payload is declarative data, never code.",
      "properties": {
        "kind": { "const": "job.spec" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["spec"],
          "properties": {
            "spec": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "JobSpecPayload": {
      "type": "object",
      "additionalProperties": true,
      "required": ["job_type"],
      "description": "The JSON payload named by a `job.spec` section's `spec` member (conventionally `job_spec/spec.json`). It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition — a validator loads the member's bytes and checks them against it. The root is open for forward growth, but engine-specific keywords SHOULD live under `options`, keeping the typed top level portable across codes; see QVF spec § 5.9 (job.spec — declarative job specification).",
      "properties": {
        "job_type": {
          "enum": ["molecular", "periodic"],
          "description": "Which class of engine runs the job. Periodicity of the geometry itself is carried by the structure section's pbc/lattice_vectors; job_type selects the runner, it does not restate periodicity."
        },
        "method": {
          "type": "string",
          "minLength": 1,
          "description": "Method identifier (e.g. 'rhf', 'rks', 'ccsd(t)', 'gfn2'). Producer-neutral lowercase recommended. Absent means the engine's default."
        },
        "basis": {
          "anyOf": [
            { "type": "string", "minLength": 1 },
            { "type": "null" },
            {
              "const": "",
              "deprecated": true,
              "description": "Deprecated spelling of null, which producers SHOULD NOT write; consumers read it as null."
            }
          ],
          "description": "Basis-set name (e.g. 'def2-svp'), or null: the method takes no basis set (a semiempirical or tight-binding method). Absent means the engine's default. The empty string is a deprecated spelling of null; see QVF spec § 5.9 (job.spec — declarative job specification)."
        },
        "functional": {
          "anyOf": [
            { "type": "string", "minLength": 1 },
            { "type": "null" },
            {
              "const": "",
              "deprecated": true,
              "description": "Deprecated spelling of null, which producers SHOULD NOT write; consumers read it as null."
            }
          ],
          "description": "Exchange-correlation functional name (e.g. 'pbe0'), for DFT methods, or null: the method takes no functional (Hartree-Fock, a correlated wavefunction or a semiempirical method). Absent means the engine's default. The empty string is a deprecated spelling of null; see QVF spec § 5.9 (job.spec — declarative job specification)."
        },
        "charge": {
          "type": "integer",
          "description": "Net charge. Absent means 0. Authoritative for the job — never inferred from the structure."
        },
        "multiplicity": {
          "type": "integer",
          "minimum": 1,
          "description": "Spin multiplicity 2S+1. Absent means 1."
        },
        "kpoints": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "type": "integer", "minimum": 1 },
          "description": "[n1, n2, n3] Monkhorst-Pack mesh. Periodic jobs only."
        },
        "tasks": {
          "type": "array",
          "items": { "type": "string", "minLength": 1 },
          "description": "Ordered task identifiers, e.g. ['single_point'], ['optimize', 'hessian']. Absent means a single point."
        },
        "structure_ref": {
          "type": "string",
          "minLength": 1,
          "description": "Id of the `structure` section the job runs on. A validator resolves it to a section of kind `structure`. A `structure_ref` on the `job.spec` section object takes precedence and is the preferred carrier, because it can be read from the manifest; producers keep the two equal. In an archive with several `structure` sections a job without either is ambiguous, and a runner refuses it; see QVF spec § 5.9 (job.spec — declarative job specification), under Job sets, and QVF spec § 4.1 (Section object)."
        },
        "solvation": { "$ref": "#/$defs/JobSpecSolvation" },
        "dispersion": {
          "type": "string",
          "minLength": 1,
          "description": "Dispersion correction, by its conventional lowercase name, e.g. 'd3bj' or 'd4'. Absent means none beyond what the method implies."
        },
        "relativistic": {
          "type": "string",
          "minLength": 1,
          "description": "Scalar-relativistic treatment, by its conventional lowercase name, e.g. 'zora', 'x2c' or 'dkh2'. Absent means none."
        },
        "scf": { "$ref": "#/$defs/JobSpecScf" },
        "geometry": { "$ref": "#/$defs/JobSpecGeometry" },
        "resources": { "$ref": "#/$defs/JobSpecResources" },
        "options": {
          "type": "object",
          "description": "Additional engine-specific keywords (JSON-safe values). A runner that does not recognize an option MUST refuse the job rather than silently drop it."
        }
      }
    },
    "JobSpecSolvation": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["model"],
      "description": "Implicit solvation of a job: the `solvation` field of `JobSpecPayload`; see QVF spec § 5.9 (job.spec — declarative job specification). Strict: any other key is an error unless it begins with `x_`; engine-specific keywords go under `options`.",
      "properties": {
        "model": {
          "type": "string",
          "minLength": 1,
          "description": "Solvation model, by its conventional lowercase name, e.g. 'pcm', 'cpcm', 'smd' or 'cosmo'."
        },
        "solvent": {
          "type": "string",
          "minLength": 1,
          "description": "Solvent, by name, e.g. 'water'."
        },
        "epsilon": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Static dielectric constant of the solvent, dimensionless."
        }
      }
    },
    "JobSpecScf": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "Self-consistent-field settings of a job: the `scf` field of `JobSpecPayload`; see QVF spec § 5.9 (job.spec — declarative job specification). Strict: any other key is an error unless it begins with `x_`; engine-specific keywords go under `options`.",
      "properties": {
        "convergence": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Convergence threshold of the SCF energy change, in hartree."
        },
        "max_iterations": {
          "type": "integer",
          "minimum": 1,
          "description": "Maximum number of SCF iterations."
        },
        "guess": {
          "type": "string",
          "minLength": 1,
          "description": "Initial guess, by its conventional lowercase name, e.g. 'core', 'sad' or 'huckel'."
        },
        "damping": {
          "type": "number",
          "description": "Damping factor applied to the density or Fock update, dimensionless."
        }
      }
    },
    "JobSpecGeometry": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "Geometry-optimisation settings of a job: the `geometry` field of `JobSpecPayload`; see QVF spec § 5.9 (job.spec — declarative job specification). Strict: any other key is an error unless it begins with `x_`; engine-specific keywords go under `options`.",
      "properties": {
        "convergence": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Convergence threshold of the optimisation: the largest Cartesian gradient component, in hartree/bohr."
        },
        "max_steps": {
          "type": "integer",
          "minimum": 1,
          "description": "Maximum number of optimisation steps."
        },
        "coordinates": {
          "enum": ["cartesian", "internal", "redundant"],
          "description": "Coordinate system the optimiser steps in."
        }
      }
    },
    "JobSpecResources": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "Resources a job would like: the `resources` field of `JobSpecPayload`. These are hints, not requirements: a runner uses what it has and may use less. What a run actually used is recorded in `provenance` (`n_threads`, `n_mpi_ranks`, `n_gpus`, `wall_seconds`). See QVF spec § 5.9 (job.spec — declarative job specification). Strict: any other key is an error unless it begins with `x_`.",
      "properties": {
        "n_cores": {
          "type": "integer",
          "minimum": 1,
          "description": "Number of CPU cores to use."
        },
        "memory_mb": {
          "type": "integer",
          "minimum": 1,
          "description": "Memory to use, in megabytes."
        },
        "walltime_s": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Wall-clock time to allow, in seconds."
        }
      }
    },
    "SectionBasisAO": {
      "description": "Basis-function visualisation — one atomic orbital (contracted shell or individual primitive) evaluated on a 3-D grid. The `ao_metadata` object carries per-function quantum numbers and provenance; the `grid` + `data` members follow the same contract as all volume.* sections.",
      "properties": {
        "kind": { "const": "basis.ao" },
        "ao_metadata": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "atom_index",
            "atom_symbol",
            "shell_index",
            "primitive_index",
            "angular_momentum",
            "shell_type",
            "exponent",
            "coefficient",
            "is_primitive",
            "is_contracted",
            "ao_index"
          ],
          "properties": {
            "atom_index": { "type": "integer", "minimum": 0 },
            "atom_symbol": { "type": "string", "minLength": 1, "maxLength": 3 },
            "shell_index": { "type": "integer", "minimum": 0 },
            "primitive_index": { "type": "integer", "minimum": 0 },
            "angular_momentum": {
              "description": "[l, m]. Element 0 is always the shell's angular momentum l. Element 1 is the real-spherical-harmonic index m in [-l, +l] and is meaningful ONLY when `cartesian_powers` is absent; when `cartesian_powers` is present the component is a Cartesian monomial with no magnetic quantum number, element 1 is 0 by convention, and a consumer MUST ignore it. See QVF spec Appendix A.3.",
              "type": "array",
              "items": { "type": "integer" },
              "minItems": 2,
              "maxItems": 2
            },
            "cartesian_powers": {
              "description": "[lx, ly, lz] powers of the Cartesian monomial this AO is, with lx+ly+lz == angular_momentum[0]. Present if and only if the AO is a component of a Cartesian (`pure: false`) shell, which has (l+1)(l+2)/2 components rather than 2l+1 and therefore no m. Absent for spherical AOs.",
              "type": "array",
              "items": { "type": "integer", "minimum": 0 },
              "minItems": 3,
              "maxItems": 3
            },
            "shell_type": {
              "type": "string",
              "enum": ["s", "p", "sp", "d", "f", "g", "h"]
            },
            "exponent": { "type": "number", "exclusiveMinimum": 0 },
            "coefficient": { "type": "number" },
            "is_primitive": { "type": "boolean" },
            "is_contracted": { "type": "boolean" },
            "ao_index": { "type": "integer", "minimum": 0 },
            "basis_label": { "type": "string" }
          }
        },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      }
    },
    "SectionEquationOfState": {
      "description": "Equation of state — volume-energy data points and fitted EOS parameters. Specified in QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kind": { "const": "equation_of_state" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["volumes", "energies", "fit"],
          "properties": {
            "volumes": { "$ref": "#/$defs/BinaryMember" },
            "energies": { "$ref": "#/$defs/BinaryMember" },
            "fit": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "EosFitPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["model"],
      "description": "The JSON payload named by an `equation_of_state` section's `fit` member: the fitted equation-of-state model and its parameters. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "model": {
          "enum": ["birch_murnaghan", "murnaghan", "vinet", "poirier_tarantola", "polynomial"],
          "description": "The fitted E(V) form: third-order Birch-Murnaghan, Murnaghan, Vinet, third-order Poirier-Tarantola, or a polynomial in V from which V0, E0, B0 and B0_prime are derived."
        },
        "V0": { "type": "number", "description": "Equilibrium volume in Å³." },
        "E0": { "type": "number", "description": "Energy at V0 in eV." },
        "B0": { "type": "number", "description": "Bulk modulus at V0 in GPa." },
        "B0_prime": { "type": "number", "description": "Pressure derivative of the bulk modulus at V0, dimensionless." },
        "residual_rms": { "type": "number", "minimum": 0, "description": "Root-mean-square residual of the fit over the data points, in eV." },
        "n_points": { "type": "integer", "minimum": 0, "description": "Number of (volume, energy) points the fit used." },
        "pressures_gpa": {
          "type": "array",
          "items": { "type": "number" },
          "description": "Pressure of the fitted model at each volume point, in GPa, parallel to `volumes`."
        },
        "energy_unit": { "type": "string", "description": "Informational restatement of the energy unit, eV; see QVF spec § 4.3 (Units and numeric conventions)." },
        "volume_unit": { "type": "string", "description": "Informational restatement of the volume unit, Å³; see QVF spec § 4.3 (Units and numeric conventions)." },
        "pressure_unit": { "type": "string", "description": "Informational restatement of the pressure unit, GPa; see QVF spec § 4.3 (Units and numeric conventions)." }
      }
    },
    "SectionFermiSurface": {
      "description": "Fermi surface — 3D k-space energy grid near E_F for metallic periodic systems. Specified in QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kind": { "const": "fermi_surface" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["mesh", "energies"],
          "properties": {
            "mesh": { "$ref": "#/$defs/JsonMember" },
            "energies": { "$ref": "#/$defs/Volume4DBinary" }
          }
        }
      }
    },
    "FermiMeshPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "The JSON payload named by a `fermi_surface` section's `mesh` member: the k-point mesh that the first three axes of `energies` sample, and the cell it lives in. Grid point (i1, i2, i3) of a uniform mesh lies at fractional reciprocal-lattice coordinates (i1/nk1 + shift[0], i2/nk2 + shift[1], i3/nk3 + shift[2]). It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "shape": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "type": "integer", "minimum": 1 },
          "description": "Mesh dimensions [nk1, nk2, nk3]; equal to the first three axes of `energies`."
        },
        "nk1": { "type": "integer", "minimum": 1, "description": "Mesh dimension along b1 as a separate key; equals shape[0] when both are present." },
        "nk2": { "type": "integer", "minimum": 1, "description": "Mesh dimension along b2; equals shape[1] when both are present." },
        "nk3": { "type": "integer", "minimum": 1, "description": "Mesh dimension along b3; equals shape[2] when both are present." },
        "shift": {
          "$ref": "#/$defs/Vec3",
          "default": [0.0, 0.0, 0.0],
          "description": "Position of grid point (0, 0, 0) in fractional reciprocal-lattice coordinates. Absent means a Γ-centred mesh."
        },
        "symmetry_expanded": {
          "type": "boolean",
          "description": "True when the producer filled the full mesh by applying symmetry operations to an irreducible set of computed k-points."
        },
        "kpoints": {
          "type": "array",
          "items": { "$ref": "#/$defs/Vec3" },
          "description": "Explicit fractional coordinates of every grid point, for a mesh that is not uniform: entry (i1 * nk2 + i2) * nk3 + i3 is grid point (i1, i2, i3). When present it replaces the uniform-mesh formula."
        },
        "fermi_energy_ev": { "type": "number", "description": "Absolute Fermi level in eV; `energies` hold E(k) - E_F." },
        "n_spin": { "type": "integer", "minimum": 1, "maximum": 2, "description": "Number of spin channels of the underlying calculation." },
        "band_indices": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "0-based index, in the producer's full band list, of each band along the last axis of `energies`."
        },
        "lattice_vectors": {
          "$ref": "#/$defs/Lattice3x3",
          "description": "Real-space cell as three row vectors in Å (the structure convention); the reciprocal lattice follows from it."
        },
        "reciprocal_lattice": {
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": { "$ref": "#/$defs/Vec3" },
          "description": "Reciprocal lattice vectors b1, b2, b3 as rows, in 1/Å, including the 2π factor (a_i · b_j = 2π δ_ij)."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional map from a field name of this payload, or the role of a member of the section, to the unit name of its values. The units are fixed by QVF spec § 4.3 (Units and numeric conventions); a declaration restates them and does not change them, so `fermi_energy_ev` and `energies` are `ev` and `lattice_vectors` is `angstrom`.",
          "properties": {
            "fermi_energy_ev": { "const": "ev" },
            "energies": { "const": "ev" },
            "lattice_vectors": { "const": "angstrom" }
          }
        }
      }
    },
    "SectionPhononBands": {
      "description": "Phonon band structure — q-path and phonon frequencies along a Brillouin-zone path, with optional phonon eigenvectors. Specified in QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kind": { "const": "phonon_bands" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["qpath", "frequencies"],
          "properties": {
            "qpath": { "$ref": "#/$defs/JsonMember" },
            "frequencies": { "$ref": "#/$defs/BinaryMember" },
            "eigenvectors": {
              "description": "OPTIONAL phonon eigenvectors, float64: [n_q, n_modes, n_atoms, 3] when real, or [n_q, n_modes, n_atoms, 3, 2] when complex, with the last axis [re, im] as for complex wavefunction.gto coefficients. The first two axes match `frequencies`. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
              "allOf": [
                { "$ref": "#/$defs/BinaryMember" },
                {
                  "properties": {
                    "dtype": { "const": "float64" },
                    "shape": {
                      "anyOf": [
                        {
                          "minItems": 4,
                          "maxItems": 4,
                          "prefixItems": [{}, {}, {}, { "const": 3 }]
                        },
                        {
                          "minItems": 5,
                          "maxItems": 5,
                          "prefixItems": [{}, {}, {}, { "const": 3 }, { "const": 2 }]
                        }
                      ]
                    }
                  }
                }
              ]
            }
          }
        }
      }
    },
    "QpathPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "The JSON payload named by a `phonon_bands` section's `qpath` member: the q-point path the frequencies are sampled on, laid out like a bands kpath. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. No field is required. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kpoints": {
          "type": "array",
          "items": { "$ref": "#/$defs/Vec3" },
          "description": "Fractional reciprocal-lattice coordinates of every q-point along the path, in the order of frequencies axis 0."
        },
        "labels": {
          "type": "array",
          "items": { "type": "string" },
          "description": "One label per q-point along the path; an empty string marks an unlabelled point."
        },
        "segments": {
          "type": "array",
          "items": { "$ref": "#/$defs/KpathSegment" },
          "description": "The straight segments of the path, in path order."
        },
        "n_kpoints": { "type": "integer", "minimum": 1, "description": "Number of q-points along the path; equals frequencies axis 0." },
        "n_atoms": { "type": "integer", "minimum": 1, "description": "Number of atoms in the cell." },
        "n_modes": { "type": "integer", "minimum": 1, "description": "Number of phonon branches (3 n_atoms); equals frequencies axis 1." },
        "has_eigenvectors": { "type": "boolean", "description": "Whether the section carries mode eigenvectors." },
        "channels": {
          "type": "array",
          "items": { "$ref": "#/$defs/DosChannel" },
          "description": "Projection channels of atom-resolved phonon bands."
        },
        "title": { "type": "string", "description": "Display title of the phonon band structure." },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional map from a field name of this payload, or the role of a member of the section, to the unit name of its values. The units are fixed by QVF spec § 4.3 (Units and numeric conventions); a declaration restates them and does not change them, so `frequencies` is `cm-1`.",
          "properties": {
            "frequencies": { "const": "cm-1" }
          }
        }
      }
    },
    "SectionPhononDOS": {
      "description": "Phonon density of states — frequency grid and total phonon DOS, with an optional projected phonon DOS. Specified in QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "kind": { "const": "phonon_dos" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["meta", "frequencies", "dos"],
          "properties": {
            "meta": { "$ref": "#/$defs/JsonMember" },
            "frequencies": { "$ref": "#/$defs/BinaryMember" },
            "dos": { "$ref": "#/$defs/BinaryMember" },
            "projected": {
              "description": "OPTIONAL projected phonon DOS, float64 [n_channels, n_points]: row c is the DOS projected on channel c, on the `frequencies` grid. The `channels` array of the `meta` member labels the rows, in order. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
              "allOf": [
                { "$ref": "#/$defs/BinaryMember" },
                {
                  "properties": {
                    "dtype": { "const": "float64" },
                    "shape": { "minItems": 2, "maxItems": 2 }
                  }
                }
              ]
            }
          }
        }
      }
    },
    "PhononMetaPayload": {
      "type": "object",
      "additionalProperties": true,
      "description": "The JSON payload named by a `phonon_dos` section's `meta` member: counts, broadening, and the channels of a projected phonon DOS. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Typed-open: the fields below are typed and further keys are allowed; an empty object is valid. See QVF spec § 5.6 (Bands, DOS, and periodic kinds).",
      "properties": {
        "n_atoms": { "type": "integer", "minimum": 1, "description": "Number of atoms in the cell." },
        "n_modes": { "type": "integer", "minimum": 1, "description": "Number of phonon branches (3 n_atoms)." },
        "smearing": { "type": "number", "minimum": 0, "description": "Broadening width in cm⁻¹." },
        "smearing_type": { "type": "string", "description": "Broadening function, e.g. 'gaussian'." },
        "channels": {
          "type": "array",
          "items": { "$ref": "#/$defs/DosChannel" },
          "description": "Channels of a projected phonon DOS, one per projection row."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional map from a field name of this payload, or the role of a member of the section, to the unit name of its values. The units are fixed by QVF spec § 4.3 (Units and numeric conventions); a declaration restates them and does not change them, so `frequencies` is `cm-1`.",
          "properties": {
            "frequencies": { "const": "cm-1" }
          }
        }
      }
    },
    "SectionTopologyQTAIM": {
      "description": "QTAIM topological analysis — critical points and bond paths from electron-density topology. The `critical_points` member's JSON payload is specified by `#/$defs/QtaimPayload`; see QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "kind": { "const": "topology.qtaim" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["critical_points"],
          "properties": {
            "critical_points": { "$ref": "#/$defs/JsonMember" }
          }
        }
      }
    },
    "QtaimPayload": {
      "type": "object",
      "additionalProperties": true,
      "required": ["points"],
      "description": "The JSON payload named by a `topology.qtaim` section's `critical_points` member: critical points of the electron density and the bond paths joining them. Permissive root with typed points: the known fields are typed, the root and each point stay open, and a later revision may tighten the definition. Every position (a point's `position`, a bond-path vertex) is Cartesian, in the unit `units.position` declares, and in Angstrom, the unit of the structure the points overlay, when that is absent. The default is provisional pending a maintainer decision, so producers SHOULD declare `units.position`; see QVF spec § 5.7 (Analysis kinds).",
      "properties": {
        "points": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["type", "position"],
            "properties": {
              "type": {
                "enum": ["bcp", "rcp", "ccp", "ncp"],
                "description": "Critical-point type by Hessian signature: bond (3,-1), ring (3,+1), cage (3,+3), nuclear (3,-3)."
              },
              "position": { "$ref": "#/$defs/Vec3", "description": "Cartesian position, in the unit `units.position` declares (default Angstrom)." },
              "rho": { "type": "number", "description": "Electron density at the point." },
              "laplacian": { "type": "number", "description": "Laplacian of the electron density at the point." },
              "ellipticity": { "type": "number", "description": "Ellipticity of the density at the point; meaningful for a bond critical point." },
              "atom_pair": {
                "type": "array",
                "items": { "type": "integer", "minimum": 0 },
                "minItems": 2,
                "maxItems": 2,
                "description": "For a bond critical point: 0-based indices of the two atoms it connects."
              },
              "atoms": {
                "type": "array",
                "items": { "type": "integer", "minimum": 0 },
                "description": "0-based indices of the atoms the point belongs to, e.g. the nucleus of a nuclear critical point or the ring atoms of a ring critical point."
              }
            }
          }
        },
        "bond_paths": {
          "type": "array",
          "description": "Gradient paths of the density joining two nuclei through a bond critical point.",
          "items": {
            "type": "object",
            "properties": {
              "atoms": {
                "type": "array",
                "items": { "type": "integer", "minimum": 0 },
                "minItems": 2,
                "maxItems": 2,
                "description": "0-based indices of the two atoms the path joins."
              },
              "path": {
                "type": "array",
                "items": { "$ref": "#/$defs/Vec3" },
                "description": "Vertices of the path as a polyline, in the position unit."
              }
            }
          }
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Unit names of the payload's numeric fields. `position` names the unit of every position; another key names the unit of the point field of the same name, for which v1 fixes no default; see QVF spec § 4.3 (Units and numeric conventions).",
          "properties": {
            "position": {
              "$ref": "#/$defs/UnitName",
              "default": "angstrom",
              "description": "Unit name of every point position and bond-path vertex, a length. Absent means 'angstrom'."
            }
          }
        }
      }
    },
    "SectionForces": {
      "description": "First derivatives of the energy at one geometry: the nuclear energy gradient (the forces are its negative) and, for a periodic system, the stress. The gradient rows follow the atoms of the structure named by the section-level structure_ref when present, else by meta.structure_ref, else of the archive's only structure section. See QVF spec § 5.10 (forces — nuclear gradient and stress).",
      "properties": {
        "kind": { "const": "forces" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["gradient"],
          "properties": {
            "gradient": { "$ref": "#/$defs/ForcesGradient" },
            "stress": { "$ref": "#/$defs/ForcesStress" },
            "meta": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "ForcesGradient": {
      "description": "The energy gradient dE/dR, float64 [n_atoms, 3], in hartree/bohr: row a holds the derivatives with respect to the x, y and z coordinates of atom a. The force on an atom is the negative of its row. That n_atoms matches the structure is checked by validators, not by this schema. See QVF spec § 5.10 (forces — nuclear gradient and stress).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 2, "maxItems": 2, "prefixItems": [{}, { "const": 3 }] }
          }
        }
      ]
    },
    "ForcesStress": {
      "description": "OPTIONAL stress tensor of a periodic system, float64 [3, 3], in hartree/bohr^3: sigma_ij = (1/V) dE/d(epsilon_ij) for the strain epsilon and the cell volume V, so the pressure is -(sigma_xx + sigma_yy + sigma_zz)/3. Symmetric. See QVF spec § 5.10 (forces — nuclear gradient and stress).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 2, "maxItems": 2, "prefixItems": [{ "const": 3 }, { "const": 3 }] }
          }
        }
      ]
    },
    "ForcesMetaPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "The JSON payload named by a `forces` section's `meta` member. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. No field is required. See QVF spec § 5.10 (forces — nuclear gradient and stress).",
      "properties": {
        "structure_ref": {
          "type": "string",
          "minLength": 1,
          "description": "Id of the structure section whose atoms the gradient rows follow. A section-level structure_ref takes precedence when both are present."
        },
        "method": {
          "type": "string",
          "minLength": 1,
          "description": "Method of the energy that was differentiated, e.g. 'rks'."
        },
        "convention": {
          "enum": ["gradient"],
          "description": "What the gradient member holds: 'gradient', the energy gradient dE/dR, is the only value in v1. Absent means 'gradient'."
        },
        "units": { "$ref": "#/$defs/DerivativeUnits" }
      }
    },
    "DerivativeUnits": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "Declared units of an energy-derivative payload (forces, hessian): `energy` and `length` name the units the derivatives are taken in. v1 fixes them at hartree and bohr, so a declaration restates them and cannot name another unit; see QVF spec § 4.3 (Units and numeric conventions).",
      "properties": {
        "energy": { "const": "hartree", "description": "Energy unit of the derivatives: hartree." },
        "length": { "const": "bohr", "description": "Length unit of the derivatives: bohr." }
      }
    },
    "SectionHessian": {
      "description": "Second derivatives of the energy with respect to the nuclear Cartesian coordinates at one geometry. The atoms are resolved as for a forces section. See QVF spec § 5.11 (hessian — Cartesian second derivatives).",
      "properties": {
        "kind": { "const": "hessian" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["matrix"],
          "properties": {
            "matrix": { "$ref": "#/$defs/HessianMatrix" },
            "meta": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "HessianMatrix": {
      "description": "The Hessian d2E/(dx_i dx_j), float64 [3N, 3N] for N atoms, symmetric; index i = 3a + c belongs to Cartesian component c (x, y, z) of atom a. In hartree/bohr^2, or hartree/(bohr^2 amu) when meta.mass_weighted is true. That the two extents are equal, divisible by 3 and match the structure is checked by validators, not by this schema. See QVF spec § 5.11 (hessian — Cartesian second derivatives).",
      "allOf": [
        { "$ref": "#/$defs/BinaryMember" },
        {
          "properties": {
            "dtype": { "const": "float64" },
            "shape": { "minItems": 2, "maxItems": 2 }
          }
        }
      ]
    },
    "HessianMetaPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "The JSON payload named by a `hessian` section's `meta` member. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. No field is required, but a mass-weighted matrix requires atom_masses_amu. See QVF spec § 5.11 (hessian — Cartesian second derivatives).",
      "properties": {
        "structure_ref": {
          "type": "string",
          "minLength": 1,
          "description": "Id of the structure section whose atoms index the matrix. A section-level structure_ref takes precedence when both are present."
        },
        "mass_weighted": {
          "type": "boolean",
          "default": false,
          "description": "True when element (i, j) of the matrix is divided by sqrt(m_a m_b) for the atoms a and b of i and j, with the masses of atom_masses_amu, which is then required. Absent means false."
        },
        "projected": {
          "type": "boolean",
          "default": false,
          "description": "True when the rigid-body translations and, for a non-periodic system, rotations have been projected out of the matrix. Absent means false."
        },
        "atom_masses_amu": {
          "type": "array",
          "items": { "type": "number", "exclusiveMinimum": 0 },
          "description": "Mass of each atom in unified atomic mass units, in atom order: one entry per atom, N in all."
        },
        "units": { "$ref": "#/$defs/DerivativeUnits" }
      },
      "if": {
        "properties": { "mass_weighted": { "const": true } },
        "required": ["mass_weighted"]
      },
      "then": { "required": ["atom_masses_amu"] }
    },
    "SectionExcitedStates": {
      "description": "Electronically excited states of one calculation (TD-DFT, CIS, ADC, EOM-CC and similar methods): a table of states with their excitation energies, transition properties and dominant orbital excitations, in the JSON member `states`, whose payload is `#/$defs/ExcitedStatesPayload`. A state may name its natural transition orbitals and its transition or difference density. See QVF spec § 5.12 (excited_states — excited states and transition properties).",
      "properties": {
        "kind": { "const": "excited_states" },
        "wavefunction_ref": {
          "type": "string",
          "description": "Id of the `wavefunction.gto` section of the reference state, usually the ground state, whose orbitals the `from_mo` and `to_mo` of the contributions index. It must name a section of kind `wavefunction.gto` in this archive; see QVF spec § 5.12 (excited_states — excited states and transition properties)."
        },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["states"],
          "properties": {
            "states": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "SectionPropertiesElectric": {
      "description": "Electric multipole moments and polarizabilities of the system: the dipole, quadrupole and octupole, and the polarizability and hyperpolarizability, each in the fixed unit of the spec. The single `properties` member's JSON payload is specified by `#/$defs/ElectricPropertiesPayload`; see QVF spec § 5.13 (Property kinds).",
      "properties": {
        "kind": { "const": "properties.electric" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["properties"],
          "properties": {
            "properties": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "ExcitedStatesPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["states"],
      "description": "The JSON payload named by an `excited_states` section's `states` member. It is an archive member, not part of manifest.json, so nothing in the manifest $refs this definition; a validator loads the member's bytes and checks them against it. `states` lists the states in ascending order of their unique `index`; `meta` describes the calculation. That the indices are unique and ascending, that `meta.n_states` equals the number of states, that the references resolve and that the contributions index existing orbitals is checked by validators, not by this schema. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.12 (excited_states — excited states and transition properties).",
      "properties": {
        "states": {
          "type": "array",
          "items": { "$ref": "#/$defs/ExcitedState" },
          "description": "The excited states, in ascending order of `index`."
        },
        "meta": { "$ref": "#/$defs/ExcitedStatesMeta" }
      }
    },
    "ExcitedState": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["index", "excitation_energy"],
      "description": "One excited state of an `ExcitedStatesPayload`. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.12 (excited_states — excited states and transition properties).",
      "properties": {
        "index": {
          "type": "integer",
          "minimum": 1,
          "description": "Number of the state, unique within the payload and counted from 1; the reference state is not listed. Spectrum peaks (`assignment.state_index`), natural transition orbitals (`mo_metadata.state_index`) and transition densities (`state_index`) name a state by this number."
        },
        "excitation_energy": {
          "$ref": "#/$defs/ValueWithUnits",
          "description": "Vertical excitation energy: the energy of the state minus the energy of the reference state. Producers SHOULD write it in `ev`."
        },
        "total_energy": {
          "$ref": "#/$defs/ValueWithUnits",
          "description": "Total energy of the state. Producers SHOULD write it in `hartree`."
        },
        "multiplicity": {
          "type": "integer",
          "minimum": 1,
          "description": "Spin multiplicity 2S + 1 of the state."
        },
        "symmetry": {
          "type": "string",
          "description": "Irreducible-representation label of the state, e.g. 'B1'."
        },
        "oscillator_strength": {
          "type": "number",
          "minimum": 0,
          "description": "Oscillator strength of the transition from the reference state, dimensionless."
        },
        "rotatory_strength_cgs": {
          "type": "number",
          "description": "Rotatory strength of the transition from the reference state, signed, in units of 10^-40 esu^2 cm^2 (the '10^-40 cgs' unit quantum-chemistry programs print)."
        },
        "transition_dipole": {
          "$ref": "#/$defs/Vec3",
          "description": "Electric transition dipole moment between the reference state and the state, Cartesian components in atomic units (e bohr) in the axes of the section's structure. Its overall sign is arbitrary."
        },
        "transition_magnetic_dipole": {
          "$ref": "#/$defs/Vec3",
          "description": "Magnetic transition dipole moment between the reference state and the state, Cartesian components in atomic units (e hbar / m_e, twice the Bohr magneton) in the axes of the section's structure."
        },
        "contributions": {
          "type": "array",
          "items": { "$ref": "#/$defs/ExcitedStateContribution" },
          "description": "The dominant orbital excitations of the state."
        },
        "nto_ref": {
          "type": "string",
          "description": "Id of the `wavefunction.gto` section that holds the natural transition orbitals of the state: its hole orbitals, since the hole and particle orbitals are two sections; see QVF spec § 5.3 (wavefunction.gto). It must name a section of kind `wavefunction.gto`."
        },
        "density_ref": {
          "type": "string",
          "description": "Id of the section that holds a density of the state on a grid: a `volume.transition_density` section, or a `volume.difference` section holding the density of the state minus that of the reference state."
        }
      }
    },
    "ExcitedStateContribution": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["from_mo", "to_mo", "weight"],
      "description": "One orbital excitation of an excited state: from orbital `from_mo` to orbital `to_mo` of the reference wavefunction. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 5.12 (excited_states — excited states and transition properties).",
      "properties": {
        "from_mo": {
          "type": "integer",
          "minimum": 0,
          "description": "0-based row of the orbital the electron leaves, in the coefficient member of the reference wavefunction."
        },
        "to_mo": {
          "type": "integer",
          "minimum": 0,
          "description": "0-based row of the orbital the electron enters, in the coefficient member of the reference wavefunction."
        },
        "spin": {
          "enum": ["alpha", "beta"],
          "description": "Spin channel of the excitation in an unrestricted reference: `alpha` indexes `mo_coefficients_alpha`, `beta` indexes `mo_coefficients_beta`. Absent for a reference with one set of orbitals."
        },
        "weight": {
          "type": "number",
          "description": "Weight of the excitation in the state: the squared amplitude X^2 (CIS, TDA), or X^2 - Y^2 (full TD-DFT, RPA), normalized so that the weights of all excitations of a state sum to 1."
        }
      }
    },
    "ExcitedStatesMeta": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "Description of the calculation an `ExcitedStatesPayload` comes from. Strict: any other key is an error unless it begins with `x_`. No field is required; see QVF spec § 5.12 (excited_states — excited states and transition properties).",
      "properties": {
        "method": {
          "type": "string",
          "minLength": 1,
          "description": "Excited-state method, e.g. 'tddft', 'cis', 'adc2' or 'eom-ccsd'."
        },
        "reference_state": {
          "type": "string",
          "description": "The state the excitations start from, e.g. 'S0'."
        },
        "n_states": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of states; equals the length of `states`."
        },
        "tda": {
          "type": "boolean",
          "description": "True when the Tamm-Dancoff approximation was used."
        },
        "spin_flip": {
          "type": "boolean",
          "description": "True when the states come from a spin-flip calculation."
        },
        "units": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/UnitName" },
          "description": "Optional declaration of units, keyed by a field of the state objects, each value a unit name. `excitation_energy` and `total_energy` carry their unit in their own {value, units} objects, and a declaration restates it for every state; `oscillator_strength` is dimensionless. The transition dipoles and `rotatory_strength_cgs` have fixed units that no unit name names, so they are not declared; see QVF spec § 4.3 (Units and numeric conventions).",
          "properties": {
            "excitation_energy": { "$ref": "#/$defs/UnitName", "description": "Unit of the `excitation_energy` of every state." },
            "total_energy": { "$ref": "#/$defs/UnitName", "description": "Unit of the `total_energy` of every state." },
            "oscillator_strength": { "const": "dimensionless", "description": "Oscillator strengths are dimensionless." }
          }
        }
      }
    },
    "SectionPropertiesElastic": {
      "description": "Elastic constants of a periodic system: the stiffness matrix in Voigt notation, in GPa, with optional compliance and isotropic moduli. The single `properties` member's JSON payload is specified by `#/$defs/ElasticPropertiesPayload`; see QVF spec § 5.13 (Property kinds).",
      "properties": {
        "kind": { "const": "properties.elastic" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["properties"],
          "properties": {
            "properties": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "SectionPropertiesDielectric": {
      "description": "Dielectric response of a periodic system: the electronic, ionic and static dielectric tensors, the Born effective charges of the atoms and the piezoelectric tensor. The single `properties` member's JSON payload is specified by `#/$defs/DielectricPropertiesPayload`. The Born charges follow the atoms of the structure named by the section-level structure_ref when present, else of the archive's only structure section; see QVF spec § 5.13 (Property kinds).",
      "properties": {
        "kind": { "const": "properties.dielectric" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["properties"],
          "properties": {
            "properties": { "$ref": "#/$defs/JsonMember" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "Matrix3x3": {
      "type": "array",
      "minItems": 3,
      "maxItems": 3,
      "items": { "$ref": "#/$defs/Vec3" },
      "description": "A 3 x 3 matrix of numbers as three rows of three; row i holds the entries (i, x), (i, y), (i, z) of Cartesian components in the axes of the structure; see QVF spec § 5.13 (Property kinds)."
    },
    "Matrix3x6": {
      "type": "array",
      "minItems": 3,
      "maxItems": 3,
      "items": {
        "type": "array",
        "minItems": 6,
        "maxItems": 6,
        "items": { "type": "number" }
      },
      "description": "A 3 x 6 matrix of numbers as three rows of six: the row is the Cartesian component x, y, z, the column a Voigt index in the order xx, yy, zz, yz, xz, xy; see QVF spec § 5.13 (Property kinds)."
    },
    "Matrix6x6": {
      "type": "array",
      "minItems": 6,
      "maxItems": 6,
      "items": {
        "type": "array",
        "minItems": 6,
        "maxItems": 6,
        "items": { "type": "number" }
      },
      "description": "A 6 x 6 matrix of numbers as six rows of six, in Voigt notation: row and column index the pairs in the order xx, yy, zz, yz, xz, xy; see QVF spec § 5.13 (Property kinds)."
    },
    "Tensor3x3x3": {
      "type": "array",
      "minItems": 27,
      "maxItems": 27,
      "items": { "type": "number" },
      "description": "A rank-3 tensor of numbers, 27 in all, in row-major order of shape [3, 3, 3]: element (i, j, k) is at index 9 i + 3 j + k, with Cartesian indices x, y, z = 0, 1, 2; see QVF spec § 5.13 (Property kinds)."
    },
    "ElectricPropertiesPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "anyOf": [
        { "required": ["dipole"] },
        { "required": ["quadrupole"] },
        { "required": ["octupole"] },
        { "required": ["polarizability"] },
        { "required": ["hyperpolarizability"] }
      ],
      "description": "The JSON payload named by a `properties.electric` section's `properties` member: the electric multipole moments and polarizabilities of the system, each block in the fixed unit of the spec. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed, here and in every block. At least one of dipole, quadrupole, octupole, polarizability and hyperpolarizability is required. See QVF spec § 5.13 (Property kinds).",
      "properties": {
        "origin": {
          "oneOf": [
            { "type": "string", "minLength": 1 },
            { "$ref": "#/$defs/Vec3" }
          ],
          "description": "Reference point of the multipole moments, as `dipole_moment.origin` of the manifest root: a conventional name ('center_of_mass', 'center_of_nuclear_charge', 'origin') or an explicit 3-vector in bohr."
        },
        "dipole": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "required": ["vector"],
          "description": "The electric dipole moment, in debye. When the manifest root also carries a `dipole_moment` block, the two statements must agree within 1e-6 debye; see QVF spec § 5.13 (Property kinds).",
          "properties": {
            "vector": {
              "$ref": "#/$defs/Vec3",
              "description": "Dipole vector components x, y, z in debye."
            },
            "total": {
              "type": "number",
              "minimum": 0,
              "description": "Magnitude of the dipole vector in debye."
            },
            "units": {
              "$ref": "#/$defs/UnitName",
              "const": "debye",
              "description": "Unit name of the dipole: debye. v1 fixes it, so a declaration only restates it."
            }
          }
        },
        "quadrupole": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "required": ["matrix", "traceless", "convention"],
          "description": "The electric quadrupole moment, in debye-angstrom, in the Cartesian axes of the structure. `convention` names the moment the matrix holds and `traceless` says whether its trace is zero; see QVF spec § 5.13 (Property kinds).",
          "properties": {
            "matrix": {
              "$ref": "#/$defs/Matrix3x3",
              "description": "Symmetric 3 x 3 quadrupole matrix in debye-angstrom, rows and columns x, y, z."
            },
            "traceless": {
              "type": "boolean",
              "description": "True when the trace of the matrix is zero. Always true for the buckingham convention."
            },
            "convention": {
              "enum": ["buckingham", "cartesian"],
              "description": "'buckingham': the traceless quadrupole of Buckingham, half the sum of q (3 r_a r_b - r^2 delta_ab) over the charges. 'cartesian': the second moment, the sum of q r_a r_b over the charges, with its trace subtracted (one third of the trace on the diagonal) when `traceless` is true."
            }
          },
          "if": {
            "properties": { "convention": { "const": "buckingham" } },
            "required": ["convention"]
          },
          "then": {
            "properties": { "traceless": { "const": true } }
          }
        },
        "octupole": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "required": ["tensor"],
          "description": "The electric octupole moment, in debye-angstrom^2, in the Cartesian axes of the structure; see QVF spec § 5.13 (Property kinds).",
          "properties": {
            "tensor": {
              "$ref": "#/$defs/Tensor3x3x3",
              "description": "The 27 octupole components in row-major order of shape [3, 3, 3], in debye-angstrom^2."
            },
            "convention": {
              "enum": ["buckingham", "cartesian"],
              "default": "cartesian",
              "description": "'cartesian': the third moment, the sum of q r_a r_b r_c over the charges. 'buckingham': the traceless octupole of Buckingham, half the sum of q (5 r_a r_b r_c - r^2 (r_a delta_bc + r_b delta_ac + r_c delta_ab)). Absent means 'cartesian'."
            }
          }
        },
        "polarizability": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "required": ["matrix"],
          "description": "The electric dipole polarizability at one frequency, in atomic units; see QVF spec § 5.13 (Property kinds).",
          "properties": {
            "matrix": {
              "$ref": "#/$defs/Matrix3x3",
              "description": "The polarizability tensor alpha_ab in atomic units (e^2 a0^2 / E_h), rows and columns x, y, z."
            },
            "frequency_ev": {
              "type": "number",
              "minimum": 0,
              "default": 0,
              "description": "Photon energy of the applied field in eV; 0 is the static polarizability. Absent means 0."
            },
            "isotropic": {
              "type": "number",
              "description": "The isotropic (mean) polarizability, one third of the trace of the matrix, in atomic units."
            }
          }
        },
        "hyperpolarizability": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "required": ["tensor"],
          "description": "The first electric dipole hyperpolarizability at one pair of frequencies, in atomic units; see QVF spec § 5.13 (Property kinds).",
          "properties": {
            "tensor": {
              "$ref": "#/$defs/Tensor3x3x3",
              "description": "The 27 components beta_abc in row-major order of shape [3, 3, 3], in atomic units (e^3 a0^3 / E_h^2)."
            },
            "frequencies_ev": {
              "type": "array",
              "minItems": 2,
              "maxItems": 2,
              "items": { "type": "number" },
              "default": [0, 0],
              "description": "The two photon energies, in eV, of the applied fields of beta(-(w1 + w2); w1, w2); [0, 0] is the static hyperpolarizability. Absent means [0, 0]."
            }
          }
        },
        "units": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "description": "Declared units, field name to unit name (QVF spec § 4.3 (Units and numeric conventions)): `dipole` is debye and `origin`, when it is a vector, bohr. v1 fixes both, so a declaration only restates them. The other fields have units that the vocabulary does not name; they are fixed by QVF spec § 5.13 (Property kinds).",
          "properties": {
            "dipole": { "const": "debye", "description": "Unit of the dipole: debye." },
            "origin": { "const": "bohr", "description": "Unit of an explicit origin vector: bohr." }
          }
        }
      }
    },
    "ElasticPropertiesPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["stiffness"],
      "description": "The JSON payload named by a `properties.elastic` section's `properties` member: the elastic constants of a periodic system in Voigt notation. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. The stiffness and compliance matrices must be symmetric, which validators check, not this schema. See QVF spec § 5.13 (Property kinds).",
      "properties": {
        "stiffness": {
          "$ref": "#/$defs/Matrix6x6",
          "description": "The stiffness matrix C in Voigt notation, rows and columns in the order xx, yy, zz, yz, xz, xy, in GPa. Symmetric."
        },
        "compliance": {
          "$ref": "#/$defs/Matrix6x6",
          "description": "The compliance matrix S, the inverse of the stiffness matrix, in Voigt notation, in 1/GPa. Symmetric."
        },
        "bulk_modulus_gpa": {
          "type": "number",
          "description": "Bulk modulus in GPa, by the scheme `average` names."
        },
        "shear_modulus_gpa": {
          "type": "number",
          "description": "Shear modulus in GPa, by the scheme `average` names."
        },
        "youngs_modulus_gpa": {
          "type": "number",
          "description": "Young's modulus in GPa, by the scheme `average` names."
        },
        "poisson_ratio": {
          "type": "number",
          "description": "Poisson's ratio, dimensionless, by the scheme `average` names."
        },
        "average": {
          "enum": ["voigt", "reuss", "hill"],
          "description": "The averaging scheme of the four isotropic moduli: 'voigt' (uniform strain), 'reuss' (uniform stress) or 'hill' (their arithmetic mean). Absent means the scheme is not stated."
        },
        "units": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "description": "Declared units, field name to unit name (QVF spec § 4.3 (Units and numeric conventions)): `stiffness` and the three moduli are gpa, `poisson_ratio` is dimensionless. v1 fixes them, so a declaration only restates them. The compliance, in 1/GPa, has no unit name and is fixed by QVF spec § 5.13 (Property kinds).",
          "properties": {
            "stiffness": { "const": "gpa", "description": "Unit of the stiffness matrix: gpa." },
            "bulk_modulus_gpa": { "const": "gpa", "description": "Unit of the bulk modulus: gpa." },
            "shear_modulus_gpa": { "const": "gpa", "description": "Unit of the shear modulus: gpa." },
            "youngs_modulus_gpa": { "const": "gpa", "description": "Unit of Young's modulus: gpa." },
            "poisson_ratio": { "const": "dimensionless", "description": "Poisson's ratio has no unit." }
          }
        }
      }
    },
    "DielectricPropertiesPayload": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["electronic"],
      "description": "The JSON payload named by a `properties.dielectric` section's `properties` member: the dielectric tensors, Born effective charges and piezoelectric tensor of a periodic system. It is an archive member, not part of manifest.json; a validator loads the member's bytes and checks them against this definition. Strict: only the fields below and keys beginning with x_ are allowed. That static equals electronic plus ionic, and that there is one Born tensor per atom of the structure, are checked by validators, not this schema. See QVF spec § 5.13 (Property kinds).",
      "properties": {
        "electronic": {
          "$ref": "#/$defs/Matrix3x3",
          "description": "The electronic (high-frequency, clamped-ion) dielectric tensor, relative permittivity, dimensionless, rows and columns x, y, z."
        },
        "ionic": {
          "$ref": "#/$defs/Matrix3x3",
          "description": "The ionic (lattice) contribution to the static dielectric tensor, dimensionless."
        },
        "static": {
          "$ref": "#/$defs/Matrix3x3",
          "description": "The static dielectric tensor, dimensionless: the sum of electronic and ionic, to which it must agree within 1e-6 when all three are present."
        },
        "born_charges": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/Matrix3x3" },
          "description": "The Born effective charge tensor of each atom, in elementary charges, one 3 x 3 matrix per atom in atom order. Entry (i, j) is the polarization along i per unit displacement of the atom along j."
        },
        "piezoelectric": {
          "$ref": "#/$defs/Matrix3x6",
          "description": "The piezoelectric stress tensor e_ia in C/m^2: the row is the polarization component x, y, z, the column the Voigt strain index in the order xx, yy, zz, yz, xz, xy."
        },
        "units": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": { "^x_": {} },
          "description": "Declared units, field name to unit name (QVF spec § 4.3 (Units and numeric conventions)): the three dielectric tensors are dimensionless and `born_charges` is e. v1 fixes them, so a declaration only restates them. The piezoelectric tensor, in C/m^2, has no unit name and is fixed by QVF spec § 5.13 (Property kinds).",
          "properties": {
            "electronic": { "const": "dimensionless", "description": "The dielectric tensor has no unit." },
            "ionic": { "const": "dimensionless", "description": "The dielectric tensor has no unit." },
            "static": { "const": "dimensionless", "description": "The dielectric tensor has no unit." },
            "born_charges": { "const": "e", "description": "Unit of the Born charges: e, the elementary charge." }
          }
        }
      }
    },
    "SectionVolumeTransitionDensity": {
      "description": "Transition density of one electronic excitation on a grid: the one-particle transition density between the reference state and an excited state, summed over spin, in e/bohr^3. Same members as volume.density (grid + data); its overall sign is arbitrary. The optional section fields name the `excited_states` section and the state. See QVF spec § 5.2 (volume.*).",
      "properties": {
        "kind": { "const": "volume.transition_density" },
        "excited_states_ref": {
          "type": "string",
          "description": "Id of the `excited_states` section the state belongs to. It must name a section of kind `excited_states` in this archive; see QVF spec § 5.12 (excited_states — excited states and transition properties)."
        },
        "state_index": {
          "type": "integer",
          "minimum": 1,
          "description": "The `index` of the state whose transition density this is, in the `excited_states` section that `excited_states_ref` names, which is then required."
        },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["grid", "data"],
          "properties": {
            "grid": { "$ref": "#/$defs/JsonMember" },
            "data": { "$ref": "#/$defs/Volume3DBinary" }
          }
        }
      },
      "dependentRequired": {
        "state_index": ["excited_states_ref"]
      }
    },
    "SectionPreview": {
      "description": "A picture of the archive's contents for file managers, quick-look panels and catalogues: a raster `thumbnail` and an optional larger or vector `image`, both opaque binary members that carry their `media_type`. The picture of the archive is the thumbnail of the first `preview` section. An SVG image is self-contained and inert: no external resources, no scripts. See QVF spec § 5.15 (preview — a picture of the archive).",
      "properties": {
        "kind": { "const": "preview" },
        "members": {
          "type": "object",
          "additionalProperties": false,
          "required": ["thumbnail"],
          "properties": {
            "thumbnail": { "$ref": "#/$defs/PreviewThumbnail" },
            "image": { "$ref": "#/$defs/PreviewImage" }
          }
        }
      },
      "required": ["id", "kind", "members"]
    },
    "PreviewThumbnail": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "format", "sha256", "media_type"],
      "description": "The raster picture of a `preview` section: PNG or JPEG bytes as an opaque binary member. Its longest side SHOULD be 256 to 1024 pixels and the member SHOULD be at most 1 MiB; see QVF spec § 5.15 (preview — a picture of the archive).",
      "properties": {
        "path": { "$ref": "#/$defs/ZipPath" },
        "format": { "const": "binary" },
        "sha256": { "$ref": "#/$defs/Sha256Hex" },
        "size": { "$ref": "#/$defs/MemberSize" },
        "media_type": { "enum": ["image/png", "image/jpeg"] }
      }
    },
    "PreviewImage": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "format", "sha256", "media_type"],
      "description": "A larger or vector rendering of a `preview` section's picture: SVG, PNG or JPEG bytes as an opaque binary member. An SVG document is UTF-8, references no external resource and contains no script; see QVF spec § 5.15 (preview — a picture of the archive).",
      "properties": {
        "path": { "$ref": "#/$defs/ZipPath" },
        "format": { "const": "binary" },
        "sha256": { "$ref": "#/$defs/Sha256Hex" },
        "size": { "$ref": "#/$defs/MemberSize" },
        "media_type": { "enum": ["image/svg+xml", "image/png", "image/jpeg"] }
      }
    },
    "SectionVendor": {
      "description": "Vendor-namespace section. The `kind` must start with `x_<vendor>`; member shape is unconstrained except that every member is a valid JsonMember, BinaryMember or OpaqueBinaryMember (binary bytes without dtype and shape, which SHOULD carry their `media_type`); see QVF spec § 7.3 (Vendor namespace x_<vendor>.*).",
      "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" },
              { "$ref": "#/$defs/OpaqueBinaryMember" }
            ]
          }
        }
      }
    },
    "Metadata": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "description": "Descriptive metadata of the archive as a whole, so that it can be cited, found and traced. Every field is optional and none changes how the rest of the archive is read. Strict: any other key is an error unless it begins with `x_`; see QVF spec § 3.5 (Root metadata).",
      "properties": {
        "title": {
          "type": "string",
          "description": "Short human-readable title of the archive."
        },
        "description": {
          "type": "string",
          "description": "Free-text description of what the archive contains."
        },
        "created_utc": {
          "type": "string",
          "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?Z$",
          "description": "When the archive was first written: an ISO 8601 date and time in UTC, YYYY-MM-DDThh:mm:ssZ with an optional fractional second, e.g. '2026-10-07T12:00:00Z'."
        },
        "modified_utc": {
          "type": "string",
          "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?Z$",
          "description": "When the archive was last changed, in the form of `created_utc`."
        },
        "uuid": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
          "description": "Identifier of this archive: an RFC 4122 UUID (version 1 to 8, RFC 4122 variant) in lowercase hexadecimal 8-4-4-4-12 form, e.g. '3f2504e0-4f89-41d3-9a0c-0305e82c3301'. Producers generate a random (version 4) one per archive."
        },
        "authors": {
          "type": "array",
          "items": { "$ref": "#/$defs/MetadataAuthor" },
          "description": "People or groups responsible for the contents, in citation order."
        },
        "license": {
          "type": "string",
          "minLength": 1,
          "description": "Licence of the archive's contents. An SPDX licence identifier or expression, e.g. 'CC-BY-4.0', is recommended."
        },
        "doi": {
          "type": "string",
          "minLength": 1,
          "description": "DOI under which the archive is published, without a resolver prefix, e.g. '10.5281/zenodo.1234567'."
        },
        "keywords": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Subject keywords for search and cataloguing."
        },
        "derived_from": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Archives or publications this archive was derived from, each given by its `uuid` or a DOI."
        },
        "tags": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Free labels for organising archives, not meant for publication."
        }
      }
    },
    "MetadataAuthor": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["name"],
      "description": "One author of an archive. `email` and `affiliation` are personal data that producers should not emit by default; see QVF spec § 3.5 (Root metadata).",
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "Name as it should be cited."
        },
        "orcid": {
          "type": "string",
          "description": "ORCID iD, e.g. '0000-0002-1825-0097'."
        },
        "affiliation": {
          "type": "string",
          "description": "Institution. Personal data: emitted only when the person concerned asks for it."
        },
        "email": {
          "type": "string",
          "description": "Contact address. Personal data: emitted only when the person concerned asks for it."
        }
      }
    },
    "ProvenanceSoftware": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["name"],
      "description": "One program or library that produced the results of an archive, an item of `provenance.software`; see QVF spec § 3.2 (provenance). Strict: any other key is an error unless it begins with `x_`.",
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "Name of the program or library, e.g. 'integral-lib'."
        },
        "version": {
          "type": "string",
          "description": "Version string, as the component reports it."
        },
        "url": {
          "type": "string",
          "description": "Where the component is published, e.g. its home page."
        }
      }
    },
    "Thermochemistry": {
      "type": "object",
      "additionalProperties": false,
      "description": "Thermochemical corrections at manifest root; see QVF spec § 3.3 (Root metadata blocks). All energy quantities in Hartree.",
      "properties": {
        "zpve_eh": {
          "type": "number",
          "description": "Zero-point vibrational energy (Hartree)."
        },
        "enthalpy_eh": {
          "type": "number",
          "description": "Thermal-corrected enthalpy (Hartree)."
        },
        "entropy_cal_mol_k": {
          "type": "number",
          "description": "Entropy (cal / mol / K)."
        },
        "gibbs_free_energy_eh": {
          "type": "number",
          "description": "Gibbs free energy (Hartree)."
        },
        "temperature_k": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Temperature (K)."
        },
        "pressure_atm": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Pressure (atm)."
        }
      }
    },
    "DipoleMoment": {
      "type": "object",
      "additionalProperties": false,
      "description": "Dipole moment at manifest root; see QVF spec § 3.3 (Root metadata blocks).",
      "properties": {
        "total_debye": {
          "type": "number",
          "description": "Total dipole magnitude (Debye)."
        },
        "vector_debye": {
          "$ref": "#/$defs/Vec3",
          "description": "Dipole vector components (Debye)."
        },
        "origin": {
          "oneOf": [
            { "type": "string" },
            { "$ref": "#/$defs/Vec3" }
          ],
          "description": "Reference point for the dipole: a conventional name for legacy producers, or an explicit 3-vector in bohr."
        }
      }
    },
    "Constraints": {
      "type": "object",
      "additionalProperties": false,
      "description": "Geometry optimisation constraints; see QVF spec § 3.3 (Root metadata blocks).",
      "properties": {
        "frozen_atoms": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "description": "Zero-based indices of atoms frozen during optimisation."
        },
        "distance_constraints": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": ["atoms", "target_angstrom"],
            "properties": {
              "atoms": {
                "type": "array",
                "items": { "type": "integer", "minimum": 0 },
                "minItems": 2,
                "maxItems": 2
              },
              "target_angstrom": { "type": "number", "exclusiveMinimum": 0 }
            }
          }
        }
      }
    },
    "Energies": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["total"],
      "description": "Energies of the calculation; see QVF spec § 3.6 (Root energies). Every energy is a {value, units} object, and producers SHOULD write hartree. Strict: only the fields below and keys beginning with x_. An energy stated here for the method that provenance.method names MUST agree with provenance.scf_energy, and components.zpve with thermochemistry.zpve_eh, within 1e-8 hartree; validators check this, which JSON Schema cannot express.",
      "properties": {
        "total": {
          "$ref": "#/$defs/ValueWithUnits",
          "description": "Energy of the archive's primary result."
        },
        "method": {
          "type": "string",
          "minLength": 1,
          "description": "Method of the primary result, whose energy `total` is, e.g. 'rhf', 'rks' or 'mp2'."
        },
        "components": { "$ref": "#/$defs/EnergyComponents" },
        "by_method": {
          "type": "array",
          "items": { "$ref": "#/$defs/EnergyByMethod" },
          "description": "Energies of the same system by further methods, e.g. the SCF reference and the correlated energy of a post-SCF calculation."
        },
        "units_note": {
          "type": "string",
          "description": "Free-text note on the units, for people; it declares nothing."
        }
      }
    },
    "EnergyComponents": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": { "$ref": "#/$defs/ValueWithUnits" } },
      "description": "Named contributions to an energy; see QVF spec § 3.6 (Root energies). Components may overlap and need not be exhaustive, so a consumer MUST NOT add them up to obtain the total. A key beginning with x_ names a further, producer-defined component.",
      "properties": {
        "nuclear_repulsion": { "$ref": "#/$defs/ValueWithUnits", "description": "Nuclear-nuclear repulsion energy." },
        "electronic": { "$ref": "#/$defs/ValueWithUnits", "description": "Electronic energy: everything but nuclear_repulsion." },
        "one_electron": { "$ref": "#/$defs/ValueWithUnits", "description": "One-electron energy: kinetic energy plus electron-nuclear attraction." },
        "two_electron": { "$ref": "#/$defs/ValueWithUnits", "description": "Two-electron energy: Coulomb plus exchange (Hartree-Fock) or Coulomb plus exchange-correlation (Kohn-Sham)." },
        "exchange_correlation": { "$ref": "#/$defs/ValueWithUnits", "description": "Exchange-correlation energy of a density functional." },
        "exchange": { "$ref": "#/$defs/ValueWithUnits", "description": "Exchange energy: Hartree-Fock exchange, or the exchange part of exchange_correlation." },
        "correlation": { "$ref": "#/$defs/ValueWithUnits", "description": "Correlation energy: the correlated energy minus its reference energy, or the correlation part of exchange_correlation." },
        "dispersion": { "$ref": "#/$defs/ValueWithUnits", "description": "Dispersion correction, e.g. DFT-D3." },
        "solvation": { "$ref": "#/$defs/ValueWithUnits", "description": "Contribution of a solvent model." },
        "zpve": { "$ref": "#/$defs/ValueWithUnits", "description": "Zero-point vibrational energy; equals thermochemistry.zpve_eh when both are present." },
        "thermal": { "$ref": "#/$defs/ValueWithUnits", "description": "Thermal correction to the energy at thermochemistry.temperature_k, excluding zpve." },
        "embedding": { "$ref": "#/$defs/ValueWithUnits", "description": "Interaction with an embedding environment, e.g. QM/MM or an embedding potential." }
      }
    },
    "EnergyByMethod": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": { "^x_": {} },
      "required": ["method", "total"],
      "description": "The energy of the system by one method; see QVF spec § 3.6 (Root energies). Strict: only the fields below and keys beginning with x_.",
      "properties": {
        "method": {
          "type": "string",
          "minLength": 1,
          "description": "Method identifier, e.g. 'rhf' or 'ccsd(t)'."
        },
        "total": {
          "$ref": "#/$defs/ValueWithUnits",
          "description": "Energy of the system by this method."
        },
        "components": { "$ref": "#/$defs/EnergyComponents" }
      }
    },
    "Extensions": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^x_[A-Za-z0-9_]+$": {
          "type": "object",
          "additionalProperties": false,
          "required": ["version"],
          "properties": {
            "version": { "type": "string", "minLength": 1 },
            "schema_uri": { "type": "string", "format": "uri" },
            "critical": { "type": "boolean", "default": false }
          }
        }
      },
      "description": "Extension governance block. Maps a vendor namespace prefix, written with its `x_` (e.g. `x_orca`, matching the prefix of the namespace's section kinds), to its version, optional schema URI, and critical flag; see QVF spec § 7.4 (Root extensions block and per-section critical)."
    }
  }
}
