every.channel: sanitized baseline
This commit is contained in:
commit
897e556bea
258 changed files with 74298 additions and 0 deletions
72
evolution/proposals/ECP-0036-multi-variant-manifests.md
Normal file
72
evolution/proposals/ECP-0036-multi-variant-manifests.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# ECP-0036: Multi-Variant Manifests (One Epoch, Many Variants)
|
||||
|
||||
Status: Draft
|
||||
Author: Codex
|
||||
Reviewers: founder@every.channel
|
||||
Created: 2026-02-07
|
||||
|
||||
## Decision
|
||||
|
||||
Extend `ec-core` manifests to optionally carry *multiple* variant hash-lists in a single signed manifest object.
|
||||
|
||||
One manifest epoch can describe:
|
||||
|
||||
- the "master" logical stream id (base)
|
||||
- N variants, each with:
|
||||
- variant id
|
||||
- variant stream id
|
||||
- chunk index range
|
||||
- per-chunk hashes
|
||||
- per-variant merkle root
|
||||
|
||||
Subscribers verify chunks by selecting the variant entry matching the chunk's `stream_id` (derived from encryption `key_id`).
|
||||
|
||||
## Motivation
|
||||
|
||||
- Quality pools (ABR ladders) need coordination: all variants should share epoch boundaries and be verifiable under one signed statement.
|
||||
- One manifest object per epoch reduces gossip/chattiness vs per-variant manifests.
|
||||
- Makes it easy to proxy to playlist-based views (HLS) without coupling the transport to playlists.
|
||||
|
||||
## Data Model
|
||||
|
||||
Add to `ec-core`:
|
||||
|
||||
- `ManifestVariant` (new)
|
||||
- `variant_id: String`
|
||||
- `stream_id: StreamId`
|
||||
- `chunk_start_index: u64`
|
||||
- `total_chunks: u64`
|
||||
- `merkle_root: String`
|
||||
- `chunk_hashes: Vec<String>`
|
||||
- `metadata: Vec<StreamMetadata>` (variant-specific; optional but useful)
|
||||
|
||||
Extend `ManifestBody`:
|
||||
|
||||
- `variants: Option<Vec<ManifestVariant>>`
|
||||
|
||||
Rules:
|
||||
|
||||
- Legacy manifests keep using `chunk_hashes` (single-variant).
|
||||
- Multi-variant manifests set `chunk_hashes` empty and populate `variants`.
|
||||
- `ManifestBody.merkle_root` becomes:
|
||||
- legacy: merkle root of `chunk_hashes`
|
||||
- multi-variant: merkle root of ordered `variants[].merkle_root` (sorted by `variant_id`)
|
||||
|
||||
## Publishing
|
||||
|
||||
- `ec-node moq-publish` can publish a CMAF ladder: one track per variant, one init track per variant.
|
||||
- After each epoch, publish a single manifest frame containing all variants' hashes for that epoch.
|
||||
|
||||
## Subscribing
|
||||
|
||||
- Subscriber requires manifests as today.
|
||||
- To validate a chunk:
|
||||
- identify `stream_id` from `object.meta.encryption.key_id` (strip `/init` suffix if present)
|
||||
- find a manifest in store that covers `(stream_id, chunk_index)`
|
||||
- compare expected hash from the matching `ManifestVariant`.
|
||||
|
||||
## Reversibility
|
||||
|
||||
- Backwards compatible: old readers ignore `variants`, new readers accept both formats.
|
||||
- If later we move to per-variant manifests, we can keep multi-variant as an optimization.
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue