every.channel/evolution/proposals/ECP-0071-archive-replay-dvr.md

2.1 KiB

ECP-0071: Archive Replay DVR Endpoints

Status: Implemented

Context

ECP-0070 added relay archival (wt-archive) into CAS objects plus JSONL indexes, but there is no read path for viewers to scrub historical content.

Decision

Add an archive replay path with these pieces:

  • ec-node wt-archive-serve: lightweight HTTP server that reads archive JSONL indexes + CAS blobs and serves:
    • /archive/<broadcast>/master.m3u8
    • /archive/<broadcast>/video.m3u8
    • /archive/<broadcast>/audio.m3u8
    • /archive/<broadcast>/init.mp4
    • /archive/<broadcast>/segment/<blake3>.m4s
    • /archive/<broadcast>/timeline.json
  • HLS playlists are EVENT style and include all retained segments by default, so scrub depth is bounded by retained archive data (effectively "infinite" until eviction).
  • Cloudflare Worker proxies /api/archive/* to a configurable archive origin (EC_ARCHIVE_ORIGIN) so every.channel can serve replay from the same site domain.
  • Web watcher adds an Archive DVR mode that plays /api/archive/<broadcast>/master.m3u8 with native HLS or hls.js fallback.
  • NixOS module adds services.every-channel.ec-node.archive.serve.* to run replay server alongside archival workers.

Rationale

  • Keeps archival and replay in one binary and one deploy surface.
  • Preserves CAS as source of truth; playlists are derived views.
  • Uses standard HLS+DVR semantics so browser playback + scrubbing works without custom protocol work in the short term.

Alternatives considered

  • Build a custom replay protocol/UI instead of HLS. Rejected because browser DVR support is stronger with standard HLS tooling.
  • Serve archive from a separate domain only. Rejected because same-domain replay keeps watch links and CORS simpler.

Rollout / teardown

  • Enable archive serve mode on archive hosts and deploy worker proxy routing to /api/archive/*.
  • Teardown by disabling archive.serve.enable and removing proxy routing.

Reversibility

  • Disable archive.serve.enable and remove worker proxy route to revert to archive-only mode.
  • wt-archive storage format remains unchanged.