LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

All Topics
Your Progress
0%

0 of 158 articles completed

🛠️Computing Foundations0/9
Git, Shell, Linux for AIDocker for Reproducible AIPython for AI EngineeringNumPy and Tensor ShapesCUDA for ML TrainingMPS & Metal for ML on MacData Structures for AISQL and Data ModelingAlgorithms for ML Engineers
📊Math & Statistics0/8
Gradients and BackpropVectors, Matrices & TensorsLinear Algebra for MLAdam, Momentum, SchedulersProbability for Machine LearningStatistics and UncertaintyDistributions and SamplingHypothesis Tests, Intervals, and pass@k
📚Preparation & Prerequisites0/13
Neural Networks from ScratchCNNs from ScratchTraining & BackpropagationSoftmax, Cross-Entropy & OptimizationRNNs, LSTMs, GRUs, and Sequence ModelingAutoencoders and VAEsThe Transformer Architecture End-to-EndLanguage Modeling & Next TokensFrom GPT to Modern LLMsPrompt Engineering FundamentalsCalling LLM APIs in ProductionFirst AI App End-to-EndThe LLM Lifecycle
🧮ML Algorithms & Evaluation0/11
Linear Regression from ScratchLogistic Regression and MetricsDecision Trees, Forests, and BoostingReinforcement Learning BasicsValidation and LeakageClustering and PCACore Retrieval AlgorithmsDecoding AlgorithmsExperiment Design and A/B TestingPyTorch Training LoopsDataset Pipelines and Data Quality
📦Production ML Systems0/6
Feature Engineering for Production MLBatch and Streaming Feature PipelinesGradient Boosted Trees in ProductionRanking and Recommendation SystemsForecasting and Anomaly DetectionMonitoring Predictive Models
🧪Core LLM Foundations0/8
The Bitter Lesson & ComputeBPE, WordPiece, and SentencePieceStatic to Contextual EmbeddingsPerplexity & Model EvaluationFile Ingestion for AIChunking StrategiesLLM Benchmarks & LimitationsInstruction Tuning & Chat Templates
🧰Applied LLM Engineering0/23
Dimensionality Reduction for EmbeddingsCoT, ToT & Self-Consistency PromptingFunction Calling & Tool UseMCP & Tool Protocol StandardsPrompt Injection DefenseResponsible AI GovernanceData Labeling and Human FeedbackEvaluating AI AgentsProduction RAG PipelinesHybrid Search: Dense + SparseReranking and Cross-Encoders for RAGRAG Evaluation for Reliable AnswersLLM-as-a-Judge EvaluationBias & Fairness in LLMsHallucination Detection & MitigationLLM Observability & MonitoringExperiment Tracking with MLflow and W&BMixed Precision TrainingModel Versioning & DeploymentSemantic Caching & Cost OptimizationLLM Cost Engineering & Token EconomicsModel Gateways, Routing, and FallbacksDesign an Automated Support Agent
🎓Portfolio Capstones0/9
Capstone: Delivery ETA PredictionCapstone: Product RankingCapstone: Demand ForecastingCapstone: Image Damage ClassifierCapstone: Production ML PipelineCapstone: Document QACapstone: Eval DashboardCapstone: Fine-Tuned ClassifierCapstone: Production Agent
🧠Transformer Deep Dives0/8
Sentence Embeddings & Contrastive LossEmbedding Similarity & QuantizationScaled Dot-Product AttentionVision Transformers and Image EncodersPositional Encoding: RoPE & ALiBiLayer Normalization: Pre-LN vs Post-LNMechanistic InterpretabilityDecoding Strategies: Greedy to Nucleus
🧬Advanced Training & Adaptation0/16
Scaling Laws & Compute-Optimal TrainingPre-training Data at ScaleBuild GPT from Scratch LabContinued Pretraining for Domain ShiftSynthetic Data PipelinesSupervised Fine-Tuning PipelineDistributed Training: FSDP & ZeROLoRA & Parameter-Efficient TuningReward Modeling from Preference DataRLHF & DPO AlignmentConstitutional AI & Red TeamingRLVR & Verifiable RewardsKnowledge Distillation for LLMsModel Merging and Weight InterpolationPrompt Optimization with DSPyRecursive Language Models (RLM)
🤖Advanced Agents & Retrieval0/14
Vector DB Internals: HNSW & IVFAdvanced RAG: HyDE & Self-RAGGraphRAG & Knowledge GraphsRAG Security & Access ControlStructured Output GenerationReAct & Plan-and-ExecuteGuardrails & Safety FiltersCode Generation & SandboxingComputer-Use / GUI / Browser AgentsHuman-in-the-Loop Agent ArchitectureAI Coding Workflow with AgentsAgent Memory & PersistenceAgent Failure & RecoveryMulti-Agent Orchestration
⚡Inference & Production Scale0/20
Inference: TTFT, TPS & KV CacheMulti-Query & Grouped-Query AttentionKV Cache & PagedAttentionPrefix Caching and Prompt CachingFlashAttention & Memory EfficiencyContinuous Batching & SchedulingScaling LLM InferenceModel Parallelism for LLM InferenceModel Quantization: GPTQ, AWQ & GGUFLocal LLM DeploymentSLM Specialization & Edge DeploymentSpeculative DecodingLong Context Window ManagementContext EngineeringMixture of Experts ArchitectureMamba & State Space ModelsReasoning & Test-Time ComputeAdvanced MLOps & DevOps for AIGPU Serving & AutoscalingA/B Testing for LLMs
🏗️System Design Capstones0/9
Content Moderation SystemCode Completion SystemMulti-Tenant LLM PlatformLLM-Powered Search EngineVision-Language Models & CLIPMultimodal LLM ArchitectureDiffusion Models: Images & TextReal-Time Voice AI AgentReasoning & Test-Time Compute
🎤AI Lab Interviewing0/4
AI Lab Coding Interview: Python SystemsAI Lab System Design InterviewAI Lab Behavioral InterviewAI Lab Technical Presentation
Back to Topics
LearnPortfolio CapstonesCapstone: Production ML Pipeline
⚙️HardMLOps & Deployment

