Files
LlamaCasty/TASKS/task-48-distribution-msix.md
T
gramps e78c58fc28 docs: bank the Windows Store + signing research, and fix the dead EV-certificate line
The distribution answer existed only in conversation, so every session re-derived
it. It is now in the map, and the route decision is explicitly parked as the
creator's.

new TASKS/research-store-certification.md — Store Policies 7.20 + MSIX packaging:
which policies bind, which don't (and why), cert economics, camera/mic gating
layers, YouTube age + COPPA, the 11.12 UGC judgment call.

Two real defects surfaced, neither fixed (docs-only unit):
- FfmpegLocator downloads an unsigned exe from GitHub and runs it. That is
  policy 10.2.2 (dynamic code inclusion) verbatim, and it is the root cause of
  the 2026-09-01 404 — the pin aged out of BtbN's 14-day retention on the
  creator's first real recording attempt. -> TASK 48 item 1, not
  Store-conditional.
- Distribution.md:318 recommended a $400+/yr EV cert for a SmartScreen bypass
  Microsoft removed in March 2024. Fixed; had it shipped it would have cost
  $400+/yr to buy what $150 buys.

Also new: TASKS/task-48 (checklist, carved out of TASK 36 item 6) and
TASKS/task-49 (chat profanity filter, not blocked). ai.md gains the durable
invariants — full trust or recording breaks silently, chat is rendered never
stored — plus a correction to the FFmpeg locator section. MyMistakes.md records
the lesson: a policy citation is a claim about scope, not just text.

MARCOM.md got the privacy-copy guard but is gitignored by design, so that edit
stays local and did not travel here.
2026-09-27 14:17:13 -07:00

9.2 KiB
Raw Blame History

TASK 48 — Distribution & packaging: route decision, MSIX, signing

Catalog: TASKS.md — status and requirements live here. Research: TASKS/research-store-certification.md — the "why". Carved out of TASK 36 item 6 (release engineering) on 2026-09-27 so distribution has one owner instead of three scattered mentions.

Status: ☐ Queued — ⏳ blocked on the creator's route decision (item 0)

Goal: get LlamaCasty in front of a user without a SmartScreen scarewall, ideally without an annual certificate bill, and without breaking recording, capture, or audio.

⚠️ Nothing in this task is decided yet. The research is done and MSIX is the front-runner, but the route is the creator's call. Items 2–8 describe the MSIX path conditional on choosing it — if the answer is Polar-hosted + a cert, most of them evaporate and only items 0, 1, and 9 remain.


0. ⛔ THE DECISION — creator, not AI

Pick one:

# Route Cert/yr SmartScreen Extra work
A Store MSIX + Store IAP $0 none MSIX packaging; Store review; Polar deleted; revenue cut
B Store MSIX + Polar $0 none MSIX packaging; Store review; two systems to maintain
C Polar file hosting + Polar + own cert $120–300 warning ramp none beyond buying the cert
D Store EXE (10.2.9) $120–300 warning ramp dominated — cert anyway + silent install + maintain our own URL

C is the status quo already sketched in Distribution.md:14/:296 — Polar hosts the signed exe (10GB, signed personal URLs, SHA-256). The Store is not needed for delivery at all; its only unique value is free Microsoft signing with no warning.

Cost table, full detail, and the dead-EV correction: research-store-certification.md §2–3.


1. ⛔ Bundle ffmpeg instead of downloading it — do this on EVERY route

Not conditional on the Store. This is worth doing regardless.

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.

  • 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.

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.

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.

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.


2. ☐ Package.appxmanifest — full trust, camera, microphone

Only if the Store is chosen. There is currently no .manifest file in the repo at all, so this is purely additive.

  • rescap:Capability Name="runFullTrust" — medium integrity, not AppContainer
  • webcam and microphone capabilities
  • uap10:TrustLevel="mediumIL", uap10:RuntimeBehavior="packagedClassicApp"
  • uap10:RuntimeBehavior="packagedClassicApp" is what allows launching package executables as child processes
  • Declare English only (10.7 — otherwise the description must be localized into every declared language)
  • Block map SHA2-256, StoreManifest, under the 25 GB cap

Do NOT use appContainer — see the invariant in item 6.

3. ☐ Remove Velopack — 3 edit sites

Only if the Store is chosen (the Store handles updates). Trivially removable; the code was written defensively for exactly this.

  • ytLive.csproj:92 — <PackageReference Include="Velopack" Version="1.2.0" />
  • App.xaml.cs:3 — using Velopack;
  • App.xaml.cs:38-46 — the sole call site, already try/caught and commented "(non-fatal) … when no URL is set, the check is a no-op"

