docs: distribution route decided — Microsoft Store MSIX + Store IAP
Creator ruling 2026-09-27. Criteria, verbatim: "zero headaches, minimal maintenance (for me) while still providing accountability and a reasonably easy upgrade flow." Route A is the only combination where all four are solved by handing the work to Microsoft rather than to a certificate vendor: $0/yr, no certificate, no HSM, no annual renewal, no SmartScreen ramp — plus Store auto-update, Store-side payments/entitlements/refunds/support, and Microsoft review as the accountability layer. The rejected options and their reasons stay in research-store-certification.md §3 so a later session reads the ruling instead of re-deriving it. What this deletes: - The entire licensing backend. PolarLicenseService, PolarLicense, MainViewModel.License.cs (PremiumUrl, customer portal, the OfflineGracePeriod = 14 days subscription-era artifact, renewal/lapse copy) and the wrong "Polar unlocks alerts" string all become dead code. IsPremium is derived from the Store entitlement instead of an HTTP call, which also removes the whole "network flaky -> app thinks I'm expired" bug class. - Velopack, the update URL, and the self-hosted droplet — the Store updates. - Distribution.md's premise: Polar as the distribution backbone, Polar file hosting, and code signing as our problem. The IP-protection sections (1, 5, 6, 7) still stand and the build-posture ceiling is unchanged. What does NOT change: the entitlement. Free gets everything; the branding flash stays the only paid delta. Store IAP changes how IsPremium is obtained, never what it gates. Still open, deliberately: the price. The Store revenue share is unverified (do not assume a percentage), and MONETIZATION.md's $29 -> $49 one-time decision is re-opened against a fresh instinct toward ~$99/yr. No price encoded yet. The first code unit is unchanged: bundle ffmpeg (TASK 48 item 1). That clears the one hard certification gate and fixes a real user-facing 404. MARCOM.md and MONETIZATION.md were edited too but are gitignored by design, so those changes stayed local.
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
| 07 | Meter scaling amplification | ✅ Done | [`TASKS/task-07-meter-scaling.md`](TASKS/task-07-meter-scaling.md) |
|
||||
| 08 | Audio milestone | ✅ SHIPPED 2026-08-14 | [`TASKS/task-08-audio-milestone.md`](TASKS/task-08-audio-milestone.md) |
|
||||
| 09 | YouTube Live Stream Management | ⏳ In progress — items 1–3, 4 shipped; item 5 open; item 6 locked (TASK 36) | [`TASKS/task-09-live-stream-management.md`](TASKS/task-09-live-stream-management.md) |
|
||||
| 10 | Monetization: watermark-only one-time license + Polar billing | 🔶 In progress — steps 1–7 shipped | [`TASKS/task-10-monetization.md`](TASKS/task-10-monetization.md) |
|
||||
| 10 | Monetization: watermark-only one-time license + Polar billing | 🔶 In progress — steps 1–7 shipped; **now a TEARDOWN: Polar is deleted in favour of Store IAP (2026-09-27)** | [`TASKS/task-10-monetization.md`](TASKS/task-10-monetization.md) |
|
||||
| 11 | Post-pause polish batch (creator's 8 review issues) | ✅ SHIPPED 2026-08-15 | [`TASKS/task-11-polish-batch.md`](TASKS/task-11-polish-batch.md) |
|
||||
| 12 | Master limiter on the live mix | ☐ Queued | [`TASKS/task-12-master-limiter.md`](TASKS/task-12-master-limiter.md) |
|
||||
| 13 | Social media launch kit | 🔶 Scoped — queued after v1 | [`TASKS/task-13-social-launch-kit.md`](TASKS/task-13-social-launch-kit.md) |
|
||||
@@ -63,7 +63,7 @@
|
||||
| 45 | TEST-tab chat fix #2: insert body must declare `snippet.type` (400 MISSING_REQUIRED_FIELD) | ✅ Done (2026-09-25) | [`TASKS/task-45-chat-insert-type.md`](TASKS/task-45-chat-insert-type.md) |
|
||||
| 46 | Drawers: click outside the rail closes whichever is open — TEST added to the existing Stream Settings + YPP dismiss behavior | ✅ Done (2026-09-25) | [`TASKS/task-46-drawer-click-outside-close.md`](TASKS/task-46-drawer-click-outside-close.md) |
|
||||
| 47 | Alert box video: built-in/custom alert clip (+ six-animation fallback) with read-time fade in/out + ticker (now in the preview too, 3 display methods) + alert volume in the live mix | ✅ Done (2026-09-26) | [`TASKS/task-47-alert-videos.md`](TASKS/task-47-alert-videos.md) |
|
||||
| 48 | Distribution & packaging: route decision, bundled ffmpeg, MSIX + code signing | ⏳ Queued — **blocked on the creator's route decision**; bundled-ffmpeg half is unblocked and recommended | [`TASKS/task-48-distribution-msix.md`](TASKS/task-48-distribution-msix.md) |
|
||||
| 48 | Distribution & packaging: **MSIX + Store IAP** | 🔶 In progress — **✅ route decided 2026-09-27 (Store MSIX + Store IAP)**; item 1 (bundle ffmpeg) is the next code unit | [`TASKS/task-48-distribution-msix.md`](TASKS/task-48-distribution-msix.md) |
|
||||
| 49 | Chat profanity filter (local, opt-in, non-persistent, user word list) | ☐ Queued (2026-09-27) | [`TASKS/task-49-chat-profanity-filter.md`](TASKS/task-49-chat-profanity-filter.md) |
|
||||
|
||||
---
|
||||
@@ -213,18 +213,44 @@ second encoder path needing a "redirect". Record+simulcast is one ffmpeg with tw
|
||||
installer, and the Velopack update URL have one owner instead of three scattered mentions.
|
||||
**EULA draft/review and the THIRD-PARTY-NOTICES license-texts gate stay in TASK 36 item 6**,
|
||||
as does the agreed build-posture ceiling (HARDENED + MOCK_REWARDS, additive-only).
|
||||
- **TASK 48 — distribution & packaging** — **⏳ the route decision belongs to the creator.**
|
||||
Research is done and MSIX is the front-runner; the four real combinations (Store+Store IAP /
|
||||
Store+Polar / Polar-hosted+own cert / dominated Store-EXE) and their cert costs are tabulated
|
||||
in `TASKS/research-store-certification.md` §3. Two things are settled and unblocked:
|
||||
**(a) bundle ffmpeg instead of downloading it** — `FfmpegLocator` currently downloads an
|
||||
unsigned exe from GitHub and runs it, which is Store policy 10.2.2 (dynamic code inclusion)
|
||||
*and* is the root cause of the 2026-09-01 expired-pin 404; **(b) the `Distribution.md` EV
|
||||
claim is dead** — Microsoft removed the SmartScreen EV bypass in March 2024, so paying
|
||||
$400+ buys what $150 buys. Full-trust MSIX is viable (mediumIL, not AppContainer, and the
|
||||
three technical disqualifiers — drivers, per-user services, elevation — are all clear).
|
||||
Packaging, Velopack removal, WACK, the demo account, the privacy policy and the IARC
|
||||
questionnaire are all specified in the task file and waiting.
|
||||
- **TASK 48 — distribution & packaging** — **✅ ROUTE DECIDED 2026-09-27: Microsoft Store,
|
||||
MSIX package, Store IAP.** Creator's criteria, verbatim: *"zero headaches, minimal
|
||||
maintenance (for me) while still providing accountability and a reasonably easy upgrade
|
||||
flow."* Route A is the only option where all four are solved by handing the work to
|
||||
Microsoft rather than to a certificate vendor — **$0/yr, no certificate, no HSM, no annual
|
||||
renewal, no SmartScreen ramp**, plus Store auto-update, Store-side payments/entitlements/
|
||||
refunds/support, and Microsoft review as the accountability layer. The rejected options
|
||||
(Store+Polar, Polar-hosted + own cert, Store-EXE) are recorded with their reasons in
|
||||
`TASKS/research-store-certification.md` §3 so the decision is not reopened.
|
||||
- **The consequence that makes it cheap: the entire licensing subsystem is deleted.**
|
||||
`Services/PolarLicenseService.cs` (HTTP validation, swallowed network failures, the
|
||||
ignored `expires_at`), `Helpers/PolarLicense.cs`, `ViewModels/MainViewModel.License.cs`
|
||||
(`PremiumUrl`, customer portal, the `OfflineGracePeriod = 14 days` subscription-era
|
||||
artifact, renewal/lapse copy), and the incorrect "Polar unlocks alerts" string in
|
||||
`Controls/OverlayHost.xaml` all become dead code. `IsPremium` is derived from the **Store
|
||||
entitlement** instead of a remote HTTP call — one locally cached bit refreshed by the OS,
|
||||
and the whole "network flaky → app thinks I'm expired" bug class disappears with the
|
||||
offline-grace machine.
|
||||
- **Unchanged:** the watermarks posture. Free gets everything; the branding flash stays the
|
||||
ONLY paid delta (TASK 36 item 2). Store IAP changes how the bit is *obtained*, never what
|
||||
it *gates*.
|
||||
- **Still to verify (does not block packaging):** current Store revenue-share terms — ⚠️ do
|
||||
not assume any percentage, verify before setting a price; and the one-time vs
|
||||
subscription shape of the IAP tier (the storefront is decided, the price is not).
|
||||
- **First code unit: item 1 — bundle ffmpeg instead of downloading it.** Unblocked,
|
||||
recommended on every route, and it fixes a real user-facing failure.
|
||||
- **TASK 10 is now a teardown, not a build** (2026-09-27) — Store IAP deletes the Polar
|
||||
licensing path. The Polar fee tables, the perpetual-key model, and the customer-portal
|
||||
plumbing in `MONETIZATION.md` (gitignored, local) are obsolete; the **watermark-only
|
||||
entitlement and the branding-flash delta carry over unchanged**. The stale Polar product
|
||||
(`$99/yr`, id `d105dfa1-…`) is not reused — Store IAP products are declared in Partner
|
||||
Center instead.
|
||||
- **Pricing is re-opened** (2026-09-27) — `MONETIZATION.md` carries a **one-time perpetual**
|
||||
decision from 2026-09-21 (`$29` founder → `$49` list) that explicitly superseded the old
|
||||
`$99/yr` subscription; the creator's current instinct is back toward a subscription.
|
||||
**Unresolved — do not encode a price until it is settled**, and note that Store IAP moves
|
||||
pricing into fixed Store tiers, so the "floor" (`~$69` per `MONETIZATION.md`) and the
|
||||
"don't break the launch-price promise" note now refer to a different storefront.
|
||||
- **TASK 49 — chat profanity filter** — queued, not blocked, size S. Local, on-device,
|
||||
**non-persistent**, opt-in, **user-supplied word list (never a hardcoded slur list)**, and it
|
||||
must **never match the SuperChat amount or reward fields** (financial data, Store 10.5.5).
|
||||
|
||||
Reference in New Issue
Block a user