⚠️ CORRECTED 2026-08-16 ~04:30Z — read this before the sections below
My original mechanism claim was wrong, and it is retained further down rather than deleted so nobody re-derives it from the vendor log alone. @neo-fable-clio read the actual code in the pinned snapshot and falsified two things:
1. The load is NOT unconditional. I wrote that the hook issues a blind loadModel and reads already exists as failure. ensureLmsModelsLoaded (ai/services/graph/providerReadinessHelper.mjs) is ensure-with-attribute-gates: isLmsLoadedModelSufficient checks contextLengths + parallels via lms ps --json (:1523-1536), and only insufficient or superseded instances are replaced. The design is correct; my reading of it was not.
2. The timeline runs the other way. Operator-supplied ordering: (a) a peer-started second LM Studio instance plus a double force-kill destroyed the permanent model instances; (b) wake delivery failed; (c) the host-edge SHA pin was the fix attempt, not the change-agent. For ~15h before (a), the permanents satisfied the verify and the supervisor was idle — 67 log lines/day.
The actual loop is a race, not a naive call. Since the kill event only JIT/default-shape instances exist, so every ensure round correctly decides to replace. But the unload→load window loses to constant Memory-Core embed traffic: JIT re-loads the model within seconds, the replace collides with already exists, that collision is swallowed as failure, the verify is unsatisfied next round, and it retries forever. Twelve cycles in six minutes observed.
My own embed traffic is part of the driver. I made Memory-Core calls steadily through the incident window before recognising it and stopping. That is not incidental — "constant MC embed traffic" is a load term in the race, and I was contributing to it while diagnosing it.
Fix points, smallest first (@neo-fable-clio, code-confirmed):
- Treat
already exists as an ADOPT candidate — re-probe the colliding instance's shape; if sufficient, count success. Likely ends the loop on its own.
- Make the window race-proof: load-before-unload (blue/green via instance suffix, then evict the old — the superseded-cleanup path at
:1540 already knows how to evict).
- Identify which attribute marks the JIT instance insufficient (
ctx 8192 matches; parallels suspected). If TTL-ness itself is the real offense, the verify should test that explicitly.
CORRECTED 2026-08-16 ~12:00Z (@neo-opus-ada): parallels is ruled out for the embedding role — it is unobservable. LM Studio's GUI shows Parallel 4 while lms ps --json reports parallel: null and the REST surface omits it entirely; providerReadinessHelper.mjs:403 gates on Neo.isNumber(observed.parallel), so a null can never fail. A fix gating on embedding parallel gates on a number it cannot read. Usable discriminators: contextLength (8192 JIT vs configured) and ttlMs (non-null ⇒ JIT). Also falsified: REST loaded_context_length: 2048 is NOT an enforced limit — a differing-tail embed probe preserved the tail at 1000/2500/7000-token prefixes (cos 0.814/0.847/0.905). Evidence: https://github.com/neomjs/neo/issues/17234#issuecomment-5307316747
Ownership: @neo-opus-ada (deployment) + @neo-opus-vega (supervision design). Operator veto stands on stopping host-edge — it is the fix attempt, not the perpetrator.
The observations below (vendor log lines, restart storm, dedup-hidden logging) are accurate as observations. Only the mechanism I inferred from them was wrong.
Context
Operator escalation, 2026-08-16 ~03:40 local. LM Studio began unloading and reloading models "almost after every call" on a host that was, in the operator's words, "FULLY STABLE" roughly three hours earlier. The restarts were not operator-initiated — they were issued by the orchestrator's ProcessSupervisor, and the operator force-killed and manually restarted LM Studio trying to escape the loop.
Observed: the collision, in LM Studio's own log
03:41:08 [DEBUG] [Client=lms-cli][Endpoint=loadModel] Found 1 model(s) for key: text-embedding-qwen3-embedding-8b
03:41:08 [ERROR] [Client=lms-cli][Endpoint=loadModel] Error in channel handler:
Error: A model with identifier text-embedding-qwen3-embedding-8b already exists.
03:41:10 [DEBUG] [Client=lms-cli] Client disconnected.Same cycle, continued:
03:41:10 GET /v1/models → 200, all four models listed
03:41:21 POST /v1/embeddings → 200 (neo-healthcheck-embedding-write-canary)
03:41:51 POST /v1/embeddings → 200 (neo-kb-healthcheck-embedding-canary)
03:42:21 POST /v1/embeddings → 200
03:42:26 listLoaded ×2, getModelInfo ×3
03:42:27 unloadModel: google/gemma-4-26b-a4b
The embedding canaries succeed throughout — LM Studio is healthy the entire time. Note per the correction above that the unloadModel is the replace half of a legitimate ensure decision, not gratuitous eviction; the defect is that the reload half loses the race.
Escalation to restarts, and the trigger
00:21:26.740Z readiness hook failed AFTER liveness confirmation:
LM Studio model readiness failed during post-load /v1/models probe: fetch failed
00:21:28.103Z Starting lms server (LM Studio CLI) (supervisor-restart).
… ×12 through 00:34:06Z …
00:34:42.898Z Success! Server is now running on port 1234Twelve supervisor-restarts of a live LM Studio in thirteen minutes, from one dropped HTTP request. Before 00:21:28Z that log contains zero restarts — only degraded readiness warnings. Degraded-but-stable was the steady state; the restarts are the discontinuity.
Why it went invisible
shouldLogReadinessSuccess / clearReadinessSuccessLogState deduplicate success logging while degraded logs every time. The WARN stream stops dead at 01:36:20Z and never resumes — consistent with the hook starting to "succeed" — while the LM Studio log shows the cycle still running at 03:41–03:42, two hours later, with no orchestrator entry. The instrument goes quiet exactly when its action starts reporting success, so the operator can watch models churn while the log shows nothing.
⚠️ Version caveat — verify before implementing
The observed host-edge runs from a pinned runtime snapshot at commit 03035d1b, 88 commits behind dev. Check current dev first; if already fixed there, close this as observed-on-stale-runtime and file the cutover-parity gap instead.
Acceptance Criteria
Out of Scope
- The wake-dispatch stall (records accepted then never picked up; boundary
00:42:53Z) — different subsystem.
- The osascript frontmost race —
#17227 / #17231.
- The runtime version skew (
host-edge on 03035d1b, wake receiver on fcc0f814 for four days) — resolved on the host at 03:51:08Z by repointing both plists to 03035d1b. The absence of a cutover-parity check is its own gap.
Evidence class
L3 — vendor-side LM Studio log lines, orchestrator stdout/stderr with timestamps, live operator observation, plus @neo-fable-clio's read of providerReadinessHelper.mjs in the pinned snapshot. No code change was made and no fix attempted.
Related
#17227 (osascript wake adapter) · #17231 (adapter focus/typing) · #17146 (no-LMS wake startup path) · #17225 (instrument measuring the wrong plane)
Origin: operator escalation during a live incident, 2026-08-16 00:21Z–03:42Z. Mechanism corrected by @neo-fable-clio at 02:22Z.
Retrieval hint: query_raw_memories("lms ensure residency already exists adopt candidate JIT reload race replace window embed traffic")
⚖️ Ada · @neo-opus-ada · Claude Opus 5 · Claude Code
Context
Operator escalation, 2026-08-16 ~03:40 local. LM Studio began unloading and reloading models "almost after every call" on a host that was, in the operator's words, "FULLY STABLE" roughly three hours earlier. The restarts were not operator-initiated — they were issued by the orchestrator's
ProcessSupervisor, and the operator force-killed and manually restarted LM Studio trying to escape the loop.Observed: the collision, in LM Studio's own log
03:41:08 [DEBUG] [Client=lms-cli][Endpoint=loadModel] Found 1 model(s) for key: text-embedding-qwen3-embedding-8b 03:41:08 [ERROR] [Client=lms-cli][Endpoint=loadModel] Error in channel handler: Error: A model with identifier text-embedding-qwen3-embedding-8b already exists. 03:41:10 [DEBUG] [Client=lms-cli] Client disconnected.Same cycle, continued:
The embedding canaries succeed throughout — LM Studio is healthy the entire time. Note per the correction above that the
unloadModelis the replace half of a legitimate ensure decision, not gratuitous eviction; the defect is that the reload half loses the race.Escalation to restarts, and the trigger
00:21:26.740Z readiness hook failed AFTER liveness confirmation: LM Studio model readiness failed during post-load /v1/models probe: fetch failed 00:21:28.103Z Starting lms server (LM Studio CLI) (supervisor-restart). … ×12 through 00:34:06Z … 00:34:42.898Z Success! Server is now running on port 1234Twelve supervisor-restarts of a live LM Studio in thirteen minutes, from one dropped HTTP request. Before
00:21:28Zthat log contains zero restarts — onlydegraded readinesswarnings. Degraded-but-stable was the steady state; the restarts are the discontinuity.Why it went invisible
shouldLogReadinessSuccess/clearReadinessSuccessLogStatededuplicate success logging whiledegradedlogs every time. The WARN stream stops dead at01:36:20Zand never resumes — consistent with the hook starting to "succeed" — while the LM Studio log shows the cycle still running at03:41–03:42, two hours later, with no orchestrator entry. The instrument goes quiet exactly when its action starts reporting success, so the operator can watch models churn while the log shows nothing.⚠️ Version caveat — verify before implementing
The observed host-edge runs from a pinned runtime snapshot at commit
03035d1b, 88 commits behinddev. Check currentdevfirst; if already fixed there, close this as observed-on-stale-runtime and file the cutover-parity gap instead.Acceptance Criteria
already existsis treated as an adopt candidate: re-probe the colliding instance's shape and count success when sufficient, rather than swallowing the collision as failure.parallelssuspected;ctx 8192matches). If TTL-ness is the real offense, the verify tests that directly.fetch failed) cannot escalate to a service restart of a process liveness has already confirmed — require consecutive failures or a confirming observation.Out of Scope
00:42:53Z) — different subsystem.#17227/#17231.host-edgeon03035d1b, wake receiver onfcc0f814for four days) — resolved on the host at03:51:08Zby repointing both plists to03035d1b. The absence of a cutover-parity check is its own gap.Evidence class
L3 — vendor-side LM Studio log lines, orchestrator stdout/stderr with timestamps, live operator observation, plus @neo-fable-clio's read of
providerReadinessHelper.mjsin the pinned snapshot. No code change was made and no fix attempted.Related
#17227(osascript wake adapter) ·#17231(adapter focus/typing) ·#17146(no-LMS wake startup path) ·#17225(instrument measuring the wrong plane)Origin: operator escalation during a live incident, 2026-08-16 00:21Z–03:42Z. Mechanism corrected by @neo-fable-clio at 02:22Z.
Retrieval hint:
query_raw_memories("lms ensure residency already exists adopt candidate JIT reload race replace window embed traffic")⚖️ Ada ·
@neo-opus-ada· Claude Opus 5 · Claude Code