Monetization policy locked + dev pause recorded (docs changeset, 2026-08-14): the one paid line becomes an annual subscription — early access $49.99/yr → $99/yr list at GA, grandfather-while-subscribed with lapse → list on renewal (no escalation matrix); free tier unchanged (branding flash is the free tier's billboard + no Alerts, which is the one paid feature); billing NOT locked to itch.io (hunted fact: itch.io has no native subscription billing — candidates Gumroad, whose native affiliate program is the tiebreaker, and Lemon Squeezy); support = in-app bug-report → git issues with a when-I-get-around-to-it cadence + emergency patches. ai.md Monetization section rewritten + stale paid-unlock seams fixed (L115 subscription-entitlement wording, the About hub's tabled billing PremiumUrl seam); TASKS.md gains TASK 23 (Monetization — billing provider decision, unlock mechanism with lapse→flash-returns enforcement, in-app bug-report loop, Unlock Premium seam lighting, Alerts gating, and line-item pointers for the early-access strategy, affiliate/ads phase 2, and the channel revival); HANDOFF.md records the decisions + the development pause (resume streaming = pair-programming dev streams via OBS + The Division 2 under the gramps/GOAT persona, 67 and gaming since 1981, 3D-printing content retired; dogfood switch to ytLlive once TASK 5 lands; resume point = TASK 5). Stale itch.io assertions corrected across comments and indexes (MainViewModel.cs PremiumUrl/IsPremium seams, MainWindow.xaml tooltip, AboutHubTests comment, ViewModels/index.md, TASK 9 out-of-scope note). Build 0 warnings, 196 tests passing

