# HANDOFF — 2026-09-12 (transparency: ROOT CAUSE FOUND + FIXED, awaiting the verify take) ## Branch / Commit State `main` HEAD lands THIS WORK UNIT: the compositor alpha fix (see ✅ below) + its ONE integration test + memory updates (`MyMistakes.md`, `ai.md`, `HANDOFF.md`). Ahead of origin by ~22 commits. **NOT pushing** — user ruling: no push until web-overlay transparency AND audio-silence are addressed. Nothing uncommitted at end of session. ## ✅ HONEST STATUS — THE TRANSPARENCY BUG IS IDENTIFIED **Root cause found by reading the unread code path to the end (the handoff's live suspect, now convicted):** `SceneCompositor.BlitContentRaw` (SceneCompositor.cs, partial-alpha `else if (sa > 0)` branch) applied the OPAQUE-dst source-over blend onto the paste-cache raster's TRANSPARENT base: `dst = (src*sa + dst*inv)/255` with dst black → color premultiplied by sa, then `dst[+3] = 255`. A 50%-alpha widget pixel became darkened color + FULL alpha; at paste time `BlendRowOpaque` saw alpha 255 → straight copy → the scene behind was overwritten by darkened ink. Transparent margins (alpha 0) and opaque content (alpha 255) survived, which is why every take showed a box while the dumps (raw capture) and the preview (raw WriteableBitmap) stayed correct. The CSS-wipe fixes (`b4bba4b`/`0f72c53`) were red herrings — they treated the PAGE as the villain, but the capture was transparent from the start (the 15:51 dumps already proved it). **The fix (committed):** `BlitContentRaw` gained `transparentDst=false`; the raster call passes `true` and writes straight color + straight alpha so the paste rows (`BlendRowOpaque`/`BlendRowWeighted`) do the real source-over onto the opaque master. The two blend rows were verified correct all along (HANDOFF accepted facts held); the divergence was the sampler feeding them. Master paths are bit-identical (`transparentDst` defaults false). **Verification:** clean build 0 warnings (app + tests); `SceneCompositorTests` + `SceneGraphTests` + `FramePumpTests` + `ChatOverlayLayerCacheTests` = 22 pass, the ONE failure is the documented pre-existing `Composite_FullScene_MasterPixels` pixel (1380,700) (reproduces with the fix stashed — see ai.md slice 9). The new `PasteCache_SemiTransparentLayer_RevealsBackdrop_NotOpaqueInk` test FAILS on the old code (exact signature: `pixel (16,16): expected rgb(127,0,128), got rgb(0,0,128)`) and PASSES on the fix — non-vacuous, proven both ways. ## NEXT STEP — ONE take (verify, no further analysis) The Good Dog Rule is satisfied (ONE integration test shipped with the fix). Record the Live scene with the widget animating, pre-record ~35s so the 30s re-arm dump fires mid-take, then read the verdict: - Element rect shows the scene backdrop behind the widget art (no black box/void, no darkened edge ring) → **transparency CLOSED, push gate #1 clears**. - If anything persists, the fix's own test contract is the diagnostic: a translucent pixel must read as scene-through-src, never inked — bring the take. ## Other threads (paused) - **Audio silence** — `f3d578c` has per-5s `Audio live:` telemetry; next take with desktop audio ACTIVE names the stage. Push gate #2. - **Webcam missing** — "MJPG negotiation refused (being used by another process)". Queued. - **Web capture speed** — ~10-14Hz effective, user satisfied. Revisit only on request. - **Layer order** — dragging an element over another does not persist `SortOrder`; user explicitly asked it not be buried. Queued after transparency. - **Known backfills when queued work resumes:** `Composite_FullScene_MasterPixels` pixel (1380,700) cyan-vs-magenta (pre-existing, recorded in ai.md slice 9); vertical-tier `BilinearScale` fresh allocation per frame. ## Landmines - testhost shares startup.log with the app — filter by time. - `taskkill //F //IM ytLive.exe` before rebuilds; re-run if `MSB3021` copy-lock. - Build/tests: `/mnt/c/Program Files/dotnet/dotnet.exe build …` / vstest. 0 warnings rule. FULL-suite vstest can hang (WASAPI teardown, pre-existing) — per-class filters are the norm (`--TestCaseFilter:"FullyQualifiedName~…"`). - Probing: `/mnt/c/Program Files/Krita (x64)/bin/ffmpeg.exe` / `ffprobe.exe` — Windows exes take Windows-style paths (do NOT re-download Linux ffmpeg — user aborted that). - Evidence artifacts (keep): `%TEMP%\ytLive-web-8d7234ec-…-w1..5.png` (15:51), recordings `ty-20260910-12\51|1534|1551-*.mp4`, decoded frames at `/mnt/c/Users/gramp/AppData/Local/Temp/w151.raw`. - The full transparency story lives in `MyMistakes.md` → "SPIN GUARD → RESOLVED" (now including the 2026-09-12 RESOLVED entry). GREP IT FIRST. Do not re-derive a fourth time.