Scene strip tile artwork + on-air indicator (creator ruling 2026-10-10). Top-bar tiles now carry their own art: each canonical scene's tile is a per-scene CRT-styled image stored in the internal DB (Scene.ThumbnailAssetId - additive migration, seeded at heal from the creator's five Downloads JPGs via SceneThumbnailSeedPaths), and the preview pane keeps rendering the scene's ORIGINAL background - never the tiles. One shared on-air image (Gemini 4zajyl...jpg) replaces the staged scene's tile and follows the scene swap ('the on-air screen jumps around the top bar as the user swaps scenes'): stored as an Asset BLOB tracked by the OnAirImageAssetId Setting (EnsureOnAirImage, same contract as the alert clip) with MainViewModel.OnAirSeedPath override; RefreshSnapshotsAsync shows it for the staged scene, otherwise thumbnail-or-background art, and a staged Live with no on-air art still falls back to the green placeholder (minis never render live captures). Removed the 6px #22c55e rectangle in PreviewPane's backdrop ('green outline around the preview screen' that surfaced when a scene had no background) - the outer PreviewGlow red border is the real live signal. Doubled the scene-tile labels (FontSize 10 -> 20). Fixed a real bug this surfaced: Save()'s Asset pruner only kept Source/alert-clip rows, so the first save would have DELETED the seeded tile + on-air assets - the keep-set now includes Scene.ThumbnailAssetId and the OnAirImageAssetId Setting. New Settings/Load/Save migrations + SceneThumbnailTests (4 tests: seeded tile in strip, preview keeps original bg, Live-staged tile, no-seed fallback, on-air swap + persistence). 427 pass, 0 build warnings. (Unit: strip tiles + on-air)

