MLOps / Pipelines and controlled delivery / Lesson 9
Registry versions, aliases, and promotion
Distinguish immutable artifact identity from mutable selection and preserve the evidence behind a change.
On this page
Lesson goals
- Separate a registered model, a concrete version, and an alias.
- Bind acceptance evidence to the exact proposed artifact.
- Explain stale decisions, compatibility, and audit requirements.
A registry organizes identities and relationships
A model name can group versions produced by different runs, while each version should refer to an identifiable package and its metadata. A selection alias points to a version and may change over time. Tags describe properties under a policy, but a tag such as approved is not proof that evaluation or authorization occurred. Registry products implement these concepts differently and evolve their interfaces. This course uses neutral in-memory records; its terminology does not prescribe a legacy stage API. Read the exact product documentation before mapping a conceptual promotion process onto a particular registry.
Resolve mutable selection at a declared boundary
The first fixture resolves an alias once and retains the resulting version for a synthetic request. Moving the alias afterward affects a new resolution while the pinned request keeps its original package. Without such a boundary, one operation could load preprocessing from one version and parameters from another if selection changes between reads. Cache invalidation and long-running batch behavior also need a policy. Decide when a consumer resolves selection, how it records the version actually used, and whether an already-started operation may switch. A mutable alias is convenient selection state, not an immutable experimental identity.
versions = {"model-1":{"digest":"lab-a", "schema":"schema-1"},
"model-2":{"digest":"lab-b", "schema":"schema-1"}}
aliases = {"selected":"model-1"}
resolved = aliases["selected"]
aliases["selected"] = "model-2"
print("pinned request", resolved, versions[resolved]["digest"])
print("new resolution", aliases["selected"], versions[aliases["selected"]]["digest"])
pinned request model-1 lab-a
new resolution model-2 lab-b
Resolving once pins this synthetic request to one version even after the mutable selection alias moves; the digest strings are synthetic identities.
Promotion consumes exact matching evidence
A proposed version needs its own evaluation report, compatibility checks, provenance, and the responsible decision under the task contract. Evidence for another version cannot be transferred merely because names or shapes match. The second fixture checks matching acceptance and an expected generation before changing its in-memory selection. The stale-decision guard illustrates why concurrent reviewers or automation should not overwrite a newer decision unknowingly. A real system requires an appropriate atomic or transactional mechanism; the dictionary program does not provide cross-process coordination, access control, or a durable audit log.
current = {"version":"model-1", "generation":4}
def promote(expected_generation, proposed, evidence):
if current["generation"] != expected_generation:
return "stale decision"
if not evidence.get("accepted") or evidence.get("version") != proposed:
return "missing matching acceptance"
current.update(version=proposed, generation=current["generation"]+1)
return "selected"
print(promote(3, "model-2", {"accepted":True,"version":"model-2"}))
print(promote(4, "model-2", {"accepted":True,"version":"model-2"}))
print(current)
stale decision
selected
{'version': 'model-2', 'generation': 5}
The in-memory generation guard models a conditional update; it is not a transactional registry implementation or authorization system.
Compatibility determines the usable selection
A numerically stronger model can still be incompatible with a consumerโs feature schema, output meaning, runtime, resource budget, or fallback. Maintain these dependencies with the version and verify the complete inference contract. Promotion should not silently change a class order or required input field for existing callers. If a change requires a coordinated interface migration, that is part of the release plan rather than a registry-label edit. Keep prior compatible versions and their dependencies according to retention requirements so rollback is a feasible procedure, not merely an alias name pointing to a missing artifact.
Record what changed and what consumers observed
Preserve old and new version identities, expected previous state, matching evidence, time, actor or automation identity, reason, and the actual outcome. After a selection change, verify the version consumers loaded and the known-input behavior under their resolution policy. Registration, acceptance, selection, and successful delivery are separate events. A registry entry can exist without any consumer using it, and a consumer can retain an older pinned version legitimately. These fixtures exercise only local mappings and a generation guard, with synthetic identifiers; no registry, approval workflow, deployment, credentials, or platform mutation is performed.
Common errors and fixes
An alias is used as permanent experiment identity
- Why it happens
- Mutable selection was confused with a concrete artifact.
- How to fix it
- Record the resolved version and package identity for every relevant operation.
- Prevent it next time
- Test alias movement while an operation is pinned.
A report for model-1 approves model-2
- Why it happens
- Acceptance was matched by display name rather than exact identity.
- How to fix it
- Require evidence for the proposed version and package.
- Prevent it next time
- Include a mismatched-report rejection fixture.
A late promotion overwrites a newer decision
- Why it happens
- The update ignored the expected previous selection state.
- How to fix it
- Use a supported conditional update and preserve the conflict.
- Prevent it next time
- Test stale generation or equivalent conflict behavior.
Check your understanding
1. Why does the pinned request keep model-1 after the alias moves?
Show worked solution
It resolved the mutable name at a defined boundary and retained that concrete version. A new request can resolve model-2. This prevents one operation from mixing version-dependent parts, provided the consumer also pins the full package and its dependencies consistently.
2. What should happen if an old selected version has been deleted before rollback?
Show worked solution
The rollback prerequisite is absent, so an alias edit cannot restore the old behavior. Apply the documented fallback or recovery plan and rebuild only with sufficient identity and compatibility evidence. Retention policy should preserve the artifacts required by the supported recovery objective.
Key takeaways
- Versions identify artifacts; aliases select them mutably.
- Promotion evidence must match the exact candidate.
- Verify consumer resolution and compatibility after a selection change.