Capstone: Production ML Pipeline

Assemble predictive ML artifacts into validated training, registry promotion, canary monitoring, and rollback.

17 min read
Learning path
Step 83 of 158 in the full curriculum
Capstone: Image Damage ClassifierCapstone: Document QA

Four products now need the same operational discipline: a late-delivery warning model, a product ranker, a warehouse demand forecast, and a damaged-package photo classifier. Each uses different metrics, but each relies on immutable data evidence, validated candidates, controlled promotion, monitoring, and rollback.

This capstone assembles that discipline into one ML platform workflow. It isn't tied to a particular orchestrator or cloud vendor. A reviewer must be able to trace any live decision back to data, feature, model, policy, and promotion evidence. That requires stored receipts, not a mutable Boolean that happens to say passed.

Production alias timeline for delivery-risk-v1. A failed offline receipt holds on critical-slice failure while accepted offline-receipt-2 opens only the canary alias beside production v0. The first-hour window has 500 requests, error rate 0.002, p95 latency 118 milliseconds, and no delayed labels, so it holds. The day-seven window has 4200 requests, error rate 0.003, p95 latency 124 milliseconds, delayed labels ready, and late-warning cost delta minus 0.08, so canary-receipt-3 becomes ready. Promotion rechecks production v0 before moving production to v1. Production-receipt-1 records a day-eight cost delta of plus 0.14, so an audited rollback restores the complete v0 release. Production alias timeline for delivery-risk-v1. A failed offline receipt holds on critical-slice failure while accepted offline-receipt-2 opens only the canary alias beside production v0. The first-hour window has 500 requests, error rate 0.002, p95 latency 118 milliseconds, and no delayed labels, so it holds. The day-seven window has 4200 requests, error rate 0.003, p95 latency 124 milliseconds, delayed labels ready, and late-warning cost delta minus 0.08, so canary-receipt-3 becomes ready. Promotion rechecks production v0 before moving production to v1. Production-receipt-1 records a day-eight cost delta of plus 0.14, so an audited rollback restores the complete v0 release.
Production stays on v0 until stored offline and canary receipts authorize promotion; a stored production-monitor receipt later records the cost regression that restores the complete v0 release.

Define the Shared Release Tuple

Models differ, but their release manifest can share a schema:

FieldETA exampleRanking exampleForecast exampleVision example
data snapshotcarrier events through cutoffcatalog and judged queriesdaily counts through cutoffreturn photos grouped by shipment
feature or preprocessing versioneta-features-v1ranking-features-v1demand-lags-v1parcel-rgb-224-center-crop-v1
model artifactdelay-model-v1market-ranker-v1warehouse-demand-v1damage-cnn-v1
action policywarning thresholdeligibility and slate rulealert thresholdquality check and review threshold
promotion policyslice recall and cost limitsblocked-listing and NDCG limitspeak underforecast-cost limitusable-image and source-slice limits
monitordelayed labels and freshnessimpressions and returnsresiduals and alert reviewphoto quality and reviewer labels
previous releasedelivery-risk-v0market-ranker-v0warehouse-demand-v0damage-cnn-v0

The release tuple prevents an incident review from asking which threshold, feature transform, or gate policy happened to be active. Sculley et al. warn that ML systems accumulate debt through data dependencies, configuration, and feedback loops unless those boundaries are managed explicitly.[1]Reference 1Hidden Technical Debt in Machine Learning Systems.https://research.google/pubs/hidden-technical-debt-in-machine-learning-systems/

Diagram showing Trigger + validate schema + cutoff, Register candidate immutable release, Offline eval gate append receipt, and pass. Diagram showing Trigger + validate schema + cutoff, Register candidate immutable release, Offline eval gate append receipt, and pass.
Trigger + validate schema + cutoff, Register candidate immutable release, Offline eval gate append receipt, and pass.

Build the Portfolio Repository

