Files
ytLlive/HANDOFF.md
T

4.4 KiB

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. The game audio bar + mic status dot + always-on capture work is uncommitted (see list below). The last committed+pushed baseline is ea250c0 (social bar click-toggle).

  • This session (audio UX follow-up): per the creator's requests —

    1. The MIC label is now a button with a status dot (Models/MicStatus: green = capturing, yellow = requested mic problem, red = no device).
    2. Mic capture runs for the app's lifetime (started at startup via StartMicCaptureAsync, disposed in Shutdown; BeginGoLive/StopStream no longer start/stop the mixer) so both meters preview live.
    3. A game audio bar (desktop/game — meter + mute + volume, mirror of the mic bar) sits centered beneath the preview and appears only while a full-screen game is producing sound (decision: fullscreen + loopback sound; silence never hides an active bar — the creator's final rule). Show after ~500ms of fullscreen+sound, hide ~1s after leaving fullscreen.
  • Uncommitted files: MainWindow.xaml/.cs, ViewModels/MainViewModel.cs, Services/Audio/{IAudioSource,WasapiMicAudioSource,WasapiLoopbackAudioSource,AudioMixer}.cs, new Models/MicStatus.cs, new Services/{IGameAudioDetector,GameAudioHysteresis,GameAudioDetector}.cs, ytLive.Tests/AudioMixerTests.cs, new GameAudioHysteresisTests.cs + GameAudioDetectorTests.cs, memory docs (TASKS.md, ai.md, Services/index.md, ViewModels/index.md, Models/index.md, HANDOFF).

  • Verified: build 0 warnings, 0 errors; 167 tests passing (full suite, after the final rebuild).

  • Landmines:

    • 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.
    • 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 the round-clip integration test (a real MainWindow), which never goes live — keep it that way.
    • Sandbox can't reach outbound HTTPS — HttpSocialValidator stub-handler tests only, never the real instance.
  • Next step: commit + push the audio UX follow-up (the whole uncommitted set above in one commit). Then TASK 4 ship step 6 — health stats: bind FramePump.HealthUpdated (bitrate/FPS/duration) into the bottom bar. 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.