- docs/architecture/models-cache-invalidation.md: add 'Invalidation modes'
section describing delete_disk=True/False and why /api/profile/switch
uses the memory-only mode (fingerprint-guarded per-profile disk cache).
- tests: replace the source-text scan of the switch route with two executed
routes.handle_post tests: one captures invalidate_models_cache kwargs and
asserts exactly [((), {'delete_disk': False})]; one runs the real
invalidate_models_cache and asserts the disk file survives while the
in-memory catalog is dropped. Both fail if the route reverts to the
default delete_disk=True.
POST /api/profile/switch called invalidate_models_cache(), whose
test-isolation contract also unlinks models_cache.<profile>.json. On a
switch nothing about the sources changed, so the delete only forced a
full cold rebuild (live provider fetch_models HTTPS calls, ~490k deepcopy
calls) on the very next /api/models — several seconds on every switch.
The disk cache is already keyed per profile and rejected on read when
_models_cache_source_fingerprint() differs, so it is safe to keep. Add a
delete_disk keyword (default True — every existing caller keeps the old
behaviour) and have the switch route pass delete_disk=False.
Regression tests cover: memory-only drop preserves the disk file, default
call still unlinks it, the next get_available_models() serves the disk
snapshot without a live rebuild, and the switch route opts out. Two
existing zero-arg stubs of invalidate_models_cache accept **kwargs now.