Files
LlamaCasty/TASKS.md
T
gramps a1d861608f feat(ypp): the three eligibility bars, with dated thresholds (TASK 39·2)
YouTube moves the goalposts, so the app stops modelling them as its own truth and shows progress against
a threshold table that carries the date it was read.

- `Models/YppProgress.cs` — pure: three metrics, per-criterion met, and `MeetsPublishedRule`, which
  encodes the real shape of the rule (subscribers AND either view route). The drawer says "x of 3 criteria
  met — YouTube reviews eligibility" and spells out the either/or, so "2 of 3" can't be misread.
- `Services/YouTubeAnalyticsService.cs` — the two numbers only Analytics publishes: long-form watch hours
  (trailing 12 months, `creatorContentType==video`) and Shorts-feed views (90 days, `==shorts`). No rows
  means NO DATA, not zero.
- **Thresholds are data with a publication date** (`YppThresholds.AsOfUtc`, shown in the drawer) and a
  test fails once that reading is more than 180 days old. The 2027-02-01 doubling (4,000h → 8,000h,
  10M → 20M Shorts views) resolves from the date, not from an edit.
- **No Analytics scope → no invented numbers:** the drawer explains the missing consent instead of drawing
  two empty bars as zero. Money stays behind 3·20's "Show monetary metrics" toggle.
- Fan-funding tier (500 subs) demoted to a single muted line, since the three bars are the ad-revenue path.

Tests: `YppProgressTests` — either/or eligibility, subscribers alone insufficient, Shorts as a qualifying
route, bars clamp at 100%, the doubling date, the staleness guard, Analytics parsing (no rows = no data),
and compact value formatting. FAST gate: 567 passed, 0 failed, 0 warnings.
2026-11-05 16:41:09 -08:00

12 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 Paid-app ownership check (BIsSubscribedApp) + Debug fake + app-wide IsAppOwned · greyed tier entries · About conversion copy + llamacasty.com link · current-launch Logs tab (replaces the separate system-message strip) · Debug-only InternalsVisibleTo A locked tier opens About without changing the selected free tier or leaving the app; the site opens only from its link
2 · Tue — release blockers Visibility flow (creator-selected at release; development/test stays Private) · OutputProfile entitlement: 30 fps free / 60 fps paid regardless of resolution · StreamConfig defaults retired (no production call sites) · TASK 53 (vertical resolution check ✅; remaining output contract open) · 9·5 webcam identity key · Move transitions (per-layer carry-across-scenes) Visibility is selectable at creation and live-editable; the 30/60-fps gate is tested; remaining Day 2 items stay queued
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 ✅ (picker, loop, lifecycle) · 49 chat profanity filter · 34 scheduled streams Text layer renders/persists; media file plays, loops; 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)

Day 4 remainder: TASK 49 (chat profanity filter) then TASK 34 (scheduled streams — its two research flags must be cited first). Day 3's resilience row (TASK 32/33) is still outstanding and is a launch blocker; the smallest slice is 32·4 (fragmented MP4 on the record block).

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
53 ✅ Output-format contract — six size/FPS modes, vertical YouTube playback, and recordings visually accepted task-53
— ✅ Output entitlement code: free at 30 fps / paid at 60 fps regardless of resolution; Steam App ID is still pending commercial
3·17 ✅ Text layer — content, font family/size/weight/style, colour, alignment, drag/resize, persisted (done 2026-11-04) task-03
21 ✅ Media source: video file added from the (+) menu decodes, composites, plays its soundtrack, loops, and stops with its last reference (done 2026-11-05) task-21
64 ✅ Green/Blue Screen — detect + key from the decode pipe, offer on add, Amount/Softness/Fringe, opt-in auto-apply, alert clips included, persisted (done 2026-11-05) task-64
— ☐ 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 ✅ Session report — derived from superChatEvents.list on demand, not persisted (YouTube is the authority; no ledger). Per-currency totals, money off by default (done 2026-11-05) task-03
32 🔶 Stream resilience: fragmented MP4 + blip retry + poll-driven RECONNECTING + ingest pre-flight done 2026-11-05 (no countdown — YouTube's cutoff is not a constant); remaining — one-click Back on air 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 — three eligibility bars (subs / watch hours / Shorts views) from Analytics, dated thresholds with a staleness test, "x of 3 criteria met" (done 2026-11-05) task-39
49 ❌ Chat profanity filter — retired 2026-11-05: YouTube owns moderation (blocked words + hold for review run before the API). Replaced by not rendering YouTube's moderation markers (tombstones / no-display events) task-49
50 ☐ One-button publish of the local recording (resumable upload) task-50
54 🔶 Freemium: EULA + privacy shipped; one codebase for free Demo + paid app. Blocked on Valve: identity verification pending, tax review up to 30 business days; app IDs, store page and build review all follow task-54
— 🔶 Steam ownership — BIsSubscribedApp(paidAppId) + Debug fake + app-wide IsAppOwned; paid app ID awaits Steamworks commercial
— ❌ Polar subscription path — retired 2026-11-01 with the one-price model. Design kept in decisions.md, not built decisions
— ✅ OutputProfile gate — resolver + EncoderOptions wiring (Models/OutputProfile.cs, one ffmpeg/two outputs, dev override); higher tiers follow IsAppOwned commercial
— ✅ Demo conversion UI — owned users get higher tiers; non-owners see greyed tiers, and selecting one opens About with conversion copy and an explicit llamacasty.com link. No browser opens until the link is clicked commercial
— ✅ System-message strip replaced by Logs tab — current launch's newest 500 raw AppLog entries, newest-first; no prior-launch import or logging-policy changes ui-surface
— ☐ Steam packaging — publish output + steam_api64.dll, paid app and associated Demo setup, depot, steamcmd upload, store pages + assets 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
— ❌ Retired: StreamConfig defaults are unused; encoder output comes from the selected quality tier Models/index.md
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.

Creator-requested follow-ups (park for Day 6)

  • Group controls under This PC and YouTube.
  • ON-AIR opens a preflight using the saved visibility default and an explicit Start Broadcast — [scope] action.
  • Persistent Help icon immediately left of Edit opens the creator-triggered, app-only 1-2-3 first-broadcast guide. Keep copy top-aligned and high-contrast; never composite the guide into broadcast output.
  • Add YouTube category selection; send tags through the video API; support thumbnail upload.
  • Add tooltips to settings tabs and make Logs wrapping effective.

1.0 gates (before the first shipped build)

  • Release visibility flow — default to Private; let the creator choose Private/Unlisted/Public in the ON-AIR preflight and change it live through UpdateBroadcast; keep development/test runs forced Private. Hide the separate TEST button as already decided for v1.
  • 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