Retires: the pending "Velopack update URL" item (TASKS.md open items, task-10-monetization.md:43) and the self-hosted DigitalOcean droplet.

4. ☐ Windows App Certification Kit

Run before submission. Technical compliance is tested by WACK; it is not optional. Known relevant check: the app must start promptly, stay responsive, and shut down gracefully (10.4.2).

5. ☐ Certification notes + the three documentation artifacts

In Partner Center (submission):

  • ☐ Working YouTube demo account (10.3.1) — required, we cannot stream without sign-in
  • ☐ Tick the secure third-party purchase API box — Polar (10.8.1 / 10.8.2)
  • ☐ The 11.12 UGC position, stated in full — "mirrored from YouTube, which moderates it at industrial scale upstream; we render transiently, persist nothing, and provide no user-to-user communication surface." Full reasoning and the Q1-2026 enforcement numbers are in research-store-certification.md §9
  • ☐ The YouTube age-gate argument — operator is 13+ by construction (§8)
  • ☐ Note that the product is general audience, not directed at under-13s

On llamachile.shop:

  • ☐ Privacy policy (10.5.1 — mandatory for Win32/Desktop Bridge). Must state: camera/mic access is user-directed and OS-gated; no retention of chat or reward payloads; no viewer data collected; ffmpeg is bundled and nothing is fetched at runtime
  • ☐ Code of conduct + content guidelines (11.12 / 11.15)
  • ☐ Confirm THIRD-PARTY-NOTICES.txt covers the bundled LGPL ffmpeg build

In Partner Center (listing):

  • ☐ IARC age-rating questionnaire (10.11.1) — general audience, 12+ territory
  • ☐ Title is exactly LlamaCasty — 10.1.1 forbids marketing text or extraneous keywords
  • ☐ Search terms: max 7, no pricing terms, and no other product titles (10.1.3 — cannot list OBS or StreamYard)
  • ☐ Real listing content — 10.1.4 requires an active, substantive presence
  • ☐ Review the Individual vs Company account question before enrolling (see research-store-certification.md §11 item 1) — getting this wrong means re-enrolling

6. ☐ The full-trust recording invariant — comment lands WITH this work

ViewModels/MainViewModel.Recording.cs:173-179 (DefaultRecordFolder()) writes to %USERPROFILE%\Downloads or SpecialFolder.MyVideos; ChooseRecordFolder() (line 151) uses Microsoft.Win32.OpenFolderDialog; the temp-write-then-move lifecycle stays in one directory (line 131-132).

This works only because the package is full trust. At mediumIL, user-profile writes pass through unvirtualized and OpenFolderDialog is an ordinary Win32 browser with no capability token. No broadFileSystemAccess needed.

⚠️ If anyone flips the manifest to appContainer, recording silently breaks — Directory.CreateDirectory and File.Move start resolving to a per-package virtualized location and output vanishes.

Add a comment at DefaultRecordFolder() in this task, not before. A comment describing a manifest that does not exist is worse than no comment.

Also verify on a real packaged build before trusting it with recordings — the docs say full trust passes writes through, but that is worth confirming with an actual package identity rather than an unpackaged run.

7. ☐ Confirm the disqualifiers stay clear after packaging

All four are currently clear (verified by grep 2026-09-27) — re-verify once the packaging project exists:

  • No Windows driver installed (we consume DShow filters, we do not install one)
  • No per-user Windows service
  • No elevation / requireAdministrator / UAC manifest
  • No shell extension, no in-process module loading by outside processes, no jump list

8. ☐ Pre-submission gates

  • ☐ 0 warnings, full suite green
  • ☐ Vertical-recording path verified end-to-end (compositor tier is proven by Render_VerticalTier_Outputs_1080x1920_From_The_Center_Crop; the record path has never been exercised — Services/Pump/FramePump.cs:645 flags off-size tiers as a known follow-up)
  • ☐ The real-output confirmation the creator has been doing manually
  • ☐ Camera/mic/wasapi capture verified from the packaged build, not just unpackaged
  • ☐ Clean uninstall verified (10.2.7)
  • ☐ Notification-disabled path leaves the app functional (10.9)

Not in this task (deliberately)

  • Velopack hardening / obfuscation / assembly splitting — stays a GA-time decision per TASK 36 item 6's agreed ceiling. Compile flags max at HARDENED + MOCK_REWARDS, additive-only.
  • EULA draft/review and the THIRD-PARTY-NOTICES gate — stay in TASK 36 item 6.
  • Vertical-canvas feature work — the feature exists; only the record-path test above is missing.
  • macOS / Avalonia port — deferred; would be a second app, not a port.