Files
LlamaCasty/TASKS.md
T
gramps 6d1c982e26 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.
2026-11-01 08:13:25 -08:00

10 KiB
Raw Blame History

TASKS — the active queue

One line per live item; the detail lives in TASKS/task-*.md. Done work is in TASKS/archive.md (2026-10-29 snapshot of the old catalogue). Retired decisions are in docs/ai/decisions.md. Markers: ☐ queued · 🔶 in progress · ⏳ blocked · ⏸ deferred · ❌ retired.

The surge — six days, all remaining coding (2026-11-02 → 11-07)

Every open coding row is assigned below. No later phase, no "after launch" list. Target is 6–8 units a day (above the measured 3–5 baseline — that is the point of a surge). If a day overruns, the smallest item moves to the next day; a launch blocker never moves.

Rules, every unit, no exceptions: one Good Dog test · clean build 0 warnings · per-class tests green · ./scripts/verify.sh on the declared scope · commit with the doc fact it falsifies corrected. No new scope mid-week; anything discovered goes on a list for day 6.

Day Units Done when
1 · Mon — licensing IEntitlement seam + Steam DLC impl + fake · HasProOutput on the seam · greyed tier entries · licence UI four states + 7/1/0-day notices + "monthly is on the website, not Steam" · licence ID in About · system messages (SystemMessage/MessageCenter strip) · Debug-only InternalsVisibleTo Fake drives all four states; Steam-less launch is the free profile; About shows the licence ID
2 · Tue — release blockers Visibility picker + UpdateBroadcast · StreamConfig defaults · TASK 53 output contract (geometry test per tier, 9:16 e2e) · 9·5 webcam identity key · Move transitions (per-layer carry-across-scenes) A public broadcast starts and changes while live; every tier pinned by a test
3 · Wed — resilience TASK 32: blip retry → measured grace → amber RECONNECTING → one-click Back on air → fragmented MP4 → ingest pre-flight · 33 bandwidth step-down Killing the network mid-broadcast recovers without ending it
4 · Thu — content & media 3·17 Text layer · 21 media acquisition wiring + file picker + loop/volume UI · 49 chat profanity filter · 34 scheduled streams Text layer renders/persists; media file plays, loops, has volume; scheduled stream created
5 · Fri — data & settings 3·20 RewardEvent persistence + superChatEvents.list backfill · 39·2 YPP slice 2 · 37 defaults-vs-current split · 35 scene-linked audio · 40·A/C/D settings round · 55·2–3 disk hygiene Session report reads persisted events; defaults can be reverted; temp clips cleaned
6 · Sat — finish & prove 50 publish recording · preview undo (Ctrl+Z) · 14 creator feedback batch · 36 gold pass · full sweep: clean build, whole per-class suite, publish.sh artifact, EULA/privacy/notices in the artifact · commit + push Gold pass list empty; artifact stages; suite green; pushed

Day 6 is the only polish day. No polish passes before it — a surge dies on cosmetic passes taken in the middle.

Next up (after the surge slice)

TASK 3·17 — the Text layer is scheduled in the surge (day 4). Placeholder detail retained for the unit itself: 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. Text content, font family/size/weight/style, colour, alignment, drag/resize, persisted; renderer mirrors Services/ChatBoxRenderer.cs.

Queue

Every open coding row here is assigned to a surge day above. Rows still marked ☐ on 2026-11-07 are a failure of the plan, not a scheduling note.

