Files
gramps e7cded6879 docs: pricing ruled — $10/mo + $400 lifetime, and the 15% fee is verified for subscriptions
Reconcile the pending doc edits with the creator's actual ruling, and close the
revenue-share question that was blocking the monthly price.

Verified from the App Developer Agreement v8.10 PDF itself (downloaded and
text-extracted, not a search excerpt). Section 6(b) has only three tiers:
6(b)(i) 15% for Apps and their In-App Products *not listed in* 6(b)(iii);
6(b)(ii) 12% Games-only; 6(b)(iii) 30% for Xbox console apps/games, Xbox
non-subscription IAP, and Windows 8/Phone 8. LlamaCasty is a Windows PC App,
so 6(b)(i) governs BOTH tiers -- there is no subscription surcharge. The
agreement's own changelog (v8.0, Oct 26 2017) states it outright: "implement
the 85/15 revenue share for non-Game subscriptions."

  => $10/mo nets $8.50 (~$102/yr); $400 lifetime nets $340.

Also confirmed: the 15% applies after VAT/GST (Net Receipts definition),
payouts are monthly above a $50 threshold, and no better small-indie rate
exists in the standard terms.

Creator ruling recorded: $10/mo subscription or $400 lifetime, no annual, no
.99. This supersedes the 2026-09-21 one-time $29 -> $49 model.

Two obligations ADA 6(h) attaches to the recurring tier, recorded because they
change its risk profile and are the reason lifetime is the hedge: we must
fulfil the subscription for the entire period as marketed (on breach Microsoft
may refund the full amount plus taxes in its sole discretion), and raising the
price disables auto-renew -- so $10 is effectively locked for the product's life.

Stale facts fixed in the same change rather than appended:
- research-store-certification.md: IARC was 11.11.1/11.11.2 in one table and
  10.11.1 in another; corrected to 10.11.x.
- research-store-certification.md: policy 10.8.1/10.8.2 still asserted "Polar
  explicitly permitted" and "tick the third-party purchase box". Void now that
  Store IAP is the route and Polar is being torn down.
- task-48: the working YouTube demo account (10.3.1) was accidentally dropped
  from the certification list during the Store-IAP edit. Restored -- a reviewer
  cannot use the app without one.
- MyMistakes.md: the verified-fact-vs-decided-outcome lesson now closes its
  loop (the creator did rule the way the research pointed), and records the
  over-correction that followed.

Docs-only. No code, no build, no tests.
2026-09-27 15:02:25 -07:00

