e69db4d26c
The bar now renders ONE surface from the FIRST decision the creator makes — Record or Stream — with each world being the whole bar. Creator directive: "I wrote the fucking thing and I still can't figure-out how to do stuff", "forget this one dog plan bullshit". OBS/streaming-tool reference for the one-surface paradigm: https://obsproject.com (single mode toggle + context actions) — cited per spin-guard habit; the go-live/test pattern follows CEV (https://cev-desktop.aSean.xyz) precedent. - Mode: single segmented REC|ON-AIR switch (SegmentToggle/SegmentLabel in Themes/Controls.xaml); radio-exclusive world selection, one tap to flip. - Record world: switch + Start Recording, zero YouTube identity. - Stream world: switch + Go Live + Test + account zone right (Sign In until connected, then avatar with Change Account/Logout context menu). - Test is a child of Stream: procs only stream-armed AND signed-in. - Running: one reality line "dot word elapsed" (REC/LIVE/TEST; green/red/ gold) + End; worlds + switch retire. - Gear moved up from bottom bar, ~3 wordmark letters past the brand, single click opens Settings/Bug/Feature/About menu (TASK 40 Unit B shipped early). - Fix folded in: BeginTestStream now arms OnAirPillOn explicitly (unarmed pump booted with zero encoder outputs -> "At least one output is required" forced-stop cascade from TASK 41's pipeline). - VM: world/reality props + RaiseTopBarModes() wired into StreamStatus, pill, IsRecording, IsTestStream, IsConnected setters. Doc: ai.md top-bar model, ViewModels/index.md, Controls/index.md, TASKS.md, HANDOFF.md, new TASKS/task-42-top-bar-redesign.md; task-40 note. Tests: TopBarModeTests.cs (new Good Dog), PillRadioTests + TestStreamTests gates updated. Build 0 warnings; full suite 314/315 — single abort is the pre-existing env-dependent RealMouseDrag test (Path of Exile 2 running)
91 lines
5.9 KiB
Markdown
91 lines
5.9 KiB
Markdown
# HANDOFF — 2026-09-22 (TASK 42 top bar redesign implemented; commit + full-suite rerun owed)
|
|
|
|
## Branch / Commit State
|
|
|
|
`main` HEAD = **`bb5dcb4` — feat(stream): TASK 41 Test Stream mode …** (TASK 41 committed).
|
|
Pushed state at `197ee81`. **Working tree DIRTY — TASK 42 implementation done, not yet committed**
|
|
(docs updated in this same pass; next step is scope-check + build + full tests + one commit):
|
|
|
|
```
|
|
M Controls/BottomBar.xaml(.cs) (gear removed)
|
|
M Controls/TopBar.xaml(.cs) (rewrite + GearButton_Click)
|
|
M Themes/Controls.xaml (SegmentToggle/SegmentLabel)
|
|
M ViewModels/MainViewModel.Streaming.cs
|
|
M ViewModels/MainViewModel.Account.cs
|
|
M ViewModels/MainViewModel.Streaming.Operations.cs
|
|
M ytLive.Tests/PillRadioTests.cs / TestStreamTests.cs
|
|
?? ytLive.Tests/TopBarModeTests.cs (new Good Dog)
|
|
M TASKS.md + TASKS/task-42-top-bar-redesign.md (new)
|
|
M ai.md, ViewModels/index.md, Controls/index.md, TASKS/task-40-app-settings-round.md
|
|
M HANDOFF.md (this rewrite)
|
|
```
|
|
|
|
Build impact: main + tests build clean, **0 warnings**; targeted suite **6/6 pass**; full-suite run
|
|
**314/315 pass** — the single abort is the known environment-dependent `RealMouseDrag` test (Path of
|
|
Exile 2 running, physical-mouse injection no-ops; see ⚠️ below and rerun with the game closed for a
|
|
clean 315/315).
|
|
|
|
## What shipped — TASK 42: top bar redesign (2026-09-22)
|
|
|
|
Full record: **`TASKS/task-42-top-bar-redesign.md`**. Creator directive: "forget this one dog plan
|
|
bullshit. Our one plan is replacing the top menu bar with something usable." The old bar's six
|
|
widget grammars (sliding pills, dots, badges, buttons, hidden sign-in context menu, live-window
|
|
status) collapsed into **ONE surface rendered by the FIRST decision — Record or Stream**:
|
|
|
|
- **Mode switch:** one segmented **REC|ON-AIR** toggle (`SegmentToggle`/`SegmentLabel` styles).
|
|
Going back = one tap on the other segment. Runs idle-only; retires while running.
|
|
- **Record world:** switch + **Start Recording** — no YouTube identity at all.
|
|
- **Stream world:** switch + **Go Live** + Test + account zone (Sign In until connected; then the
|
|
avatar, right-click Change Account/Logout). **Test is a child of Stream** — procs only ON-AIR-armed
|
|
AND signed-in (`ShowTestButton`/`CanStartTest`).
|
|
- **Running:** one reality line `● REC|LIVE|TEST 00:12:34` (green/red/gold `RunningDotBrush`) + End.
|
|
- **Gear** moved up from bottom bar, ~3 wordmark letters past the brand, one click = Settings / Bug /
|
|
Feature / About menu (`GearButton_Click`). Bottom-bar gear removed. Task 40 Unit B is DONE by this.
|
|
- **Sign-in = the account-confirm step:** no Google API enumerates machine accounts; OAuth is
|
|
single-account, so Switch Account re-runs the chooser (`login_hint`+`select_account`) — login and
|
|
account-confirmation are one surface. Existing `ChangeAccountCommand`/`LogoutCommand` resurface via
|
|
the avatar.
|
|
- **PRIVATE/TEST chips gone from the bar** (dev-phase forced-private becomes an OPTION at ship).
|
|
|
|
**Good Dog** — `ytLive.Tests/TopBarModeTests.cs` (one `[Fact]`, `RealAppHost.Run`): default record
|
|
world → arm ON-AIR → sign-in/avatar/Test gating flips → one-tap flip back → direct stream status
|
|
changing + running reality values. Also folded in: TASK 41's latent **Test pipeline bug fix** —
|
|
`BeginTestStream` now arms `OnAirPillOn` explicitly (unarmed → encoder booted with zero outputs →
|
|
"At least one output is required" → forced stop cascade). The TestStreamTests gate updated to match.
|
|
|
|
## ⚠️ Around the task
|
|
|
|
- **Full-suite run today: 314/315** — the one abort is the pre-existing
|
|
`LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder`, which injects
|
|
REAL physical mouse input (`SetCursorPos` + `mouse_event`, see its own docstring) and no-ops while
|
|
another window interferes. Cause observed 2026-09-22: **Path of Exile 2 + NVIDIA Overlay were
|
|
running** (fullscreen-game window hides the test window's rows; the drag never lands → reorder
|
|
assert fails). Close the game before running that test; it is unrelated to TASK 42 and has passed
|
|
on clean reruns previously.
|
|
- **Manual verification owed** (needs a real run on Windows): the app is a new build number when
|
|
next launched — check the new one-surface bar (switch ↔ worlds, gear menu, reality line).
|
|
- The app may be **RUNNING** — an in-place build fails MSB3021/MSB3027 until closed (temp-OutDir
|
|
workaround in ai.md). Close it before the manual pass.
|
|
- Full-suite note: the pre-existing real-camera startup flake did **not** occur in the 315/315 run.
|
|
- Test-env trap (recorded in the TASK): a dev machine's saved OAuth session loads synchronously and
|
|
makes `IsConnected` come back true in the VM ctor — signed-in-world tests must force
|
|
`vm.IsConnected = false/true` explicitly.
|
|
- `subscriberCount` rounded to 3 sig figs (YPP); carried. YPP slice 2 needs re-consent — do NOT
|
|
merge with other units.
|
|
- Polar product `d105dfa1…` still `$99/yr` — must become one-time before launch (carried).
|
|
`MARCOM.md`/`MONETIZATION.md` gitignored — never commit.
|
|
|
|
## Next step
|
|
|
|
Scope-check the declared list → build (0 warnings) → full test suite rerun → **one commit** for
|
|
TASK 42 (docs + code same change). Push only on the user's say-so. Then **TASK 40 App Settings
|
|
round** is queued (`TASKS/task-40-app-settings-round.md`) — units **A (camera) → C (defaults) → D
|
|
(accent)** remain (B/gear shipped early); Unit A's SharedReadOnly control-write question is the one
|
|
genuinely uncertain technical point — run its mitigation ladder before a third guess.
|
|
|
|
## Critical working rules (unchanged, still binding)
|
|
|
|
- **Good Dog = ONE integration test per change.**
|
|
- **Scope lock:** declare the file list before editing; `./scripts/scope-check.sh` before commit.
|
|
- WSL builds use the Windows dotnet host (`/mnt/c/Program Files/dotnet/dotnet.exe`, quoted paths).
|
|
- One runtime model, no model switching, no compaction summaries (user directive). |