Phase 2 of the ② Serve rework (Phase 1 = #635 dead-end fix): a Route-C brought model can be re-tuned before serve, without hand-editing a compose. Fields (pre-filled from the resolved slug's defaults, dropdowns to avoid typos): • served name → SERVED_NAME (Input) • ctx → MAX_MODEL_LEN (Select — presets + the slug's own default) • KV cache → KV_CACHE_DTYPE (Select — fp8_e5m2/e4m3/turboquant_4bit_nc/…) • spec-decode → SPEC on/off (Select) • VRAM util → GPU_MEMORY_UTILIZATION (Select) Mechanism (all five ride env — no per-serve compose rewrite): - data.py: ActionPlan gains `env`; dispatch merges {**os.environ, **plan.env}. - services.py: serve_generated(compose_path, overrides) → plan.env (+ pins MODEL_DIR); serve_override_defaults() parses the sibling compose's ${VAR:-default} for pre-fill (stdlib regex, no PyYAML). - swap_apply.py: emit parameterizes --served-model-name ${SERVED_NAME:-…} and gates --speculative-config behind ${SPEC:-on} via the SAME entrypoint the shipped nvfp4 compose uses — so SPEC=off drops the MTP drafter at up-time. - app.py: LaneServePane fields, revealed + pre-filled only for a Route-C armed model (hidden otherwise); collect_overrides() → serve_generated. Loose validation (dropdowns constrain; the reconcile gate + boot are the real check). Validated: emitted compose `docker compose config` resolves SERVED_NAME=X and SPEC=off (entrypoint gate) cleanly; 169 byo/serve/override tests pass. Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm Co-authored-by: noonghunna <[email protected]> Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>