Advance forge NBC worker and Ethereum full nodes

This commit is contained in:
every.channel 2026-04-03 02:01:34 -07:00
parent 7d84510eac
commit 3402f7dab2
No known key found for this signature in database
17 changed files with 3066 additions and 414 deletions

View file

@ -0,0 +1,15 @@
# ECP-0101: Decode Archived Object Frames Before HLS Replay
## Why
`wt-archive` stores raw MoQ object frames in CAS. `wt-archive-serve` was replaying those framed bytes directly as `init.mp4` and `.m4s`, which yields HLS playlists that look valid but cannot be decoded by players.
## Decision
Decode archived object frames back into their media payload bytes before serving replay responses. If archived bytes are already raw payloads, pass them through unchanged.
## Consequences
- Local and forge replay can hand archived CMAF data to normal HLS consumers.
- Existing archives remain usable without rewriting CAS objects.
- Replay failures now point at genuinely bad archive contents rather than envelope bytes leaking over HTTP.

View file

@ -0,0 +1,35 @@
# ECP-0102: Linux Widevine NBC Worker on `ecp-forge`
## Why
NBC live playback currently exists only in the desktop app:
- macOS native `WKWebView` for in-app auth and playback capture
- local Chrome fallback for browser-driven playback capture
`ecp-forge` cannot originate an NBC live stream today because `ec-node` has no NBC source worker, no Adobe auth bootstrap flow, and no Linux browser runtime with Widevine.
## Decision
Build a forge-capable NBC source worker around Linux Google Chrome plus a persistent authenticated profile.
1. Use Google Chrome on `x86_64` Linux, not bare Chromium, as the browser runtime for NBC on forge.
2. Run Chrome in a virtual display session on `ecp-forge` so DRM playback remains in a normal browser path even when no physical display is attached.
Keep the forge worker on a dedicated display number and disable GPU acceleration by default under Xvfb.
3. Persist the NBC/Adobe browser profile on forge so auth warmup is amortized across runs.
4. Add an explicit bootstrap path that surfaces interactive auth only when the stored session is cold or expired.
5. Launch Chrome as an external process and attach over DevTools rather than relying on the crate-managed Chrome launcher path.
6. Publish the resulting captured stream through the existing `ec-node` relay path so archive, replay, and downstream nodes stay unchanged.
7. Expose the forge operator surface as `ec-node nbc-bootstrap` and `ec-node nbc-wt-publish`, with a persistent virtual display on `ecp-forge`.
## Consequences
- NBC live origin becomes possible from forge without depending on a users macOS desktop session.
- We keep the existing every.channel transport/archive model and only replace the source worker.
- The first forge implementation should be browser-frame capture first; audio and full unattended auth renewal can follow once the Linux worker is stable.
## Rejected Alternatives
- Reuse the macOS `WKWebView` path on forge: impossible on Linux.
- Depend on bare Chromium only: rejected because Widevine support is the central requirement.
- Require true headless-only DRM playback from the start: rejected because the safer first implementation is a normal Chrome session inside a virtual display.

View file

@ -0,0 +1,24 @@
# ECP-0103: Mullvad Philadelphia Egress for Forge NBC Philadelphia
## Why
The forge-side NBC worker is currently dependent on a reverse-tunneled proxy for US egress.
That is enough to prove the geo-boundary, but it is the wrong long-term operator shape for `NBC Sports Philadelphia`.
## Decision
1. Enable the Mullvad daemon on `ecp-forge`.
2. Keep the Mullvad account number out of committed Nix configuration; log in operationally from founder-provided material.
3. Use a Philadelphia Mullvad relay for `NBC Sports Philadelphia` work on forge.
4. Start the forge NBC publish worker after the Mullvad daemon is available.
## Consequences
- Forge NBC egress becomes self-contained instead of depending on a local reverse proxy.
- The account credential stays operational-only rather than being copied into repo config.
- Relay choice remains runtime-controlled, so it can be swapped if a specific Philadelphia host degrades.
## Rejected Alternatives
- Keep relying on the reverse-tunneled local proxy: rejected because it couples forge origin to a founder workstation.
- Commit the Mullvad account number into NixOS config: rejected because it expands secret exposure for no benefit.

View file

@ -0,0 +1,45 @@
# ECP-0104: `ecp-forge` dual Ethereum full nodes on dedicated NVMe ZFS
## Why
`every.channel` now has OP Stack and Ethereum contract rails on `ecp-forge`, but it still depends on
public L1 RPC and beacon providers for Ethereum itself.
The forge host has enough raw capacity in `tank`, but `tank` is a large HDD `raidz3` pool that is
well suited for archive bytes, not for the random-read/write pattern of concurrent Ethereum
execution and consensus sync. The same host also has a free 7 TB NVMe device, which is the right
media class for a self-hosted node.
## Decision
1. Create a dedicated single-device ZFS pool for Ethereum on the free NVMe in `ecp-forge`.
2. Run two full-sync Ethereum node pairs on that pool:
- Ethereum mainnet
- Ethereum Sepolia
3. Use Reth for execution and Lighthouse for consensus.
4. Keep raw execution and beacon RPC local-only on `ecp-forge` for the first tranche.
5. Publish sync and finality status on `https://eth.every.channel`.
6. Because this tranche is explicitly full-sync from genesis, run Lighthouse with
`--allow-insecure-genesis-sync` instead of checkpoint bootstrap.
## Consequences
- `every.channel` gets repo-owned L1 execution and consensus rails for both mainnet and Sepolia.
- Ethereum state no longer competes with `tank` archive I/O.
- The first public surface is intentionally conservative: health and sync visibility, not
unauthenticated public JSON-RPC.
- The dedicated Ethereum pool is single-device NVMe, so it optimizes for node performance rather
than storage redundancy.
- Consensus sync starts from genesis without checkpoint assistance, which is slower but matches the
requested full-sync posture.
## Rejected Alternatives
- Put Ethereum state on `tank`: rejected because the HDD `raidz3` pool is the wrong latency profile
for concurrent execution and consensus sync.
- Keep using only public upstream Ethereum providers: rejected because the OP Stack and settlement
rails should not depend on third-party RPC availability.
- Expose raw JSON-RPC on `eth.every.channel` immediately: rejected for the first tranche because it
creates an unauthenticated public abuse surface before auth and rate policy exists.
- Use checkpoint sync for Lighthouse: rejected for this tranche because the requested posture is
full sync from genesis on both networks.