QVF governance

QVF (the Quantum Visualization Format) is an open standard for quantum-chemistry visualization and analysis data. This document describes how the format is stewarded, versioned, and evolved, so that adopters can rely on it as a stable, multi-vendor interchange format rather than a single code’s captive output.

Origin and stewardship

QVF was created by the vibe-qc project and is stewarded by it. That origin is a matter of record, not something the format hides: vibe-qc designed the container model, the section-kind vocabulary, and the reference implementations, and it maintains the specification and the JSON Schema.

Stewardship here means the vibe-qc maintainer is the current custodian of the spec and registry — merging changes, cutting versions, and arbitrating the vendor→canonical promotion process. It does not mean the format is vibe-qc-specific:

  • The specification and reference implementations are Apache-2.0 (this qvf-writer/ toolkit), so anyone can implement a producer or consumer, including in a proprietary code, with no obligation back to vibe-qc.

  • The format is producer-neutral by design: source.program names any code, and no canonical section kind is vibe-qc-specific. vibe-qc’s own non-standard data lives under its x_vibeqc.* vendor namespace, exactly like any other adopter’s.

  • Governance decisions are made in the open (spec + schema + registry are public and versioned), and the process below is the same for everyone.

As independent adopters ship QVF, stewardship is intended to broaden — see “Evolving the governance” below.

What is under governance

  1. The specification (spec/qvf-format-spec.md) and the machine-readable JSON Schema (spec/qvf_manifest.schema.json), which is the single source of truth for the manifest contract.

  2. The registry (registry.json) of canonical section kinds and registered vendor namespaces.

  3. The versioning policy and the vendor→canonical promotion process.

