From e475402b4d7a6ff8cca6666369510475b829e1b0 Mon Sep 17 00:00:00 2001 From: glass beadian Date: Sun, 18 Oct 2026 09:44:30 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20compute=20fabric=20design=20=E2=80=94?= =?UTF-8?q?=20shared=20box,=20collective=20workers,=20LLM=20engine=20regis?= =?UTF-8?q?tration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/reports/streaming-playback-spec.md | 58 +++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 docs/reports/streaming-playback-spec.md diff --git a/docs/reports/streaming-playback-spec.md b/docs/reports/streaming-playback-spec.md new file mode 100644 index 0000000..734b0de --- /dev/null +++ b/docs/reports/streaming-playback-spec.md @@ -0,0 +1,58 @@ +# Spec: progressive playback for encrypted media (the "decrypting…" lag fix) + +## Problem +Playing a Files video (SPENC2, client-sealed) waits for the WHOLE sealed file to +download + decrypt before the first frame — length-dependent, brutal for 1-2 GB. + +## Why it's fixable cleanly +SPENC2 frames are already stored as INDEPENDENT 10 MiB AES-GCM segments +(header 135 B + per-segment 4+12+ctLen). Every segment decrypts on its own, +so any plaintext range can be served by fetching + decrypting only the +covering segments. No re-encryption, no format change. + +## Design +1. API: `GET /files/:id/range?offset=N&length=M` (auth = download route; + direct/ objects only) → decrypts just the covering segments via + `S3Storage.readDirectRange` (ranged R2 GET covering the needed segments, + CEK unwrap from the same fetch, per-segment GCM), returns the plaintext + slice + headers: X-Total-Size, X-Segment-Bytes. 16 MiB per-request cap. +2. Player integration (no Service Worker, no MSE): progressive blob — + fetch [0, 16 MiB) → objectURL → play immediately (our encodes are + +faststart, so a truncated mp4 plays head-first); background-fetch the + remaining chunks, appending; when playback nears the fetched edge or the + user seeks past it, await the covering chunk before continuing. On full + fetch: swap in the complete blob (scrub-anywhere). +3. SPENC1 (server-sealed legacy): the single-stream GCM cannot be sliced — + keep the whole-file fetch (these are the small/older items; new uploads + are all SPENC2). + +## Non-goals / later +- True MSE/fMP4 streaming with a Service Worker (better scrub UX, bigger build) +- Audio file streaming (same endpoint serves it; the