Background
aicr validate consumes three artifacts produced by potentially different aicr versions: the running binary, the recipe, and the snapshot. Today there is no enforced compatibility contract between them.
PR #1386 added a soft, advisory warning (version skew detected across validate inputs) that fires when the three report different release versions. That is a debugging breadcrumb only — it does not fail the command, and it compares the unsigned, advisory binary-version string rather than a real schema contract.
This issue tracks the stronger, durable fix: a schema-versioned compatibility gate.
Problem
The artifact apiVersion cannot serve as a compatibility gate in its current state:
- Frozen since inception —
aicr.nvidia.com/v1alpha1 has never been bumped; breaking schema changes are deliberately shipped within v1alpha1 (see pkg/validator/v1/doc.go).
- Defined in ~5 independent string literals (
pkg/snapshotter/version.go, pkg/recipe/metadata.go, pkg/recipe/criteria.go, pkg/config/config.go, plus the validator domain) that agree only by coincidence. Doc drift already exists (/v1 vs /v1alpha1).
- Not enforced on read — snapshot loading (
serializer.FromFile) ignores apiVersion entirely; recipe loading checks only Kind, and tolerates an empty Kind.
- No evolution policy — no documented rule for when to bump, no backward-compat guarantee tied to the version.
So an apiVersion match guarantees nothing about structural compatibility, and a mismatch essentially never occurs.
Proposed work
- Single source of truth — collapse the duplicate
apiVersion literals into one shared constant (likely in pkg/header), referenced by snapshot, recipe, and config.
- Documented evolution policy — additive-only within a version; bump on breaking change. Capture as an ADR under
docs/design/.
- Enforcement on read — gate the snapshot and recipe loaders on a known/supported
apiVersion (model after the strict \!= reject already in pkg/config/validate.go), with a --strict-version style escape hatch decision (warn vs. reject).
- Actually bump to
v1alpha2 (or v1beta1) the next time the artifact schema changes incompatibly, and add a regression test asserting the loader rejects an unknown version.
Acceptance criteria
Related
Background
aicr validateconsumes three artifacts produced by potentially differentaicrversions: the running binary, the recipe, and the snapshot. Today there is no enforced compatibility contract between them.PR #1386 added a soft, advisory warning (
version skew detected across validate inputs) that fires when the three report different release versions. That is a debugging breadcrumb only — it does not fail the command, and it compares the unsigned, advisory binary-version string rather than a real schema contract.This issue tracks the stronger, durable fix: a schema-versioned compatibility gate.
Problem
The artifact
apiVersioncannot serve as a compatibility gate in its current state:aicr.nvidia.com/v1alpha1has never been bumped; breaking schema changes are deliberately shipped withinv1alpha1(seepkg/validator/v1/doc.go).pkg/snapshotter/version.go,pkg/recipe/metadata.go,pkg/recipe/criteria.go,pkg/config/config.go, plus the validator domain) that agree only by coincidence. Doc drift already exists (/v1vs/v1alpha1).serializer.FromFile) ignoresapiVersionentirely; recipe loading checks onlyKind, and tolerates an emptyKind.So an
apiVersionmatch guarantees nothing about structural compatibility, and a mismatch essentially never occurs.Proposed work
apiVersionliterals into one shared constant (likely inpkg/header), referenced by snapshot, recipe, and config.docs/design/.apiVersion(model after the strict\!=reject already inpkg/config/validate.go), with a--strict-versionstyle escape hatch decision (warn vs. reject).v1alpha2(orv1beta1) the next time the artifact schema changes incompatibly, and add a regression test asserting the loader rejects an unknown version.Acceptance criteria
apiVersionconstant; no independent literals for the snapshot/recipe/config artifacts.apiVersionis rejected (or warned, per the policy decision) on load in the validate path.Related