diff --git a/HANDOFF.md b/HANDOFF.md index f89d10d..9edcffc 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -18,11 +18,13 @@ ## Next action -1. **Greyed tier entries + entitlement wiring** — the rule is in place and tested - (`Models/OutputProfile.cs`); the dropdown still shows every tier as equally available, and - `HasProOutput` is `IsPremium || DeveloperMode` with no Steam DLC path yet. -2. Then the **entitlement seam** (`IEntitlement`: Steam DLC via `steam_api64.dll`, Polar lease). -3. Steamworks: App ID waits on identity verification; then depot, store page and the DLC app. +**Tomorrow, day 1 of the surge: the entitlement seam.** `IEntitlement` (`HasDlc`, `IsValid`), the +Steam DLC implementation on `Steamworks.NET` behind it, a fake for tests, and `HasProOutput` +consuming the interface instead of `IsPremium` directly. The Steam-less path must fall back to the +free profile. Then the licence UI's four states against the fake. + +Full week in `TASKS.md` → "Surge week — coding only": day 2 greyed tiers, day 3 visibility picker, +days 3–4 stream resilience, day 4 output contract, day 5 gold pass. ## Landmines diff --git a/TASKS.md b/TASKS.md index c582933..0cd51a2 100644 --- a/TASKS.md +++ b/TASKS.md @@ -5,27 +5,40 @@ > decisions are in [`docs/ai/decisions.md`](docs/ai/decisions.md). > Markers: ☐ queued · 🔶 in progress · ⏳ blocked · ⏸ deferred · ❌ retired. -## Next up +## Surge week — coding only (starts 2026-11-02) -**The surge week (3 days, in this order).** Not every row below — this slice only, because it is -what the first public release is waiting on. Day 1 (artifact shape) is **done**: the exe is -`LlamaCasty.exe` and `scripts/publish.sh` stages the depot folder. +**Non-coding is parked** (Steam identity verification, store page, depot upload, marketing) — it is +waiting on Valve, not on us. The week is code, tests, debugging, polish. Sized at 3–5 units a day; +~50 units remain overall, so this plan is the five days, not the whole queue. -1. **OutputProfile gate** — ≤921,600 px / ≤30 fps for the stream **and** the recorder, greyed tier - entries, plus the TASK 53 geometry tests that pin every tier. -2. Then the **entitlement seam** (`IEntitlement`, Steam DLC path behind a fake, Polar path) and the - licence UI. +**Definition of done for every unit:** clean build 0 warnings · per-class tests green · +`./scripts/verify.sh` with the declared scope · commit with the doc fact it falsifies, corrected. -Detail: [`commercial.md`](docs/ai/commercial.md) → Output profile / Entitlement; -[`Distribution.md`](Distribution.md). After that: the visibility picker (a hard prerequisite for -any *public* build). +| Day | Unit | Done when | +|---|---|---| +| **1** | **Entitlement seam** — `IEntitlement` (`HasDlc`, `IsValid`), Steam DLC impl on `Steamworks.NET` behind the interface, fake for tests, `HasProOutput` consumes it; app starts without Steam → free | Fake proves the resolution; real impl compiles; Steam-less launch shows free | +| **1–2** | **Licence UI** — four states, upgrade path per state, 7/1/0-day notices, "monthly is on the website, not Steam" line, licence ID in About | Each state renders from the fake; no modal, never blocks Start | +| **2** | **Greyed tier entries** — dropdown marks the four Pro tiers, keeps them clickable, routes to the upgrade path | Free user sees 720p30 available and the rest annotated | +| **3** | **Visibility picker + `UpdateBroadcast`** — replace the forced-Private lock, hide TEST | A public broadcast can be started and changed while live | +| **3–4** | **TASK 32 stream resilience** — blip retry → measured grace → amber RECONNECTING → one-click Back on air → fragmented MP4 → ingest pre-flight | A killed network recovers without ending the broadcast | +| **4** | **TASK 53 output contract** — geometry test per tier, 9:16 end-to-end, recorded file matches output | Every tier pinned by a test; the cap cannot drift | +| **5** | **TASK 36 gold pass** — screens/layers audit on real Windows, native verification, branding-flash decision | The audit list is empty | -**TASK 3·17 — the Text layer** stays the first product row after the surge. The `TextOverlay` source -type exists as a placeholder and nothing else does: `AddSource` creates it 0×0, all four compositor -paths `continue` past it, `FramePump`'s hash skips it, it is not draggable, and it has no -text/font/colour properties or persistence. The unit: text content, font family/size/weight/style, -colour, alignment, drag/resize, persisted; renderer mirrors `Services/ChatBoxRenderer.cs`. One Good -Dog test. +**Week 2 candidates, in order:** 3·17 Text layer · 21 media wiring · 55 disk hygiene · +40·A/C/D settings · preview undo · 9·5 webcam identity · `StreamConfig` defaults · +3·20 reward persistence · 33 bandwidth step-down · 49 profanity filter · 50 publish recording. + +**Explicitly after launch (complete-v1 ruling risks the date):** 34 scheduled streams · 35 +scene audio · 37 defaults split · 39·2 YPP slice 2 · 14 feedback batch — each is a week-apiece item +and none blocks a public build. + +## Next up (after the surge slice) + +**TASK 3·17 — the Text layer.** The `TextOverlay` source type exists as a placeholder and nothing +else does: `AddSource` creates it 0×0, all four compositor paths `continue` past it, `FramePump`'s +hash skips it, it is not draggable, and it has no text/font/colour properties or persistence. +The unit: text content, font family/size/weight/style, colour, alignment, drag/resize, persisted; +renderer mirrors `Services/ChatBoxRenderer.cs`. One Good Dog test. ## Queue