Submit a small but inspectable platform surface:

text
1production-ml-platform/ 2 contracts/ 3 release_manifest.schema.json 4 promotion_policy.json 5 pipelines/ 6 validate_snapshot.py 7 train_candidate.py 8 evaluate_candidate.py 9 promote_alias.py 10 registry/ 11 releases.jsonl 12 monitoring/ 13 live_windows.py 14 rollback_policy.py 15 receipts/ 16 offline_gate_report.json 17 canary_monitor_report.json 18 alias_audit.jsonl 19 projects/ 20 eta/ 21 ranking/ 22 forecast/ 23 vision/ 24 tests/ 25 test_failed_gate_never_promotes.py 26 test_empty_monitor_window_holds.py 27 test_unregistered_receipt_never_promotes.py 28 test_alias_race_blocks_promotion.py 29 test_delayed_labels_block_promotion.py 30 test_rollback_restores_manifest.py

Google Cloud's MLOps architecture separates automated data/model validation, metadata, serving, monitoring, and continuous-training triggers around promotion.[2]Reference 2MLOps: Continuous Delivery and Automation Pipelines in Machine Learning.https://docs.cloud.google.com/architecture/mlops-continuous-delivery-and-automation-pipelines-in-machine-learning Your repository needn't copy that platform, but it should prove each boundary through a deterministic local fixture and test.

Register a Candidate Without Moving Production

Training completion is evidence, not permission to change live behavior. Start by freezing the whole release tuple. The candidate records both its previous release and its promotion policy, so a reviewer can replay the rollback target and gate thresholds before any traffic moves.

01-register-release-registry.py
1from dataclasses import asdict, dataclass 2import json 3 4@dataclass(frozen=True) 5class PromotionPolicy: 6 policy_id: str 7 required_offline_gates: tuple[str, ...] 8 min_canary_windows: int 9 max_error_rate: float 10 max_p95_latency_ms: int 11 max_late_warning_cost_delta: float 12 13@dataclass(frozen=True) 14class Release: 15 release_id: str 16 data_snapshot: str 17 feature_version: str 18 model_artifact: str 19 action_policy_version: str 20 promotion_policy_version: str 21 previous_release: str | None 22 23@dataclass(frozen=True) 24class OfflineReceipt: 25 receipt_id: str 26 candidate: str 27 production_before: str 28 promotion_policy_version: str | None 29 failed_gates: tuple[str, ...] 30 decision: str 31 32POLICIES = { 33 "eta-promotion-v1": PromotionPolicy( 34 policy_id="eta-promotion-v1", 35 required_offline_gates=( 36 "schema_valid", 37 "no_leakage", 38 "critical_slice_pass", 39 "cost_improves", 40 ), 41 min_canary_windows=2, 42 max_error_rate=0.01, 43 max_p95_latency_ms=250, 44 max_late_warning_cost_delta=0.0, 45 ) 46} 47 48registry = { 49 "delivery-risk-v0": Release( 50 "delivery-risk-v0", 51 "carrier-events-through-2026-04-30", 52 "eta-features-v1", 53 "delay-model-v0", 54 "eta-threshold-v1", 55 "eta-promotion-v1", 56 None, 57 ), 58 "delivery-risk-v1": Release( 59 "delivery-risk-v1", 60 "carrier-events-through-2026-05-31", 61 "eta-features-v1", 62 "delay-model-v1", 63 "eta-threshold-v1", 64 "eta-promotion-v1", 65 "delivery-risk-v0", 66 ), 67} 68aliases = {"production": "delivery-risk-v0"} 69offline_receipts: dict[str, OfflineReceipt] = {} 70 71print("registry:", list(registry)) 72print("production:", aliases["production"])
Output
1registry: ['delivery-risk-v0', 'delivery-risk-v1'] 2production: delivery-risk-v0
02-open-canary-after-offline-gates.py
1def open_canary(candidate_id: str, gates: dict[str, bool]) -> OfflineReceipt: 2 candidate = registry.get(candidate_id) 3 production_before = aliases["production"] 4 failed = [] 5 policy = POLICIES.get(candidate.promotion_policy_version) if candidate else None 6 if candidate is None: 7 failed.append("candidate_not_registered") 8 elif policy is None: 9 failed.append("promotion_policy_not_registered") 10 else: 11 failed.extend( 12 gate for gate in policy.required_offline_gates if not gates.get(gate, False) 13 ) 14 if candidate is not None and candidate.previous_release != production_before: 15 failed.append("previous_release_mismatch") 16 if aliases.get("canary") not in (None, candidate_id): 17 failed.append("another_canary_is_active") 18 19 receipt = OfflineReceipt( 20 receipt_id=f"offline-receipt-{len(offline_receipts) + 1}", 21 candidate=candidate_id, 22 production_before=production_before, 23 promotion_policy_version=( 24 candidate.promotion_policy_version if candidate is not None else None 25 ), 26 failed_gates=tuple(sorted(failed)), 27 decision="hold_offline" if failed else "open_canary", 28 ) 29 offline_receipts[receipt.receipt_id] = receipt 30 if receipt.decision == "open_canary": 31 aliases["canary"] = candidate_id 32 return receipt 33 34bad_gates = { 35 "schema_valid": True, 36 "no_leakage": True, 37 "critical_slice_pass": False, 38 "cost_improves": True, 39} 40good_gates = {**bad_gates, "critical_slice_pass": True} 41 42bad_offline_receipt = open_canary("delivery-risk-v1", bad_gates) 43accepted_offline_receipt = open_canary("delivery-risk-v1", good_gates) 44print(json.dumps(asdict(bad_offline_receipt), indent=2)) 45print(json.dumps(asdict(accepted_offline_receipt), indent=2)) 46print("aliases:", json.dumps(aliases, sort_keys=True))
Output
1{ 2 "receipt_id": "offline-receipt-1", 3 "candidate": "delivery-risk-v1", 4 "production_before": "delivery-risk-v0", 5 "promotion_policy_version": "eta-promotion-v1", 6 "failed_gates": [ 7 "critical_slice_pass" 8 ], 9 "decision": "hold_offline" 10} 11{ 12 "receipt_id": "offline-receipt-2", 13 "candidate": "delivery-risk-v1", 14 "production_before": "delivery-risk-v0", 15 "promotion_policy_version": "eta-promotion-v1", 16 "failed_gates": [], 17 "decision": "open_canary" 18} 19aliases: {"canary": "delivery-risk-v1", "production": "delivery-risk-v0"}

