Every Companion gets its own config.
How CareOS resolves voice, prompt, and provider per-device at session start — Firestore for truth, Redis Ring for speed.
A facility in Phoenix asked for a Spanish-speaking voice on the assisted-living floor. A memory-care unit two states away wants slower TTS and a calmer system prompt — fewer questions, longer pauses, more reassurance. One wing is piloting a regional ElevenLabs voice; the wing across the courtyard is on Grok. None of this can live in firmware, and none of it can live in a constant in the Go API. Hardcoding any of it is technical debt that compounds with every new building.
So CareOS resolves routing per-device on every session start. When a Companion opens its WebSocket, the API reads a device_config document from Firestore keyed by device_id, falling back through room, wing, facility, and finally organization. The first non-null field wins at each layer. Org-level defaults set the floor; device-level overrides set the ceiling.
Firestore for truth, Redis Ring for speed
Firestore holds the canonical config: provider, voice ID, prompt variant, TTS rate, feature flags, language. We picked it over Postgres because the schema is genuinely sparse and nested — most devices override two or three fields out of forty — and because care staff edit it from a console that already lives in the Firebase Admin SDK. Strongly typed migrations would slow that loop down for no real gain.
Hot rows are cached in a Redis Ring cluster with a 30-second TTL and a pub/sub invalidation channel for explicit edits. Session start hits Redis first; on miss, we read Firestore and backfill. The Ring client shards by device_id, so a single facility's traffic lands on the same node and stays warm.
What this buys the product
A wing can A/B a new voice for two weeks without a code change — flip one Firestore field, wait for the TTL, done. The Companion in room 12 always sounds the way that resident's family asked for, because the override is pinned to her device, not her building. When her daughter calls and says make him a little slower, she's having a rough week, that is a two-line edit in the console, live before the next good-morning.