diff --git a/TASKS.md b/TASKS.md index 866fdc7..3d63b5f 100644 --- a/TASKS.md +++ b/TASKS.md @@ -679,7 +679,7 @@ the validator → persisted), compositor bar overlay (top/bottom + above-flash), 3. ☑ **Health monitoring** — poll `liveStreams.list` `healthStatus` + `configurationIssues[]`, surface banner only on warning/error (SHIPPED: `GetStreamHealthAsync(streamId)` 30s while live; pure `StreamHealthReporter.BannerFor` = report-by-exception; banner strip under the top bar, amber warning / dark-red error, via `HealthIssueBanner`/`HealthIssueBackground`; poll failures log-only; ONE integration test `GetStreamHealthAsync_Report_By_Exception_Banner_Only_On_Warning_Or_Error`) 4. ☐ Live chat — poll `liveChat/messages`, render in right panel, support Super Chat + membership badges 5. ☐ Error handling — the YouTube error codes: `errorStreamInactive`, `invalidTransition`, `redundantTransition`, `liveStreamDeletionNotAllowed`, `liveStreamModificationNotAllowed`, `liveBroadcastBindingNotAllowed` -6. ☐ **Visibility picker** — remove temporary "always Private" enforcement (shipped as test-only; now unlocked for v1). User picks Private/Unlisted/Public from the go-live dialog. Trivial: remove the hardcoded override in `YouTubeStreamService.CreateBroadcast` (currently `privacyStatus = "private"` regardless of dialog selection) +6. ❌ **Visibility picker** — DELIBERATE TEST-PHASE LOCK (creator decision 2026-09-01), not open work: "always Private" stays during multi-month real-world testing so breakage VODs never clutter the channel. `recordFromStart`/DVR stay on — Private VODs are invisible review tapes; bulk-delete pre-GA. Unlock = TASK 36 gold-pass item (remove the override in `YouTubeStreamService.CreateBroadcast`, wire the dialog selection). See `ai.md` → YouTube Live API constraints. 7. ☐ **Full broadcast form** — expose all YouTube API-supported fields in the go-live dialog. Core tab: title, description, visibility, made-for-kids, schedule (start + optional end). Advanced tab (expandable, sane defaults): latency (Normal/Low/Ultra-Low), DVR, embed, record-from-start, projection (rectangular/360°), closed captions, auto-start, auto-stop, monitor stream, region restrictions. Monetization via `liveBroadcasts.update` (insert-only on that resource) — separate step after broadcast creation. Remove unsupported `categoryId` (not a `liveBroadcast` field, silently ignored) ### Design decisions (v3) diff --git a/ai.md b/ai.md index a03b3b7..90a0d6e 100644 --- a/ai.md +++ b/ai.md @@ -180,9 +180,9 @@ C# / WPF (.NET 8) following MVVM: - Resolution tiers: 1080p60@8 (default) → 1080p30@8 → 720p60@6 → 720p30@6 → **Vertical 1080p60@8 (9:16, 1080×1920)**. The composition master frame is **always 1920×1080** — a tier is an output rect + target resolution over that master, so source geometry is never rewritten (no rounding drift). 16:9 tiers use the full frame; the vertical tier uses a centered **607×1080** window and the preview dims the cropped side strips at 55% black with an accent outline (semi-crop — the cut area stays visible). A resolution badge in the preview corner shows the active tier. Bottom bar: gear icon far left, stream stats (bitrate/FPS/dropped/duration) centered under preview, resolution dropdown far right. A **tooltip** explains finding upload bandwidth — an in-app speed test was deliberately dropped (unreliable). The future encoder crops the master to the rect and scales to the tier's Width×Height - Crash diagnosis: `AppLog` writes startup checkpoints to `%APPDATA%\ytLlive\startup.log`; `App.xaml.cs` logs `DispatcherUnhandledException`/`AppDomain.UnhandledException`. When WPF won't run from WSL, this log is how you find the failure (it caught the `MenuItemRole.Separator` XAML crash and the ComboBox SelectionBoxItem bug) -### ⚠️ Known issue: screens/layers settings audit needed (2026-08-22) +### ⚠️ Known issue: screens/layers settings audit — RETIRED INTO THE GOLD PASS (2026-08-22, dispositioned 2026-09-01) -The AI hallucinated through multiple commits tonight on background/scene property placement, repeatedly misreading the spec and introducing bugs. Specifically: moved properties to the wrong superclass level, used `new` instead of `override` breaking WPF bindings, removed working code, and added UI elements that weren't spec'd. **All screens/layers settings need a fine-tooth-comb audit** — every screen's Background layer properties, pill toggle persistence, context menu visibility, and the "Add Layer" menu items. Who knows what else got fucked up. Trust nothing the AI touched tonight without manual verification on a live build. +The AI hallucinated through multiple commits that night on background/scene property placement, repeatedly misreading the spec and introducing bugs. Specifically: moved properties to the wrong superclass level, used `new` instead of `override` breaking WPF bindings, removed working code, and added UI elements that weren't spec'd. The audit was never run since. The creator ruled (2026-09-01): it is a **going-gold requirement**, not session debt — the fine-tooth-comb pass (every screen's Background layer properties, pill toggle persistence, context menu visibility, "Add Layer"/"(+)" menu items) is a named checklist item under **TASK 36 (gold pass)** and this landmine is closed here. ### Current limitations / TODOs @@ -851,6 +851,14 @@ crooked. an intermittent full-frame flash can't be cropped and is impractical to edit around on a live feed. **The flash is also the free tier's billboard** — every free stream advertises LlamaCasty to its own viewers; the free tier is distribution, not compromise. + **Escalation model (2026-09-01, creator decision):** the cadence is *obnoxiously* self-promoting — + intervals shorten with use, starting at the 300s cadence and creeping toward a floor (the exact + curve is a build-time design knob). License activation still flips exactly one bit: `IsPremium` → + flash off. Nothing else changes between free and paid, ever. + **Pre-GA posture:** while the app is unreleased the flash renders **in the preview only** and is + never composited onto the live output or local recording — test VODs stay clean (same channel- + protection stance as the visibility lock), and creators can be shown what free looks like without + it ever touching a real broadcast. Flipping the flash live-on is a **TASK 36** unlock item. - **Paid (annual subscription):** branding flash removed (flips `BrandFlashEnabled` off). That's it. No feature gating. Alerts, social bar slots, voice filters, TRAX, recording — everything is free. - **Pricing:** early-access founders rate **$49.99/yr** → **$99/yr list at GA** (v1). **Grandfathering: @@ -925,10 +933,13 @@ These are the hard facts behind every decision. Full list in `TASKS.md`. `enableAutoStart=true`, `enableAutoStop=true`, `enableMonitorStream=false`, `selfDeclaredMadeForKids=false`, `latencyPreference=low`. The encoder starting brings YouTube live. `enableMonitorStream=false` is what lets us skip the testing stage. -- **Visibility picker (TASK 9 item 6)** — the "always Private" enforcement was temporary for testing - during development ("always Private until v1"). For v1, the go-live dialog exposes Private/Unlisted/Public - and `YouTubeStreamService.CreateBroadcast` uses the dialog's selection (not a hardcoded override). - The PRIVATE badge in the top bar still shows when the stream is actually private. +- **Visibility picker (TASK 9 item 6) — DELIBERATE TEST-PHASE LOCK, not drift (2026-09-01).** + The "always Private" enforcement in `YouTubeStreamService.CreateBroadcast` stays while the creator + runs multi-month real-world testing: non-private test streams would clutter the channel with VODs + highlighting where the product breaks. `recordFromStart`/DVR stay ON — Private VODs are invisible + to subscribers and serve as post-mortem review tapes; bulk-delete pre-GA. The unlock is a + deliberate final-pass item in **TASK 36 (gold pass)**, wired with the dialog selection — never + opportunistic. The PRIVATE badge keeps showing when the stream is actually private. - **Full broadcast form (TASK 9 item 7)** — the go-live dialog exposes all YouTube API-supported fields. **Core tab** (always visible): title, description, visibility (Private/Unlisted/Public), made-for-kids, schedule (start + optional end datetime). **Advanced tab** (expandable, sane defaults): latency