Two native apps are a deliberate cost decision
Mira does not use one cross-platform client. iPhone and iPad are built with Swift, SwiftUI and AVFoundation; Android uses Kotlin, Compose and Media3. The difficult parts already sit close to the operating system: decoder capability, picture in picture, AirPlay or Cast, background downloads, remote controls and network transitions.
The cost is real. Shared product rules must be implemented twice and checked for parity. Modules and type names therefore follow a common architecture contract even though code remains separate. Native is not a quality badge here; it is a decision to pay for two implementations because the product depends deeply on each platform.
A server session has a route and an epoch
The same Jellyfin library may be reachable through a local address at home and a remote address elsewhere. Mira keeps one endpoint resolver per server session. It publishes the active route, an epoch, probe status and diagnostics together as an atomic state. HTTP reads that state when sending; playback observes changes.
The epoch makes a network world explicit. A new route is more than a different string: it may affect requests, cached resources and media URLs. Keeping the decision central prevents UI, library and player code from developing slightly different fallback rules.
Change the path, not the film
Older project documentation still describes rebuilding the player after a route change. Current Android code goes further. A custom Media3 data source remembers the byte offset of the stream. When the reachable base address changes, it rebases the URL and reopens at the same position, preserving the media session where the server exposes equivalent bytes.
A route change is kept distinct from a quality change. The latter can require a new transcode or representation and a controlled player transition. The former is first a transport problem.
This has boundaries: range requests, authentication and media identity must remain valid, and transitions can still fail. The claim is a concrete continuation mechanism for a common case, not invisible switching under every network condition.
Shared listening begins with a shared clock
Jam distributes one queue across devices. A server timestamp is not enough because clocks differ and messages take time. The client estimates clock offset in an NTP-like exchange and schedules playback relative to that offset. Each device waits its own measured difference rather than assuming identical clocks.
WebSocket messages carry queue and state. Real multi-device tests across different networks are still required for a release claim. The architecture makes latency measurable; it does not pretend latency vanished.
What this demonstrates for client work
Mira shows native product development at a hard platform boundary. CIDIX can structure separate clients around one product model without forcing system integration into an undersized common layer.
For streaming, communications or sensor sessions, the transferable question is what must survive an infrastructure change. Mira makes route, epoch and media session explicit. A new engagement would define those invariants first, then choose native, cross-platform or a hybrid based on actual platform dependencies.

