docs: purge the dead $29/$49 + Polar model from every tracked file, add the Y1 forecast

The pricing ruling landed twice (2026-09-21 one-time, then 2026-09-27 Store IAP
$10/mo + $400 lifetime) and the map never caught up. Six tracked files still told
a future session that billing was Polar and the price was $29/$49. A stale memory
map is worse than a stale comment: it is the file every session trusts, and this
one was actively steering work toward a deleted provider.

MONETIZATION.md (gitignored, so not in this commit) was rebuilt first:
- "Revenue projections" now carries a modelled Year 1 forecast —
  pessimistic $4.0K / base $15.4K / optimistic $53.3K net, ~$22K weighted.
  Funnel is installs -> 35-45% activate -> 1.5-3% of active users pay.
- Three findings recorded: Year 1 is ~97% lifetime transactions (subs net $392
  of $15.4K, so MRR is not a Year-1 planning input); conversion dominates price
  (~1pp of conversion = ~$7K net, and ADA 6(h) locks $10 anyway); subscriber
  churn moves Year 1 by under $200 and is a Year-2 problem.
- Break-even restated for $400: $25K net = 74 lifetime buyers, not 862.
  The price cut the volume requirement ~10x and raised the skill requirement
  to match.
- Market sizing willingness-to-pay row rewritten. The 100K-400K TAM was
  price-bound to $29-49 and is wrong at $400; revised ~20K-60K, flagged as an
  estimate rather than a sourced number.
- Flagged a real contradiction: $500K ARR needs ~4,900 concurrent subscribers,
  so the Exit section's ARR multiples do not describe what Years 1-3 produce.
  The defensible asset there is lifetime cash flow, not ARR.

Tracked files corrected to match:
- ai.md: paid-delta, pricing and billing bullets rewritten; Polar product id,
  org id, LCYT- key prefix and LLAMAFOUNDER/LLAMA50 marked as deleted;
  15% share + net-after-tax recorded with the ADA 6(b)(i) citation.
- TASKS.md: catalog row retitled as a teardown; the "still to verify — the
  price is not decided" note closed (it contradicted the ruling 20 lines
  below it); the OverlayHost "Polar unlocks alerts" open question marked
  resolved; Polar file-hosting deliverable removed from the release build.
- task-10: reframed as a teardown. Steps 4-5 marked as surviving, 1-2-3-6-7 as
  deleting, 8 as a compliance action (Velopack downloads AND executes, which
  Store policy 10.2.2 does not permit).
- task-36 item 5 (license-expiry reminders) struck — no key, no expiry, no
  lapse under Store IAP, so there is nothing to remind anyone about.
- Distribution.md 4.2 / 4.4 / 4.5 marked obsolete; 4.5's "already implemented"
  corrected, since PolarLicenseService is being deleted rather than shipped.
- README: "one-time license" -> "paid tier".

Historical Polar sections are retained deliberately — the reasoning is reusable
(merchant-of-record, fee comparison), only the conclusions are dead. Each is now
labelled so it cannot be mistaken for the plan.

