PR #17075 fixed a production-severity LM Studio eviction regression under the deployment deadline. The repair is correct containment, but its cost is not an acceptable permanent architecture:
PR #17075: +1,418 / -438 across three files (+980 net).
ai/services/graph/providerReadinessHelper.mjs: +718 / -189 (+529 production lines).
The helper grew from 2,913 raw lines at the pre-PR base to 3,442 raw lines after merge.
ensureLmsModelsLoadedOnce() grew from roughly 472 lines before #17075 to roughly 879 lines after it, with 28 return paths.
The additional machinery exists largely because routine readiness was allowed to unload an exact configured resident and then had to prove freshness, serialize effects, compensate ambiguous outcomes, fail-stop later replacements, reclassify post-effects, and preserve truthful receipts across every destructive boundary.
That is the wrong permanent complexity budget for a system whose desired local contract is simpler: the configured chat and embedding models stay resident. A routine readiness or recovery pass may add a genuinely missing model; it must not evict one.
Problem
The merged state machine remains capable of automatic exact-resident replacement and numeric-suffix cleanup. Making those destructive operations evidence-bound required a large policy and test matrix, but the resulting code still owns more authority than routine readiness needs.
This creates three forms of debt:
Safety debt: every automatic unload path can interrupt admitted work or eject a model that should remain permanently resident.
Maintenance debt: one readiness helper now contains an approximately 879-line LMS state machine with repeated observation, authority, compensation, and receipt branches.
Review debt: small future residency changes must re-prove a destructive transition matrix that should not exist in routine operation.
Architectural Reality
lms ps --json is the residency authority. /v1/models is a catalog/availability surface, not proof of residency.
The production consumer census has two call shapes:
routine host-edge post-spawn readiness;
privileged warm-provider recovery through repairProviderRoleSetResidency().
Both shapes can satisfy the operational requirement with additive-only repair:
valid exact absence permits lms load;
sufficient exact residency is a no-op;
unknown or mismatched exact residency degrades truthfully without mutation.
Discussion #16648 already identified why deleting all LMS supervision is wrong: cold-start prewarming is load-bearing. The additive load path therefore stays.
#17051 / #17053 and #17054 / #17055 remain valid concurrency predecessors. This ticket deletes excess mutation authority; it does not reopen them.
Fix
Collapse LMS readiness to one additive-only state machine at the existing owner:
A failed, invalid, conflicting, or partial lms ps observation returns metadata-unknown, performs zero mutations, and remains degraded.
A valid snapshot with the exact configured identifier absent performs one bounded, serialized lms load --identifier <exact>, then verifies the result.
A valid sufficient exact resident performs zero mutations and returns ready.
A valid exact resident with a proven shape mismatch returns degraded replacement-required and performs zero mutations.
Remove automatic exact-resident unload/reload, mandatory replacement compensation, and numeric-suffix cleanup from both routine readiness and recovery.
Remove unloadLmsModel from this module when the post-change consumer census is zero. Do not move the same authority into another helper or service.
Retain the bounded child deadline, hard-kill settlement, and shared FIFO for the remaining additive lms load path.
Wrong-shape replacement becomes an explicit operator/maintenance action outside routine readiness. This ticket does not add that action: LM Studio already provides it, and adding a new automatic wrapper would recreate the authority being removed.
Routine readiness and repairProviderRoleSetResidency() contain zero automatic lms unload calls.
A valid exact absence still performs one bounded additive load and verifies the configured provider-specific identifier.
Unknown telemetry and proven exact-resident mismatch perform zero loads and zero unloads and return distinct truthful degraded reasons.
Exact sufficient chat and embedding residents remain no-op/ready, including LM Studio's supported parallel: null readiness shape.
Numeric-suffix cleanup is report-only; no automatic code path evicts a suffixed resident.
unloadLmsModel is deleted if the post-change production consumer census is zero; no equivalent unload wrapper is introduced elsewhere.
The retained load wrapper remains serialized, deadline-bound, hard-kills a timed-out child, waits for settlement, and admits the next FIFO operation.
ensureLmsModelsLoadedOnce() is at most 500 raw source lines, measured from its declaration to the next top-level exported readiness function.
The implementing PR deletes at least 500 net lines across production plus the two existing LMS readiness spec files.
providerReadinessHelper.mjs growth versus pre-#17075 base 1b0e20111890965e963d464765cbbc24ba87b129 is reduced from +529 net lines to no more than +150 net lines.
No new file, service, daemon, config leaf, lease, or residency abstraction is introduced to meet the deletion targets.
Focused tests retain the additive load, unknown, mismatch, timeout/settlement, FIFO, provider-identifier, and no-real-lms-child falsifiers while deleting replacement-only fixtures.
Live acceptance observes both exact configured models resident with no TTL across concurrent chat and embedding traffic for at least three supervisor intervals, with zero LMS unload RPCs from Neo.
Context
PR #17075 fixed a production-severity LM Studio eviction regression under the deployment deadline. The repair is correct containment, but its cost is not an acceptable permanent architecture:
ai/services/graph/providerReadinessHelper.mjs: +718 / -189 (+529 production lines).ensureLmsModelsLoadedOnce()grew from roughly 472 lines before #17075 to roughly 879 lines after it, with 28 return paths.The additional machinery exists largely because routine readiness was allowed to unload an exact configured resident and then had to prove freshness, serialize effects, compensate ambiguous outcomes, fail-stop later replacements, reclassify post-effects, and preserve truthful receipts across every destructive boundary.
That is the wrong permanent complexity budget for a system whose desired local contract is simpler: the configured chat and embedding models stay resident. A routine readiness or recovery pass may add a genuinely missing model; it must not evict one.
Problem
The merged state machine remains capable of automatic exact-resident replacement and numeric-suffix cleanup. Making those destructive operations evidence-bound required a large policy and test matrix, but the resulting code still owns more authority than routine readiness needs.
This creates three forms of debt:
Architectural Reality
lms ps --jsonis the residency authority./v1/modelsis a catalog/availability surface, not proof of residency.warm-providerrecovery throughrepairProviderRoleSetResidency().lms load;Fix
Collapse LMS readiness to one additive-only state machine at the existing owner:
lms psobservation returnsmetadata-unknown, performs zero mutations, and remains degraded.lms load --identifier <exact>, then verifies the result.replacement-requiredand performs zero mutations.unloadLmsModelfrom this module when the post-change consumer census is zero. Do not move the same authority into another helper or service.lms loadpath.Wrong-shape replacement becomes an explicit operator/maintenance action outside routine readiness. This ticket does not add that action: LM Studio already provides it, and adding a new automatic wrapper would recreate the authority being removed.
Contract Ledger
lms psrejected, invalid, conflicting, or partialmetadata-unknownreplacement-requiredAcceptance Criteria
repairProviderRoleSetResidency()contain zero automaticlms unloadcalls.parallel: nullreadiness shape.unloadLmsModelis deleted if the post-change production consumer census is zero; no equivalent unload wrapper is introduced elsewhere.ensureLmsModelsLoadedOnce()is at most 500 raw source lines, measured from its declaration to the next top-level exported readiness function.providerReadinessHelper.mjsgrowth versus pre-#17075 base1b0e20111890965e963d464765cbbc24ba87b129is reduced from +529 net lines to no more than +150 net lines.lms-child falsifiers while deleting replacement-only fixtures.Out of Scope
Avoided Traps
lms psabsence remains additive repair authority./v1/modelsas residency. It remains catalog-only.replacement-required; they do not perform it.Related
Duplicate Sweep
LMS,LM Studio,providerReadinessHelper, residency, unload, refactor, and simplification: no equivalent owner.Origin Session ID:
019fe0b3-53bc-7ef2-8665-41a0ef3f7b62Retrieval Hint:
LM Studio additive-only residency remove unload replacement providerReadinessHelperRetrieval Hint:PR 17075 +1418 -438 ensureLmsModelsLoadedOnce 879 lines