# HANDOFF — current state **Branch:** `main` (pre-1.0, no feature branches). **Last pushed:** `7f14ffb`. **This session's work is COMMITTED LOCALLY, NOT PUSHED** — two commits ahead of `origin/main`. Push only when the creator says so. ## Two work units landed this session ### 1. Branding flash is now composited into the OUTPUT (TASK 36 shipped) It used to be a WPF `BrandFlashLayer` TextBlock in the preview at 25% opacity on a 300s timer — a credit the creator could see and **no viewer ever could**. Now one rendered `VideoFrame` goes to **both** the frame pump and the preview, so they cannot drift: - `Services/Compositor/BrandFlashPresenter.cs` (new) — neon raster (white core + feathered red/blue halo, channels split opposite), 2s envelope, random on-canvas placement per presentation, licence gate re-checked on every read. - `ViewModels/MainViewModel.BrandFlash.cs` (new) — `BrandFlashFrame()` for the pump + `PublishBrandFlashPreview()` for the pane. - `FramePump` gained `brandFlash:` → the existing per-frame `flashFrame` slot, and mixes it into the C4 cache signature. `SceneCompositor.Overlay` is now `internal` for the shortcut path. - `PreviewPane.xaml`: `BrandFlashLayer` → `BrandFlashElement` (bound to the published frame). - `BrandFlashEnabled` is derived `!IsPremium` and no longer assignable. Spec met: 500ms in / 1000ms hold / 500ms out, first credit ~5s after go-live then every `rand(30s)+30s`, single unwrapped line, random spot every time, fully on canvas. ### 2. Dev-only: two instances side by side `Helpers/InstanceProfile.cs` (new). Set `YTLIVE_INSTANCE=` and that process gets a private `%APPDATA%\ytLlive\instances//` root for the **layout DB, auth file, startup.log and the WebView2 user data folder**. Chromium locks that folder exclusively — without this the second instance does not start at all. Recording folder and the ffmpeg `tools` cache stay shared on purpose; global hotkeys stay un-namespaced. **Usage:** `$env:YTLIVE_INSTANCE=2; dotnet run` The entire implementation is inside `#if DEBUG`. Release compiles to `DataRoot => DefaultRoot` + `WebViewDataFolder => null`; the call sites are unconditional so Release cannot drift. ## Bugs found and fixed along the way - **Pre-existing, not mine:** `FramePump`'s **fully-static shortcut** stretched the cached bake and returned it, silently discarding **every per-frame overlay** — the social bar and the alert ticker were already lost there, not just the flash. Now composites overlays onto a copy before stretching. - **Cadence bug caught by my own test:** the interval was an absolute deadline, not a period, so gaps collapsed (6.7s / 3.5s / 2.8s instead of 30–60s). Fixed. - `BrandFlashPresenter` recycles one 8MB master buffer and **must** stamp `VideoFrame.Epoch` per read, or the paste cache freezes the credit. It does. ## Test state — VERIFIED - **357 total, 356 pass.** 18 new facts (10 brand flash, 8 instance isolation). - The one failure is `LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder`, and it is **flaky by environment, not a regression** — 2 fail / 1 pass in isolation. Its own doc comment: "Requires an interactive desktop session: if the window is covered or the session is locked, the pointer no-ops and the drag never lands." The symptom matches exactly (order unchanged). **Run the suite with ytLive CLOSED** (see `MyMistakes.md` 2026-08 era note). - `RealAppHost.RunAsync` was added for this: a frame-pump test MUST `await` inside it. A blocking wait in `RealAppHost.Run` occupies the one shared STA thread and hangs the whole suite with no output. **Always background a `vstest` run and poll the log** — foreground piped `vstest` returns nothing in this shell even on success. ## Landmines - A stale `ytLive.exe` (PID 2544) locked `bin/.../ytLive.exe` and broke `dotnet run` with MSB3027. Killed. **If the build fails to copy `ytLive.exe`, check for a running instance first.** - `GlobalHotkeys`: two instances registering the SAME global hotkey — Windows refuses the second. Left alone deliberately. - `OverlayHost.xaml` says Polar unlocks alerts too; alerts are not gated. Unresolved, queued. ## Next 1. Push the two commits when the creator asks. 2. Test-console chat UX (queued): don't clear the chat window, 20px right padding on the pull-out input, Enter inserts a newline. 3. Decide the alert-gating copy question above. 4. Ship-checklist items live in `TASKS.md` → "1.0 gates".