Progressive delivery
- Weighted stable/canary routing
- 10% → 25% → 50% → 100% traffic stages
- Promotion and rollback through explicit state transitions
MLOps / AI Platform
Policy-driven ML release control plane for progressive canary traffic, delayed ground-truth quality gates, automated promotion and rollback, and continuous desired-versus-observed router reconciliation.
A model can be healthy as a process and still be wrong for production traffic. This platform exposes a candidate gradually, waits for the evidence that can actually judge it, and records the decision that follows.
Reliability signals and model-quality signals are deliberately different. Delayed labels are allowed to mature, insufficient data stays INCONCLUSIVE, and the worker acts through the same control-plane API that an operator uses.
ModelOps Control Plane turns a model release into an inspectable, policy-driven rollout with real traffic, real label ingestion and an explicit recovery path.
The quality-failure scenario makes the control loop concrete. A deliberately weak canary receives real routed traffic, but the worker does not call its result decisive until delayed ground truth is sufficient.
A new model version enters a weighted canary rollout while the stable version keeps the remaining traffic.
Fresh traffic measures reliability; an older matured window gives delayed ground truth time to arrive before quality is judged.
Missing label coverage or too few positive labels produces INCONCLUSIVE. The worker does not mistake a thin sample for a healthy model.
Once sufficiency gates pass, minimum_recall can genuinely resolve to PASS or FAIL using labels joined to the exact prediction_id.
PASS advances 10% → 25% → 50% → 100%; FAIL triggers rollback; INCONCLUSIVE freezes for human review.
Policy snapshots, state transitions and worker actions form one chronological audit story instead of a final status without context.
The important distinction is between “not enough evidence yet” and “this candidate failed.” A policy engine that collapses them will either promote too early or roll back a healthy model on a thin sample.
The control plane decides the desired traffic state. The router owns its static version-to-host mapping and reports what it actually observes. Model serving runs predictions; it does not decide whether a version deserves more traffic.
| Control plane owns | Serving / router owns |
|---|---|
|
|
Desired state is durable intent. Observed router state is a cache that can drift. The reconciliation loop exists because a successful decision and a successful push are not the same event.
Client traffic enters a weighted router, while the control plane collects metrics and delayed labels. A stateless worker evaluates fresh reliability and matured quality windows, then advances or resolves the rollout through the same API as a human. Reconciliation closes the gap between database intent and router reality.
The router owns the version → host mapping; an unhealthy selected target returns an error rather than silently failing over.
Client Traffic requests Weighted Router. Weighted Router routes Stable Model (current version). Weighted Router routes Canary Model (candidate version, no fallback). Stable Model and Canary Model emits Control Plane.
Label and metric writes are independent; a GroundTruthLabel is durable even before its matching PredictionMetric arrives.
Delayed Label Source ingests GroundTruthLabel. GroundTruthLabel join by prediction_id Quality Aggregation. Quality Aggregation summarizes Quality Summary.
A separate stateless worker acts only through the same Control Plane endpoints available to an operator.
Automation Worker evaluates Two Evaluation Windows. Two Evaluation Windows feeds Policy Engine. Policy Engine verdict PASS (advance · 10% → 25% → 50% → 100%). Policy Engine verdict FAIL (automatic rollback). Policy Engine verdict INCONCLUSIVE (freeze for manual review).
The database's desired state commits first; the router push is best-effort and repaired on drift, not assumed to always land.
Deployment + TrafficAllocation pushes Best-Effort Router Push. Best-Effort Router Push updates Router Observed Config. Router Observed Config reconciles Reconcile Tick.
Manual actions use the same endpoints the worker does; every action and policy verdict lands on one merged timeline.
Dashboard calls Control Plane API. Control Plane API records Deployment Timeline.
Architecture notes
Predictions mint a stable prediction_id and labels arrive through a separate idempotent API. GroundTruthLabel is written even when its metric has not arrived yet, then both are joined at read time. Quality gates wait for label coverage and minimum positive labels before trusting recall.
Reliability and quality checks produce explicit persisted evaluations. FAIL beats INCONCLUSIVE, which beats PASS; insufficient evidence cannot silently become approval, and a frozen rollout remains visible for human resolution.
The database commits the desired allocation first. The router receives a best-effort push and keeps only observed in-memory state. A worker-triggered reconcile tick compares revisions and repairs drift after a router restart or transient push failure.
Optimistic concurrency, a partial unique index for one unresolved deployment per model, and model-scoped routing generations prevent concurrent actions or delayed pushes from corrupting the rollout currently in charge.
These are curated repository screenshots from the public `origin/main` walkthrough. Each image links back to the source file so the full-size timeline remains available on desktop and mobile.



The evidence below describes different parts of the control loop: automated rollout, quality rollback, restart recovery and deterministic verification. They are not merged into one synthetic score.
| Evidence slice | Current result | What it means |
|---|---|---|
| Automated healthy rollout | 10% → 25% → 50% → 100% | A real-stack CI scenario waits for the stateless worker to advance a healthy canary on live routed traffic and delayed labels, then promote it on a genuine minimum_recall PASS. |
| Quality-driven rollback | Recall FAIL → automatic rollback | A deliberately weak canary follows the same delayed label path; after sufficiency gates clear, minimum_recall fails and the worker rolls the deployment back. |
| Restart-safe routing | CI scenarios 5–6 | The router is restarted during a rollout and after a terminal promotion. Reconciliation or startup sync restores the desired allocation without a human replay. |
| Backend verification | 279 tests · ~91% coverage | Ruff, mypy --strict and pytest run alongside a separate integration job that boots the real nine-container stack and exercises six scenarios. |
The dashboard does not stop at “promoted” or “rolled back.” It shows traffic allocation, latency and error-rate comparisons, label coverage, positive-label counts, policy explanations, desired and observed router revisions, and one merged deployment timeline.
Each policy evaluation snapshots the window and data it used, so an old decision does not silently change its explanation when traffic moves later.
This is a production-oriented local control-plane reference implementation, not a production certification. The current scope intentionally uses SQLite, one router, Docker Compose and open demo endpoints.
Kubernetes, PostgreSQL at deployment scale, Kafka-backed metrics, MLflow, OIDC/RBAC, multi-router reconciliation and longer soak testing are documented production evolution steps, not claims about the current implementation.