A failed offline slice leaves production unchanged. Passing evaluation gates opens only the canary alias. Each attempt appends an immutable receipt with candidate, production base, policy version, verdict, and reasons. Nothing in this cell can overwrite production.

Wait for Canary Evidence

Fast checks catch broken schemas, errors, and latency spikes. They can't prove prediction quality when labels arrive later. A canary rollout needs both kinds of evidence. The controller below stores each observation window inside an immutable receipt, refuses to promote after the first hour because late-delivery outcomes aren't ready yet, and handles an empty window list as a hold rather than crashing.

03-canary-window-contract.py
1@dataclass(frozen=True) 2class CanaryWindow: 3 window_id: str 4 release_id: str 5 observed_day: int 6 requests: int 7 error_rate: float 8 p95_latency_ms: int 9 delayed_labels_ready: bool 10 late_warning_cost_delta: float | None 11 12@dataclass(frozen=True) 13class CanaryReceipt: 14 receipt_id: str 15 candidate: str 16 production_before: str 17 offline_receipt_id: str 18 promotion_policy_version: str | None 19 windows: tuple[CanaryWindow, ...] 20 failed_gates: tuple[str, ...] 21 decision: str 22 23canary_receipts: dict[str, CanaryReceipt] = {} 24 25print("canary policy windows:", POLICIES["eta-promotion-v1"].min_canary_windows)
04-evaluate-canary-evidence.py
1def evaluate_canary( 2 candidate_id: str, 3 offline_receipt_id: str, 4 windows: list[CanaryWindow], 5) -> CanaryReceipt: 6 candidate = registry.get(candidate_id) 7 policy = POLICIES.get(candidate.promotion_policy_version) if candidate else None 8 offline_receipt = offline_receipts.get(offline_receipt_id) 9 failed = [] 10 abort_reasons = [] 11 if candidate is None: 12 failed.append("candidate_not_registered") 13 abort_reasons.append("candidate_not_registered") 14 elif policy is None: 15 failed.append("promotion_policy_not_registered") 16 abort_reasons.append("promotion_policy_not_registered") 17 if aliases.get("canary") != candidate_id: 18 failed.append("canary_alias_missing") 19 if ( 20 offline_receipt is None 21 or offline_receipt.candidate != candidate_id 22 or offline_receipt.decision != "open_canary" 23 ): 24 failed.append("accepted_offline_receipt_missing") 25 abort_reasons.append("accepted_offline_receipt_missing") 26 if candidate is not None and candidate.previous_release != aliases["production"]: 27 failed.append("production_changed_during_canary") 28 abort_reasons.append("production_changed_during_canary") 29 if policy is not None and len(windows) < policy.min_canary_windows: 30 failed.append("observation_window_incomplete") 31 if len({window.window_id for window in windows}) != len(windows): 32 failed.append("duplicate_window_id") 33 abort_reasons.append("duplicate_window_id") 34 observed_days = [window.observed_day for window in windows] 35 if observed_days != sorted(set(observed_days)): 36 failed.append("window_order_invalid") 37 abort_reasons.append("window_order_invalid") 38 if any(window.release_id != candidate_id for window in windows): 39 failed.append("mixed_release_windows") 40 abort_reasons.append("mixed_release_windows") 41 if any(window.requests <= 0 for window in windows): 42 failed.append("request_count_missing") 43 abort_reasons.append("request_count_missing") 44 if policy is not None and any(window.error_rate > policy.max_error_rate for window in windows): 45 failed.append("error_rate_regression") 46 abort_reasons.append("error_rate_regression") 47 if policy is not None and any( 48 window.p95_latency_ms > policy.max_p95_latency_ms for window in windows 49 ): 50 failed.append("latency_regression") 51 abort_reasons.append("latency_regression") 52 53 latest = windows[-1] if windows else None 54 if latest is None or not latest.delayed_labels_ready: 55 failed.append("delayed_quality_not_ready") 56 elif ( 57 policy is not None 58 and ( 59 latest.late_warning_cost_delta is None 60 or latest.late_warning_cost_delta > policy.max_late_warning_cost_delta 61 ) 62 ): 63 failed.append("late_warning_cost_regression") 64 abort_reasons.append("late_warning_cost_regression") 65 66 decision = ( 67 "abort_canary" 68 if abort_reasons 69 else "hold_canary" 70 if failed 71 else "ready_for_promotion" 72 ) 73 receipt = CanaryReceipt( 74 receipt_id=f"canary-receipt-{len(canary_receipts) + 1}", 75 candidate=candidate_id, 76 production_before=aliases["production"], 77 offline_receipt_id=offline_receipt_id, 78 promotion_policy_version=( 79 candidate.promotion_policy_version if candidate is not None else None 80 ), 81 windows=tuple(windows), 82 failed_gates=tuple(sorted(failed)), 83 decision=decision, 84 ) 85 canary_receipts[receipt.receipt_id] = receipt 86 if decision == "abort_canary": 87 aliases.pop("canary", None) 88 return receipt 89 90first_hour = CanaryWindow("first-hour", "delivery-risk-v1", 0, 500, 0.002, 118, False, None) 91day_seven = CanaryWindow("day-seven", "delivery-risk-v1", 7, 4200, 0.003, 124, True, -0.08) 92 93empty_receipt = evaluate_canary("delivery-risk-v1", accepted_offline_receipt.receipt_id, []) 94early_receipt = evaluate_canary( 95 "delivery-risk-v1", accepted_offline_receipt.receipt_id, [first_hour] 96) 97ready_receipt = evaluate_canary( 98 "delivery-risk-v1", accepted_offline_receipt.receipt_id, [first_hour, day_seven] 99) 100print("empty decision:", empty_receipt.decision) 101print("early decision:", early_receipt.decision) 102print("ready decision:", ready_receipt.decision)
05-print-canary-receipts.py
1print("empty:", json.dumps(asdict(empty_receipt), indent=2)) 2print("early:", json.dumps(asdict(early_receipt), indent=2)) 3print("ready:", json.dumps(asdict(ready_receipt), indent=2))
Output
1empty: { 2 "receipt_id": "canary-receipt-1", 3 "candidate": "delivery-risk-v1", 4 "production_before": "delivery-risk-v0", 5 "offline_receipt_id": "offline-receipt-2", 6 "promotion_policy_version": "eta-promotion-v1", 7 "windows": [], 8 "failed_gates": [ 9 "delayed_quality_not_ready", 10 "observation_window_incomplete" 11 ], 12 "decision": "hold_canary" 13} 14early: { 15 "receipt_id": "canary-receipt-2", 16 "candidate": "delivery-risk-v1", 17 "production_before": "delivery-risk-v0", 18 "offline_receipt_id": "offline-receipt-2", 19 "promotion_policy_version": "eta-promotion-v1", 20 "windows": [ 21 { 22 "window_id": "first-hour", 23 "release_id": "delivery-risk-v1", 24 "observed_day": 0, 25 "requests": 500, 26 "error_rate": 0.002, 27 "p95_latency_ms": 118, 28 "delayed_labels_ready": false, 29 "late_warning_cost_delta": null 30 } 31 ], 32 "failed_gates": [ 33 "delayed_quality_not_ready", 34 "observation_window_incomplete" 35 ], 36 "decision": "hold_canary" 37} 38ready: { 39 "receipt_id": "canary-receipt-3", 40 "candidate": "delivery-risk-v1", 41 "production_before": "delivery-risk-v0", 42 "offline_receipt_id": "offline-receipt-2", 43 "promotion_policy_version": "eta-promotion-v1", 44 "windows": [ 45 { 46 "window_id": "first-hour", 47 "release_id": "delivery-risk-v1", 48 "observed_day": 0, 49 "requests": 500, 50 "error_rate": 0.002, 51 "p95_latency_ms": 118, 52 "delayed_labels_ready": false, 53 "late_warning_cost_delta": null 54 }, 55 { 56 "window_id": "day-seven", 57 "release_id": "delivery-risk-v1", 58 "observed_day": 7, 59 "requests": 4200, 60 "error_rate": 0.003, 61 "p95_latency_ms": 124, 62 "delayed_labels_ready": true, 63 "late_warning_cost_delta": -0.08 64 } 65 ], 66 "failed_gates": [], 67 "decision": "ready_for_promotion" 68}

