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:
@@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user