Files
LlamaCasty/HANDOFF.md
T

3.8 KiB

HANDOFF — 2026-09-20 (ON-AIR armable signed-out shipped + pushed; Good Dog ONE-test ruling)

Branch / Commit State

main HEAD = 0c55645 — feat(pills): ON-AIR armable signed-out; Start face reads "Sign In" while armed signed-out (Good Dog 2026-09-20 ruling) — PUSHED to origin/main (5a1993b..0c55645, non-force). Working tree clean (all 6 units of the change committed).

This is a continuation of the 2026-09-18 drag-reorder + 2026-09-20 radio-exclusive-pill work: the ON-AIR setter could only light while IsConnected, so a signed-out creator found a greyed pill = dead end. The ruling ships the armable signed-out pill.

✅ What shipped this session (commit 0c55645, pushed)

  • ON-AIR pill is intent, not account reality — OnAirPillOn setter is armable signed-out (greyed/disabled-until-IsConnected gate REMOVED; a pill that could not light offline was the dead end the guard existed to forbid). REC-OR-live radio exclusivity is untouched — arming one clears the other; the radio constraint lives at the pills.
  • Start button face is reality-aware: PrimaryStartButtonLabel = "Start" while IsConnected || !OnAirPillOn, else "Sign In" when an ON-AIR pill is armed signed-out. Clicking Start while the ON-AIR pill is armed signed-out routes to sign-in, not a dead-end go-live (no dead ends — creator ruling; see ai.md §Streaming pills).
  • One Good Dog test (ytLive.Tests/PillRadioTests.cs): PillRadioTests.Arming_One_Output_ Pill_Clears_The_Other (radio-exclusive) + the signed-out armable-pill headless test (RealAppHost + temp DB, no browser).
  • ai.md updated in the SAME commit: tooltip wording + the armable-signed-out ruling (2026-09-20) recorded; stale "greyed/disabled until IsConnected" fact replaced.

Deferred / queued (recorded in TASKS.md, NOT folded into this change)

  • TASK 37 — defaults vs current layout split: DB holds static brandable default layout; the current layout carries the build-id and only loads when it matches BuildStamp.Id — enables one-click revert to factory defaults. Files: TASKS/task-37-defaults-vs-current.md.
  • Manual take on webcam-between-sources order (cross-type z-order fix 94e114b already committed/pushed): relaunch, live view, drag Web Resource-0 below the webcam, restart, expect it pinned. Closes the bug with the builder before any further streaming work.
  • Build-id-on-exit demand: still queued for a later slice (do not fold in).

Critical working rules (failure cap)

  • Good Dog = ONE integration test per change. Do not pile up multiple tests for one guard.
  • Scope lock: declare the exact file list BEFORE editing; run scripts/scope-check.sh with the declared list before commit. No "while I'm here" edits.
  • Run from WSL always uses the Windows dotnet host (/mnt/c/Program Files/dotnet/dotnet.exe) with quoted paths — a path containing a space left unquoted was the #1 tool-spin cause this session. Test filter runs go through dotnet vstest <dll> --filter … (Windows DLL path), NOT dotnet test (WSL re-downloads the windowsdesktop packs + double-restores).
  • Never type the username in paths. Canonical root is $(pwd). Byte-verify every edit anchor (node fs on path.join(R, p)) — the phantom-tree reads wasted this whole session.
  • ai.md + code in the SAME commit; rewrite HANDOFF.md at session end or interruption.

Where the machine facts live

  • %APPDATA%\ytLive\ytLive.db = real layout DB (layout.db is a 0-byte legacy file). sqlite3 at /root/android-sdk/platform-tools/sqlite3 (or the SDK copy) for DB checks.
  • ffmpeg/ffprobe: /mnt/c/Program Files/Krita (x64)/bin/ with Windows paths.
  • ai.md §Local recording (TASK 18, ≈lines 605-640) = the authoritative pill/state-model doc (record-OR-live, armable signed-out, Start-button-face).