022 spec: registry-driven LLM serving + operator model selection#64
Conversation
The LLM is the sole engine that ignores the registry @Serving alias — it loads a host-configured GGUF, so promoting an LLM in the console does nothing, fine-tunes aren't discoverable, and the served-model label diverges from what runs (corrupting monitoring). Spec makes the LLM a registry-driven, console-operable engine like the others. 5 prioritized user stories: US1 promote-to-serve (P1), US2 honest served identity (P1), US3 serve LoRA fine-tunes base+adapter (P2), US4 fine-tunes first-class serving targets (P2), US5 safe switch under the lease (P3). FR-254..274, SC-143..151. Quality checklist 16/16 PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Grounded in the confirmed reference pattern: every non-LLM child resolves its @Serving version's artifact from MLflow on each cold load (pinned to a model name via env); the llama.cpp adapter alone loads a fixed GGUF path and never touches the registry. Plan makes the LLM adopt the same cold-load resolution, extended to base+adapter, plus honest agent-reported identity. Artifacts: plan.md (Constitution Check PASS — Principle II reuses the existing swap), research.md (R1–R8: platform-scoped active-serving-LLM pointer, base+adapter registry resolution, reload-on-select via swap, honest identity, task-tag backfill), data-model.md, contracts/ (serving resolution + agent identity/allowlist), quickstart.md. CLAUDE.md marker → 022 plan. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
29 tasks across setup (store pointer + base GGUF registration), foundational (cold-load resolver + gateway registry pointer), US1 promote-to-serve (MVP), US2 honest identity, US3 base+adapter serving, US4 discoverability+backfill, US5 safe switch under the lease ([HW]), and polish. pytest for backend + lint/build for the console + [HW] drills; no phase relaxes Principle II. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ope, immediate reload) Session 2026-07-05 clarifications integrated into the spec: - Promote = immediate go-live activation (single action) — sharpened FR-255. - Immediate controlled reload (not lazy) — FR-255. - Operator-only served-LLM switching; policies gate but never auto-switch — new FR-275 + Out of Scope. - Scope kept to the LLM serving quirks; dataset byte-download (FR-215) + streamed-prediction logging deferred to their own specs — Out of Scope. All four matched the recommended options; no contradiction; tasks already honor them. Checklist 16/16 still PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- I1 (MEDIUM): propagate 'promote = go live' into T467/T482 + the identity/ allowlist contract — the gated promote IS the switch; no separate select action, so no new route beyond the existing promote. - G1 (MEDIUM): T485 asserts FR-273 (no new resident process + budget). - G2 (LOW): T485 guards FR-275 (auto-promote path cannot switch the LLM). - T1 (LOW): harmonize 'base reference' → registered base model version. - A1 (LOW): SC-146 names the concrete observable (a trained response marker). Cross-artifact analysis: 31 requirements, 29 tasks, ~100% coverage after G1/G2, 0 duplication, 0 ambiguity remaining, Constitution PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@claude please review the spec design in this spec-only PR (feature 022 — making the LLM a registry-driven, console-operable engine). Focus on the design, not code (there is none):
Flag any real gap, unstated assumption, or Principle II risk. (@codex is auto-reviewing on open.) |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Claude finished @kurtvalcorza's task in 3m 22s —— View job Claude's review of the 022 spec designTodo list
This is a well-reasoned spec (research.md's R1–R8 rationale is unusually thorough), but I cross-checked the design against the actual 1. The "reload-on-promote" path may be a no-op in the most common case (FR-255/257, SC-144)Research R4 and task T466 say switching the served LLM "reuses # hostagent/swap.py:56-59
holder = admission.holder()
if holder is None or holder["tenant"] == target_engine_id:
load_ms = target.ensure_loaded()
return {"swapped": False, "evicted": None, "load_ms": load_ms}and # hostagent/lifecycle.py:89-92
if self._resident() and self.adapter.ready():
self.last_used = self.clock()
return 0.0Admission's tenant identity is per engine ( Reusing the swap machinery correctly here needs an explicit same-tenant force-reload path (unload → ensure_loaded) distinct from 2. FR-262 (no divergence between "internal display alias" and registry record) isn't fully covered by a task
# hostagent/adapters/llama.py:45-46, 106-112, 123, 141-142
self.alias = os.getenv("MODEL_ALIAS", DEFAULT_ALIAS)
...
return {"text": ..., "model": self.alias, ...}
3.
|
@claude spec review (PR #64) caught 3 real gaps where 'reuses existing X' didn't hold against the code; @codex rate-limited → acting on @claude's verdict: - §1 (headline): the same-tenant LLM model switch (promote B while A resident) is a no-op under preempt_for — admission tenancy is per-ENGINE ('llm'), so holder==target short-circuits ensure_loaded and the old GGUF keeps serving, silently breaking FR-255/SC-144. Fix: explicit same-tenant force-reload (unload llm child → ensure_loaded) distinct from cross-engine eviction (research R4, contracts/serving-resolution, T466). - §2: the adapter's /infer response 'model' echoes static self.alias (MODEL_ALIAS env), not the resolved identity → FR-262 divergence one layer below the gateway. Fix: T465 sets the response identity from the resolved model_name. - §3: serving/tasks emits a row per model with ANY @Serving alias; a promote leaves prior models' aliases set → stale/duplicate LLM panels. Fix: new FR-276 + T479 filter serving/tasks to the active-serving-LLM pointer. - R2 note: base_model must resolve directly to a full-model base; adapter-of- adapter is a resolution error (contract + data-model). No Principle II violation found. Checklist still 16/16. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@claude thanks — all three findings were real and code-grounded; fixed in-spec in §1 (headline — same-tenant reload no-op): Confirmed against §2 (FR-262 adapter response echo): T465 now sets the adapter's response §3 (stale R2 note: contract + data-model now state Please re-review. Your Principle-II read (no two-resident window; the risk was the same-tenant no-op, not a lease violation) matched my re-check exactly. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Claude finished @kurtvalcorza's task in 1m 18s —— View job Re-review of
|
Spec-only PR — the complete spec-kit artifact set for feature 022 (no implementation code). Reviewing the design before building it, the way 021's spec landed via #62.
Why
Driving the merged 021 console end-to-end surfaced that the LLM is the only engine that ignores the registry. Every other child (vision/embed/ASR/tabular) resolves its
@servingversion's artifact from MLflow on each cold load; thellama.cppadapter alone loads a fixed GGUF file path from an env var. So four quirks:.envedit + agent restart.tasktag → show as "no renderer", not selectable.(All four reproduced live: I trained
ops-bot-v2, and only a host-level override could serve it.)What the spec proposes
Make the LLM a registry-driven, console-operable engine like the others: promoting a text-generation version (a full base or a LoRA fine-tune) makes it serve, under the single-GPU lease, with honest agent-reported identity everywhere.
5 user stories — US1 promote-to-serve (P1), US2 honest identity (P1), US3 base+adapter serving (P2), US4 fine-tunes discoverable + backfill (P2), US5 safe switch under the lease (P3, [HW]). FR-254…275, SC-143…151, 29 tasks (T461–T489).
Artifacts in this PR
specs/022-registry-driven-llm-serving/— spec.md, plan.md, research.md, data-model.md, contracts/ (serving-resolution + agent-identity/allow-list), quickstart.md, tasks.md, checklists/requirements.md. (+ the.specify/feature.json+CLAUDE.mdmarker bumps.)Design decisions worth reviewing
-m base --lora adapter(register bases as first-class full-model versions; resolve the base from lineage) rather than merge-on-promote.Process already run on these artifacts
/speckit-specify→/speckit-plan→/speckit-tasks→/speckit-clarify(4 decisions ratified) →/speckit-analyze(0 critical / 0 high; 5 MEDIUM/LOW findings remediated).Please review the spec design — especially R1 (the active-LLM pointer vs an env-pinned name), the Principle II framing of the switch, and whether the scope boundary (LLM-only) is right.
@claude review this spec design
@codex review
🤖 Generated with Claude Code