diff --git a/HANDOFF.md b/HANDOFF.md index 15d1c6c..97d32f8 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,69 +1,70 @@ -# HANDOFF — 2026-09-22 (TASK 39 YPP journey tracker slice 1 DONE, COMMITTED `a9d5f29`, PUSHED) +# HANDOFF — 2026-09-22 (TASK 39 shipped+pushed; TASK 40 App Settings round plan SAVED in `4d9188a`, uncommitted here) ## Branch / Commit State -`main` HEAD = **`a9d5f29` — feat(ypp): YPP journey tracker slice 1 — the YPP pull-out below -Stream Settings (TASK 39, Good Dog ONE test)**. **PUSHED** `4e0915a..a9d5f29`. **Working tree -CLEAN.** +`main` HEAD = **`4d9188a` — docs(plan): TASK 40 App Settings round — saved plan**. Pushed state +at `197ee81`. **Working tree DIRTY — ONE docs work unit:** + +``` +?? HANDOFF.md (this rewrite) +``` +Build impact: none — docs only. + +## What's in flight — TASK 40: App Settings round (plan saved 2026-09-22) + +Creator (this session) scoped three asks and answered four decision questions. Full plan: +**`TASKS/task-40-app-settings-round.md`** (created + committed in `4d9188a`). Four units, one +Good Dog test + one scope-checked commit each: + +- **Unit A — App Settings "Active Web Camera"** (ask 1): new section under "Default Location + for Recordings" — **Change…** opens a sub-menu of a *fresh* webcam enumeration incl. vcams + (adopt+base-lock if `_webcam == null`, else existing `SwapWebcamIdentityAsync`); **Tune…** + opens a `CameraConfigDialog` of the device's `VideoDeviceController` MediaDeviceControls + (Auto + Min/Max/Step sliders, **live-only**, no persistence). Tech risk to verify at impl: + whether MediaDeviceControl writes work under `SharedReadOnly` (ladder: probe capture → running + source's controller → read-only + note; spin-guard = research before a 3rd guess). +- **Unit B — gear** (ask 2): move from BottomBar lower-left to **TopBar right of the wordmark, + gap ≈ 3 letters**; left-click = App Settings, right-click = Bug/Feature/About. +- **Unit C** (ask 3): persist default output resolution (currently resets every launch), surface + default scene transition + duration (persisted but editable NOWHERE), Confirm-before-End toggle. +- **Unit D — accent/theme** (ask 3, split out as its own unit): 69 hardcoded accent sites across + 15 files → consolidate into a `Themes/Controls.xaml` accent brush (DynamicResource) + picker + + `App.AccentColor` Settings key; `Source.ChatMemberColor` stays per-source. ## ⚠️ Open action items / landmines -- **The app is RUNNING on the desktop** (`ytLive` pid 8696 was seen locking `bin\net8.0…\ytLive.dll`) - — normal `dotnet build` to `bin` fails with MSB3021/MSB3027 until it's closed. Sessions verified - the build with `-p:OutDir=C:\Users\gramp\AppData\Local\Temp\ytLive-build39\ -p:UseAppHost=false` - and ran vstest against the temp dll. Close the app before committing/final verification. -- **`subscriberCount` is rounded to 3 significant figures** by Google — near-threshold ETA/bar - reads are coarse; documented in `TASK 39` doc + the drawer's `WhatCounts` text. -- **LayerReorderPersistenceTests.RealMouseDrag…** flaked once pre-TASK-38 (fullscreen game on the - desktop); unrelated, re-ran green. -- **Slice 2 (Analytics) needs Google re-consent** — `yt-analytics.readonly` added to - `YouTubeAuthService.Scope` (line 18) triggers it; do NOT merge with slice-1 work. -- Polar product `d105dfa1…` still `$99/yr` — must become one-time before launch (carried; see - `TASKS/task-10-monetization.md`). `MARCOM.md`/`MONETIZATION.md` are gitignored — never commit. - -## What this session did (TASK 39 slice 1 — creator ruling 2026-09-21, plan 2026-09-22) - -Add the **"YPP"** pull-out below **Stream Settings** on the Live screen's right edge. Current-OAuth- -scope data (no re-consent) shown in-app: subscriber bars for both tiers (500 f.funding / 1,000 ad — -the 1,000/4,000h/10M→8,000h/20M doubling on **2027-02-01** handled as versioned data in -`YppThresholds`), 3-uploads/90d bar, live standing from `auditDetails`, self-reported 2FA/AdSense -checkboxes + deep links, and the "what counts" education text. Every refresh appends a `YppSnapshot` -(SQLite v10) so slice 2's velocity/ETA has history from day one. - -- `ChannelStatsService` (`channels.list statistics,auditDetails,contentDetails` + - `playlistItems.list`, virtual `CaptureCurrentAsync` = test seam); `YppTrackerViewModel` mirrors - `LiveBroadcastFormViewModel` (drawer state + commands); `MainViewModel.Ypp.cs` wires `Ypp`, - `ChannelStatsFactoryOverride`, and **one-open-at-a-time exclusivity** (both directions); - account hooks in `MainViewModel.Account.cs`. -- `PreviewPane.xaml` — `TextPullOutHost` is now a drawer bank: [broadcast drawer][ypp drawer] - [stacked white-tab column]; same animated-width pattern (To=320, 0.2s CubicEase). Outside-click - collapse in `MainWindow.xaml.cs` covers both. `IsClickInsideDrawer` unchanged. -- **Good Dog = ONE integration test** (`YppPullOutTests`): connected-VM snapshot capture + - persistence + checklist round-trip + drawer toggles; real-window exclusivity both ways. +- **The app may still be RUNNING** (a `ytLive` instance locked `bin\…\ytLive.dll` earlier today) + — in-place `dotnet build` fails with MSB3021/MSB3027 until it's closed. Workaround that worked: + build with `-p:OutDir=C:\Users\gramp\AppData\Local\Temp\ytLive-buildNN\ -p:UseAppHost=false` + and run vstest against the temp dll. Close the app before Unit-A final verification. +- **Unit A SharedReadOnly control-write risk** is the one genuinely uncertain technical point — + do NOT hand-wave it; run the mitigation ladder and (if needed) the spin-guard research. +- **`subscriberCount` rounded to 3 sig figs** by Google (YPP numbers are coarse). Carried. +- **Slice 2 (YPP Analytics) needs Google re-consent** (`yt-analytics.readonly`) — do NOT merge + with any TASK 40 unit. +- LayerReorderPersistenceTests.RealMouseDrag flaked once pre-TASK-38 (fullscreen game); unrelated. +- Polar product `d105dfa1…` still `$99/yr` — must become one-time before launch (carried, + `TASKS/task-10-monetization.md`). `MARCOM.md`/`MONETIZATION.md` gitignored — never commit. ## Next step -## Next step - -1. TASK 39 **slice 2** (Analytics scope re-consent → watch-hours/Shorts + velocity/ETA + - sparkline) per `TASKS/task-39-ypp-journey-tracker.md`, when the user queues it. Before any - build, close the running ytLive instance or use the temp-OutDir build described below. +The user has a **new task spec waiting** — take it, then execute TASK 40 units A → B → C → D per +the saved plan (each: declared file list → code → Good Dog test → `./scripts/scope-check.sh` → +commit with docs in the SAME commit → push only on the user's say-so). HANDOFF rewrite is due +when this docs work unit commits. ## Critical working rules (unchanged, still binding) - **Good Dog = ONE integration test per change.** -- **Scope lock:** declare the exact file list before editing; run `scripts/scope-check.sh` 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 and `--TestCaseFilter` for filtered vstest runs. -- **ai.md + code in the SAME commit**; rewrite HANDOFF.md at session end. +- **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). +- ai.md + code in the SAME commit; HANDOFF rewritten at session end. ## 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`. Schema is now **user_version = 10**. +- `%APPDATA%\ytLive\ytLive.db` = real layout DB (`layout.db` is a 0-byte legacy file); schema + `user_version = 10`. sqlite3 at `/root/android-sdk/platform-tools/sqlite3`. - ffmpeg/ffprobe: `/mnt/c/Program Files/Krita (x64)/bin/` with Windows paths. -- `ai.md` §Screen backdrop capture = authoritative backdrop/capture-key/heal doc (incl. TASK 38). -- `ai.md` §Monetization awareness = authoritative monetization roadmap (incl. the TASK 39 - journey-tracker state). YPP thresholds/date doubling live there + `Models/YppThresholds.cs`. -- Business/marcom facts: `MONETIZATION.md` + `MARCOM.md` (both gitignored). \ No newline at end of file +- `ai.md` §Screen backdrop capture = authoritative backdrop doc (incl. TASK 38); + §Monetization awareness = monetization roadmap (TASK 39 state, YPP thresholds). +- Business/marcom: `MONETIZATION.md` + `MARCOM.md` (gitignored). \ No newline at end of file