every.channel/evolution/proposals/ECP-0123-instant-station-guide-and-player-warmup.md
Conrad Kramer 81724b7030
Some checks failed
ci-gates / checks (push) Failing after 1s
deploy-cloudflare / checks (push) Failing after 1s
deploy-cloudflare / deploy (push) Has been skipped
Use local Forgejo runner label
2026-06-10 03:19:02 -07:00

53 lines
3.2 KiB
Markdown

# ECP-0123: Instant Station Guide and Player Warmup
Status: Draft
## Problem statement
The hosted watch page can feel broken when `/api/public-streams` is slow, empty, or temporarily
unreachable: the channel rail waits on the network before showing stations. Even after stations
appear, the first channel tap pays the `@moq/watch` module import cost before the player element can
mount. That increases time to first playing frame and makes channel selection feel unreliable.
## Constraints
- Keep the first screen a usable TV/player interface, not a marketing page.
- Preserve manual tuning, share links, DVR mode, public station refresh, and existing relay fields.
- Keep rollback simple: the live API remains authoritative after it answers.
- Avoid Chrome-only transport assumptions and keep live playback failure messages actionable.
- Keep the change static-site compatible so Cloudflare Worker asset deployment stays simple.
## Decision
Embed the current starter LA station guide in `index.html` and render it immediately on first load.
Also keep a short-lived local guide cache, merge cached entries with the HTML seed, and refresh
`/api/public-streams` in the background with a bounded timeout. A slow or empty refresh no longer
clears already visible channels.
Change the web client, publisher CLI/module defaults, runbook examples, and remote watch E2E default
relay to `https://relay.every.channel/anon`. Default `wt-publish` and `nbc-wt-publish` to fMP4
passthrough so hotpatch-launched publishers emit the `timescale` and `trackId` CMAF catalog metadata
expected by the hosted `@moq/watch` element. Preload/preconnect the primary player dependencies and
warm the `@moq/watch` custom element after first paint. Let `@moq/watch` use its available live
transport fallback instead of forcing WebTransport-only playback. Add client performance marks for
guide first render, guide fetch, watch request, player module readiness, player mount, catalog/live
status, and first observable canvas frame when the browser exposes it.
## Alternatives considered
- Wait only for `/api/public-streams`. Rejected because the UI becomes blank when the directory is
slow and because children should be able to tap visible channels immediately.
- Make the API response cacheable at the CDN. Rejected as the only fix because active streams are
short TTL and stale-but-visible fallback belongs in the client.
- Bundle `@moq/watch` into the static site. Deferred because CDN import fallback is already in use;
warming and modulepreload reduce tap latency without changing the build graph.
## Rollout / teardown plan
Ship the static web change with the existing Worker asset deploy and roll the publisher hotpatch
binary to the LA nodes so their catalogs match the current watcher schema. Validate with clean-cache
desktop/mobile browser loads and check the app's `window.__ecPerf` marks plus a live tune through the
public relay. The Forgejo workflows use the locally registered `namespace-profile-linux-medium`
runner label so the Cloudflare deploy can actually leave the queue on the self-hosted forge.
Teardown is removing the HTML seed/cache/warmup path, returning to live-API-only station rendering,
and explicitly passing `--passthrough=false` only if an older watcher path is restored.