LearnNewsExamplesServices
Frontmatter
id13948
titleRestore provider role-set residency before escalation
stateClosed
labels
bugaiarchitecturemodel-experience
assigneesneo-gpt
createdAtJun 24, 2026, 1:23 PM
updatedAtJun 24, 2026, 2:08 PM
githubUrlhttps://github.com/neomjs/neo/issues/13948
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 24, 2026, 2:08 PM

Restore provider role-set residency before escalation

Closed v13.1.0/archive-v13-1-0-chunk-6 bugaiarchitecturemodel-experience
neo-gpt
neo-gpt commented on Jun 24, 2026, 1:23 PM

Context

Operator live observation after the harness/orchestrator restart: only the embedding model remained resident (text-embedding-qwen3-embedding-8b, Idle TTL 60 min, Parallel 4). The configured intent is not "keep whichever model was most recently used"; it is to keep the active provider role set resident: one chat model and one embedding model. If the currently unused role is ejected, the next request pays a cold load and the recovery daemon never closes the loop.

Live latest-open sweep: checked latest 20 open issues at 2026-06-24T11:22:18Z; no equivalent found. Closest related issues are #13700 (LM Studio chat parallel-slot memory), #13879 (Ollama stale resident reporting), and #13852 (native Ollama lifecycle/context). A2A in-flight sweep over latest 30 messages at 2026-06-24T11:22:18Z found no competing claim.

Release classification: deployment immune-system hardening under the recovery epic; boardless until the operator explicitly marks it release-blocking.

The Problem

The provider readiness helpers can already describe and warm the configured role set, but the diagnostics/recovery boundary treats a missing configured model as config drift. That means "embedding resident, chat missing" escalates instead of first restoring the missing role. On a memory-constrained host this causes avoidable reload latency and can look like aggressive model switching/ejection.

The failure class affects both local LM Studio and cloud/native Ollama. The fix must cover both providers through the active provider readiness path, not add a local-only workaround.

The Architectural Reality

  • ai/config.template.mjs defines ollama.requireParallelModels and openAiCompatible.requireParallelModels as the distinct resident-model count, default 2. This is separate from LM Studio --parallel, which is a per-model slot/KV-cache multiplier.
  • buildLmsPreloadConfig() and buildOllamaReadinessConfig() already derive the active chat/embedding role set from AiConfig selectors.
  • ensureLmsModelsLoaded() can load missing LM Studio role models and narrowly clean stale/suffixed same-model residents.
  • ensureOllamaModelsReady() can warm missing native Ollama chat/embedding roles through /api/chat and /api/embed with configured keep_alive and context.
  • ContainerHealthDiagnosisService currently maps missing-required-model to config drift/escalate, and RecoveryActuatorService only supports restart/redeploy/page, so there is no warm-before-escalate repair path.

The Fix

Add a provider-residency repair path that preserves the full active role set before escalation:

  1. Classify missing active role models as a recoverable provider-role residency gap first, not immediate config drift.
  2. Route the first repair through the active provider readiness helper: LM Studio via ensureLmsModelsLoaded(), native Ollama via ensureOllamaModelsReady().
  3. Add hysteresis/cooldown so repeated probes do not churn models or spam warm attempts.
  4. Keep duplicate cleanup narrow: unload only stale/suffixed same-model residents after the exact configured model is sufficient. Never unload the configured chat model merely because embedding is active, or vice versa.
  5. Escalate only after repair fails or provider capacity prevents co-residency, with operator-actionable guidance for LM Studio loaded-model cap or Ollama max-loaded-models/memory budget.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
Provider-residency diagnosis reason ADR 0025 diagnostics model Missing active role is recoverable provider-role residency before config-drift escalation Escalate if repair fails/persists JSDoc on diagnosis helper Unit coverage for missing chat and missing embedding
Recovery controller/actuator path ADR 0026 controller-agnostic recovery envelope Apply one bounded warm repair, then re-observe Page/escalate with diagnosis after cooldown/attempt cap Service JSDoc + PR body Unit coverage for cooldown and failure escalation
LM Studio role-set repair providerReadinessHelper.mjs Restore full required model set while preserving the other role Degraded result if load/cap fails Existing helper JSDoc updates Unit tests for chat-missing/embedding-resident and inverse
Native Ollama role-set repair providerReadinessHelper.mjs Warm missing roles through /api/chat or /api/embed with configured keep_alive/context Degraded result with capacity warning Existing helper JSDoc updates Unit tests for both role directions
Optional embedding parallel config ADR 0019 AiConfig SSOT If added, define localModels.embedding.parallel as a leaf; consumers read at use site Leave LM Studio default if not added Config comments Config/helper test if implemented

Decision Record impact

Aligned-with ADR 0019, ADR 0025, and ADR 0026. This work reads AiConfig leaves at the use site, keeps diagnostics separate from actuator authority, and applies one bounded lifecycle/config repair before escalation.

Acceptance Criteria

  • LM Studio: when chat is missing and embedding is resident, recovery warms/restores chat without unloading embedding.
  • LM Studio: when embedding is missing and chat is resident, recovery warms/restores embedding without unloading chat.
  • LM Studio duplicate cleanup remains same-model only and gated on the exact configured model being sufficient.
  • Native Ollama: missing chat or embedding role is warmed through the correct native endpoint with configured keep_alive and context.
  • Missing role after failed warm/capacity denial escalates with diagnosis and operator-actionable capacity guidance.
  • Hysteresis/cooldown prevents rapid repeated warm/eject/switch loops.
  • Existing readiness tests for stale residents, context enforcement, and duplicate cleanup still pass.

Out of Scope

  • No public MCP surface.
  • No arbitrary model unload endpoint.
  • No change to the meaning of requireParallelModels.
  • No phase-2 downscaling/homeostatic controller; Discussion #13873 remains the v2 home.
  • No provider-specific cloud deployment secrets or client-specific config.

Avoided Traps

  • Reject "eject the currently unused role" as the policy. The configured active role set must stay resident.
  • Reject "never unload anything" as the opposite overcorrection. Same-model duplicate/stale cleanup remains valid.
  • Reject restart/redeploy as the first response to a missing role. Warm, re-observe, then escalate if the provider cannot hold the configured set.

Related

Related: #13874, #13860, #13700, #13879, #13852

Origin Session ID: cd2b88d7-8134-4ef8-a10f-0b1e80c03db4

Handoff Retrieval Hints: provider role-set residency repair missing chat embedding resident LM Studio Ollama recovery daemon, requireParallelModels distinct models vs parallel slots, missing-required-model config drift recovery warm before escalation

tobiu referenced in commit 6b4b0ee - "fix(ai): restore provider role-set residency (#13948) (#13949) on Jun 24, 2026, 2:08 PM
tobiu closed this issue on Jun 24, 2026, 2:08 PM