feat(entitlement): IEntitlement seam — Steam DLC answers, everything fails closed

The first half of surge day 1. One question, "may this session emit Pro output?", with
one method on the interface so nothing downstream knows which rail proved it.

SteamEntitlement reads the lifetime SKU the way Valve intends: SteamAPI.Init() then
SteamApps.BIsDlcInstalled(dlcAppId). Four different failure paths all resolve to the
free tier rather than to Pro or to a crash — no DLC id configured, no Steam client,
steam_api64.dll missing (a throw on first touch), and simply not owned. A copied folder
run without Steam is the common case, not an exceptional one.

NotConfigured() is the shipping default until Steamworks creates the DLC app; it answers
false without ever touching the native library, so today's builds behave exactly as they
did before this commit.

HasProOutput is now IsPremium || DeveloperMode || rail, with an internal EntitlementOverride
test seam (internal, because a public setter here is a licence bypass). Four tests: no id
reads false, no client reads false without throwing, the fake reports what a test sets, and
the view model takes its answer from the rail.

Steamworks.NET 2024.8.0 added; the native DLL still comes from scripts/steam-sdk.sh, so the
csproj change is three lines and no formatting churn.
This commit is contained in:
2026-11-01 08:13:25 -08:00
parent 279eb08dea
commit 6d1c982e26
10 changed files with 226 additions and 13 deletions
+5 -5
View File
@@ -17,11 +17,11 @@
## Next action
**Surge, 2026-11-02 → 11-07 — six days, all remaining code.** Undo/redo, the rail gear and the
EDIT alignment landed early on 11-01, so day 6 has room. Day 1 unchanged: licensing —
`IEntitlement` + Steam DLC + fake, `HasProOutput` on the seam, greyed tiers, licence UI's four
states, system messages, licence ID in About. Days 2–6 in `TASKS.md` → "The surge".
No scope beyond that list. No polish before day 6.
**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".
## Landmines