late_warning_cost_delta=-0.08 means the candidate reduced late-warning cost by eight percent relative to the previous release on this local fixture. It's a teaching threshold, not a universal production policy. Real teams choose windows and limits from product risk, traffic volume, and label delay.

An incomplete window returns hold_canary: gather more evidence without widening exposure. A measured latency, error-rate, or delayed-quality regression returns abort_canary and removes the canary alias. Corrupted or mismatched telemetry aborts too because the controller can't prove safe exposure. Missing evidence and negative evidence aren't the same operational state.

Promote Last, Then Prove Rollback

The final cell makes alias movement explicit. Promotion fetches a stored canary receipt by ID rather than trusting a caller-supplied decision dictionary. Rollback follows the same rule: production metrics become a stored receipt before they can restore the previous release. Both paths recheck the live production alias immediately before movement.

06-promote-with-stored-receipt.py
1@dataclass(frozen=True) 2class AliasEvent: 3 action: str 4 from_release: str 5 to_release: str 6 evidence_receipt_id: str 7 reasons: tuple[str, ...] 8 9@dataclass(frozen=True) 10class ProductionReceipt: 11 receipt_id: str 12 window: CanaryWindow 13 failed_gates: tuple[str, ...] 14 decision: str 15 16audit_events: list[AliasEvent] = [] 17production_receipts: dict[str, ProductionReceipt] = {} 18 19def promote(candidate_id: str, canary_receipt_id: str) -> dict[str, object]: 20 candidate = registry.get(candidate_id) 21 canary_receipt = canary_receipts.get(canary_receipt_id) 22 failed = [] 23 if candidate is None: 24 failed.append("candidate_not_registered") 25 if aliases.get("canary") != candidate_id: 26 failed.append("canary_alias_missing") 27 if canary_receipt is None: 28 failed.append("canary_receipt_not_registered") 29 elif canary_receipt.candidate != candidate_id: 30 failed.append("canary_receipt_candidate_mismatch") 31 elif canary_receipt.decision != "ready_for_promotion": 32 failed.append("canary_receipt_not_ready") 33 elif ( 34 candidate is not None 35 and canary_receipt.promotion_policy_version != candidate.promotion_policy_version 36 ): 37 failed.append("canary_receipt_policy_mismatch") 38 elif ( 39 offline_receipts.get(canary_receipt.offline_receipt_id) is None 40 or offline_receipts[canary_receipt.offline_receipt_id].decision != "open_canary" 41 ): 42 failed.append("offline_receipt_not_registered") 43 if candidate is not None and candidate.previous_release != aliases["production"]: 44 failed.append("production_changed_since_canary_open") 45 if canary_receipt is not None and canary_receipt.production_before != aliases["production"]: 46 failed.append("production_changed_since_canary_receipt") 47 if failed: 48 return {"action": "hold_promotion", "reasons": sorted(failed)} 49 50 previous = aliases["production"] 51 aliases["previous_production"] = previous 52 aliases["production"] = candidate_id 53 aliases.pop("canary") 54 event = AliasEvent("promote", previous, candidate_id, canary_receipt_id, ()) 55 audit_events.append(event) 56 return asdict(event) 57 58print("promote helper ready")
07-monitor-production-and-rollback.py
1def rollback_reasons(window: CanaryWindow) -> list[str]: 2 release = registry.get(window.release_id) 3 if release is None: 4 return ["production_window_release_not_registered"] 5 policy = POLICIES.get(release.promotion_policy_version) 6 if policy is None: 7 return ["production_policy_not_registered"] 8 failed = [] 9 if window.error_rate > policy.max_error_rate: 10 failed.append("error_rate_regression") 11 if window.p95_latency_ms > policy.max_p95_latency_ms: 12 failed.append("latency_regression") 13 if not window.delayed_labels_ready: 14 failed.append("delayed_quality_not_ready") 15 elif ( 16 window.late_warning_cost_delta is None 17 or window.late_warning_cost_delta > policy.max_late_warning_cost_delta 18 ): 19 failed.append("late_warning_cost_regression") 20 return failed 21 22def evaluate_production(window: CanaryWindow) -> ProductionReceipt: 23 failed = rollback_reasons(window) 24 release_mismatch = window.release_id != aliases["production"] 25 if release_mismatch: 26 failed.append("production_window_release_mismatch") 27 decision = ( 28 "hold_rollback" 29 if release_mismatch 30 else "rollback_required" 31 if failed 32 else "keep_production" 33 ) 34 receipt = ProductionReceipt( 35 receipt_id=f"production-receipt-{len(production_receipts) + 1}", 36 window=window, 37 failed_gates=tuple(sorted(failed)), 38 decision=decision, 39 ) 40 production_receipts[receipt.receipt_id] = receipt 41 return receipt 42 43def rollback_if_needed(production_receipt_id: str) -> dict[str, object]: 44 receipt = production_receipts.get(production_receipt_id) 45 if receipt is None: 46 return {"action": "hold_rollback", "reason": "production_receipt_not_registered"} 47 if receipt.decision == "hold_rollback": 48 return {"action": "hold_rollback", "reasons": list(receipt.failed_gates)} 49 if receipt.window.release_id != aliases["production"]: 50 return {"action": "hold_rollback", "reason": "production_changed_since_monitor_receipt"} 51 if receipt.decision == "keep_production": 52 return {"action": "keep_production", "release": aliases["production"]} 53 if receipt.decision != "rollback_required": 54 return {"action": "hold_rollback", "reason": "production_receipt_decision_invalid"} 55 56 previous = aliases.get("previous_production") 57 if previous is None or previous not in registry: 58 return {"action": "hold_rollback", "reason": "previous_production_not_registered"} 59 failed_release = aliases["production"] 60 aliases["production"] = previous 61 aliases["rollback_from"] = failed_release 62 event = AliasEvent( 63 "rollback", 64 failed_release, 65 previous, 66 receipt.receipt_id, 67 receipt.failed_gates, 68 ) 69 audit_events.append(event) 70 return asdict(event) 71 72print("rollback helper ready")
08-attempt-promotion-paths.py
1print("fabricated promotion:", promote("delivery-risk-v1", "canary-receipt-missing")) 2print("early promotion:", promote("delivery-risk-v1", early_receipt.receipt_id)) 3print("approved promotion:", promote("delivery-risk-v1", ready_receipt.receipt_id))
09-detect-production-regression.py
1degraded = CanaryWindow("production-day-eight", "delivery-risk-v1", 8, 900, 0.004, 130, True, 0.14) 2degraded_receipt = evaluate_production(degraded) 3rollback_result = rollback_if_needed(degraded_receipt.receipt_id) 4print("production decision:", degraded_receipt.decision) 5print("rollback action:", rollback_result["action"])
10-audit-alias-movements.py
1print("production receipt:", json.dumps(asdict(degraded_receipt), indent=2)) 2print("rollback:", rollback_result) 3print("aliases:", json.dumps(aliases, sort_keys=True)) 4print("audit:", json.dumps([asdict(event) for event in audit_events], indent=2))
Output
1production receipt: { 2 "receipt_id": "production-receipt-1", 3 "window": { 4 "window_id": "production-day-eight", 5 "release_id": "delivery-risk-v1", 6 "observed_day": 8, 7 "requests": 900, 8 "error_rate": 0.004, 9 "p95_latency_ms": 130, 10 "delayed_labels_ready": true, 11 "late_warning_cost_delta": 0.14 12 }, 13 "failed_gates": [ 14 "late_warning_cost_regression" 15 ], 16 "decision": "rollback_required" 17} 18rollback: {'action': 'rollback', 'from_release': 'delivery-risk-v1', 'to_release': 'delivery-risk-v0', 'evidence_receipt_id': 'production-receipt-1', 'reasons': ('late_warning_cost_regression',)} 19aliases: {"previous_production": "delivery-risk-v0", "production": "delivery-risk-v0", "rollback_from": "delivery-risk-v1"} 20audit: [ 21 { 22 "action": "promote", 23 "from_release": "delivery-risk-v0", 24 "to_release": "delivery-risk-v1", 25 "evidence_receipt_id": "canary-receipt-3", 26 "reasons": [] 27 }, 28 { 29 "action": "rollback", 30 "from_release": "delivery-risk-v1", 31 "to_release": "delivery-risk-v0", 32 "evidence_receipt_id": "production-receipt-1", 33 "reasons": [ 34 "late_warning_cost_regression" 35 ] 36 } 37]

