# Versioning

Semver on the spec. Every object carries `specVersion`; every export carries it too.

## What a minor may do

Until 1.0, a minor version may **add optional depth groups and optional fields**. That is
all.

A minor may **not**:

- add a required field inside an existing depth group
- rename a group
- invalidate any document that was previously valid

Renaming a group is a **major**, even though it feels like a rename. A consumer pinned to
the old name stops seeing the data and has no way to know it happened.

A patch release is docs, examples and validator bugfixes that keep every old document
valid.

## The compatibility check

Two directions, both enforced in CI:

- Every 0.1 example still passes the 0.2 schemas.
- Every 0.2 document, with its 0.2-only fields omitted, still passes the 0.1 schemas.

Plus a schema lint: a `required[]` appearing inside a depth group fails the minor. The test
suite carries both of these — see `test/validate.test.mjs`.

## additionalProperties

**Root schemas must never set `additionalProperties: false`.** This is the mechanism the
whole additive-minor promise rests on: a 0.1 reader encountering a 0.2 document has to
accept the keys it does not recognise.

If a 0.1 tool rejects a 0.2 export, that is a bug in the spec or a closed schema in the
consumer. It is never correct behaviour.

## Pinning

Third-party implementers pin a major, or a full semver tag, and accept unknown optional
keys.

Tagged `$id` URLs are immutable and served `Cache-Control: immutable`. If one is
unreachable, fall back to a vendored copy or the GitHub raw URL of that tag.

`v0-draft/` is explicitly unstable and **must not be pinned by anyone** — not by a producer,
not by an implementation. Moving files inside the draft folder is allowed. Moving a tagged
file is not.

## Upgrading a pin

A work pins a version, and reads validate against **the pin, not latest**. Mixing majors
inside one work is invalid.

Upgrading is an explicit action on the work:

1. Change the pin.
2. Immediately re-validate everything.
3. **Fail closed.** Nothing is coerced, nothing is dropped, no field is auto-mapped.
4. The pin stays where it is until every object passes.

Recovery is to reconcile the objects or revert the pin. There is no partial upgrade.

## After 1.0

A frozen major's schemas never change meaning. Additive optional fields become a new minor
of that major.
