docs: compute fabric design — shared box, collective workers, LLM engine registration
This commit is contained in:
parent
04f5f7e3aa
commit
e475402b4d
1 changed files with 58 additions and 0 deletions
58
docs/reports/streaming-playback-spec.md
Normal file
58
docs/reports/streaming-playback-spec.md
Normal file
|
|
@ -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 <audio> path is trivial)
|
||||
|
||||
## Effort
|
||||
API endpoint + segment math: ~80 lines + tests. Player progressive fetcher:
|
||||
~60 lines in video-player/viewer. Total: half a session.
|
||||
|
||||
---
|
||||
|
||||
# Appendix: compute fabric design (2026-10-17)
|
||||
|
||||
## Tiers
|
||||
1. **Shared worker (moxexleyhp1)** — the operator's box: 3090 CUDA (transcription sidecar live),
|
||||
NVENC + QuickSync transcodes. Serves ALL collectives as baseline capacity.
|
||||
2. **Collective-owned workers** — a collective registers additional boxes via the hub
|
||||
(collective-scoped worker token + Windows downloader + setup/connection instructions).
|
||||
Those pull only that collective's jobs — increasing its compute without touching others.
|
||||
3. **LLM engines** — collectives (or the operator) register LiteLLM/OpenAI-compatible endpoints
|
||||
as inference providers (per-collective model routing: a collective's AI features point at its
|
||||
own engines first, hub defaults second).
|
||||
|
||||
## Building blocks (when implemented)
|
||||
- worker_registrations table: workspace_id (NULL = shared), type (transcode | llm),
|
||||
token_hash, endpoint_url / capabilities, last_seen_at, created_by
|
||||
- Poll/claim protocol scoped per registration (the produce_job_claim lane pattern extends)
|
||||
- Windows downloader + PowerShell installer + connection instructions (the ipfs3 failover
|
||||
pattern: token + instructions served from the collective's Workers settings page)
|
||||
- LLM engine registrations join the model routing for AI features (transcription, captions,
|
||||
search embeddings)
|
||||
Loading…
Add table
Add a link
Reference in a new issue