This commit is contained in:
2026-10-10 13:27:26 -07:00
parent 06f88f4142
commit 8e1d6f44db
12 changed files with 576 additions and 61 deletions
+50 -48
View File
@@ -1,65 +1,71 @@
# HANDOFF — 2026-10-10 (scene-order F-key fix + desktop-lock fix; both LOCAL, uncommitted)
# HANDOFF — 2026-10-10 (strip tile artwork + on-air tile unit; uncommitted)
## At a glance
- **Branch** main (no feature branch). Pushed through `5685c5d`; 18 commits local, **not pushed**
- **Branch** main (no feature branch). Pushed through `5685c5d`; 19 commits local, **not pushed**
(push at the creator's call).
- Desktop-lock fix committed as `63bf844`; **scene-order fix below is uncommitted**.
- Scene-order unit committed `06f88f4`; desktop-lock committed `63bf844`. The **strip tile
artwork unit below is uncommitted**.
## Branch
- main (no feature branch). Pushed through `5685c5d` (TRAX toggle); everything after is local,
**not pushed** (push at the creator's call).
## New work unit (this handoff) — READY TO VERIFY, do not commit yet
- **Fix** for the scene-strip / F-key ordering report — `ViewModels/MainViewModel.Scenes.cs` new
`ReorderScenesToCanonical()` (canonical F1-F5 order at load, renamed scenes after; next save
re-stamps SortOrder) called from `MainViewModel.cs:LoadLayout`; `ytLive.Tests/SceneOrderTests.cs`
(new, seeds a Chat-before-BRB DB and asserts order + F1-F5 labels + persisted SortOrder).
See `bugs.md` entry 2026-10-10. Scope-locked files: `ViewModels/MainViewModel.Scenes.cs`,
`ViewModels/MainViewModel.cs` (1 call line), `ytLive.Tests/SceneOrderTests.cs`, `bugs.md`,
`HANDOFF.md`.
- Full suite **423 passed / 0 failed / 0 warnings**. Root cause was the creator's own DB (Chat
SortOrder 2, BRB 3); the fix heals it on next launch regardless of DB history.
- **To commit later (this unit only):** the files listed above. Then the working tree is back to
just the creator's pinned-chat unit (NOT mine to commit).
## New work unit (this handoff) — VERIFIED, ready to commit
Strip tile artwork + on-air indicator (creator ruling 2026-10-10). Three sub-parts:
## Desktop-lock unit (COMMITTED 63bf844 — desktop "lock" fix)
- `ShowActivated = !FullscreenGameRunningNow` + `FullScreenDetectorOverride` seam + `DesktopLockTests`
(3 tests). Committed 2026-10-10. Creator still to verify in-game (launch while an
exclusive-fullscreen game owns the foreground — the game must stay live).
1. **Per-scene CRT tile art** — each canonical scene's top-bar tile is its OWN image stored in the
internal DB (`Scene.ThumbnailAssetId`, additive migration, seeded at heal from the creator's five
Downloads JPGs via `SceneThumbnailSeedPaths`). The preview pane keeps rendering the scene's original
background — never the tile. `Save()` Asset prune now keeps `Scene.ThumbnailAssetId` rows
(this was a real bug: the first save would have deleted the seeded tiles).
2. **On-air image** — one shared image (`Gemini_Generated_Image_4zajyl4zajyl4zaj.jpg`) that REPLACES the
staged scene's tile ("the on-air screen jumps around the top bar as the creator swaps scenes").
Stored as an Asset BLOB tracked by the `OnAirImageAssetId` Setting (`EnsureOnAirImage`, same contract
as the alert clip; prune keep-set extended). Seed path override: `MainViewModel.OnAirSeedPath`.
`RefreshSnapshotsAsync`: staged scene → on-air art; unstaged → own thumbnail or background art;
staged Live without on-air art → green placeholder (unchanged invariant: minis never render captures).
3. **Preview + labels polish** — removed the 6px `#22c55e` rectangle in `BackdropLayer`
(`Controls/PreviewPane.xaml`) — the ONLY live signal is the outer `PreviewGlow` red border
(`MainViewModel.Streaming.cs`, transparent otherwise); the redundant rect was only visible when a
scene had no background ("green outline around the preview screen" the creator saw). Scene-tile
labels doubled: `Controls/SceneThumbnailStrip.xaml` FontSize 10 → 20.
- Files: `Models/Scene.cs`, `Services/LayoutStore.{Migrations,Load,Save,Settings}.cs`,
`ViewModels/MainViewModel.Background.cs`, `Controls/PreviewPane.xaml` (rect removed),
`Controls/SceneThumbnailStrip.xaml` (label), `ytLive.Tests/SceneThumbnailTests.cs` (4 tests).
- Full suite **427 passed / 0 failed / 0 warnings** (one run flaked on the known
`RealMouseDrag_…PersistsTheReorder` env test — needs an idle desktop — and passed on re-run;
nothing in this unit touches layer reorder). Existing 3 tile tests stub seed paths + `OnAirSeedPath`
so the suite is hermetic; the new 4th test covers the on-air swap + persistence.
- **To commit later (this unit only):** the files above. Then the working tree is back to just the
creator's pinned-chat unit (NOT mine to commit).
## Desktop-lock unit (COMMITTED 63bf844)
- `ShowActivated = !FullscreenGameRunningNow` + `FullScreenDetectorOverride` seam + `DesktopLockTests`.
Creator still to verify in-game (launch while an exclusive-fullscreen game owns the foreground).
## Scene-order unit (COMMITTED 06f88f4)
- `ReorderScenesToCanonical()` + `SceneOrderTests`. The creator's DB (Chat SortOrder 2, BRB 3) heals to
canonical F1-F5 order at load; next save re-stamps SortOrder.
## Dirty files — current reality (2026-10-10)
- **NOT mine — do NOT commit:** the creator's in-flight "pinned chat" unit (`Models/YouTube.cs`,
`ViewModels/MainViewModel.Chat.cs`, untracked `Helpers/RelayCommandGeneric.cs`, and **its hunks in
`Controls/LeftPanel.xaml`**), plus the creator's untracked `Assets/llamacasty*` art.
- ⚠️ Pre-commit (scene-order unit): `scripts/verify.sh` runs `scripts/scope-check.sh` against ALL
working-tree changes — the not-mine pinned-chat + art files WILL flag. Pass them as declared-known.
## What just happened — TASK 51 quality pass (committed 2026-10-09)
1. **Jitter fix (`3057069`) — `MaskSmoother`**: per-session blend 0.75×new + 0.25×previous at the
ONE worker (`CameraManager.RunEffectWorker` → `session.Smoother.Smooth(TrySegment(source))`).
State on `CameraSession`, NOT the segmenter (shared app-wide, contract-pinned to raw output). Null
resets history; first frame passes through; never aliases caller's array; ping-pong buffers (no
per-frame LOH alloc). Weights: OBS obs-backgroundremoval 0.85 default, Jitsi 0.7/0.3 best
(0.5/0.5 smears). Test `Temporal_Smoothing_Damps_Segmentation_Jitter_Across_Frames`: x=6 → first
255 / smoothed 58 / raw-unsmoothed 0. ⚠️ Gotcha: worker guards a re-queued identical frame
reference — pump frame2 as a NEW instance.
2. **Blur "heavy" fix (this commit) — quadratic radius**: `BlurRadius(strength)` = 1 + 5·s²,
`MaxBlurRadius` 12→6 small px (≈ 24 full px max). Default 0.5 = 2 small px (was 6 under the old
linear curve) — ~3× lighter spread. Rationale: StreamFX defaults Box blur Size to 5, author stops
downscaled blurs ~8px. Test `Blur_default_strength_is_gentle_and_full_strength_is_strong` pins the
mapping and step-edge behaviour (reach 9px default vs 26px max). Point-source probes vanish below
the 0.5 rounding (3 box passes dilute a spike) — use a step edge, not a spike, to measure blur.
- ⚠️ Pre-commit: `scripts/verify.sh` runs `scripts/scope-check.sh` against ALL working-tree changes —
the not-mine pinned-chat + art files WILL flag. Pass them as declared-known.
## Next step
- Creator launches the app: the scene strip must show Starting/Live/BRB/Chat/Ending in order with
F1-F5 correct (the creator's DB had Chat before BRB; the load-time reorder heals it and the next
save re-stamps SortOrder). Also still to verify when convenient: the desktop-lock fix while an
exclusive-fullscreen game owns the foreground. Then I can commit the scene-order unit.
- Commit this unit (files listed above; gate already green at 427/427, 0 warnings). Then the creator
launches the app on the real DB: the five CRT tiles seed from `C:\Users\gramp\Downloads\Gemini_…`,
the staged scene's tile shows the on-air image, the preview shows the scene's real background with no
green frame, and the tile labels are legible (FontSize 20). Push is still at the creator's call.
## Tests
- Full suite **423 passed / 0 failed / 0 skipped / 0 warnings** (2026-10-10; includes the new
`SceneOrderTests`). Known env flakes remain `Mix_HonorsProviderGains…` (fails while system audio
plays) and `RealMouseDrag…` (needs an idle desktop).
- Full suite **427 passed / 0 failed / 0 skipped / 0 warnings** (2026-10-10). Known env flakes:
`Mix_HonorsProviderGains…` (fails while system audio plays), `RealMouseDrag…` (needs an idle desktop),
`Round_Clip_Corner…` (grab/geometry under active mouse). The verify gate whitelists only the latter two —
`RealMouseDrag…` failing mid-session needs one re-run when the desktop idles.
## Also still open
- **Vertical-format regression (STALE, not fixed):** 1080p60 vertical selection no longer shrinks the
@@ -68,9 +74,5 @@
`MainViewModel.Streaming.cs` `ApplyStreamQuality` from `SelectedQuality` (binding + ctor only,
`new("Vertical 1080p60", 60, 8.0, 1080, 1920)`), `DimRects` in `MainViewModel.cs:91-94`. Root cause
unknown — paused.
- **Vertical recording file closed:** the recording itself is 1080×1920 60fps correctly; the
"whitespace" was the app's preview UI, not the file. Audio loudness (`ebur128`) for the private video
was never run and the thread is closed unless the user reopens it.
- Blur-heaviness = fixed (above). Yellow-border regression = stale thread.
- ⛔ Sudo password rotation pending (user; then update both password lines in `CREDENTIALS.md`).
- TASK 56 secret scan before `gramps/LlamaCasty` goes public. TASK 55 disk hygiene queued.