Rollback restores delivery-risk-v0, not its weights alone. That distinction matters because preprocessing, features, thresholds, and policy can all change serving behavior. Each audit event names the stored receipt that authorized its alias movement, so a later reviewer can reconstruct both promotion and rollback.

Join Fast and Delayed Monitoring

Live checks differ by product, but the promotion controller handles the same categories:

Gate typeETARankingForecastVision
immediate data healthscan freshnesseligible candidate supplylatest counts loadedphoto quality
immediate service healthlatency/errorsscoring latencyforecast API availabilityimage scoring latency
delayed qualitylate warning costpurchase/return experimentMAE and peak residualreviewer-confirmed damage
rollback eventstale warning spikeblocked listing exposurebroken alert floodunsupported escalations

For scoring systems with delayed labels, canary monitoring should pause wider promotion until enough outcomes arrive. A model that hasn't failed yet isn't the same as a model that has passed.

Continuous training is appropriate when a schedule or monitored condition creates a candidate run. It should never skip data validation, offline comparisons, or a promotion record. The pipeline's value isn't automation alone; it's refusing untraceable changes.

Practice: break the release controller

Run the runnable examples again after each mutation. Predict which receipt or alias changes before reading output.

  1. Change the delivery-risk-v1 constructor's previous_release from "delivery-risk-v0" to "delivery-risk-v-missing".
  2. Set good_gates["critical_slice_pass"] back to False.
  3. Pass [day_seven, first_hour] to one evaluate_canary call. Confirm that the receipt records window_order_invalid.
  4. Change the day_seven constructor's delayed_labels_ready argument from True to False.
  5. Change the day_seven constructor's late_warning_cost_delta argument from -0.08 to 0.05.
  6. Replace ready_receipt.receipt_id with "canary-receipt-missing" in the approved promotion call.
  7. Before approved promotion, set aliases["production"] = "delivery-risk-v1" to simulate an out-of-band alias move. Confirm that promotion holds, then reset it to "delivery-risk-v0".
  8. Change the degraded constructor's late_warning_cost_delta argument from 0.14 to -0.01.
  9. Change the degraded constructor's release ID from "delivery-risk-v1" to "delivery-risk-v0". Confirm that monitoring evidence for a different release can't move the current alias.
  10. Replace degraded_receipt.receipt_id with "production-receipt-missing" in the rollback call. Which authorization check holds the alias?