No code touched.
This commit is contained in:
2026-10-02 20:56:37 -07:00
parent d95a23c6fb
commit f3fed0a2a8
7 changed files with 145 additions and 70 deletions
+37 -10
View File
@@ -318,9 +318,17 @@ Single-file means everything is inside the `.exe`. No DLLs, no runtime dependenc
**Caveat:** Self-contained single-file means ~80-120MB due to bundled .NET runtime. For smaller size, use framework-dependent publishing (requires .NET 8 runtime on user machines) — drops to ~5-10MB.
### 4.2 Distribution via Polar
### 4.2 Distribution via Polar — ⛔ OBSOLETE (2026-09-27)
**Product setup on Polar:**
> **Superseded by Microsoft Store MSIX + Store IAP** (ruling in
> `TASKS/task-48-distribution-msix.md` item 0). The Store re-signs, hosts, updates, and takes
> payment — so file hosting, license keys, checkout, the customer portal, device deactivation and
> key rotation are **all** handled by Microsoft and none of it needs building. Retained below as a
> record of the model that was designed and abandoned. ⚠️ **The `$29`/`$49` one-time prices in this
> section are dead** — the settled pricing is **`$10/mo` or `$400` lifetime**, net of a verified
> 15% Store share.
**Product setup on Polar (as designed, never shipped):**
1. Create a product: "LlamaCasty" — **one-time purchase** (perpetual license; $29 founder / $49 list).
2. Add two benefits:
@@ -345,6 +353,11 @@ Single-file means everything is inside the `.exe`. No DLLs, no runtime dependenc
- If a key is compromised, customer or merchant can rotate it via Polar.
- Previous key stops validating immediately. Status, usage, limits, expiry preserved.
**What the Store does instead:** the customer installs from the Store listing, pays through Store
checkout, and the app reads the entitlement the OS already holds. There is no key to enter, no
activation call, no portal to visit, and no offline-grace period to maintain — which also retires
the whole "network flaky → app thinks I'm expired" bug class in §4.5.
### 4.3 Code Signing
> ⚠️ **The cert choice below is a live decision, and the old plan's EV recommendation is
@@ -393,7 +406,13 @@ Set-AuthenticodeSignature -FilePath "LlamaCasty.exe" `
**Storage:** Certificate `.pfx` file stored in GitHub Secrets (or Azure DevOps secure files). Never committed to the repo.
### 4.4 Update Mechanism
### 4.4 Update Mechanism — ⛔ OBSOLETE (2026-09-27)
> **Superseded by Store updates.** Microsoft delivers and updates the app from the listing, so
> there is nothing to check and no manifest to host. The Velopack updater currently in
> `App.xaml.cs` **downloads *and executes***, which Store policy **10.2.2** does not permit — its
> removal is a **compliance action**, not optional cleanup (TASK 48 item 3). The Polar-native design
> below is retained as a record of the approach that was rejected; it is not an option.
**Polar-native approach (no custom infrastructure):**
@@ -428,10 +447,18 @@ public class UpdateCheckService
- Download link points to Polar's customer portal (not direct download).
- This adds one external dependency (GitHub) but keeps Polar as the source of truth.
### 4.5 Licensing Logic (already implemented)
### 4.5 Licensing Logic — ⛔ BEING DELETED (2026-09-27)
> ⚠️ **"Already implemented" was true as of 2026-09-21 and is no longer.** `PolarLicenseService`
> and `Helpers/PolarLicense.cs` are being **removed** as part of the TASK 10 teardown (TASK 48 item 0).
> Store IAP replaces the whole validation hop: `IsPremium` is derived from the **OS-supplied Store
> entitlement**, so there is no network call, no key, and — importantly — **no 14-day offline-grace
> machine to protect**, which retires the entire "network flaky → app thinks I'm expired" bug class.
> What survives is only `IsPremium` → `BrandFlashEnabled = !value`. Retained below as the record of
> what shipped and why it no longer applies.
```csharp
// Services/PolarLicenseService.cs — already ships
// Services/PolarLicenseService.cs — shipped under Polar; being deleted
// Calls Polar's customer-portal validation endpoint (no auth required)
// Survives obfuscation — property names excluded via [Obfuscation(Exclude = true)]
[Obfuscation(Exclude = true)]
@@ -444,11 +471,11 @@ public class LicenseValidationResult
}
```
**What's already done:**
- `PolarLicenseService` validates keys against Polar API.
- `OrganizationId` is hardcoded (safe — it's public knowledge, tied to our Polar account).
- License state persists in `LayoutStore.Settings` (SQLite) with offline grace period.
- `PremiumUrl` points to Polar checkout.
**What shipped under Polar (now being deleted):**
- `PolarLicenseService` validated keys against the Polar API.
- `OrganizationId` was hardcoded.
- License state persisted in `LayoutStore.Settings` (SQLite) with an offline grace period.
- `PremiumUrl` pointed to Polar checkout.
**What survives obfuscation:** The validation logic in `Services.dll` is obfuscated. An attacker who decompiles the exe sees only the UI calling an interface — the actual Polar API call is in the obfuscated DLL.
+1 -1
View File
@@ -54,7 +54,7 @@ text sources, chat on-stream, the social bar, mic/desktop audio with auto-duck a
recording, variable quality tiers with auto step-down, one-click go-live + scheduling, stream
resilience (auto-reconnect inside YouTube's grace, one-click back on air), built-in monetization
awareness (reward capture, session reports, YPP journey tracker), Alerts — all free and ungated;
the one-time license only removes the branding flash.
the paid tier only removes the branding flash.
## Structure
+14 -8
View File
@@ -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; **now a TEARDOWN: Polar is deleted in favour of Store IAP (2026-09-27)** | [`TASKS/task-10-monetization.md`](TASKS/task-10-monetization.md) |
| 10 | Monetization: watermark-only paid delta (branding flash) | 🔶 **TEARDOWN, not a build** — Polar deleted in favour of Store IAP (2026-09-27); `$10/mo` + `$400` lifetime, no annual | [`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) |
@@ -120,8 +120,9 @@ second encoder path needing a "redirect". Record+simulcast is one ffmpeg with tw
- **Shipping / release build (creator-queued 2026-09-26)** — no publish config exists yet:
the csproj has only `OutputType=WinExe` + `TargetFramework`, so a plain `dotnet publish`
is **framework-dependent** (customer needs the .NET 8 Desktop Runtime preinstalled).
`Distribution.md` targets a self-contained ~80–120MB `LlamaCasty.exe` uploaded to Polar
as a File Download benefit. Two deliverables:
`Distribution.md` targets a self-contained ~80–120MB `LlamaCasty.exe`. ⛔ **The Polar
File-Download benefit is dead** — the Store hosts and updates the app, so there is no upload
step (TASK 48). Two deliverables:
1. **`scripts/publish.sh`** wrapping
`dotnet publish ytLive.csproj -c Release -r win-x64 --self-contained true -o ./publish/win-x64`,
and **asserting the output contains no test/xunit artifacts**. (The compile side needs
@@ -235,9 +236,12 @@ second encoder path needing a "redirect". Record+simulcast is one ffmpeg with tw
- **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).
- **Both formerly-open questions are now CLOSED (2026-09-27).** Store revenue share is
**verified at 15%, subscriptions included** (ADA v8.10 §6(b)(i) — read from the PDF, not a
search excerpt), and the IAP tier shape is **decided: `$10/mo` subscription + `$400`
lifetime, no annual**, declared in Partner Center as two products. Full detail in
`TASKS/task-48-distribution-msix.md` item 0. ⚠️ Do **not** re-open the fee question without
re-reading the ADA, and do not *assume* 15% if the terms ever move.
- **✅ item 1 SHIPPED 2026-09-28 — bundle ffmpeg instead of downloading it.** The app no
longer fetches an executable at runtime (Store policy 10.2.2, and the pin 404'd on the
creator's first real recording on 2026-09-01). `scripts/fetch-ffmpeg.sh` populates a
@@ -310,8 +314,10 @@ second encoder path needing a "redirect". Record+simulcast is one ffmpeg with tw
- Still queued from earlier: `scripts/publish.sh` (self-contained win-x64, no test artifacts,
Debug-only `InternalsVisibleTo`, no WPF trimming), and the `LlamaCasty.exe` assembly rename
(three pack URIs incl. `MainWindow.xaml:14` — do not rename `%APPDATA%\ytLlive`).
- Decide the open business question: `OverlayHost.xaml` copy says Polar unlocks *alerts* too, but
alerts are not gated by `IsPremium`. Either fix the copy or gate the alerts — do not leave it.
- ✅ **RESOLVED — do not re-open.** The `OverlayHost.xaml` copy claimed Polar unlocked *alerts*;
alerts were never gated by `IsPremium`. The file is **deleted outright** by the TASK 10 teardown
(TASK 48 item 0), so the copy is gone with it. The "or gate the alerts" option is **permanently
closed** — there is no feature gating, ever.
---
+55 -25
View File
@@ -1,12 +1,36 @@
# TASK 10 — Monetization: watermark-only one-time license + Polar billing
# 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.
**Goal:** a **one-time perpetual license** via Polar.sh that removes the branding watermark. All features
are free — the only difference between free and paid is the watermark. (Model changed 2026-09-21 from
annual subscription to one-time "own it": $29 founder / $49 list lifetime. See `MONETIZATION.md` →
Pricing for the reasoning.)
**⚠️ 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 —
@@ -19,26 +43,32 @@ narrative, not a separate task number — it ships in its own code slices with o
**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, Polar product/checkout/discounts) in `MONETIZATION.md` (gitignored).**
**Business details (pricing, Partner Center product declaration) in `MONETIZATION.md` (gitignored).**
**Polar product:** `d105dfa1-497e-423b-8cd4-e0ee2e3abbc0` (LlamaCasty, ⚠️ currently configured as
$99/yr **subscription** — must be re-created as a **one-time** product: $29 founder / $49 list lifetime)
**Checkout:** `llamacasty.com` → Polar hosted page (~80% configured)
**Discounts:** `LLAMAFOUNDER` (100% off, 50 uses, `once`), `LLAMA50` (50% off, `once`)
**Org ID:** `c05fb364-b967-4f6c-adf2-8a144e46d085` (org-scoped OAT — `organization_id` can be omitted from API calls)
**Key prefix:** `LCYT-`
**Validate endpoint:** `POST https://api.polar.sh/v1/customer-portal/license-keys/validate` (no auth required for client-side validation)
### Status: 🔶 TEARDOWN — steps 1–7 shipped under Polar, all now to be removed
### Status: 🔶 In progress — steps 1–7 shipped, Velopack update URL pending
1. ✅ **Billing provider** — Polar (polar.sh) chosen and configured. Product, price, license key benefit, discounts, checkout link all created.
2. ✅ **License key entry + verification UI** — About overlay swap panel (same pattern as Licenses panel). Text input + "Activate" button + status message. "Enter License Key" button in the hub.
3. ✅ **Offline entitlement** — `LayoutStore` Settings table: `LicenseKey`, `LicenseValidatedAt`, `IsPremium`. 14-day offline grace period. Startup re-validates online, falls back to cache.
4. ✅ **BrandFlash → watermark toggle** — `IsPremium` property setter flips `BrandFlashEnabled = !value`. Flash stops immediately on premium activation. Flash asset VideoFrame rendering deferred to TASK 4 compositor.
5. ✅ **Remove social slot locks** — all 6 social bar slots open to everyone (no `IsPremium` gating on slots 3-6) — shipped as TASK 10c
6. ✅ **"Unlock Premium" button** — `PremiumUrl` set to Polar checkout; `IsPremiumAvailable` is true; button lights up in the About hub.
7. ✅ **Licensing model** — startup re-validates against Polar API. **Perpetual key (2026-09-21): the
license never expires, `IsPremium` never lapses, and the flash does not return.** The former
renewal/lapse path is dead. Offline grace period (14 days) still applies to the validation call only.
8. 🔶 **Velopack auto-updates** — NuGet packages + bootstrap in `App.xaml.cs`. Update URL self-hosted on DO droplet (pending configuration).
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 packages + bootstrap in `App.xaml.cs`. **TEARDOWN is a
compliance action, not cleanup:** the updater downloads *and executes*, and Store policy 10.2.2
does not permit it. Tracked as [`TASKS/task-48-distribution-msix.md`](task-48-distribution-msix.md)
item 3; the Store updates the app instead.
+1 -1
View File
@@ -39,7 +39,7 @@ The tasks below are ordered by dependency and risk. Each task builds on the prev
1. ✅ **TASK 9.4** — Live chat (right panel) — wire `YouTubeChatService.Start()`, parse messages, render in panel. Foundation for chat box source.
2. ✅ **TASK 3.18** — Chat box source — renders chat ON the stream. Depends on TASK 9.4 (same message parsing).
3. ✅ **TASK 10** — Polar billing — license key entry + watermark toggle + Velopack auto-updates (steps 1-7 shipped; Velopack update URL pending).
3. ✅ **TASK 10** — watermark-only paid delta (brand flash). Steps 1–7 shipped under **Polar**, which is **now deleted in favour of Microsoft Store IAP** (2026-09-27) — TASK 10 is a **teardown**, and the Velopack updater goes with it (Store policy 10.2.2).
4. ✅ **TASK 19/23** — Control Surface UX — director's control room: thumbnails above central monitor, transitions (Cut/Fade/Move), edit mode offline only, left panel two-state (layers/props ↔ chat), right panel eliminated. Verified shipped 2026-08-24.
5. ✅ **TASK 20** — Hotkeys — global keyboard shortcuts. Shipped 2026-08-26: F1-F9 defaults + config UI with modifier chords, persistence, conflict detection, unbinding.
5b. ✅ **Broadcast metadata pull-out + launch geometry** — shipped 2026-08-24 (row 29 above). Live-screen "Text" tab → broadcast form, persistence + remote update; window default/minimums bumped (1920×1040 / 1366×768) with size+position restore.
+5 -4
View File
@@ -17,10 +17,11 @@ may be done opportunistically mid-development — each item has a lock/comment p
real mp4 decode/loop/pacing (TASK 21 picker must have landed), real recording file opens +
plays (fragmented MP4), a real private go-live end-to-end, GUI/RealApp test classes green on
the desktop (they've only ever run against fakes).
5. ☐ **License-expiry reminders** — T-14 / T-7 / T-1 toasts via the existing notification stack
("renews <date> — manage here" → `PremiumUrl`); lapsed: flash returns (the product itself is the
notice) + one Info toast; active paid users see ZERO license UI. Research: does Polar's
validate response carry `expires_at` reliably — cite before building.
5. ⛔ **STRUCK — License-expiry reminders are dead.** This item assumed a Polar license with an
`expires_at` we could warn about. Under **Store IAP** there is no key, no expiry, and no lapse:
the lifetime entitlement never ends and the subscription is renewed by Microsoft. **Nothing to
remind anyone about — do not build.** (The `expires_at` question is moot for the same reason:
`PolarLicenseService` is being deleted.)
6. ☐ **Release engineering** (the `Distribution.md` plan, 644 lines, finally tasked): code signing
(HARD blocker — an unsigned installer is a SmartScreen scarewall), installer + Velopack update URL
(TASK 10 item 8), EULA draft/review, THIRD-PARTY-NOTICES license-texts gate (TASK 4 req 9).
+32 -21
View File
@@ -1506,7 +1506,8 @@ Apply this to every UI decision:
## Monetization (design decision — the branding flash is the sword)
Full pricing, discount codes, and Polar product details in `MONETIZATION.md` (gitignored).
Full pricing and the Year 1 revenue forecast in `MONETIZATION.md` (gitignored). ⚠️ **No Polar
product, discount code, or license key exists any more** — billing is Microsoft Store IAP.
Brand palette and assets in `MARCOM.md` (gitignored). This section covers the in-app model.
Free forever: **all features unlocked for everyone** — no feature lock between free and paid.
@@ -1554,30 +1555,40 @@ crooked.
credit — `Advance` both *opens* the presentation and *ages* it by the same delta, so a single
5.1s step blows clean through the 2s window. Always step in 1/30s increments like the real timer
(the `Step` helpers in `BrandFlashOutputTests`).
- **Paid (one-time perpetual license):** branding flash removed. `BrandFlashEnabled` is now a
**derived, non-assignable** `!IsPremium` and the presenter's own `Enabled` gate is re-checked on
every frame, so a key entered (or revoked) mid-credit cuts the advertisement on the next tick
rather than letting it finish. That's it. No feature gating. Alerts, social bar slots, voice
filters, TRAX, recording — everything is free.
- **Pricing (2026-09-21 — switched from subscription to one-time "own it"):** **$29 lifetime** founder's
price (launch → 90 days) → **$49 lifetime** list at GA. The key is **perpetual** (`IsPremium` never
lapses; the old renewal/lapse path is dead). Rationale: a local app with no per-user server cost and a
renewal-averse, free-surrounded audience — minimize commitment size, don't charge rent. Accessibility is
the driver: the free tier is the *full* app (only the watermark differs), so a broke new streamer pays $0;
the low one-time price is the "no recurring bill" entry. Full reasoning, and the dropped $49.99/yr →
$99/yr subscription model, in `MONETIZATION.md`.
- **Billing:** **Polar (polar.sh)** — open-source MoR (Apache 2.0), handles payments, **one-time orders**,
license keys, and global tax compliance. Startup Program gives Scale plan free for 12 months.
Product: `d105dfa1-497e-423b-8cd4-e0ee2e3abbc0` (⚠️ currently a $99/yr *subscription* product — must be
re-created as a one-time product for the new model). Checkout: `llamacasty.com` → Polar hosted page.
Org ID: `c05fb364-b967-4f6c-adf2-8a144e46d085` (org-scoped OAT — `organization_id` omitted from API calls).
Key prefix: `LCYT-`. Discounts: `LLAMAFOUNDER` (100% off, 50 uses), `LLAMA50` (50% off, 12 months). Details in `MONETIZATION.md`.
- **Paid:** branding flash removed. `BrandFlashEnabled` is now a **derived, non-assignable**
`!IsPremium` and the presenter's own `Enabled` gate is re-checked on every frame, so the
entitlement changing mid-credit cuts the advertisement on the next tick rather than letting it
finish. That's it. No feature gating. Alerts, social bar slots, voice filters, TRAX, recording —
everything is free. **How `IsPremium` is obtained is a billing concern and has changed twice;
what it gates has not.**
- **Pricing (✅ DECIDED 2026-09-27 — supersedes the 2026-09-21 one-time "own it" model):**
**`$10/mo` subscription, or `$400` lifetime. No annual. No `.99` prices.** ⛔ The old `$29`
founder → `$49` list lifetime ruling is **dead — do not cite it.** Two tiers, one delta: they
break even at **month 40**, so they barely compete, which is why lifetime is safe to offer at
launch instead of saving it for later. The free tier is the *full* app (only the watermark
differs), so accessibility is preserved without pricing down. ⛔ No annual tier: Microsoft does
not pro-rate and **the developer cannot refund** the forfeited remainder — verbatim the
grievance that drove the ruling. **ADA §6(h): raising the price disables auto-renew, so `$10` is
effectively locked for the product's life.** Full reasoning in `MONETIZATION.md` → Pricing.
- **Billing: ⛔ Polar is DELETED — Microsoft Store IAP, Microsoft as merchant of record** (ruling
2026-09-27; teardown in `TASKS/task-48-distribution-msix.md` item 0). **Revenue share 15%,
subscriptions included** — verified from the ADA v8.10 PDF, §6(b)(i); the agreement's own v8.0
changelog says *"85/15 revenue share for non-Game subscriptions"*. ⇒ net **~$8.50/mo**,
**~$340** lifetime. Microsoft handles VAT/GST/sales tax, refunds, chargebacks, the customer
portal, and device deactivation — the strongest argument for the switch. Net receipts are after
tax, so commission is not paid on pass-through tax. Payouts monthly, $50 threshold.
⚠️ **No Polar product, org ID, key prefix, or discount code exists any more** — `d105dfa1-…`,
`c05fb364-…`, `LCYT-`, `LLAMAFOUNDER`/`LLAMA50`, the customer-portal validate endpoint, and the
14-day offline-grace machine are all being deleted. Products are declared in **Partner Center**
instead: one auto-renewing monthly subscription + one non-expiring lifetime IAP.
⛔ A discounted subscriber→lifetime upgrade SKU is **not** approved.
- **Support (creator's model, corrected 2026-09-01):** support = email + GitHub issues — the
once-planned in-app bug-reporter is **out of product** (TASKS.md → closed list). Most queries are
how-tos / feature requests / manual-skimmers. Maintenance cadence = "when I get around to it" with
emergency patches; not a 24/7 service promise. The only license chatter is the paid-user **expiry
reminder — now moot** (perpetual keys never expire, one-time model 2026-09-21); paid users see zero
license UI. TASK 36 item 5 (expiry reminder) is superseded.
reminder — now moot** (superseded twice: keys are moot because the lifetime entitlement never
expires, and the entire license-key system is moot because Store IAP has no keys); paid users see
zero license UI. TASK 36 item 5 (expiry reminder) is struck.
**Monetization awareness (built-in, ungated, free — 2026-09-01; v1 SCOPE per the complete-v1
ruling — build order: capture → report → journey → Alerts):** the app is monetization-aware by