MLflow MLOps Migration
A phased, gated workflow that turns an arbitrary ML codebase — however unstructured — into a
production-grade open-source MLflow 3 setup covering the full MLOps cycle: tracked experiments,
a domain-modelled registry, dev/staging/prod separation, evaluation-gated promotion, and served
models. It is written to be driven with a developer who has no MLflow 3 experience: every phase
produces a reviewable artifact before anything is changed, and every API decision defers to the
sibling mlflow-3 rule pack (which is pinned to mlflow 3.15.1 and names the
MLflow 2-era idioms this migration exists to remove).
When to Apply
Use this skill when:
- A team wants MLflow (or has a messy/partial MLflow 2 setup) and needs the path to a
production-grade MLflow 3 deployment — not just API fixes.
- Training code exists but experiments are untracked, models are shipped by copying files, or
"deployment" means a pickle in a bucket.
- You are asked to design or review a dev/staging/prod model-promotion story.
- An MLflow 2 → 3 migration touches infrastructure (stages,
./mlruns file stores, MLServer),
not only client code.
Don't use it for a single API question — read the relevant mlflow-3 rule directly.
Workflow Overview
0 assess ─▶ 1 domain-model ─▶ 2 environments ─▶ 3 instrument ─▶ 4 promote ─▶ 5 serve ─▶ 6 operate
audit registry tracking per training code eval-gated validate, retrain loop,
report naming, alias env (dev local, → MLflow 3 copy_model_ serve, challenger,
(script, + gate design stg/prod DB+S3 idioms (rule version + smoke-test maintenance
read-only) (interview) + auth) pack) alias flip /invocations (gated)
| Phase |
Action |
Deliverable |
Risk |
| 0 |
Run scripts/00-assess.sh <codebase> — read-only audit |
mlflow-assessment.md report |
read-only |
| 1 |
Interview + domain modelling |
Registry domain doc (names, aliases, gates) |
read-only |
| 2 |
Stand up tracking per environments; dev via scripts/scaffold-dev-tracking.sh |
Reachable tracking server(s), config.json filled |
write |
| 3 |
Restructure training code to MLflow 3 idioms (sibling rule pack) |
Refactored code, first LoggedModels registered |
write |
| 4 |
Wire promotion — evaluate gate, tags, copy_model_version, alias flip |
Promotion script/CI job |
write |
| 5 |
Serve — mlflow.models.predict, then serve/build-docker, smoke /invocations |
Served model per environment |
write |
| 6 |
Operate — retraining, challenger evaluation, maintenance (see workflow) |
Runbook habits, scheduled jobs |
write |
| ✓ |
Run scripts/verify.sh after phases 2–5 |
Pass/fail assertion report |
read-only |
Phases run in order — each has entry/exit criteria in references/workflow.md,
and scripts/verify.sh is the exit gate for the infrastructure phases. Re-running any phase is safe:
00-assess.sh regenerates only its own report (and refuses to clobber anything else),
scaffold-dev-tracking.sh refuses to overwrite (exit code 2 = already done), and verify.sh only
reads. The one non-idempotent step is promotion's copy_model_version — see
references/promotion.md for how to resume instead of re-copying.
Risk Level: Write
This workflow edits training code, writes infrastructure files, and stands up services. Guardrails:
- Nothing in phase 0–1 modifies anything — always complete both before touching code or infra.
- Confirm with the user before: starting/replacing any tracking server, rewriting a training
entrypoint, flipping a prod
@champion alias (dev/staging flips may be automated by the
phase-4 pipeline), and exposing a serving endpoint beyond localhost.
- Two maintenance commands are destructive and must be run only with explicit user confirmation and
a stated reason:
mlflow gc (permanently deletes soft-deleted runs and experiments — registry
entities are untouched) and mlflow db upgrade (irreversible schema migration — snapshot the
database first). A PreToolUse hook in hooks/hooks.json blocks both unless
MLFLOW_MAINTENANCE_ACK=yes is set for that command, so they cannot run un-confirmed by accident.
Requirements
- Python ≥ 3.10 with
mlflow==3.15.1 installed in the project environment
- bash, curl, jq — the scripts use them
- uv — the serving phase uses
--env-manager uv for fast isolated environment rebuilds
(substitute virtualenv everywhere if uv is unavailable)
- Docker + docker-compose — for the dev tracking stack and
build-docker serving images
- A database + object store per shared environment (staging/prod) — PostgreSQL/MySQL and
S3/GCS/Azure; dev runs on the scaffolded local stack
- The sibling
mlflow-3 skill — phase 3 cites its rules; if it is not installed, read the
MLflow 3 migration guide instead (the workflow still works, with more manual verification)
Setup
config.json starts empty. Phase 2 fills it (tracking URIs per environment, registry namespace,
model name, serving URL). If fields are empty when a script needs them, the script says which ones —
fill them via the _setup_instructions in the file.
Quick Reference
| I need to… |
Go to |
| Audit what the codebase does today |
scripts/00-assess.sh <dir> + references/assessment.md |
| Decide model names / aliases / gates |
references/domain-modelling.md |
| Stand up dev tracking in one command |
scripts/scaffold-dev-tracking.sh <dir> |
| Design staging/prod tracking topology |
references/environments.md |
Rewrite log_model / stages / evaluate calls |
sibling mlflow-3 rules (log-*, reg-*, eval-*) |
| Build the promotion pipeline |
references/promotion.md |
| Serve and smoke-test a model |
references/serving.md |
| Check the setup actually works |
scripts/verify.sh |
| See every phase's entry/exit criteria |
references/workflow.md |
Gotchas
See gotchas.md — failure points discovered while running this workflow, including the
migrate-filestore SQLite-only target and the basic-auth bootstrap credentials.
Related Skills
mlflow-3 — the sibling library-reference rule pack this workflow cites at every API decision
1---2name: mlflow-mlops-migration3description: Guided workflow for taking any ML codebase — including one with no experiment tracking at all, or one full of MLflow 2-era idioms — to a production-grade open-source MLflow 3 setup with dev/staging/prod environments, registry-based promotion, and served models. Walks seven phases with a developer who may have zero MLflow 3 experience — assess the codebase (scripted read-only audit), model the registry domain (per-environment model names, aliases, gates), stand up tracking per environment, restructure training code to MLflow 3 idioms, wire evaluation-gated promotion, serve and smoke-test, then run the ongoing MLOps loop. Use when asked to set up MLflow, migrate to MLflow 3, productionize model training and serving, or design a dev/staging/prod MLOps cycle. Pairs with the sibling mlflow-3 rule pack for every API decision.4---5
6# MLflow MLOps Migration
7
8A phased, gated workflow that turns an arbitrary ML codebase — however unstructured — into a
9production-grade **open-source MLflow 3** setup covering the full MLOps cycle: tracked experiments,
10a domain-modelled registry, dev/staging/prod separation, evaluation-gated promotion, and served
11models. It is written to be driven *with* a developer who has no MLflow 3 experience: every phase
12produces a reviewable artifact before anything is changed, and every API decision defers to the
13sibling [`mlflow-3`](../mlflow-3/) rule pack (which is pinned to mlflow 3.15.1 and names the
14MLflow 2-era idioms this migration exists to remove).
15
16## When to Apply
17
18Use this skill when:
19- A team wants MLflow (or has a messy/partial MLflow 2 setup) and needs the path to a
20 production-grade MLflow 3 deployment — not just API fixes.
21- Training code exists but experiments are untracked, models are shipped by copying files, or
22 "deployment" means a pickle in a bucket.
23- You are asked to design or review a dev/staging/prod model-promotion story.
24- An MLflow 2 → 3 migration touches infrastructure (stages, `./mlruns` file stores, MLServer),
25 not only client code.
26
27Don't use it for a single API question — read the relevant `mlflow-3` rule directly.
28
29## Workflow Overview
30
31```
320 assess ─▶ 1 domain-model ─▶ 2 environments ─▶ 3 instrument ─▶ 4 promote ─▶ 5 serve ─▶ 6 operate
33 audit registry tracking per training code eval-gated validate, retrain loop,
34 report naming, alias env (dev local, → MLflow 3 copy_model_ serve, challenger,
35 (script, + gate design stg/prod DB+S3 idioms (rule version + smoke-test maintenance
36 read-only) (interview) + auth) pack) alias flip /invocations (gated)
37```
38
39| Phase | Action | Deliverable | Risk |
40|-------|--------|-------------|------|
41| 0 | Run `scripts/00-assess.sh <codebase>` — read-only audit | `mlflow-assessment.md` report | read-only |
42| 1 | Interview + [domain modelling](references/domain-modelling.md) | Registry domain doc (names, aliases, gates) | read-only |
43| 2 | Stand up tracking per [environments](references/environments.md); dev via `scripts/scaffold-dev-tracking.sh` | Reachable tracking server(s), `config.json` filled | write |
44| 3 | Restructure training code to MLflow 3 idioms (sibling rule pack) | Refactored code, first LoggedModels registered | write |
45| 4 | Wire [promotion](references/promotion.md) — evaluate gate, tags, `copy_model_version`, alias flip | Promotion script/CI job | write |
46| 5 | [Serve](references/serving.md) — `mlflow.models.predict`, then serve/`build-docker`, smoke `/invocations` | Served model per environment | write |
47| 6 | Operate — retraining, challenger evaluation, maintenance (see [workflow](references/workflow.md)) | Runbook habits, scheduled jobs | write |
48| ✓ | Run `scripts/verify.sh` after phases 2–5 | Pass/fail assertion report | read-only |
49
50Phases run in order — each has entry/exit criteria in [references/workflow.md](references/workflow.md),
51and `scripts/verify.sh` is the exit gate for the infrastructure phases. Re-running any phase is safe:
52`00-assess.sh` regenerates only its own report (and refuses to clobber anything else),
53`scaffold-dev-tracking.sh` refuses to overwrite (exit code 2 = already done), and `verify.sh` only
54reads. The one non-idempotent step is promotion's `copy_model_version` — see
55[references/promotion.md](references/promotion.md) for how to resume instead of re-copying.
56
57## Risk Level: Write
58
59This workflow edits training code, writes infrastructure files, and stands up services. Guardrails:
60- Nothing in phase 0–1 modifies anything — always complete both before touching code or infra.
61- Confirm with the user before: starting/replacing any tracking server, rewriting a training
62 entrypoint, flipping a **prod** `@champion` alias (dev/staging flips may be automated by the
63 phase-4 pipeline), and exposing a serving endpoint beyond localhost.
64- Two maintenance commands are destructive and must be run only with explicit user confirmation and
65 a stated reason: `mlflow gc` (permanently deletes soft-deleted runs and experiments — registry
66 entities are untouched) and `mlflow db upgrade` (irreversible schema migration — snapshot the
67 database first). A PreToolUse hook in [hooks/hooks.json](hooks/hooks.json) blocks both unless
68 `MLFLOW_MAINTENANCE_ACK=yes` is set for that command, so they cannot run un-confirmed by accident.
69
70## Requirements
71
72- **Python ≥ 3.10** with `mlflow==3.15.1` installed in the project environment
73- **bash, curl, jq** — the scripts use them
74- **uv** — the serving phase uses `--env-manager uv` for fast isolated environment rebuilds
75 (substitute `virtualenv` everywhere if uv is unavailable)
76- **Docker + docker-compose** — for the dev tracking stack and `build-docker` serving images
77- **A database + object store per shared environment** (staging/prod) — PostgreSQL/MySQL and
78 S3/GCS/Azure; dev runs on the scaffolded local stack
79- **The sibling `mlflow-3` skill** — phase 3 cites its rules; if it is not installed, read the
80 MLflow 3 migration guide instead (the workflow still works, with more manual verification)
81
82## Setup
83
84`config.json` starts empty. Phase 2 fills it (tracking URIs per environment, registry namespace,
85model name, serving URL). If fields are empty when a script needs them, the script says which ones —
86fill them via the `_setup_instructions` in the file.
87
88## Quick Reference
89
90| I need to… | Go to |
91|------------|-------|
92| Audit what the codebase does today | `scripts/00-assess.sh <dir>` + [references/assessment.md](references/assessment.md) |
93| Decide model names / aliases / gates | [references/domain-modelling.md](references/domain-modelling.md) |
94| Stand up dev tracking in one command | `scripts/scaffold-dev-tracking.sh <dir>` |
95| Design staging/prod tracking topology | [references/environments.md](references/environments.md) |
96| Rewrite `log_model` / stages / evaluate calls | sibling `mlflow-3` rules (`log-*`, `reg-*`, `eval-*`) |
97| Build the promotion pipeline | [references/promotion.md](references/promotion.md) |
98| Serve and smoke-test a model | [references/serving.md](references/serving.md) |
99| Check the setup actually works | `scripts/verify.sh` |
100| See every phase's entry/exit criteria | [references/workflow.md](references/workflow.md) |
101
102## Gotchas
103
104See [gotchas.md](gotchas.md) — failure points discovered while running this workflow, including the
105`migrate-filestore` SQLite-only target and the basic-auth bootstrap credentials.
106
107## Related Skills
108
109- `mlflow-3` — the sibling library-reference rule pack this workflow cites at every API decision