Practice answer sketches

Submission checklist

ArtifactAcceptance condition
release schemaidentifies data, features, model, action policy, promotion policy, and previous release
registrycontains immutable stable and candidate releases
append-only receiptsrecord why each candidate passed, held, aborted, promoted, or rolled back
alias promotion codefetches stored receipt and rechecks production before moving alias
monitor policydefines canary pause, promote, abort, rollback
testsexecute empty-window, failed-gate, fabricated-receipt, alias-race, and rollback paths

This completes the conventional production ML portfolio. The next capstone returns to LLM products: document QA must apply the same lineage and release discipline to retrieved evidence and generated answers.

Mastery check

Evaluation rubric

ArtifactStrong submission demonstrates
reproducible runversioned data, features, model artifact, threshold policy, and evaluation evidence
controlled promotioncandidate alias, automated gates, canary criteria, and explicit production move
recoverymonitoring tied to actions, rollback trigger, and deployable prior release

Common failures

SymptomCauseFix
Retrain job changes behavior with no reviewtraining and promotion mergedseparate candidate registry from aliases
Rollback restores weights but not thresholdpolicy omitted from release bundleversion complete release tuple
Empty canary window crashes controllerlatest observation indexed before evidence existsreturn a stored hold receipt for missing evidence
Canary promotes before outcomes existonly latency checkedrequire delayed quality window
Fabricated ready dictionary promotes candidatealias mover trusts caller-owned statefetch immutable receipt by stored ID
Production changed after canary openedrollback base checked only oncerecheck current alias before promotion
Old monitoring window rolls back current releaserollback trusts reasons without release identityverify monitor window matches production alias
Caller fabricates rollback reasonsalias mover accepts an unregistered reason listevaluate monitoring once, store receipt, and fetch it by ID
Rollback points at an unknown statecandidate omits previous releaseverify rollback target before opening canary traffic
Production changes but incident review has no historyalias moves aren't auditedappend promotion and rollback events
Complete the lesson

