Files
LlamaCasty/HANDOFF.md
T

59 lines
3.8 KiB
Markdown

# 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).