Files
club-3090/scripts/tests/test-compose-image-drift.sh
T
noonghunnaandClaude Opus 4.8 a9ffb532ef refactor(vllm): reconcile vLLM engines to v0.22.0 — two-engine split (#254)
Replace the purged `vllm-nightly-clean` pin (nightly-bf610c2f, now 404 on
Docker Hub — so the launcher injected a dead image for every slug on it)
with a v0.22.0 two-engine design:

- `vllm-stable`: OVERLAY-FREE v0.22.0 — the broad successor to
  vllm-nightly-clean. Serves Qwen3-Next (hybrid 27b + MoE 35B-A3B), generic
  `dense` transformers, and uncurated derived-emission bases. Migrates
  vllm/qwen-35b-a3b-dual, vllm/dual, vllm/minimal (live-validated on stock
  v0.22.0: TP=2 + MTP + tool-call clean; marlin-pad confirmed unnecessary).
  Added as the first loads:true arch pin on the qwen + dense rows.
- `vllm-gemma-stable`: KEPT as the OVERLAY-CARRYING v0.22.0 engine (#40391
  per-head INT8 KV + #42006 tool-parser) — the Gemma 4 path. Unchanged.
- `vllm-pip-baseline`: the renamed pip `dense` lower-bound (frees the
  `vllm-stable` name for the docker engine above).

Why two engines and not one: `vendored_overlays` is LOAD-BEARING, not
documentation. `derived_emittable` (CONTRACT-5) refuses any engine whose
`vendored_overlays != []` as a derived-emission base, and `diagnose-profile`
expects the Gemma overlay declared on its engine. A single engine cannot be
both overlay-free (for derived/Qwen bases) and overlay-carrying (for Gemma
provenance) — so the two stay split. Compose owns patch APPLICATION; engine
owns provenance/compatibility. (An attempt to fold both into one engine broke
4 tests via exactly these two consumers; the split is the validated shape.)

Also adds scripts/tests/test-compose-image-drift.sh: asserts every fixed
`${VLLM_IMAGE:-<tag>}` compose default equals its engine's `install.spec`
(catches bump-the-engine-forget-the-literal drift), and a docs/ADDING_MODELS.md
"Coherence rules" section codifying the compose/engine/patch separation.

42/42 gate green; resolver emits v0.22.0 for all migrated Qwen + Gemma slugs.
The remaining experimental/preview slugs still on vllm-nightly-clean migrate
in follow-up as each is validated, then that engine is deprecated.

Refs #254.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-05 11:27:17 +00:00

82 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Drift guard (Codex review, #254/#324): every vLLM compose whose
# `image: ${VLLM_IMAGE:-<literal>}` default is a FIXED docker image must match the
# install.spec of the engine its registry slug resolves to. This catches the
# "bump the engine spec but forget the compose literal" drift that would silently
# feed direct `docker compose` users a stale image (the launcher injects VLLM_IMAGE
# from the engine and is fine; the compose literal is the unguarded path).
#
# Skipped (by design):
# - templated literals like `…:nightly-${VLLM_NIGHTLY_SHA}` — self-sync via the
# launcher-injected var, so the literal is always in step with the engine.
# - pip-method engines (vllm-pip-baseline) — no docker image to match.
set -euo pipefail
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)"
python3 - "$ROOT_DIR" <<'PY'
import sys, re, pathlib
ROOT = pathlib.Path(sys.argv[1])
sys.path.insert(0, str(ROOT))
from scripts.lib.profiles.compose_registry import COMPOSE_REGISTRY
from scripts.lib.profiles.compat import load_profiles
# Slugs whose ENGINE is itself pending the #254 migration off the purged
# vllm-nightly-clean nightly (the engine repoint needs its own stock-v0.22.0
# boot + tool-call/MTP validation — out of the #324 leg). Their compose literal
# was pre-bumped to v0.22.0, so they read as "drifted" against the dead nightly
# spec until the engine is repointed. Exempted + reported (NOT silently skipped);
# delete each from this set when it migrates to vllm-stable, and the guard then
# covers it. Tracked in #254.
PENDING_254 = set()
profiles = load_profiles()
pat = re.compile(r'image:\s*\$\{VLLM_IMAGE:-([^}]+)\}')
drift, checked, pending, deprecated = [], 0, [], 0
for slug, entry in COMPOSE_REGISTRY.items():
if entry.get("status") == "deprecated":
deprecated += 1
continue # on its way out — not drift-guarded
if slug in PENDING_254:
pending.append(slug)
continue
eng_id = entry.get("engine")
eng = profiles.engines.get(eng_id) if eng_id else None
if eng is None:
continue
install = getattr(eng, "install", None) or {}
if install.get("method") != "docker_image":
continue # pip baseline etc. — no docker image to compare against
spec = install.get("spec", "")
cpath = entry.get("compose_path")
if not cpath:
continue
p = ROOT / cpath
if not p.exists():
continue
m = pat.search(p.read_text())
if not m:
continue
literal = m.group(1).strip()
if "${" in literal:
continue # templated (e.g. nightly-${VLLM_NIGHTLY_SHA}) — self-syncs
checked += 1
if literal != spec:
drift.append(
f" {slug}: compose default `{literal}` != engine `{eng_id}` install.spec "
f"`{spec}` ({cpath})"
)
if drift:
print("IMAGE DRIFT — a fixed compose `${VLLM_IMAGE:-…}` default disagrees with the")
print("engine its slug resolves to (direct `docker compose` would serve a stale image):")
print("\n".join(drift))
print("Fix: bump the compose literal to the engine install.spec (or vice-versa).")
sys.exit(1)
if pending:
print(f"NOTE: {len(pending)} slug(s) exempt pending #254 engine migration: {', '.join(sorted(pending))}")
print(
f"test-compose-image-drift: ok ({checked} fixed-image vLLM composes match their engine spec; "
f"{deprecated} deprecated skipped, {len(pending)} pending-#254 exempt)"
)
PY