TASK 48 item 1: bundle ffmpeg — the app no longer downloads an executable

Store policy 10.2.2 forbids dynamic code inclusion, and this was the only
third-party binary the app ever downloaded and ran. It had already failed in
production: the pin aged out of BtbN's 14-day retention and the download 404'd
on the creator's first real recording attempt (2026-09-01). Bundling kills
that failure class permanently and deletes the startup network dependency.

- scripts/fetch-ffmpeg.sh populates a gitignored ./ffmpeg from a pinned
  month-end BtbN LGPL-shared artifact, SHA-256 verified before extraction,
  idempotent, FFMPEG_ZIP= override. 135 MB of DLLs in git would tax every
  commit on this 9p tree; the URL + hash are the audit trail LGPL §6 wants.
- ytLive.csproj copies ffmpeg\** to output and publish (Always), and a
  GuardBundledFfmpeg target fails the BUILD if the folder is missing, so a
  fresh clone finds out before a take rather than during one.
- FfmpegLocator loses the downloader, the zip extraction and the
  %APPDATA%\ytLlive\tools cache. Order is now bundle -> PATH, deliberately
  inverted: a PATH ffmpeg may be a different major version or a GPL build,
  and the bundle is what was pinned, license-vetted and tested. A missing
  bundle throws loudly; the old "found something on disk" path could satisfy
  a missing bundle with a stale copy, and silent drift is the worst failure
  mode for a dependency certification inspects.
- ffplay.exe (18 MB) is not shipped; nothing calls it.
- THIRD-PARTY-NOTICES.txt: "downloads" -> "bundled" throughout, and the stale
  build tag autobuild-2026-08-09-13-03 — the tag that 404'd — corrected to
  autobuild-2026-08-31-13-27 with the exact artifact name and archive hash.
  OpenH264 made precise: compiled INTO avcodec-63.dll, no separate binary.

Checked whether other third-party binaries needed bundling: no. e_sqlite3.dll
and WebView2Loader.dll already ship via NuGet into runtimes\win-x64\native\,
OpenH264 is inside avcodec-63.dll, the rest are managed. Two gaps remain that
bundling cannot fix, recorded in the map: the WebView2 Evergreen runtime is a
machine prerequisite (TASK 48 item 2), and Velopack's updater downloads and
executes, so its teardown is a compliance action.

Tests: 16 locator facts, suite 379/379, 0 warnings. The integration test runs
the bundled ffmpeg -version, which is the only assertion that proves the
sibling libav*.dll resolved — presence checks pass with the DLLs missing and a
shared build then fails to start. TheLocatorCarriesNoNetworkCapability keeps
10.2.2 from rotting back.

