Course outline

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.

About 4 min readContent reviewed
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.

python Deterministic offline standard-library fixture
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"])
Expected output
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.

python Deterministic offline standard-library fixture
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)
Expected output
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.

Official references