This commit is contained in:
2026-08-14 18:48:42 -07:00
parent f2f6401fef
commit 86fcd868a8
7 changed files with 110 additions and 47 deletions
+47 -2
View File
@@ -115,7 +115,7 @@ Lifecycle: `created → ready → [testing] → live → complete` (transitional
18.**Chat box** — YouTube live chat rendered *on* the stream so viewers read along in-video
19.**Background removal (milestone 2)** — ONNX Runtime + DirectML, MediaPipe Selfie Segmentation — deliberately NOT in this build
20.**Alerts** — Super Chat / membership / subscribe pop-ins; build after the six; **the one paid feature** (see Monetization in `ai.md`)
21.**Logo + richer in-app About (2026-08-13, queued → 2026-08-14 SHIPPED)** — the ytLlive wordmark in the top bar opens the About overlay (already wired); the About overlay is now the **creator hub**: the real logo (the "llama fortnite superman logo" from the creator's vault, copied to `Assets/llama-logo.png` — the creator's own art, no third-party license), plus **creator-hub links** — llama chile shop on YouTube (`MainViewModel.ChannelUrl`), Mastodon (`https://mastodon.llamachile.tube/@gramps`), **Buy me a coffee** (`https://buymeacoffee.com/llamachiley` — live), and **Unlock Premium** (greyed "coming soon" — the itch.io product URL is a tabled seam, `PremiumUrl`, until the account is set up). A **Licenses & legal** button flips the About overlay to an in-app scrolling panel that loads the full `THIRD-PARTY-NOTICES.txt` text (`MainViewModel.ShowLicenses` reads the shipped file from the executable directory on first open; graceful "not found" fallback — **never the OS viewer, everything stays in-app**); "← Back to About" returns. The About overlay is also the in-app home of the notices — the top-bar About button that opened the file in the OS viewer was removed on 2026-08-13 for exactly this reason. Integration test (Good Dog Rule — ONE): `AboutHubTests.About_Opens_InApp_Licensing_Loads_Shipped_Notices` drives the real window + VM, asserting the hub opens, the link URLs are real, the licensing panel loads the shipped notices text (contains "Third-Party Notices" + "LGPL"), and back returns to the hub. 174 tests passing, 0 warnings
21.**Logo + richer in-app About (2026-08-13, queued → 2026-08-14 SHIPPED)** — the ytLlive wordmark in the top bar opens the About overlay (already wired); the About overlay is now the **creator hub**: the real logo (the "llama fortnite superman logo" from the creator's vault, copied to `Assets/llama-logo.png` — the creator's own art, no third-party license), plus **creator-hub links** — llama chile shop on YouTube (`MainViewModel.ChannelUrl`), Mastodon (`https://mastodon.llamachile.tube/@gramps`), **Buy me a coffee** (`https://buymeacoffee.com/llamachiley` — live), and **Unlock Premium** (greyed "coming soon" — the **billing** product URL is a tabled seam, `PremiumUrl`, until TASK 23 picks the subscription provider). A **Licenses & legal** button flips the About overlay to an in-app scrolling panel that loads the full `THIRD-PARTY-NOTICES.txt` text (`MainViewModel.ShowLicenses` reads the shipped file from the executable directory on first open; graceful "not found" fallback — **never the OS viewer, everything stays in-app**); "← Back to About" returns. The About overlay is also the in-app home of the notices — the top-bar About button that opened the file in the OS viewer was removed on 2026-08-13 for exactly this reason. Integration test (Good Dog Rule — ONE): `AboutHubTests.About_Opens_InApp_Licensing_Loads_Shipped_Notices` drives the real window + VM, asserting the hub opens, the link URLs are real, the licensing panel loads the shipped notices text (contains "Third-Party Notices" + "LGPL"), and back returns to the hub. 174 tests passing, 0 warnings
22.**Voice filters on the mic channel (2026-08-13 queued → SHIPPED 2026-08-14 inside TASK 9, the audio milestone)** — the standard four applied to the sound input path (before the meter/encoder mix): **bass boost, treble, noise suppression, compressor** (set decided with the creator 2026-08-13). Noise suppression = a **pure-C# noise gate** (creator chose over RNNoise / a second ffmpeg `afftdn` pipe, 2026-08-14 — KISS). Always-on — no UI knobs; the mic stays the creator's single audio control
### The Minimal Source Set (design decision — do not expand casually)
@@ -554,7 +554,7 @@ the validator → persisted), compositor bar overlay (top/bottom + above-flash),
**Testing (Good Dog Rule — ONE integration test):** `AudioPipelineTests.Mix_WithFiltersDuckAndGain_Lands_On_AudioPipe` — real filter chain + mixer + ducker + `NamedPipeAudioWriter`, fake `IAudioSource`s, test-side `NamedPipeClientStream` reads the bytes and asserts post-filter/post-gain/post-duck mixed stereo (ring buffers pre-filled so the first pipe tick already carries real audio — avoids a start-of-stream silence race). Units: each DSP stage (known sine-in → expected gain), ring buffer wrap/underflow/overwrite, ducker envelope, resampler (down/up/stateful/identity), `FfmpegArgs` pipe+map, schema v9 roundtrip + no-music-row. Existing tests stay green.
**Out of scope (this branch):** IP webcam (video-only when it lands — never an audio input), chat box source (TASK 3 item 18), alt-key crop, credits, background removal, music-off-VOD, itch.io `PremiumUrl` (TASK 21 seam).
**Out of scope (this branch):** IP webcam (video-only when it lands — never an audio input), chat box source (TASK 3 item 18), alt-key crop, credits, background removal, music-off-VOD, `PremiumUrl` (TASK 23 seam).
---
@@ -590,6 +590,51 @@ the validator → persisted), compositor bar overlay (top/bottom + above-flash),
---
## TASK 23 — Monetization: subscription billing + in-app unlock + support (2026-08-14, scoped)
**Goal:** turn the settled monetization policy (see `ai.md` → Monetization) into a paying product line:
annual subscription billing, an in-app unlock seam, and the in-app bug-report → git-issues support loop.
**Decisions already locked (2026-08-14, creator):** one paid line = **annual subscription** (early
access **$49.99/yr** → **$99/yr list at GA**; grandfather-while-subscribed, lapse → list on renewal;
no escalation matrix). Free tier unchanged (branding flash + no Alerts; the flash is the free tier's
billboard — distribution, not compromise). Billing **not locked to itch.io** (hunted fact: itch.io has
no native subscription billing); candidates **Gumroad** (native affiliates = tiebreaker) and **Lemon
Squeezy**. Support = in-app bug-report → git issues; "when I get around to it" cadence + emergency
patches. Unlock outcome: flash removal flips `BrandFlashEnabled` off + **Alerts** on.
### Status: 🔶 Scoped — nothing built; this entry records the plan + decisions
1. ☐ **Billing provider decision** — Gumroad vs Lemon Squeezy (annual subs + license-key verification
APIs; Gumroad's native affiliate program is the tiebreaker if the TASK 23 affiliate line-item matters)
2. ☐ **Unlock mechanism** — license-key entry + online/offline verification + persisted entitlement
(extends `LayoutStore`, schema bump) + renewal/lapse handling (**lapse → branding flash returns** —
the flash is the enforcement and the billboard)
3. ☐ **In-app bug-report → git issues** — a built-in report control that files an issue (title/body/
log attachment) into the creator's git repo; the support loop, per the settled support model
4. ☐ **"Unlock Premium" seam** — the About hub's greyed button (TASK 21; `PremiumUrl` is the tabled
billing URL) lights up and routes to the billing page / unlock dialog
5. ☐ **Alerts gating** — the Super Chat pop-ins (TASK 3 item 18 / minimal source set item 7) are the
one paid feature; subscription state gates them
6. **Line-item pointers (their own big tasks — do NOT start here):**
- ☐ **Early-access strategy** — the 90-day funnel (founder window $49.99 → GA $99), waitlist,
testimonials/QA, clips → Shorts. Separate planning effort.
- ☐ **Affiliate & ads (phase 2)** — own-channel gear affiliates from day one (organic), a
ytLlive referral program gated behind GA + happy users, YPP as the channel's ad revenue, paid
ads deferred.
- ☐ **Channel revival (the prequel to both)** — **resume streaming**: pair-programming dev
streams via **OBS** (ytLlive can't go live yet — private-only + `_rtmpUrlProvider` null) +
**The Division 2** gaming streams under the **"gramps/GOAT"** persona (67, gaming since 1981).
3D-printing content retired (printer hard down, novelty gone). **Dogfood switch** — once TASK 5 +
go-live capability land, stream *with* ytLlive; Division 2 (loud game + voice) is the demo for the
ducking/voice-filter story. The flash billboard + the grandfather promise are the monetization
hooks this line-item feeds.
**Out of scope (TASK 23):** the early-access strategy itself, the affiliate program, channel content
planning — those are separate line-item tasks. TASK 23 owns billing + unlock + support + gating only.
---
## TASK 6 — Layout Persistence (SQLite)
**Goal:** Scenes, sources, and asset bytes survive restarts; assets are always available.