155 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HANDOFF — current state
**Branch:** `main` (pre-1.0, no feature branches — creator ruling 2026-08-24).
**Last pushed:** `b2036a3`. This unit (reconciling the pricing ruling + verifying the Store
revenue share) is **docs-only** — no code touched, no build, no tests run.
## ✅ DECIDED 2026-09-27 — pricing: `$10/mo` subscription, or `$400` lifetime, **no annual**
**Creator's ruling, verbatim: *"Let's just go with $10 monthly recurring subscription for option
A and, for option B, a lifetime sub for $400. No annual."* ⛔ **No `.99` prices** (earlier
ruling: *"Let's stop with the x.99 stuff - I find that irritating. Just say: ten bucks a
month"*). This **supersedes** the 2026-09-21 one-time `$29 → $49` model and the old `$99/yr`
sub. No feature gating: free gets everything, the branding flash is the only paid delta.
**✅ Store revenue share VERIFIED — 15%, and subscriptions are NOT penalised.** Read from the
ADA v8.10 PDF itself (downloaded, text-extracted — not a search excerpt). §6(b)(i) charges
**15%** on "any Apps (and any In-App Products in such Apps) that are **not listed in Section
6(b)(iii)**"; 12% is Games-only; 30% covers Xbox console apps/games, Xbox non-subscription
IAP, and Windows 8/Phone 8. LlamaCasty is a Windows PC App — not a Game, not Xbox, not Win8 —
so **6(b)(i) governs both tiers.** The agreement's own changelog (**v8.0, Oct 26 2017**) says
it outright: *"implement the **85/15 revenue share for non-Game subscriptions**."*
⇒ **`$10/mo` nets `$8.50/mo` (~$102/yr). `$400` lifetime nets `$340`.** Also confirmed: the
15% applies *after* VAT/GST (Net Receipts), payouts are monthly above a **$50** threshold, and
no better small-indie rate was found in the standard terms.
**⛔ Two obligations §6(h) attaches to the recurring tier** (why lifetime is the hedge):
(1) we must **fulfil the subscription for the entire period as marketed**, and on breach
Microsoft may refund the customer *"the full amount, plus taxes... in Microsoft's sole
discretion"*; (2) **raising the price disables auto-renew** — so `$10` is effectively locked
for the product's life absent Microsoft's price-change process.
**⏳ Still open:** the `$50` subscriber→lifetime upgrade-discount SKU was discussed and is
**not approved** — do not declare it. Individual vs Company Partner Center account still
unanswered (get it right before enrolling).
## ✅ DECIDED 2026-09-27 — distribution is the Microsoft Store: MSIX + 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 and their reasons are in
`TASKS/research-store-certification.md` §3 — **read that before reopening the question, not
before re-deriving it.**
**The big consequence: the whole licensing backend is deleted.** `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` comes from the **Store
entitlement** instead of an HTTP call — which also deletes the entire "network flaky → app
thinks I'm expired" bug class. **Velopack, the update URL and the DO droplet go too.**
**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*.
**⛔ The old "still open: the price" note is retired — the price is settled, see the top of
this file.** The old "~$69 floor" and "don't break the launch-price promise" notes refer to
the old Polar storefront and are **not** current.
### The first code unit: bundle ffmpeg (TASK 48 item 1)
Two real defects the research surfaced — **neither is fixed yet**, this was a docs unit:
1. **⛔ `FfmpegLocator` downloads an unsigned exe from GitHub and runs it.** Store policy
**10.2.2** (dynamic code inclusion) verbatim, *and* the root cause of the 2026-09-01
failure — the pin aged out of BtbN's 14-day retention and the download **404'd on the
creator's first real recording attempt**. `FfmpegLocator.cs:30-35` records the incident but
still reads like a design choice. **Fix: bundle it.** Also deletes the startup network
dependency.
2. **⛔ `Distribution.md:318` recommended a $400+/yr EV certificate for a SmartScreen bypass
Microsoft removed in March 2024.** Fixed last commit — had it shipped, it would have cost
$400+/yr to buy what $150 buys. Now moot anyway (MSIX is signed by Microsoft), but the
lesson in `MyMistakes.md` stands: a policy citation is a claim about **scope**, not just
text.
### ⛔ Two invariants that break silently if touched
- **Full trust, or recording breaks.** `DefaultRecordFolder()` writes to Downloads/MyVideos;
that passes through unvirtualized **only** at `mediumIL`. Flip the manifest to
`appContainer` and output vanishes with no error. A comment is owed there **when the
manifest lands** (TASK 48 item 6) — not before.
- **Chat is rendered, never stored.** That non-persistence half is the load-bearing part of
the 11.12 certification answer. No chat history, moderation log, analytics, or crash payload
may be added without re-arguing 11.12 first.
## Landmines
- **Stale fact inside `TASKS.md` (left alone, flagged here per the Scope Lock).** The "1.0 gates"
section asserts "**TASK 36 is now shipped**", but the catalog row 36 reads **☐ Queued** and
`task-36-gold-pass.md` still shows items 1–6 unchecked. The line most likely means *item 2*
(branding flash goes live) shipped at `9761b1d`. **Needs a one-line fix, not a code change** —
flagging rather than fixing because it is not this unit's job.
- **A stale `ytLive.exe` (PID 2544) locked `bin/.../ytLive.exe`** and broke `dotnet run` with
MSB3027. Killed. **If the build fails to copy `ytLive.exe`, check for a running instance first.**
- **`LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder` is flaky by
environment** (needs an interactive desktop session; 2 fail / 1 pass in isolation). **Run the
suite with ytLive CLOSED.** Not a regression.
- **`RealAppHost.RunAsync` exists for a reason** — a frame-pump test MUST `await` inside it. A
blocking wait occupies the one shared STA thread and **hangs the whole suite with no output.**
Always background a `vstest` run and poll the log; a foreground piped `vstest` returns nothing
in this shell even on success.
- **`GlobalHotkeys`: two instances registering the SAME global hotkey** — Windows refuses the
second. Left alone deliberately.
- **MSIX writes under a real package identity are unverified.** The docs say full trust passes
user-profile writes through, but confirm on a real packaged build before trusting it with
recordings (TASK 48 item 6).
## Test state
**367/367 as of `938c5b3`.** Not re-run for this unit — docs only, no code touched.
## Uncommitted / untracked
- `MARCOM.md`, `MONETIZATION.md` — both edited (privacy-copy guard; the Polar-obsolete banner
and the re-opened-price note) and both **gitignored by design** (confidential business
files, `.gitignore:10-11`). They stay local, as intended. Same for `CREDENTIALS.md` —
**never commit those.**
## Next
1. **Bundle ffmpeg (TASK 48 item 1)** — unblocked, first code unit, fixes a real user-facing
failure and clears the one hard certification gate.
2. **Settle the price** — one-time vs subscription, and the number. Then declare the IAP
products in Partner Center. **Blocks:** the Store listing, and the `OverlayHost.xaml` copy.
3. **The packaging project + `Package.appxmanifest`** (TASK 48 items 2–3) — full trust,
`webcam`/`microphone`, English only; Velopack deleted. Add the `DefaultRecordFolder()`
comment in the same unit.
4. **Polar teardown** (TASK 48 item 0) — `PolarLicenseService`, `PolarLicense`,
`MainViewModel.License.cs`, the `OverlayHost.xaml` string, the `csproj`/`App.xaml.cs`
Velopack sites. `IsPremium` ← Store entitlement. **Do this as one unit** — a half-torn-down
licensing path is worse than either end state.
5. **Verify the Store revenue-share rate** — before step 2, not after.
6. **Vertical recording verification** — the compositor tier is proven by
`Render_VerticalTier_Outputs_1080x1920_From_The_Center_Crop`; the *record* path has never
been run. `FramePump.cs:645` flags off-size tiers as a known follow-up.
7. **WACK + certification notes + the privacy policy** (TASK 48 items 4–5) — the policy must
state camera/mic is OS-gated, nothing is retained, and nothing is fetched at runtime.
8. **Post-session efficacy report** — roll up `CurrentHealth` (dropped frames, duration, health
message) when a stream or recording ends. `SessionTeardownTests` is the natural home.
9. **Measure whether the Windows camera toggle gates DShow** — gates all privacy-forward copy
(`MARCOM.md` guard). Not a certification risk; a trust risk.
10. **TASK 36:212 stale "shipped" line** — one-line fix, needs a hand.
**Dropped from the list** because the ruling made them moot: multi-instance's ffmpeg tools-dir
race (item 1 makes it disappear), `scripts/publish.sh` + the `LlamaCasty.exe` rename (the Store
packages and delivers — *revisit only if we ever ship outside the Store*), and the alert-gating
copy (the wrong string dies with the Polar teardown in step 4).
**Everything else in the v1 queue:** stream resilience (32), bandwidth step-down (33), scheduled
streams (34), scene-linked audio (35), the master limiter (12), text source (3.16), reward
events (3.20), the media picker (21), webcam identity (9.5), settings units A/C/D (40), and the
defaults split (37). Ship-checklist items live in `TASKS.md` -> "1.0 gates".