Chapter 17 of 18

From Experiment to Production

Explain this chapter with AI

Copy this prompt into ChatGPT, Claude, Gemini, a local model, or another AI.

Apply this chapter with AI

Copy this prompt into ChatGPT, Claude, Gemini, a local model, or another AI.

From Experiment to Production

Chapter 16 gave us a candidate that can be evaluated without obvious leakage.

That still does not mean:

optimizer.compile(...)
production

The lifecycle is closer to:


1. Offline win is insufficient

A candidate may beat an aggregate metric and still be unacceptable:


2. CoCoder’s promotion boundary

CoCoder stores separate records:

ProgramEvaluationCaseResultDTO
ProgramEvaluationDTO
ProgramComparisonDTO
ProgramPromotionDTO

The docs summarize the invariant:

optimizer proposes
CoCoder evaluates
CoCoder compares
operator/system policy promotes

Promotion requires a persisted comparison, a promote recommendation unless there is an explicit override, the comparison baseline still being the single active version, the target still being a candidate, and optimizer lineage—when present—matching that active baseline.

An override changes the governance decision; it does not erase the underlying comparison evidence. Both should remain queryable.

In CoCoder, promote(...) then performs the status transition transactionally:


3. DSPy artifact vs deployment manifest

DSPy can save compiled parameter state:


4. Service boundary

A minimal service shape:


5. Observability is part of activation

A production run should produce a record even when nothing dramatic happens. Runtime identity should come from the deployment/runtime boundary, not from fields the model happened to return.

For repository repair, add tool-call summaries, repository revision, changed files, test targets, validation artifact IDs, scope result, and isolated-workspace identity. For editorial work, add candidate source, evidence-packet fingerprint, review decision, application status, and any later outcome references.

Do not put every raw input, tool observation, or model trace into one analytics row by default. Production records may contain sensitive or high-volume material. Keep durable identity/fingerprints in the run record and store larger evidence under an explicit retention and access policy.

The record is not automatically a training example. It becomes source material for a future controlled dataset only after:


6. Shadow, canary, activation

Safe activation is staged.

Shadow:


7. Production feedback is not automatically a label

Be careful:

program produced result
user did not complain


positive label

Also:

human preferred candidate
candidate was not applied


successful production outcome

Writer’s architecture distinguishes preference evidence, candidate-generation evidence, blind review, application evidence, and later statistics/ranker evaluation. That separation illustrates a broader production rule:


8. Rollback is a feature, not a failure

If a system can activate a version, it must be able to reverse that activation:


What Usually Goes Wrong

Symptom Likely cause How to diagnose it What to change
Candidate wins offline and breaks production Offline/online execution contract differs Compare deployment fingerprint, LM/adapter, tools/indexes, traffic slices, latency, and fallback behavior Fix parity first; shadow and canary before full activation
Shadow run changes production state Candidate has side-effecting tools despite hidden output Audit tool calls and external mutations Use read-only or isolated shadow dependencies
Cannot explain active behavior Active registry points to a version without an immutable deployment manifest Resolve a production request back through run → deployment → promotion/comparison evidence Require manifest fingerprint on every active deployment and run
Run claims the wrong model/version Runtime provenance came from model output or mutable global config Compare run record with deployment snapshot and provider telemetry Resolve identity at the runtime boundary per request
Canary result is hard to interpret Assignment or stop thresholds changed during the run Audit routing history and gate versions Freeze assignment and rollback policy before canary start
Rollback restores code but still fails Historical external dependencies drifted or disappeared Reconstruct the full rollback bundle in staging Pin/version dependencies and continuously test rollback readiness
Optimizer score becomes deployment policy Optimization, comparison, and activation are fused Trace the active-version transition Require persisted independent evaluation, comparison, and promotion decision
Production feedback corrupts training data Observation was converted directly into a label or leaked later outcome into generation view Audit label lineage and dataset-building policy Separate observation, mature outcome, derived label, and decision-time training view

Conclusion

We gained a production lifecycle for DSPy programs: immutable candidate state, independent evaluation, deterministic comparison, explicit promotion, deployment reconstruction checks, controlled activation, attributable production runs, staged exposure, mature feedback, and rollback.

We removed three assumptions: that an optimized program should serve real work automatically, that a saved DSPy state is the same thing as a deployment, and that rollback means loading an old prompt file.

The full lifecycle is now visible: