Skip to content

storage(cache): local AI model caches are not positively ownership-scoped, and Factory Reset leaves them behind #526

Description

@qnbs

Summary

Found during the v1.28.2 release-prep review (PR #524) of the DA-03 (SW cache-ownership) fix. Two related gaps in services/ai/localModelStorageService.ts, distinct from the service-worker cache-ownership work already landed:

1. Settings → AI → Clear Local Models is now narrowed, but not proven-owned

LOCAL_MODEL_CACHE_PATTERNS was tightened from a loose substring regex (/webllm|mlc|tvmjs|transformers/i) to exact literal matches against the real vendor CacheStorage bucket names (confirmed via source: webllm/model, webllm/config, webllm/wasm from @mlc-ai/web-llm; transformers-cache, experimental_transformers-hash-cache from @huggingface/transformers). This closes the concretely-demonstrated false-positive match (e.g. other-transformers-assets) a review found.

It is not a full positive-ownership proof, though: these are vendor-fixed literal names, not WorldScript-scoped ones. A different app sharing this exact GitHub Pages origin and using the identical library could in principle create an identically-named cache and collide.

Investigated fix paths for a real ownership boundary:

  • @huggingface/transformers (v4.2.0 installed) exposes a genuine app-level override: env.cacheKey (default "transformers-cache") — WorldScript could set this to something namespaced (e.g. worldscript-transformers-cache) at init time, giving true ownership for that runtime.
  • @mlc-ai/web-llm (v0.2.84 installed) does not expose an equivalent knob — webllm/model/webllm/config/webllm/wasm are hardcoded literals in the library with no app-scoping parameter (confirmed via createScopedArtifactCache/getCacheAccessOptions — the appConfig argument only affects the storage backend, not the cache name). Achieving true ownership for WebLLM's own caches would need either a newer library version (unverified whether a newer major exposes this) or a different architectural approach (e.g. wrapping/monkey-patching cache access, which has its own risk).

2. Factory Reset does not clear local AI model caches

services/factoryResetService.ts's cache cleanup (fixed for DA-03 in #524, now isWorldScriptOwnedCacheName) intentionally does not call clearLocalModels() — wiring it in directly would reintroduce the exact class of risk #524 was fixing, since clearLocalModels()'s matching (even after the narrowing above) is not a true ownership proof.

But Settings copy currently promises Factory Reset "permanently deletes all projects, settings, API keys, and local data" and restarts "as a fresh install" (locales/en/settings.json, settings.data.dangerZone.factoryReset.hint/modalDescription). Downloaded WebLLM/Transformers models — potentially multiple GB — survive a Factory Reset today and are re-detected after reload. This gap predates PR #524 (localModelStorageService.ts already existed); it was not introduced by it.

Scope for a fix

Needs its own bounded design, not a rushed addition to a release-bump PR:

  • Decide whether to set env.cacheKey for transformers.js to a WorldScript-namespaced value (small, real ownership win for that runtime specifically).
  • Decide how (or whether) to handle WebLLM's un-namespaced caches — accept the narrowed-but-not-proven exact-match residual, or investigate a real namespacing mechanism.
  • Wire whatever the resulting safe deletion authority is into Factory Reset, OR narrow the Settings UI copy (all 19 locales) to be honest about what Factory Reset does and doesn't clear until that authority exists.
  • Regression tests proving foreign shared-origin caches survive both "Clear Local Models" and Factory Reset, mirroring the pattern already used for tests/unit/factoryResetService.test.ts.

Release relevance

Non-blocking for v1.28.2: real finding, but a pre-existing production gap (not a v1.28.2 regression), same disposition class as #525.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions