Skip to content
VERASPEC
Repository
Versioning policystable

§2 What may change at each level

2.1 Patch (1.0.0 → 1.0.1)

A patch release is corrective. It may:

  • correct or disambiguate prose whose literal reading was wrong, self-contradictory, or not interoperable, always siding with observed producer behaviour where one reading is already deployed;
  • tighten a schema constraint only where every already-conformant Record already satisfied the tightening — that is, where the prose already required what the schema forgot to enforce;
  • correct a published example so that its self-referential digests are true;
  • add non-normative guidance, editorial notes, and traceability material.

A patch release may not:

  • add a field, a value, an enum member, or a capability;
  • move ver_version or cpnp_version;
  • relax a constraint — except where the relaxation resolves a contradiction in the published text and no Record that was conformant under a coherent reading becomes non-conformant. Two such relaxations shipped in 1.0.1, and both are named so the exception stays auditable rather than implicit: E13 (the conformance table marked L3 contextual embeddings mandatory while §8 called them optional) and E15 (§7.1's byte-exact preservation MUST against §7.5's redaction requirement — see COMPATIBILITY.md §4.2). A relaxation with no contradiction behind it is additive — see §2.2;
  • edit any file of an already-published release (see §3).

The test: after a patch release, every Record that was conformant before is still conformant, and every consumer that worked before still works. If either fails, it is not a patch — with one bounded exception, stated next, for text that had no single conformant reading to begin with.

Where 1.0.1 sits against that test. Five annex items — E3, E6, E7, E8, E9 — each resolve a place where 1.0.0 admitted two readings that produced different Canonical Buffers. Resolving an ambiguity necessarily selects one reading, so a Record produced under a non-selected reading becomes non-conformant; its pixel_hash is withdrawn, not recomputed, because it was never a value another implementation could reproduce. In every case the selected reading is the reference implementation's, which is also every deployed producer's. A text with no single correct reading has no conformant implementations to protect — which is why these ship in a patch rather than waiting for 2.0. COMPATIBILITY.md §4.1 states all five, item by item, with what each withdraws.

2.2 Minor (1.0.x → 1.1)

A minor release is additive. It may:

  • add optional fields, optional objects, and new enum members;
  • relax a constraint that was wrong (a pattern that rejected legal values);
  • promote a SHOULD to a MUST only for records that declare the new ver_version;
  • add a new conformance capability, a new registry, or a new profile.

A minor release may additionally encode a requirement the previous release stated in prose and did not enforce, and may close an object under §2.3's evident-intent carve-out. Both of those mean a record valid under the previous schema can fail the new one.

A minor release moves ver_version to "1.1". Records declaring "1.0" remain valid forever and are never retroactively re-graded.

The superset property is not a requirement of a minor release. It was treated as one during the 1.1 drafting — the draft schema was to be a superset of the 1.0.1 schema for every shared structure, with ver_version and dim/dtype as the only differences — and the effect was to suppress the standard's own machine-checkable rules in order to protect a mechanical upgrade path. That trade is rejected: a rule JSON Schema can express is expressed, and the upgrade is documented rather than made free. The record's declared ver_version is what decides which schema judges it, so a record that has not been migrated is never evaluated against the new schema in the first place.

What a minor release MUST do instead:

  • State the version gate. ver_version is a const naming the new version.
  • Publish the migration, enumerated. Every edit a record valid under the previous release needs, with the validator failure pointer each omission produces. The enumeration MUST be verified against the previous release's published example and the conformance fixtures, and the verification command MUST be in the release's RELEASE.md. For 1.1 this is standards/ver/1.1-draft/VER-1.1-draft.md §12.1.
  • Never re-grade a published record. A record declaring the previous version stays valid under the previous release's schema in perpetuity, and no conformance claim already made is withdrawn by a minor.
  • Classify every change in `COMPATIBILITY.md`, including the ones that make a previously-valid record invalid under the new schema.

The converse never holds in either direction: a record using a 1.1 field fails the 1.0.1 schema, which is exactly why the new field set is gated behind ver_version: "1.1".

Version-gated requirements: the mechanism. A minor release may promote optional members to REQUIRED only for records declaring the new ver_version. The gate is the record's declared ver_version, and the mechanism that expresses it depends on the schema:

  • In a version-pinned schema — one whose ver_version is a const, which is what every VER release publishes — a flat required entry is the gated form. The const already partitions the document sets: no record declaring "1.0" is ever evaluated against the 1.1 schema in the first place, so an explicit if/then on a sibling property would be redundant machinery expressing a condition the const has already decided. This is why standards/ver/1.1-draft/ver-record.schema.json lists dim and dtype in $defs/embedding's required array, and that is correct.
  • A multi-version schema — one that accepts more than one ver_version in a single document — would need a conditional subschema keyed on ver_version, because there the version const does no partitioning.

Either way the normative statement is the same: the requirement binds records that declare the new version and no others. Records declaring "1.0" stay valid under the 1.0.x schemas forever.

2.3 Major (1.x → 2.0)

A major release is required for any of:

  • any change to CPNP-1 — see §4;
  • removing a field, an enum member, or a capability;
  • narrowing a value space that producers already populate;
  • changing the meaning of an existing field;
  • changing the pixel_hash preimage, including its domain tag.

Carve-out: evident-intent closure. Narrowing a value space no conformant producer relies on is not a major change, and may be taken at a minor release by an explicit ratification vote. The narrow case this exists for is the seven schema objects left open by oversight rather than by design — the prose enumerates their members, the schema forgot to close them, and one of them (identity.pixel_hash) carries inert "alg": true, "value": true entries that prove closure was intended (SCH-03, SCH-04, ADR-0002). Three conditions govern the carve-out, and all three must hold:

  1. the constraint's evident intent is recoverable from the published text, not merely desirable in hindsight;
  2. no conformant Record populates the space being narrowed — a producer relying on it was already outside the prose;
  3. the narrowing is carried as a named item on the ratification checklist, voted on explicitly, and recorded in COMPATIBILITY.md.

The 1.1 draft exercises the carve-out once: it closes all seven objects (draft §15.2). The closure is carried as a named row on the 1.1 ratification checklist (standards/ver/1.1-draft/RELEASE.md, row 6) and recorded in `COMPATIBILITY.md` §2, which is what condition 3 requires; the vote itself is taken at ratification, and until it is, the closure is drafted rather than decided. space_id uniqueness is not a candidate — no schema can express it (draft §15.4), so there is no narrowing to vote on. Anything failing any of the three conditions is 2.0 material, unchanged.

A major release ships with a dual-publish migration window: producers emit both the old and the new record for a stated period, and consumers are given that period to migrate. The window's length is set at ratification and stated in the release's RELEASE.md.