Analysis: TASKS/research-store-certification.md §4.
This commit is contained in:
2026-09-28 09:38:21 -07:00
parent eb0dd91126
commit 4fcf76289c
11 changed files with 638 additions and 361 deletions
+47 -16
View File
@@ -81,31 +81,62 @@ ONLY paid delta (TASK 36 item 2). Store IAP changes how the bit is *obtained*, n
---
## 1. ⛔ Bundle ffmpeg instead of downloading it — **do this on EVERY route**
## 1. ☑ Bundle ffmpeg instead of downloading it — **SHIPPED 2026-09-28**
**This is item 1 because it is genuinely first** — it fixes a user-facing failure on its own and is a hard certification gate.
`Services/Encoder/FfmpegLocator.cs:37-38` pins a GitHub release URL; `LocateAsync`
downloads (line 69), extracts (line 73), and the encoder executes the result. On a cold
cache the app downloads an unsigned executable from the internet and runs it.
`Services/Encoder/FfmpegLocator.cs` used to pin a GitHub release URL, download it on first run,
extract it, and execute the result. On a cold cache the app downloaded an unsigned executable from
the internet and ran it.
- **Store blocker:** policy 10.2.2 forbids dynamic code inclusion (download-and-execute).
- **Route-independent bug class:** `FfmpegLocator.cs:30-35` records that the previous
daily pin aged out of GitHub retention and **404'd on the first real recording attempt
(2026-09-01)**. Bundling kills this permanently and removes the startup network
dependency.
- **Route-independent bug class:** the previous daily pin aged out of GitHub retention and
**404'd on the first real recording attempt (2026-09-01)**. Bundling kills this permanently and
removes the startup network dependency.
**Do:** ship `ffmpeg.exe` + `ffprobe.exe` + the `libav*.dll` family inside the package;
`FfmpegLocator` resolves PATH → package-local → cache, and never downloads.
`IFfmpegLocator`'s contract, the `ExtractBinaries` staging discipline, and the existing
`FfmpegLocatorTests` cold/cache/PATH coverage all still apply.
**What shipped (2026-09-28, `eb0dd91` docs + this unit):**
- `scripts/fetch-ffmpeg.sh` — populates `./ffmpeg` from a pinned month-end BtbN LGPL-shared
artifact, **SHA-256 verified before extraction**, idempotent, `FFMPEG_ZIP=` override. The
binaries are **gitignored** (135 MB of DLLs would tax every commit on the 9p tree); the pinned
URL + SHA-256 are the audit trail the LGPL written-offer actually needs.
- `ytLive.csproj` — copies `ffmpeg\**` to the output with `CopyToPublishDirectory="Always"` (the
MSIX one), plus a **`GuardBundledFfmpeg` target that fails the build** if the folder is missing,
so a fresh clone finds out before a take rather than during one.
- `FfmpegLocator` — downloader, zip extraction, and the `%APPDATA%\ytLlive\tools` cache are all
**gone**. Order is now **bundle → PATH** (deliberately inverted from "the user's install wins":
a PATH ffmpeg may be a different major version or a GPL build). A missing bundle throws a loud
`IOException` naming the folder and the fetch script — the "found something on disk" path that
could mask a missing bundle is deliberately deleted.
- `ffplay.exe` (18 MB) is **not** shipped; nothing calls it.
- `THIRD-PARTY-NOTICES.txt` — "downloads" → "bundled" throughout, and the stale build tag
`autobuild-2026-08-09-13-03` (**the tag that 404'd**) corrected to `autobuild-2026-08-31-13-27`
with the exact artifact name and archive SHA-256 recorded. OpenH264 item made precise: it is
**compiled into `avcodec-63.dll`**, not a separate binary.
**Immutable tag (licensing rule):** `autobuild-2026-08-31-13-27`, artifact
`ffmpeg-N-126342-gf88b741dbf-win64-lgpl-shared.zip`, SHA-256
`46ea6521ed3877689d2ff0bd03640ac2637104415f6237d42625d13408767146`. The URL is now a **provenance
record, not a runtime fetch**. Month-end on purpose: BtbN keeps ~14 dailies but month-end builds
~2 years — a daily pin is what aged out.
**Licensing:** the LGPL-shared build was chosen for LGPL §6 compliance (dynamic linking =
"license text + source offer"). That reasoning is **unaffected**. Confirm
`THIRD-PARTY-NOTICES.txt` covers the bundled build.
"license text + source offer"). That reasoning is **unaffected**, and the notices now cover the
bundled copy explicitly.
**Record the immutable tag** in `TASKS.md` per the licensing rule, and note the URL is now
a provenance record rather than a runtime fetch.
**Tests (16 facts, `FfmpegLocatorTests`, suite 379/379):** the Good Dog integration test walks the
real build output, asserts the 9 files ship, resolves via the locator with an empty PATH, and
**executes `ffmpeg -version`** — running it is the part that matters, because a shared build only
starts if every `libav*.dll` is a sibling. Plus: bundle-over-PATH, PATH fallback, zero-byte bundle,
the loud failure, `TheBuildRefusesToCompileWithoutTheBundle`, and
`TheLocatorCarriesNoNetworkCapability` — a source-level fact that no `HttpClient`/URL/downloader
can reappear, so 10.2.2 cannot rot back.
**Answering "were there other 3p binaries needing bundling?" (verified 2026-09-28): no.** ffmpeg was
the only download-and-execute. `e_sqlite3.dll` + `WebView2Loader.dll` already ship via NuGet into
`runtimes\win-x64\native\`; OpenH264 is inside `avcodec-63.dll`; everything else is managed. The two
real gaps are **not** bundling problems: the **WebView2 Evergreen runtime** is a machine prerequisite
(item 2's manifest dependency + a graceful-failure path), and **Velopack's updater downloads and
executes** — its teardown (item 3) is a compliance action, not just cleanup.
---