Following the TTS service v1 planning meeting (T419288#12049854), the ML team owns the inference layer, the Data Engineering team owns the orchestration layer, Data Persistence owns storage, and Traffic owns serving. In this task, we shall implement the inference layer: a custom KServe model-server, hosted on LiftWing, that turns pre-normalized article text into spoken audio with word-level timestamps. It is the v1 successor to the inference half of the v0 Toolforge prototype (T419288#11924778, T424378#12068767).
Scope of this task: the model-server only. The orchestrator, storage, and serving layers are out of scope here and tracked separately. For this to make sense, here is where the rest of v1 lives.
- Orchestrator: The stateful glue this server depends on: resolves title -> page_id -> revision, fetches + cleans article text (v0's wikipedia_utils.py / text.py), runs _split_text, checks the index for existing audio, calls this model-server per section, writes results to storage, dedupes concurrent generation (v0's Redis lock pattern), and drives edit-triggered regeneration. Successor to v0's routes.py + submit_articles.py.
- Storage: Where audio + timestamps live, behind an S3 interface (Swift-backed for the PoC, scoped to ~7k Featured Articles, relocatable to Ceph). Replaces v0's local audio_output/. Includes the revision-scoped key schema and the index (LAC / page properties / TBD) that answers "does audio exist for this revision, and where?"
- Serving / delivery: How the mobile app retrieves audio, including CDN / Varnish caching and the cache-invalidation / purge path for vandalism and stale revisions. Replaces v0's FastAPI file responses.