All posts
StreamingProduct22 Sep 2026 · 3 min read

Three labs and a seam

JPJean Perez

Cloud Video, Platform Architectures and Media Network are three tools that simulate real streaming infrastructure: a VOD chain through a cloud provider, an ingest-to-CDN topology, an origin-and-edge map with incidents you can trigger. All three shipped from the same design prototype, in a four-PR stack, and only one of those PRs was allowed to touch more than one directory.

The order was deliberate. BMU-303 built the shared seam first, alone: routes, the ViewerPlayer component, the tours, the shell wiring. Only once that merged could Cloud Video (BMU-300), Platform Architectures (BMU-301) and Media Network (BMU-302) run in parallel, each confined to one apps/web/components/* directory.

The porting brief says why, pointing at the wave before it: two hand-off links had been given the new-tab treatment and nothing else, because each slice was correct inside its own edges and nobody owned the seam between them. Three parallel slices can each ship a correct lab and still leave the space between the labs unowned. Landing the seam first, alone, gave the parallel wave a shared floor instead of three separate ones.

Landmines named in advance

The porting brief listed its own traps before anyone wrote a line of the labs themselves.

d3 (d3-geo, d3-zoom, d3-selection, d3-transition, topojson-client) had to become a real npm dependency. The prototype loaded it from unpkg inside an iframe, which works for a static mockup and not for a Next.js build.

The world-atlas countries TopoJSON was the sharper one. It's fetched from jsdelivr at runtime in the prototype; the brief wanted it vendored into public/ instead, so the map works offline. The repo's root .gitignore blanket-ignores every *.json, so git add on the vendored file would silently do nothing, the local build would still pass because the file exists on disk, and only Vercel would fail, with "Module not found." This wasn't a guess. The same rule had already eaten the generated output of @beemmeup/ffmpeg-catalog back on 2 September, and it caught turbo.json on 14 September badly enough that the PR fixing it called itself, in its own words, the "third casualty of that rule today." The countries file was next. A ! allowlist line went in ahead of time, confirmed with git ls-files, before the parallel wave started.

One dependency stayed exactly as risky as it looked on paper. Of the four fallback video sources <viewer-player> cycles through, the last one, storage.googleapis.com/gtv-videos-bucket, returned a live 403 when the brief checked it on 21 September. The element already degrades to a labelled veil when every source fails, so that behavior stayed rather than getting papered over with a fifth source nobody had checked either.

Mux or Bitmovin

The Learn-catalog porting brief, written for the same wave, flagged something specific. BMU-324's own ticket named the Cloud Video preview's provider chips as "AWS, Google Cloud, Azure, Mux," matching the marketing copy already in courses.js. The actual Cloud Video Lab's own data module, shell/cloud-video-data.js, lists "GCP, AWS, Azure and Bitmovin." There is no Mux anywhere in the lab.

The brief's instruction was explicit: don't silently pick one. "BMU-324's own acceptance criterion is... 'matches the lab's real vocabulary'... the ticket fails its own test as written." The fix sided with the lab over the ticket. It swapped Mux for Bitmovin in the preview card and said so in the PR body as a deliberate departure from what was asked for.

Two smaller versions of the same discipline turn up in the same PR: "Ingest PoP" replaced "Ingest edge" to match the lab's real stage name, and the network graph's spawn point moved 10px because, at a 320px card width, its top label touched the tool chip next to it.

One more fix, in the data itself

The Media Network Lab's topology editor got a data-integrity fix in the same wave. Commit 9698390 (BMU-320) makes the import path coerce every stored or imported node instead of trusting it. A topology editor that loads arbitrary saved or shared graphs shouldn't assume the JSON on the other end is shaped the way the editor expects it to be.

The vocabulary check costs one file read: open the lab's data module and compare it with the ticket.