feat(entitlement): pivot to paid app ownership
Check Steam ownership of the paid app with BIsSubscribedApp; keep Debug fake ownership out of Release. Ref: https://partner.steamgames.com/doc/api/ISteamApps#BIsSubscribedApp
This commit is contained in:
+23
-31
@@ -1,40 +1,32 @@
|
||||
# HANDOFF — 2026-11-01 (exe renamed, depot builds, output rule enforced)
|
||||
# HANDOFF — 2026-11-02 (Steam ownership check)
|
||||
|
||||
## State
|
||||
|
||||
- Branch `main`, level with `origin` through `8f79b20`; this unit is local.
|
||||
- **The shipped exe is `LlamaCasty.exe`** (`AssemblyName` renamed; four pack URIs fixed — the docs
|
||||
said three, `KeepBroadcastDialog.xaml:5` was the fourth). Guarded by `AssemblyIdentityTests`.
|
||||
- **`scripts/publish.sh`** stages `artifacts/steam-stage` and refuses to finish if `ffmpeg\`, the
|
||||
licence, privacy or notices file is missing, or test assemblies leaked in. Output 257 MB.
|
||||
- **The output-profile rule is built and enforced**: `Models/OutputProfile.cs` (921,600 px / 30 fps,
|
||||
fail closed) resolved once in `BuildEncoderOptions` — one ffmpeg process, two outputs.
|
||||
`MainViewModel.DeveloperMode` bypasses it in Debug only.
|
||||
- **Distribution is Steam-exclusive** (2026-10-31): free app + paid edition as a Steam **DLC**; the
|
||||
**$10/month** plan sold off-Steam by Polar, *stated, never sold*, in-app. Entitlement is
|
||||
`steamDlcOwned || polarKeyValid`; the app must start without Steam, falling back to free.
|
||||
- **Site live with Steam** (`a9d07ce`); `www.llamacasty.com` 301s to the apex.
|
||||
- `main`; local work unit, not pushed.
|
||||
- Distribution plan: one paid Steam app ($79 announced launch price, then $99) plus its associated
|
||||
free Demo. Same code; no subscription, DLC purchase, or GitHub binary.
|
||||
- `IEntitlement.IsAppOwned` feeds the app-wide `MainViewModel.IsAppOwned` flag. Debug uses a fake
|
||||
owned result; the fake is excluded from Release.
|
||||
- Release ownership uses `BIsSubscribedApp(paidAppId)` and fails closed when the ID or Steam is
|
||||
unavailable. **The paid app ID is not configured yet; the Steamworks application is pending.**
|
||||
- Steam's private-use clause is not, by itself, a proven blocker. EULA wording should expressly
|
||||
allow commercial/monetized streaming; OBS is the relevant Steam software precedent. See
|
||||
`MyMistakes.md` → Steam distribution.
|
||||
|
||||
## Next action
|
||||
|
||||
**Surge, 2026-11-02 → 11-07 — six days, all remaining code.** Day 1 is partly done ahead of time:
|
||||
`IEntitlement` + `SteamEntitlement` (Steamworks.NET, fail-closed on every path) + `FakeEntitlement`,
|
||||
with `HasProOutput` reading the rail. Undo/redo, the rail gear and the EDIT alignment also landed
|
||||
early. Remaining on day 1: greyed tiers, licence UI's four states, system messages, licence ID in
|
||||
About. Days 2–6 in `TASKS.md` → "The surge".
|
||||
Day 1: grey out higher tiers for non-owners and link to the paid Steam page; then the system-message
|
||||
strip. The queued Debug-only test-access rule also needs checking. Keep one integration test per
|
||||
change.
|
||||
|
||||
## Landmines
|
||||
|
||||
- **⛔ `ExcludeFromSingleFile="true"` on the ffmpeg content** — without it the publisher bundles
|
||||
libav\*.dll into the exe and the app ships unable to find ffmpeg. Recipe in `MyMistakes.md`.
|
||||
- **Dev affordances are compiled out, not hidden** — `DeveloperPanel` is removed from the Release
|
||||
build; `Helpers/DevBuild.cs` is the single source for the flag (never `const`).
|
||||
- **Nothing may gate a feature.** The only paid delta is the output profile; `ShowBrandFlash` stays
|
||||
`false` and entitlement must never enable it.
|
||||
- **No checkout inside a Steam build** — the Wallet rule. The monthly is named, never sold, in-app.
|
||||
- **The org access token never ships.** `organization_id` is public; the token is not.
|
||||
- **The site publishes the model, never the numbers**, and never takes payment or links a checkout.
|
||||
- **No self-updater and no version banner**: Steam updates the app.
|
||||
- Pre-existing: the **full test suite hangs** (WASAPI teardown) — per-class runs; `ytLive.Tests`
|
||||
carries 3 xUnit warnings the app-only gate does not see.
|
||||
- Not every hex is a theme colour — `BorderColorPalette`/chat defaults are USER DATA, not tokens.
|
||||
- The Demo has its own App ID. Ownership must check the paid app ID, never the Demo ID or test ID
|
||||
`480`.
|
||||
- No fake ownership code or developer panel in Release.
|
||||
- No Steam checkout in the app; Steam handles purchase and updates.
|
||||
- The paid app ID is not available yet; Release stays fail-closed until it is configured.
|
||||
- `verify.sh` clean app build passes; `EntitlementTests` passes 5/5. Full suite currently has 13–14
|
||||
UI/content failures; connection to this change is unconfirmed, investigate separately.
|
||||
- Bundled FFmpeg must stay outside the single-file exe (`ExcludeFromSingleFile="true"`).
|
||||
- Build with Windows `dotnet.exe`; run tests per class (the whole suite can hang in WASAPI teardown).
|
||||
|
||||
Reference in New Issue
Block a user