The creator's ruling (2026-09-27) is Store MSIX + Store IAP, so Microsoft delivers the updates and the in-app updater is gone rather than parked. This is a COMPLIANCE action, not cleanup: the Velopack bootstrap downloaded and executed a payload, which Store policy 10.2.2 does not permit. Three edit sites, as planned: the PackageReference in ytLive.csproj, 'using Velopack;' in App.xaml.cs, and the bootstrap block. The self-hosted DigitalOcean update-URL droplet dies with it. Guard: ytLive.Tests/StorePackagingTests.cs - the ONE test asserts the app project references no updater package (Velopack/Squirrel/NetSparkle/AutoUpdater/WinSparkle) and that no app source file uses the updater API. The check matches CODE (a using directive, a type usage), not a bare word, so a file's prose may still name what it deliberately does not do. Smoke-tested after the removal: MainWindow loaded, 0 exceptions in startup.log. Full suite 437/437, 0 warnings.
74 lines
5.3 KiB
Markdown
74 lines
5.3 KiB
Markdown
# TASK 10 — Monetization: watermark-only paid delta (branding flash)
|
||
|
||
> Catalog: [`TASKS.md`](../TASKS.md) — status and requirements live here.
|
||
|
||
**Goal:** a **paid tier that removes the branding flash and nothing else.** Every feature is free
|
||
— Alerts, social bar slots, voice filters, TRAX, recording, analytics. The free tier is the *full*
|
||
app. ⛔ **There is no feature gating, ever** — revenue argument, not taste: the free tier's reach
|
||
is the funnel, and the flash is an ad running inside other people's content, so a free user with a
|
||
flash every 30–60s is already paying in exposure.
|
||
|
||
**⚠️ STATUS: THIS IS A TEARDOWN, NOT A BUILD (2026-09-27).** The billing provider is
|
||
**Microsoft Store IAP**, not Polar. Everything below describing Polar is **dead** and is retained
|
||
only as history. **Do not resurrect any of it.** The teardown's file-by-file list lives in
|
||
[`TASKS/task-48-distribution-msix.md`](task-48-distribution-msix.md) item 0 — **work from there,
|
||
not from this file.**
|
||
|
||
**Pricing — ✅ DECIDED 2026-09-27: `$10/mo` subscription, or `$400` lifetime. No annual.**
|
||
|
||
| Tier | Price | Net after 15% | Role |
|
||
|---|---|---|---|
|
||
| Free | $0 | — | Everything, plus the branding flash. The funnel. |
|
||
| **Pro monthly** | **$10/mo** | ~$8.50/mo | The default. Low-risk entry. |
|
||
| **Pro lifetime** | **$400** | ~$340 | The hedge. Committed / subscription-hostile buyers. |
|
||
|
||
- **15% Store revenue share, subscriptions included** — verified from the ADA v8.10 PDF, §6(b)(i).
|
||
Net receipts are after VAT/GST, so commission is not paid on pass-through tax.
|
||
- **Break-even is month 40**, so the two tiers barely compete — which is why lifetime is safe to
|
||
offer at launch rather than saving it for later.
|
||
- ⛔ **No annual tier** — Microsoft does not pro-rate and the developer cannot refund the
|
||
forfeited remainder. ⛔ **No `.99` prices.** ⛔ **No discounted upgrade SKU.**
|
||
- **ADA §6(h): raising the price disables auto-renew ⇒ `$10` is effectively locked for life.**
|
||
- ⛔ **Superseded pricing, do not cite:** the 2026-09-21 one-time model (`$29` founder → `$49`
|
||
list lifetime) and the earlier `$49.99/yr → $99/yr` subscription.
|
||
|
||
**Related work — monetization awareness (2026-09-01, ungated, free):** this task's billing is the
|
||
*payer* side; the *product* also carries built-in, ungated monetization awareness for every creator —
|
||
reward-event capture (all 7 `liveChatMessage` reward event types → canonical `RewardEvent` → SQLite
|
||
persistence), per-session/broadcast reports (members, Super Chat $, stickers, gifts, milestones — the
|
||
in-app replacement for the emailed "stream activity report"), and a journey tracker (position % +
|
||
ETA vs. versioned, date-aware YPP thresholds; the Tier-2 bar doubles for new applicants 2027-02-01).
|
||
Details and design notes: `ai.md` → Monetization. This is tracked as related work under this task's
|
||
narrative, not a separate task number — it ships in its own code slices with one integration test each.
|
||
**Scope: v1** (2026-09-01 complete-v1 ruling — there is no v1.x): slice order = reward-event capture →
|
||
session report → journey tracker → Alerts (TASK 3 item 20).
|
||
|
||
**Business details (pricing, Partner Center product declaration) in `MONETIZATION.md` (gitignored).**
|
||
|
||
### Status: 🔶 TEARDOWN — steps 1–7 shipped under Polar, all now to be removed
|
||
|
||
Steps 1–7 below are a **record of what was built**, not a description of what ships. The Polar
|
||
licensing path is being deleted because Store IAP supplies the same bit from the OS entitlement.
|
||
|
||
1. ⛔ **Billing provider** — was Polar (polar.sh). **DELETED.** The product, checkout link, and the
|
||
discount codes `LLAMAFOUNDER` / `LLAMA50` no longer exist. Store IAP products are declared in
|
||
**Partner Center**, not Polar.
|
||
2. ⛔ **License key entry + verification UI** — was the About-overlay swap panel
|
||
("Enter License Key"). **DELETING.**
|
||
3. ⛔ **Offline entitlement** — was `LayoutStore` Settings (`LicenseKey`, `LicenseValidatedAt`,
|
||
`IsPremium`) + a 14-day offline grace period + startup re-validation. **DELETING.** The OS
|
||
supplies license state, so the entire offline-grace machine goes with it — along with the whole
|
||
"network flaky → app thinks I'm expired" bug class.
|
||
4. ✅ **BrandFlash → watermark toggle** — `IsPremium` setter flips `BrandFlashEnabled = !value`, so
|
||
the flash stops the moment the entitlement flips. **This survives the teardown.** Under Store IAP
|
||
`IsPremium` is derived from the Store entitlement rather than a remote HTTP call. One bit,
|
||
locally cached, refreshed by the OS. ⚠️ **This is the whole product surface of the paid tier.**
|
||
5. ✅ **Remove social slot locks** — all 6 social bar slots open to everyone. **Survives.**
|
||
6. ⛔ **"Unlock Premium" button** — `PremiumUrl` pointed at Polar checkout. **DELETING**; the Store
|
||
handles purchase. Paid users see zero license UI.
|
||
7. ⛔ **Licensing model / renewal-lapse path** — already dead before the Store ruling (a perpetual
|
||
key never expires). Now superseded again: **Store IAP has no keys at all.**
|
||
8. ✅ **Velopack auto-updates** — NuGet package + bootstrap in `App.xaml.cs`. **DELETED
|
||
2026-10-22 (TASK 48 slice 3)** — a compliance action, not cleanup: the updater downloaded
|
||
*and executed*, and Store policy 10.2.2 does not permit it. The Store updates the app
|
||
instead. Guard: `ytLive.Tests/StorePackagingTests.cs`. |