Task Status Scope Detail
3·17 ☐ NEXT Text layer — content, font family/size/weight/style, colour, alignment, drag/resize, persisted task-03
21 🔶 Media source: acquisition wiring + file picker + loop/volume UI (decoder, manager, pacing, loop all shipped — no AcquireAsync caller exists) task-21
— ☐ Transitions Move: per-layer carry-across-scenes flag, per-scene placement, fixed z band ui-surface
55·2–3 ☐ Disk hygiene: delete %TEMP% alert clips on close + sweep at startup; low-disk guard before REC (slice 1 shipped) task-55
40·A/C/D ☐ App Settings: active-camera picker; persist output resolution + surface transition defaults + confirm-before-End; accent consolidation task-40
3·20 ☐ RewardEvent persistence: canonical RewardEvents table + superChatEvents.list 30-day backfill (the session report and journey read it) task-03
32 ☐ Stream resilience: blip retry → measured grace + amber "RECONNECTING" → one-click Back on air → fragmented MP4 → ingest pre-flight task-32
33 ☐ Bandwidth auto step-down: pure policy over dropped-frame rate, one-way within a broadcast task-33
34 ☐ Scheduled streams (Text-drawer version) task-34
35 ☐ Scene-linked audio task-35
37 ☐ Defaults vs current layout split (build-id); enables one-click revert to defaults task-37
— ✅ Preview undo (Ctrl+Z / Ctrl+Shift+Z) — done 2026-11-01: Models/PreviewHistory + MainViewModel.Preview, one step per gesture, gated on EditingActive, cleared on layout load. Property edits not yet in the stack ui-surface
39·2 ☐ YPP slice 2: Analytics scopes, watch-hours/Shorts velocity + ETA task-39
49 ☐ Chat profanity filter: local, opt-in, non-persistent, user-supplied word list task-49
50 ☐ One-button publish of the local recording (resumable upload) task-50
53 ☐ Output-format contract: pin every tier with a geometry test, prove 9:16 end-to-end, recorded file matches output task-53
54 🔶 Freemium: EULA + privacy shipped; no licence path built — needs the entitlement seam, the output-profile cap and the licence UI below; site copy still says free forever task-54
— 🔶 Steamworks entitlement — IEntitlement + SteamEntitlement (Steamworks.NET) + fake done; needs the DLC app id from Steamworks, then the ownership path is live commercial
— ☐ Entitlement seam — Polar customer-portal path for the monthly (org ID public, org token never in the app), conditions: {channel_id}, 7–14 day lease, --activate CLI. No claim page, no server commercial
— 🔶 OutputProfile gate — resolver + EncoderOptions wiring done (Models/OutputProfile.cs, one ffmpeg/two outputs, dev override); remaining: greyed tier entries in the dropdown, entitlement wiring commercial
— ☐ Licence UI — four states, 7/1/0-day notices, "monthly is on the website, not Steam" line, portal link, licence ID in About commercial
— ☐ System messages — SystemMessage + MessageCenter, strip above the dock, dedupe by key, short history, never composited ui-surface
— ☐ Steam packaging — rename, publish output + steam_api64.dll, depot, steamcmd upload, store page + assets, DLC app Distribution.md
— ☐ Training-video series — capture the first 8–10 recurring questions as videos on @llamacasty; each is documentation, channel content and monetization at once MARCOM → support→content loop
9·5 ☐ Webcam identity key reconciliation task-09
14 🔶 Creator feedback batch — branch 3+ task-14
— ☐ Small: StreamConfig defaults (TargetBitrate=6000, 1920x1080) are stale — the dropdown drives StreamHealth this line
36 ☐ Gold pass — the v1 gate, always the last unit (see 1.0 gates) task-36
48 ⏸ Distribution & packaging — route settled 2026-10-31 (winget/portable first; Steam + Store parked). Build steps: Distribution.md; starts after the entitlement seam task-48
10 ❌ Retired 2026-10-08; superseded by the TASK 54 rows above — the Polar design it described is rebuilt as a lease (commercial.md), not revived as written task-10

Pending the creator's hands (not programming)

  • ✅ App Settings grouping + right-click gear — reported working 2026-10-29.
  • ✅ Transition picker/durations, Wipe, preview + program transitions — reported working 2026-10-29.
  • ✅ Brand logo layer — reported working 2026-10-29.
  • ⏳ Vertical-tier camera check (Live tile inside the band, Chat rect-only) — outstanding.
  • ⏳ Webcam cadence: a Release take in the failing geometry (vertical tier first) blocks Units 1–2. No fix until a reading names the stage.

1.0 gates (before the first shipped build)

  • Visibility picker — replace the always-Private lock, hide the TEST button, and wire UpdateBroadcast in the same unit (it is the only code that can change a broadcast's privacy).
  • Kill the dev multi-instance affordance — Helpers/InstanceProfile.cs is already #if DEBUG; re-prove it on a Release build.
  • Release engineering — scripts/publish.sh done (self-contained win-x64, ffmpeg\ guarded, no test artifacts), LlamaCasty.exe assembly rename done, full license texts beside THIRD-PARTY-NOTICES.txt (TASK 4 req 9). Outstanding: Debug-only InternalsVisibleTo.
  • Gold pass (TASK 36): the screens/layers audit, native-Windows verification, and the branding-flash decision.

Research

research-youtube-api.md · research-store-certification.md