Mastery Check

Answer every question, then check your score. Score above 75% to mark this lesson complete.

1.An incident team restores the damage-cnn-v0 weight file, but the failed cropper and review threshold from damage-cnn-v1 remain active. Which release design prevents this rollback failure?
2.A nightly job trains warehouse-demand-v2 on a new snapshot and writes the model artifact, but no offline gate or canary receipt exists. What should the platform allow next?
3.In the release registry, delivery-risk-v1.previous_release is delivery-risk-v-missing while production still points to delivery-risk-v0. What should open_canary do?
4.A registered ETA candidate passes schema_valid, no_leakage, and cost_improves, but fails critical_slice_pass. Production is delivery-risk-v0. What is the correct result?
5.Canary service health is within limits. One evaluation receives no observation windows. Another has enough ordered windows, but its latest labeled window has late_warning_cost_delta=0.05 while the maximum is 0.0. How should the decisions differ?
6.evaluate_canary receives windows for delivery-risk-v1 in this order: day-seven with observed_day=7, then first-hour with observed_day=0. The accepted offline receipt and canary alias are valid. Which decisive status should it include?
7.An API caller passes a real canary receipt ID for delivery-risk-v1, and the stored receipt says ready_for_promotion. Before promote runs, production no longer equals the receipt's production_before. What should happen?
8.Production is delivery-risk-v1. One monitor window for delivery-risk-v1 has passing health and late_warning_cost_delta=-0.01; another window has regression reasons but release_id='delivery-risk-v0'. Which rollback behavior is correct?
9.A promotion endpoint accepts a caller-created dictionary saying ready_for_promotion and moves production without recording an alias event. Which change establishes traceable authorization?

9 questions remaining.

Next Step
Continue to Capstone: Document QA

You have shipped a validated predictive-ML promotion path. Next you'll carry the same evidence discipline into a document-answering service whose outputs must cite approved source material or abstain.

PreviousCapstone: Image Damage Classifier
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

Hidden Technical Debt in Machine Learning Systems.

Sculley et al. · 2015

MLOps: Continuous Delivery and Automation Pipelines in Machine Learning.

Google Cloud. · 2026 · Official documentation

Discussion

Questions and insights from fellow learners.

Discussion loads when you reach this section.