A dead encoder used to run the whole stop path, so a one-second blip ended the broadcast. Now a dropped push is relaunched against the same ingest while the broadcast is still alive. - `Services/StreamRetryPolicy.cs` — immediate, +1 s, +2 s, +3 s. Minimum waits on purpose (creator ruling): YouTube's grace is short, so every second not pushing is grace spent. - `Services/StreamRecovery.cs` — the loop, with the audio pipe recreated before every attempt (its server is single-instance and unusable after the old client dies, so a naive relaunch fails on a missing input). After a push comes up it asks the API whether the broadcast survived: "complete" ends recovery as `BroadcastComplete` instead of showing a live sign over a dead stream; an API hiccup counts as recovered rather than ending a healthy session. - `FramePump.EncoderFailed` — a dead push is recoverable; a compositor fault still goes through `Failed` and ends the session, because retrying it would loop. - `MainViewModel.Recovery.cs` — wires the steps, reports each episode into the left panel alert stack (one row per episode, updated in place, log range painted), and cancels on Stop. - Alert stack polish: a rule and a gap now separate the stack from the scene layers (they read as one list before), and the licence indicator uses the creator's wording — `STEAM ID NOT PRESENT` / `Steam ID Limit: 30fps` / `Click for More Info`, becoming `STEAM ID PRESENT` / `60fps` with a close control once owned. Tests: `StreamRecoveryTests` (schedule, recover on attempt 2 with the pipe restarted each time, complete-broadcast honesty, unknown liveness, give-up, cancel, audio-restart fault), `FramePumpTests` now pin that process death raises `EncoderFailed` and not `Failed`. FAST gate: 538 passed (one documented pre-existing audio failure), 0 warnings.
12 KiB
TASKS — the active queue
One line per live item; the detail lives in
TASKS/task-*.md. Done work is inTASKS/archive.md(2026-10-29 snapshot of the old catalogue). Retired decisions are indocs/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 |
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 | 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 commercial3·17 ✅ Text layer — content, font family/size/weight/style, colour, alignment, drag/resize, persisted (done 2026-11-04) task-0321 ✅ 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-2164 ✅ 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-surface55·2–3 ☐ Disk hygiene: delete %TEMP%alert clips on close + sweep at startup; low-disk guard before REC (slice 1 shipped)task-5540·A/C/D ☐ App Settings: active-camera picker; persist output resolution + surface transition defaults + confirm-before-End; accent consolidation task-403·20 ☐ RewardEvent persistence: canonical RewardEventstable +superChatEvents.list30-day backfill (the session report and journey read it)task-0332 🔶 Stream resilience: fragmented MP4 + blip retry done 2026-11-05; remaining — measured grace + RECONNECTING countdown → one-click Back on air → ingest pre-flight task-3233 ☐ Bandwidth auto step-down: pure policy over dropped-frame rate, one-way within a broadcast task-3334 ☐ Scheduled streams (Text-drawer version) task-3435 ☐ Scene-linked audio task-3537 ☐ 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 onEditingActive, cleared on layout load. Property edits not yet in the stackui-surface39·2 ☐ YPP slice 2: Analytics scopes, watch-hours/Shorts velocity + ETA task-3949 ❌ 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-4950 ☐ One-button publish of the local recording (resumable upload) task-5054 🔶 Freemium: EULA + privacy shipped; free Steam Demo and paid app use one codebase; paid app ID and Steam Demo setup still pending task-54— 🔶 Steam ownership — BIsSubscribedApp(paidAppId)+ Debug fake + app-wideIsAppOwned; paid app ID awaits Steamworkscommercial— ❌ Polar subscription path — retired 2026-11-01 with the one-price model. Design kept in decisions.md, not builtdecisions— ✅ OutputProfile gate — resolver + EncoderOptionswiring (Models/OutputProfile.cs, one ffmpeg/two outputs, dev override); higher tiers followIsAppOwnedcommercial— ✅ 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 — publishoutput +steam_api64.dll, paid app and associated Demo setup, depot,steamcmdupload, store pages + assetsDistribution.md— ☐ Training-video series — capture the first 8–10 recurring questions as videos on @llamacasty; each is documentation, channel content and monetization at onceMARCOM → support→content loop 9·5 ☐ Webcam identity key reconciliation task-0914 🔶 Creator feedback batch — branch 3+ task-14— ❌ Retired: StreamConfigdefaults are unused; encoder output comes from the selected quality tierModels/index.md36 ☐ Gold pass — the v1 gate, always the last unit (see 1.0 gates) task-3648 ⏸ Distribution & packaging — route settled 2026-10-31 (winget/portable first; Steam + Store parked). Build steps: Distribution.md; starts after the entitlement seamtask-4810 ❌ 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 writtentask-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.csis already#if DEBUG; re-prove it on a Release build. - Release engineering —
scripts/publish.shdone (self-contained win-x64,ffmpeg\guarded, no test artifacts),LlamaCasty.exeassembly rename done, full license texts besideTHIRD-PARTY-NOTICES.txt(TASK 4 req 9). Outstanding: Debug-onlyInternalsVisibleTo. - Gold pass (TASK 36): the screens/layers audit, native-Windows verification, and the branding-flash decision.