Versioning policy

  • qvf_version is an integer in every manifest. v1 = 1. It changes only on a breaking change (a removed kind, a required-member change, an incompatible unit change). A consumer that only understands qvf_version = 1 must refuse a file with a higher version.

  • The format grows additively within a major version: new canonical kinds and new optional members may be added without bumping qvf_version. Consumers detect capability by supported-kind checking and the extensions block, not by a minor-version number.

  • The schema $id carries the major version (https://vibe-qc.org/spec/qvf/1/manifest.schema.json).

  • Changes to the format are recorded in the toolkit’s CHANGELOG and reflected in registry.json.

Version history and decisions

Governance decisions that affect the on-disk contract are recorded here, in the open. Recording a mistake is part of the process working, not evidence against it.

2026-07-10 — qvf_version: 2 withdrawn (periodic reaction.path)

Decision. The qvf_version: 2 bump is withdrawn. reaction.path gains an optional lattice member under v1; a periodic reaction path is detected by that member’s presence, not by a version number.

Background. vibe-qc v0.10.0–v0.15.x stamped qvf_version: 2 on any archive containing a periodic reaction.path. The entire schema-visible difference from v1 was one optional member (lattice); a companion dim field lives inside a JsonMember payload and is not schema-visible at all.

Rationale. Under the versioning policy above, an optional member is the additive case and must not bump qvf_version. The bump also created a real interoperability break: the specification requires a v1-only consumer to refuse any archive with a higher major version, so conforming third-party consumers were obliged to reject archives the reference producer routinely wrote. Finally, a major version is the format’s scarcest signal — qvf_version: 2 must mean “a v1 consumer genuinely cannot read this” — and spending the format’s first bump on a backward-compatible optional field would have permanently muddied that meaning.

Compatibility. Archives stamped qvf_version: 2 exist in the wild (shipped from v0.10.0 onward). They are v1-compatible. Therefore:

  • Producers MUST NOT emit qvf_version: 2.

  • Consumers SHOULD accept qvf_version: 2 and treat it as 1, for at least one minor line. This is a deprecation, not a deletion.

  • qvf_manifest_v2.schema.json is retained as a frozen generated artifact so anything resolving its $id continues to validate (it is a strict superset of v1).

2026-07-10 — structure payload schema’d; pbc required when periodic

Decision. The structure member’s JSON payload is now specified, as $defs/StructurePayload. pbc is REQUIRED whenever lattice_vectors is non-null, and dimensionality is optional and derived, with the invariant dimensionality == sum(pbc). No qvf_version bump.

Background. pbc, lattice_vectors, and dimensionality were prose-only, and the prose made dimensionality a MAY on the section object while the reference producer wrote it into the payload. A consumer could not assert that a structure was a 2-D slab, only infer it — and inferring wrong renders a slab inside a vacuum box.

Rationale for no bump. Absent pbc had no defined meaning; a periodic archive that omitted it was already unrenderable. Every known producer emits it, and every archive in the conformance corpus validates unchanged. This is the clarification case in “Change process” above, not a required-member change.

The periodic axes are deliberately not required to be the leading ones. pbc = [true, false, true] — a slab whose normal lies along y — is conforming. Ordering the periodic axes first is an internal convention of one producer (vibe-qc’s periodic.hpp); making it normative would have forced other producers to permute their lattice, against the producer neutrality asserted at the top of this document. It survives in the spec as an informative note describing the legacy dimensionality-without-pbc fallback.

Compatibility. dimensionality moved from the section object to the payload. Archives carrying it in the old position remain fully interpretable, because pbc — which every such archive also carries — is what a consumer reads. A consumer MUST NOT read dimensionality off the section object.

The registry

registry.json is the machine-readable list of:

  • Canonical kinds — the section kinds defined in the spec + schema. A drift test keeps this list in lock-step with the schema’s Section branches, so the registry can never claim a kind the schema doesn’t define (or vice versa).

  • Reserved names — planning names not yet portable contracts.

  • Vendor namespaces — registered x_<vendor>.* prefixes, their owner, and purpose. Registration is advisory (any code may use its own x_<vendor>.* without asking), but registering avoids collisions and signals intent to standardize.

  • Promotions — vendor kinds that have become canonical.

Change process

Anyone may propose a change by opening an issue or merge request against the repository:

  • Register a vendor namespace — add a row to registry.json (vendor_namespaces). Lightweight; no design review needed, it just records who is using which prefix.

  • Extend a canonical kind (a new optional member) — a spec + schema change, reviewed for backward compatibility. No qvf_version bump.

  • Add a new canonical kind — via the promotion process below, or directly when a clear ecosystem need exists and a reference consumer will render it.

  • Report a spec issue / ambiguity — an issue; clarifications land in the spec without a version bump.

The maintainer reviews and merges. Decisions that affect the contract are recorded in the CHANGELOG and the registry.

Vendor → canonical promotion

The path from an experimental x_<vendor>.* section to a standard kind (spec § 5.7 / § 7.5):

  1. The kind is used in production by at least two independent producers for at least one release cycle.

  2. Its member contract is stable across those producers.

  3. A spec + schema + validator change adds the canonical kind, and at least one reference consumer renders it.

This threshold is what makes a promotion earned by real interoperability rather than declared. (The maintainer may promote ahead of the two-producer threshold when a canonical target is needed to seed adoption — as was done for spectra.epr — but such promotions are noted as maintainer decisions in registry.json.)

Compatibility commitments

  • No canonical kind is removed or has its required members changed without a major qvf_version bump.

  • A consumer may always safely ignore vendor (x_<vendor>.*) sections it does not understand, unless they are flagged critical: true (in which case a consumer that cannot support them must refuse to open the file, by design).

  • Units and numeric conventions (spec § 3) are stable within a major version.

Getting involved / becoming a supported producer

  1. Emit valid QVF for your code’s outputs and self-certify against the conformance suite.

  2. Register your vendor namespace in registry.json if you ship non-standard data.

  3. Reach out — once your code emits conforming archives, it can be listed as a supported producer and its native format considered for direct vibe-view support. See docs/integration_guide.md.

Evolving the governance

The current model is maintainer-led because there is, so far, one reference producer/consumer ecosystem. It is explicitly designed to broaden as the format is adopted:

  • As independent producers ship QVF, they earn a say in the promotion process (a promotion requires their real-world use, per the threshold above).

  • If and when adoption warrants it, the spec + registry can move to a vendor-neutral hosting home with a small steering group of adopters. The standard is open regardless of where it is hosted — the Apache-2.0 license, the public schema, and this governance document travel with it — and vibe-qc’s origin and stewardship remain acknowledged.

That is a decision for the maintainer and the adopter community to make together, not a prerequisite for adopting QVF today.