Skip to content

Build1 publisher3 min readPublished

WorldScript Studio confines every AI failure to a single tested provider seam

WorldScript Studio's writing app stays fully usable with no API key, model or network because every AI feature reaches providers through one service. That leaves one module for a test suite to check when a provider goes down.

The Engineer · Build desk

Illustration accompanying WorldScript Studio confines every AI failure to a single tested provider seam

What happened

  • Providers plug in as adapters for Gemini, OpenAI, OpenRouter, Anthropic and OpenAI-compatible local servers like Ollama, normalised to one Vercel AI SDK model type.
  • Provider failures are sorted into classes such as rate limits, bad keys and offline, and each class carries a stable message key the interface can show.
  • The code described comes from commit 2d9157c0 of release v1.28.8, dated 28 September 2026.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint A team adding an AI feature to an app built this way has to route it through the shared service, so per-feature retry loops and private key handling are ruled out.
  • capability Enforcing 'AI off' with a throwing gate lets CI check each routing mode, so a change that sends a cloud call in local mode fails a test before it ships.
  • decision Retry policy has to branch on error class, since backing off on a wrong key only delays a failure the user must fix by hand.
  • exposure Writers who pick a cloud provider still send it the manuscript context each request needs; only the LoRA training path is guaranteed to stay local.

The post opens with a test anyone can run: revoke the API key, switch off the network, open the app again [1]. Its author wrote that "a surprising number of products fail this test" [2]. The failures listed belong to the product, not the AI features: spinners that never resolve, a settings page that errors out, a startup sequence blocked on a model ping [2].

The author's rule for WorldScript Studio is that "the AI layer may fail in every way it wants, as long as the failure is typed, explained, and contained" [17]. Containment starts with routing. No feature talks to a provider directly, so none can grow its own retry loop, its own key handling or its own definition of offline [5]. In the factory excerpt, a local server such as Ollama is one config variant, `openaiCompatible`, with a `baseURL` field [6]. Keys sit behind the same service. The browser build encrypts them under a random non-extractable AES-256-GCM key in IndexedDB, and no provider SDK touches storage [8].

Routing has four user-visible modes, with hybrid as the default [9]. Enforcement is one function. `assertCloudAiAllowedSync` returns early for local inference providers, then hits this line [10]:

`if (mode === 'local' || mode === 'eco') { throw new Error(...) }`

It throws again if `privacy.localStorageOnly` is set [10]. I think this is the right call for any app that makes a local-only promise, because a convention spread across components can only be verified by reading every component. The author wrote that a gate which throws can be tested in a way that a gate which merely ought to be checked cannot [11]. The policy test suite exercises the mode matrix directly [12].

The error taxonomy is the part I would copy first. A rate limit, a wrong key and a dead network need different responses. The seam puts each failure in its own class with a stable message key [15]. The interface can then say "check your key" or "you are offline", and the retry layer fails fast on a call that will never succeed instead of backing off politely [15]. The alternative, familiar to anyone who has shipped it, is a toast saying "something went wrong" above a dead feature, the author wrote [19].

The privacy claim is scoped with care. Training data is manuscript data, so the LoRA path is allowlisted to local providers [13]. I would rather read the next sentence than a blanket guarantee, and the author wrote it: the rule covers the training path only, and a cloud provider the user calls receives the context sent to it [14].

Whether the pattern transfers depends on what is left when the model is gone. In WorldScript the AI assists with outlines, character work and prose feedback, and the app is built to work with no model at all [3]. A product whose main output is model output has less to fall back to. The design allows for that case, because its fallback layer is permitted to say "no fallback exists" [16]. The evidence is one author's account of their own code at commit 2d9157c0, release v1.28.8 [4]. The post includes no outage or failure-rate data, and it describes the fallback layer only in outline.

What to watch

  • Whether the repository's policy tests cover app startup with no key and no network, the path the author says other apps block on a model ping.
  • What hybrid, the default mode, does when a cloud provider fails mid-session: the post does not say whether it falls back to a local model.
  • How the fallback layer decides, feature by feature, when to report that no fallback exists.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories