Files

6.2 KiB
Raw Permalink Blame History

HANDOFF — session state

Current operational state, read right after TASKS.md. Trust this file as the truth of what is in flight — do not re-derive from git/fs unless it points at a problem. Conventions: schema.md. Rewrite this file at session end, compaction, or any interruption.

Session state (last updated: 2026-08-13)

  • Branch: main, in sync with origin/main.

  • This session (TASK 7 — UI polish batch, gramps's 6-point review):

    1. Scenes list cleaned: the per-row edit/trash/visibility icons and the inline rename TextBox are gone. Scenes are pure selection rows; IsHidden stays persisted and still dims a hidden row to 45%. Removed dead surface: EditSceneCommand/RemoveSceneCommand/ToggleSceneVisibilityCommand + BeginEditScene/ToggleSceneVisibility/RemoveScene handlers + Scene.IsEditing.
    2. Sources list upgraded: each row now has edit + visibility eye + trash. New EditElementCommand (SceneElement.IsEditing → inline rename TextBox, Enter/Esc/ lost-focus commits) and ToggleElementVisibilityCommand (flips SceneElement.IsVisible); the eye style now binds IsVisible and hidden rows dim to 45%.
    3. Duplicate naming: shared NextSourceName(scene, baseName)Image, Image2, Image3… (no space), next free number derived from actual names so deletions never collide. Used by both AddSource and AddReusedImage.
    4. Social bar: MaxWidth=200 + CharacterEllipsis removed from BOTH SocialBarRenderer.cs and the preview DataTemplate — full validated handle renders.
    5. Panels: left 220 / right 300 fixed widths are deliberate — panels never re-layout on resize; the preview absorbs it. No change.
    6. Focus-loss capture lag: recorded in ai.md as a known OS limit (DWM/WGC throttling when unfocused + GPU readback contention + the _framePending / DispatcherPriority.Render gates). NOT an in-app throttle; deferred by user decision.
  • Test infra change: the two real-WPF-App tests (round-clip + new source-naming) now share RealAppHost — a dedicated STA thread owning the single App — via the RealApp serial collection. WPF allows exactly one Application per AppDomain; never add a test that calls new App() directly again — marshal onto RealAppHost instead.

  • Uncommitted: MainWindow.xaml + MainWindow.xaml.cs (rows), ViewModels/MainViewModel.cs (commands + naming), Models/SceneElement.cs (+IsEditing), Models/Scene.cs (IsEditing), Services/Compositor/SocialBarRenderer.cs (no truncation), ytLive.Tests/SourceNamingTests.cs (new), ytLive.Tests/RealAppCollection.cs (new), ytLive.Tests/RoundClipInteractionTests.cs (now uses the shared host), TASKS.md (TASK 7 ), ai.md, ViewModels/index.md, HANDOFF.

  • Verified: build 0 warnings / 0 errors; 170/170 tests pass (169 + the naming test).

  • Landmines:

    • Never add another test that constructs new App() — use RealAppHost.Run(...).
    • Never set a local Canvas.SetTop on the social bar — a local value permanently overrides {Binding SocialBarTop} (the ClearValue lesson from 5.5).
    • AudioMixer meter Push is unconditional by design now: OnMicSample/ OnLoopbackSample compute the level first, then raise the event — a ?.Invoke(meter.Push(...)) short-circuit skipped the meter update when nothing was subscribed (found by RestartMic_ResetsLevel, fixed).
    • MicConnected comes from the source Started event, raised right after StartRecording() succeeds — tests must MarkStarted() the fake source before asserting connection state.
    • The mic dot is red until a resource connects (see contract below) — green only after Started, yellow on Failed.
    • Zero mic devices at startup = red dot AND the mixer is never started, so loopback + the game bar can't run either (no capture at all) — acceptable.
    • The game detector is polled on the UI thread via a 250ms DispatcherTimer; OnGameAudioPollTick wraps Poll() in try/catch + AppLog.
    • The pump reads the active scene on a background thread while the UI can still edit it — a concurrent-mutation exception is contained (logged + Failed + the pump stops), not a crash.
    • StopAsync must stop the encoder (closes stdin) before awaiting the pump loop — closing stdin unblocks a write stuck on pipe backpressure; the reverse order deadlocks.
    • Tests never instantiate MainViewModel directly except via a real MainWindow on the RealAppHost STA thread (round-clip + naming), which never go live.
    • Sandbox can't reach outbound HTTPS — HttpSocialValidator stub-handler tests only, never the real instance.
  • Mic status contract (creator's rule, verified — do NOT "fix"): the status dot is red until a mic resource is actually connected. MicStatus starts NotConnected (red); it goes green ONLY when the mixer's MicConnected fires, which comes strictly from the mic source's Started event raised after StartRecording() succeeds. Zero devices at startup → stays red and the mixer is never started; capture failure → yellow.

  • Next step: commit + push this TASK 7 batch (one commit). Then the remaining TASK 4 requirement is ship step 7 — one-click go live + private-only enforcement (honor the dialog's chosen visibility / enforce privacyStatus = "private"; also fixes the REC sign's private state — see round-3 note). Also queued: task 21 (logo + About hub), task 22 (voice filters). Nothing else queued — do not expand the task queue on your own. Optional, not queued: rewriting the healed entry's ProfileUrl to https://mastodon.llamachile.tube/@gramps (user must say the word).

  • Secret/DB/port facts live: OAuth client id/secret in Helpers/OAuthCredentials.cs; OAuth session token in Helpers/TokenStore.cs (DPAPI → %APPDATA%\ytLlive\ytLlive.auth); layout DB %APPDATA%\ytLlive\ytLlive.db (schema v8; SocialEntry.Software column is a column-presence migration like the others, no version bump); OAuth callback http://localhost:8765/oauth2/callback; crash log %APPDATA%\ytLlive\startup.log.