Temporarily raise the selected preview item and prioritize it in the custom hit test without changing scene order. Refresh integration-test expectations for Brand logo layers and explicit thumbnail assets. WPF references: https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.panel.zindex?view=windowsdesktop-10.0 https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/hit-testing-in-the-visual-layer
35 KiB
HANDOFF — 2026-10-28 (selected-layer preview stacking; suite green)
Current state
- Branch
main;origin/mainremains at7ae30d4. The five feature commits since that point are90cd039(fade starts from outgoing picture),f67a263(transition picker),b86b6bb(Wipe),841c905(brand logo layer), and7da2872(preview and program transitions). They are not pushed; no push was requested. - Four UI-redesign commits already on
origin/mainwere missing from the older handoff:24aca7dmoved the scene strip above the preview and removed the default CRT/on-air image seeds;3239808added the Scene Layers header/count and layer icons plus scene-card names, hotkeys, and PROGRAM badge;a8814b4added the explicit EDIT toggle and fixed the scene-card/left-column sizing;7ae30d4moved readouts/resolution into the top-left cell, added the Socials rail drawer, and restored webcam/chat border controls and vertical 1080p30.b7ab169addedDESIGN.mdwith exploratory color/type tokens; it explicitly is not a layout spec or a theme implementation.ai.mdandControls/index.mdnow describe the landed surface. No new task was added to the queue. - Shipped in those commits: type/duration picker persisted with the layout; CPU left-to-right
Wipe; one locked Brand logo image layer per scene; preview transition animation in every mode;
program transitions while recording or streaming. The
7da2872commit omitted a memory update;TASKS.mdandai.mdnow reflect it. - Current work unit: when a draggable element is selected from the layer list,
PreviewPanetemporarily raises its item container and gives it priority in the custom preview hit test. On deselection, normal preview stacking returns; the scene collection order and saved/program z-order never change.SelectedLayerPreviewHitTestingTestsverifies the overlapping Brand logo/webcam visual hit, custom hit priority, and deselection restore. - The six prior suite failures are resolved in their tests, not by reverting current behavior: LayerReorder now accounts for the permanent Brand logo after Background; BorderColorPicker validates every palette picker and scopes its rendered-widget lookup to the visible webcam control; both thumbnail cases persist explicit tile assets instead of relying on removed default seed files; SourceNaming only considers user-created Text overlays; ZoomBox locates its placeholder by type, not a list index changed by Brand logo.
- The worktree already had three uncommitted user edits before this docs sync; they are preserved:
Controls/OverlayHost.xamlgroups App Settings into Recordings, Brand logo, Preview, and Scene transition sections with compact controls;Controls/TopBar.xamlwires right-click on the gear;Controls/TopBar.xaml.csopens App Settings directly on right-click while left-click keeps the menu. These are active UX-redesign work, not part of the selected-layer fix. On-screen verification is still pending. - This work unit is committed locally, not pushed. The three pre-existing user edits above remain uncommitted and untouched.
- Next: continue the creator's UX redesign and verify the current App Settings/gear changes, transitions, and Brand logo on-screen. The earlier vertical-webcam hands-on check is also still pending unless the creator confirms it was completed. Move's persistent-layer behavior and Cube remain queued; distribution remains deferred until near v1.
- Verification state:
verify.shpassed: clean build with 0 warnings, 444/444 tests passed, and scope check passed. The new selected-layer integration test also passes by itself. - Follow-up, not fixed here:
ytLive.csproj'sGenerateBuildStampcomment still describes a commit-count-based+1 per commitcounter, but the target now reads/writes localBuildCounter.txtand increments it per build.ai.mdrecords the code's current behavior; correct the stale source comment in a separately scoped change.ViewModels/MainViewModel.Socials.csalso still calls the Socials surface a modal dialog in its method comment; the committed UI is now a preview-rail drawer. Correct that source comment separately if the file is next in scope. The new deterministic WPF hit-test recipe is inMyMistakes.md; the final commit cites its Microsoft reference. - WPF stacking reference:
Panel.ZIndexgoverns preview container order. The code also prioritizes the selected element inHitElementAt, because the custom hit test does not consult WPF's visual z-order. The deterministic test recipe and hit-testing reference are recorded inMyMistakes.md; cite that Microsoft reference in the commit.
Historical notes (retained reference; current checkout state is above)
At a glance (2026-10-26 docs session)
ai.mdis being split intodocs/ai/*.md(user-approved: verbatim move, staged units, "ai.md only"). Three units landed as separate commits, docs only, not pushed:804b1d2(frame pipeline: cadence/timing/budget/compositor/pump),096bf6d(capture: backdrop/webcam/background effects/vertical tier),a4dfca6(output: ffmpeg/encoder/recording/audio). Each move is byte-identical in the new file;ai.mdkeeps a short stub with the load-bearing invariants + a link.docs/ai/index.mdroutes.ai.mdis now 1,289 lines (~32k tokens), down from 2,702 (~64k) — more than half the mandatory-read cost is gone.- Also landed (docs only, not pushed):
ef60f1f— distribution & packaging deferred until near v1 (creator ruling 2026-10-26); see "Next step" below for the still-open route contradiction. - Remaining split candidates in
ai.md(not yet moved — smaller, more interleaved with law that should stay): Architecture's "Social bar" (46) + "Toast notifications" (24) + "Licensing — do not violate" (60); "YouTube Live API — design constraints" incl. "Native events & alerts" (349 total, 99 of it alerts); "Monetization" (136); "Windows packaging & distribution" (135, frozen per the deferral above). None of these is urgent — pick back up only if the user asks to continue the split. - Scope-check passed on all three commits; no source touched this session.
Earlier detailed state (2026-10-22) — properties-panel asks shipped, incl. TASK 63, and pushed; vv webcam Units 1+2 state below
At a glance
- Branch main, tracking
origin/main. The six-commit properties-panel batch is PUSHED (2026-10-22, as a sub-milestone): TASK 58 the theme sweep, TASK 59 the properties hierarchy, TASK 60 the colour names, a docs commit, TASK 61+62 the geometry field widths and the colour name beside the hex, and TASK 63 the border-colour picker as the app's own drop-down — the creator's properties-panel asks, done in one batch.origin/mainis now987fdda.- The vv feature (Units 1+2) was pushed at its close (2026-10-21 — the creator approved the Unit 1 push after testing it, and the completed feature is a milestone).
- The push path changed:
originis nowhttps://llgit.llamachile.tube/gramps/LlamaCasty.git(HTTPS + the credential helper/home/gramps/bin/gitea-credential, which reads the password from the gitignoredCREDENTIALS.md; plaingit pushworks). The old SSH remote was broken twice over: the repo was renamedgramps/ytLlive→gramps/LlamaCasty, andllgit:2214refuses the publickey of this machine's key even though it IS registered (account key id 6 "Corsair VSC"). Ask the Gitea REST API, don't do key archaeology — recipe inMyMistakes.md→ 2026-10-21.
- This session shipped vv webcam Units 1+2 (the vertical 9:16 tier keeps its OWN camera placement
per scene; 16:9 restores the desktop layout exactly; the Chat scene in vv is rect-only and can be
enlarged to fill a whole 607×540 area). Code + memory in ONE commit each; the ONE Good Dog tests
are
ytLive.Tests/VerticalWebcamLayoutTests.cs(Unit 1) andytLive.Tests/VerticalChatCameraLayoutTests.cs(Unit 2). Only the creator's hands-on check is left — see the vv section. - TASK 58 — the properties panel now wears the theme (shipped 2026-10-21). The creator's
"why is the drop-down not in the same style as the others?" was a real defect: those drop-downs
(and every check box, and every properties field) had been hand-painted with a
Background/Foregroundinstead of a style, so WPF drew the light system template on top of the dark panel. Now:ComboBox→YtComboBox,CheckBox→YtCheckBox(new), properties fields →YtTextBoxCompact(new, BasedOnYtTextBox). Guard:ytLive.Tests/PropertiesStyleTests.cs. - TASK 59 — the properties panel is a hierarchy (shipped 2026-10-21). A title owns its
content and the content is indented one level (10px):
Shape(new title) over the Mirror switch and the shape choice, the drag hint indented under that row, Geometry / Border Color / Border Thickness as titles with their fields indented, Background's Remove + Blur indented, and Strength one level deeper under Blur. The shape became a CHOICE:Rect|Circleas two segment options with Rect selected by default (the old single button showed the next action, "Round"). The mutual exclusion lives in the model (IsRectShape/IsRoundShapeonSceneElement) — a WPFRadioButtongroup would kill the bindings. Guard:ytLive.Tests/PropertiesHierarchyTests.cs. - TASK 60 — the border-colour drop-down names every colour (shipped 2026-10-21). The creator:
"the #hex values are good, but add a corresponding color name/label next to the value" — each row
now reads
#e94560 Crimson(the name dimmed, the tooltip "Crimson (#e94560)"). The 14 colours moved out of the click handler intoModels/BorderColorPalette.cs(NamedColor(Hex, Name)+NameOf(hex)), so the list is testable and extensible. Guard:ytLive.Tests/BorderColorPaletteTests.cs. - TASK 61 + 62 — the geometry fields and the border-colour field (shipped 2026-10-21).
- 61: the X/Y/W/H fields share ONE fixed width (44px — the largest geometry value, 1920,
plus a sign) and their rows set
LastChildFill="False", so Y/H no longer stretch to fill the row while X/W sized themselves to their text. Guard:ytLive.Tests/GeometryFieldWidthTests.cs(it MEASURES the widest value with WPF'sFormattedText— measure, don't guess). - 62: the border-colour field shows the palette's name beside the hex
(
SceneElement.BorderColorName, empty for a custom hex), and the hex field keeps a fixed width so the name stays next to the hex. The field stays editable (a custom hex can still be typed). Guard:ytLive.Tests/BorderColorNameTests.cs.
- 61: the X/Y/W/H fields share ONE fixed width (44px — the largest geometry value, 1920,
plus a sign) and their rows set
- TASK 63 - the border-colour picker IS the app's drop-down (shipped 2026-10-21; popup click
deselection fixed 2026-10-22). The creator:
"why does the drop down under the web cam properties not show the same style for the border
color drop down list box?" and "we established look-and-feel standards. And yet you keep
ignoring these and I'm wondering why." Root cause of the miss: the TASK 58 sweep looked for
control types (
ComboBox/CheckBox/TextBox) without a theme style - and the border picker was NONE of those: it was a...ButtonwhoseClickhandler built aContextMenuin code. It was never in the sweep's scope, andPropertiesStyleTests.cs(a type-based guard) could not see it either. Now: the picker is aYtComboBoxbound to the palette (SelectedElement.BorderColorOptions/BorderColorEntry), the closed box shows the swatch + the colour's NAME, the rows show swatch + hex + name, the hex field stays for a custom colour, the swatch is painted by the theme'sHexToBrushconverter, and the hand-built menu +WebcamBorderColorPicker_Clickare gone. The closed box != the rows only throughHelpers/ClosedBoxTemplateSelector.cs(WPF copiesItemTemplateinto the read-onlySelectionBoxItemTemplate; the selector is told them apart by theContentPresenter's templated parent -ComboBox= closed box,ComboBoxItem= a row). 2026-10-22 creator bug fix: clicking a colour in the openComboBoxpopup registered as an exit from the properties listing becauseLeftPanel.IsDescendantOfusedchild is Visual ? VisualTreeHelper.GetParent(child) : LogicalTreeHelper.GetParent(child)— atPopupRoot(which IS aVisual),VisualTreeHelper.GetParentreturnsnull, soIsDescendantOfstopped without crossingPopupRoot's logical parent (PART_Popup→ComboBox→ElementsScrollViewer), andMainWindow.Window_PreviewMouseLeftButtonDownclearedSelectedElement = null. Fixed by falling back toLogicalTreeHelper.GetParent/TemplatedParentwhenVisualTreeHelper.GetParentreturnsnull. Guard:ytLive.Tests/BorderColorPickerTests.cs(model + panel + the real widget, includingLeftPanel.IsClickInsideon an open popup row and clicking a row to changeBorderColor). The TASK 60 guard (BorderColorPaletteTests) was updated to guard the new wiring (the drop-down is bound to the palette; no second list of colours anywhere). - TASK 55 slice 1 — the log is capped (shipped 2026-10-22).
startup.logwas uncapped (23 MB and growing every few seconds — ffmpeg logs every stderr line). Now it rolls tostartup.1.logat 5 MB (one rolled copy kept), so the growth is bounded. The policy isHelpers/LogRotation.cs(a pure function over a path —AppLog's 156-call-site surface is unchanged; the seams are twointernalproperties). Guard:ytLive.Tests/AppLogRotationTests.cs. Slices 2 (temp alert-clip cleanup) and 3 (low-disk guard before recording) are still open. - TASK 48 slice 2 — the app PACKS as a Store MSIX (shipped 2026-10-22).
Packaging/Package.appxmanifest(full trust:Windows.FullTrustApplication+uap10:TrustLevel=mediumIL+uap10:RuntimeBehavior=packagedClassicApp+rescap runFullTrust, plus webcam/microphoneDeviceCapabilitys, x64, en-US only) +Packaging/Assets/(four logo tiles generated from the app's own artwork byscripts/make-store-logos.py) +scripts/package-msix.sh(publishRelease -r win-x64 --self-contained→ stage →makeappx pack, optionalMSIX_PFXsigning). First real package built:artifacts/LlamaCasty.msix, 159 MB, 509 files,Package creation succeeded(artifacts/is gitignored). Guard:StorePackagingTests.The_package_manifest_declares_full_trust_camera_and_microphone. ⚠️ Before submission the manifest'sIdentity/@PublisherandPublisherDisplayNamemust be set to the exact values Partner Center shows — a mismatch is a rejection. - TASK 48 slice 3 — the self-updater is gone (shipped 2026-10-22). The Store route (creator
ruling 2026-09-27) means the Store updates the app, so the Velopack package + bootstrap were
deleted (
ytLive.csproj,App.xaml.cs) — a compliance action, not cleanup: the updater downloaded and executed, which Store policy 10.2.2 does not permit. The DO update-URL droplet dies with it. Guard:ytLive.Tests/StorePackagingTests.cs(no updater package, no updater API in any app source file). The app was smoke-tested after the removal:MainWindow loaded, no exceptions. Still open on TASK 48: slice 2 (thePackage.appxmanifest+ packaging project), slice 6 (the full-trust recording invariant comment), slice 7 (disqualifier re-check), slice 8 (the pre-submission gates) — and slices 4/5 are the creator's (Certification Kit, Partner Center listing, the demo account). - The previous session (HA lights) produced NO ytLive code — it was spent on the creator's Home
Assistant light alert system (off-repo,
192.168.50.145). SeeMyMistakes.md→ 2026-10-21: the plan was one tweak to a verified-working script; the script was rewritten twice, the alert path broke, and the day was burned. The HA work landed OK in the end (recipes + measurements now inMyMistakes.md). Records below so the next session does not re-hunt.
HA light alert system — current, verified state (2026-10-21)
Five Tapo bulbs: light.br1, light.br2, light.officeone, light.officetwo,
light.death_star_light. Purpose: the creator is deaf — lights are the alert channel; the phone
(notify.mobile_app_mis_lx9) is secondary. The iPhone is gone — never notify it.
| State | br1 / officeone | br2 / officetwo | Death Star |
|---|---|---|---|
| Idle | off | off | off |
| Pump running | off | off | blue only (creator directive) |
| Leak | warm-white 100% | purple | purple |
| Alarm | warm-white 100% | red | red |
| Doorbell | green, 8s | green, 8s | green, 8s |
| Doorbell during an alert | — | suppressed — | — |
| Clear | off | off | off |
Architecture: script.alerts_arm / alerts_clear write only input_text.light_alert
(none|leak|alarm|motion, restart-surviving). script.alerts_render_lights is the single writer of
the bulbs — flat top-level if/else blocks (nested if and choose: both silently lit nothing;
do not "improve" the shape). Priority: an alert always beats pump status.
⛔ THE ENTITY-ID TRAP (cost this session hours): the YAML key is alerts_render but the entity id is
script.alerts_render_lights. script.turn_on on a non-existent entity returns HTTP 200 and does
nothing — no error, no log. All callers now use the _lights id. Check this first on any "script does
nothing" symptom.
Pump status is a status, not an alert (auto-clearing), and is keyed off
sensor.water_pump_current_consumption — never switch.water_pump_2, which was observed latched
on for hours at 0.0A draw and painted the bedroom blue at 5am.
HA files touched (/config, root-owned → writes need sudo): scripts.yaml, automations.yaml,
configuration.yaml (added input_text.light_alert / _prev). Backups: scripts.yaml.bak-alertbuild,
automations.yaml.bak-alertbuild, automations.yaml.bak-notify-20261020, configuration.yaml.bak-tplinkfix.
Zombie entities deleted from the registry: script.leak_strobe, script.doorbell_flash (old one),
automation.leak_strobe_notify_clear_restore, script.alerts_render_lights_2.
Leak sensor is healthy (binary_sensor.pump_leak_moisture = off, battery 100, signal 3) — an earlier
"unavailable" claim was a bad read during a reload; alert_leak_on now also triggers on the latched
sensor.pump_leak_last_water_leak_alert.
vv webcam feature — locked rules (creator, 2026-10-17) — Units 1+2 shipped 2026-10-21
| mode | shape | size | position |
|---|---|---|---|
| 16:9 | as today | as today | as today |
| vv · Live | circle OR rect, creator's choice | small tile | one of six spots: top/bottom × L/C/R |
| vv · Chat | rect only — no circle option | normal, or enlarged to fill one area (607×540) | enlarged → top or bottom |
| Starting / BRB / Ending | unchanged | unchanged | unchanged |
- Placement is set by tap/click-drag with snap, exactly like the socials today, plus manual entry in properties. vv keeps its own camera position, size and shape per scene — switching back to 16:9 restores the desktop layout exactly.
- No explicit borderless/no-background mode is needed (round + border/bg options already allow it).
- Creator's "square" means the rectangular view (the camera's own aspect), not a literal 1:1 box.
What the code already gives us (do not re-hunt)
- vv = the active tier's centred band crop. 1080p60-vertical: master band x 656.25–1263.75
(607.5 wide), full height, upscaled to 1080×1920 (
MainViewModel.Streaming.csApplyStreamQuality→OutputRect*). The band splits into two 607×540 areas (top/bottom). - The Live webcam sits at x≈1425 → entirely outside the band — in vv it is invisible. That is the whole motivation.
- Geometry only — no render-path change. Preview (
Controls/PreviewPane.xaml144–230) and compositor (Services/Compositor/SceneCompositor.cs389–397) both read the element's ownX/Y/W/H+ClipShape. - Round / border / background are independent:
ClipShape.Round;HasBorder= width > 0 AND valid 6-hex colour;BackgroundEffect= None/Remove/Blur. - Per-scene camera size policy exists:
MaxWebcamWidthFor/HeightFor(Chat 1358×764, others 960×540)ClampWebcamToBounds. A 607×540 tile sits inside both → no clamp change.
- Storage:
WebcamSceneConfigtable; new columns viaMigrateWebcamConfigTable()as idempotentALTER TABLE … ADD COLUMNguarded onPRAGMA table_info+LayoutStore.Save.csINSERT andLayoutStore.Load.csSELECT. - Precedent for remembered geometry:
RectWidth/RectHeight+ToggleClipShape(Models/SceneElement.cs124–152).
What shipped in Unit 1 (2026-10-21) — do not re-hunt
- Geometry only — NO render-path change. The tier switch swaps the element's LIVE geometry; the
preview and the compositor read
X/Y/W/H+ClipShapeexactly as before. Models/VerticalCameraLayout.cs(new): the pure math — band x 656.25, w 607.5, h 1080; two 607×540 areas; six spots; default tile 270×152 master px (= 480×270 in the 1080×1920 output), bottom-right spot; inset 32 master px.Models/WebcamSceneConfig.cs: the vertical placement is persisted in seven additive columns (VerticalX/Y/Width/Height/VerticalClipShape/VerticalRectWidth/VerticalRectHeight, NULL = "this scene has no vertical placement yet"); the 16:9 layout stays in the old columns and is parked in the transientLandscape*fields while the vertical tier is live.BeginVerticalLayout/EndVerticalLayout/CommitLiveLayoutToVerticaldo the swap.Models/SceneElement.cs:X/Y/Width/Heightare nowvirtualso the webcam clamps EVERY write (drag, resize, typed fields) into the band — outside the band = invisible in vv.ViewModels/MainViewModel.Webcam.cs:IsVerticalTier/VerticalBand+ResolveVerticalCameraLayouts(the tier swap; the Live scene gets its tile automatically on the first vertical switch) +MoveWebcamInVerticalTier/SnapWebcamInVerticalTier(the six-spot snap, by the tile's CENTRE).MainViewModel.Streaming.csApplyStreamQualityis the tier-change hook.Controls/LeftPanel.xaml: the webcam properties gained a Geometry section (X/Y/W/H) bound to the live placement, gated on the VM'sIsWebcamSelected(NOTSelectedElement.IsWebcam— the TASK 51 test finds that panel by binding text and would match twice).Controls/PreviewPane.xaml.cs: dragging/resizing a webcam under the vertical tier routes through the VM's snap instead of free-floating over the master.- Test seam: the drag lives in a VM method, so the test drives it without synthesising mouse input.
What shipped in Unit 2 (the Chat scene, 2026-10-21) — do not re-hunt
- Rect only, and the lock is on the MODEL, not the UI.
WebcamSceneConfig.VerticalShapeLocked(set per scene by the VM) overrides theClipShapeproperty → a locked camera cannot become Round by any writer (the toggle, the Shape button, the placement swap).SceneElement.ClipShapeandSceneElement.ToggleClipShape()arevirtualfor this. The lock is cleared before the 16:9 layout comes back, so the desktop shape is restored. - The circle is not OFFERED:
MainViewModel.CanToggleClipShapeis false for a Chat camera in the vertical tier → the Shape button in the webcam's properties disappears (not just disabled).MainViewModel.csraises it on the selection change;MainViewModel.Streaming.cson the tier change. - Two sizes, snapped by the nearer one:
VerticalCameraLayout.SizeFor(band, requestedWidth)→ the small tile (270×152) or one whole area (607.5×540). The resize handle therefore has two detents instead of any size in between. - An enlarged camera fills the area its centre is in — top or bottom (
VerticalCameraLayout.AreaFor). - The Chat camera is auto-tiled like the Live one when the vertical tier is picked (otherwise the
vertical chat stream has no camera at all).
ResolveVerticalCameraLayoutnow auto-tiles Live and Chat; Starting/BRB/Ending keep their 16:9 placement. - The preview's resize routes through
MainViewModel.ResizeWebcamInVerticalTier(the Chat camera's discrete size + the snap); the drag routes throughMoveWebcamInVerticalTier(assign → clamp → snap, so the enlarged camera can be dragged from the top area to the bottom one). - Test:
ytLive.Tests/VerticalChatCameraLayoutTests.cs— PASSES (in Chat under the vertical tier, enlarging fills the full top area and the circle option is not offered).
Units (each: ONE Good Dog integration test, own commit, memory in the same commit)
- ✅ vv camera layout (Unit 1) — shipped 2026-10-21. Stored separately per scene, resolved when the
tier changes. Live: small tile (circle or rect) snapped to one of six spots; drag like the socials +
properties entry.
Test:
ytLive.Tests/VerticalWebcamLayoutTests.cs— with the vertical tier active, dragging the Live camera to top-right places it top-right inside the band; switching back to 16:9 restores the original layout exactly; both placements survive a save + reload. PASSES. - ✅ vv · Chat (Unit 2) — shipped 2026-10-21. Rect enforced with the circle option unavailable, plus
enlarge-to-one-area (607×540) filling the top or the bottom area by where the camera is.
Test:
ytLive.Tests/VerticalChatCameraLayoutTests.cs— in Chat under the vertical tier, enlarge sets the full top area and the circle option is not offered. PASSES.
Historical next step (2026-10-22; superseded by Current state above)
- ✅ TASK 63 + popup-click fix verified by creator (2026-10-22) — clicking a colour in the
Border Color
YtComboBoxdropdown now stays insideLeftPanel(IsDescendantOfcrossesPopupRoot→PART_PopupviaLogicalTreeHelper.GetParent), updates the webcam border colour, and does not exit the properties listing. - Creator check (needs the creator's hands) — the last piece of the vv feature: switch the resolution dropdown to "Vertical 1080p60", confirm the Live camera tile lands inside the band and the Circle option (TASK 59 turned the Shape button into a Rect | Circle choice) turns the tile into a circle there, open the Chat scene and confirm the Circle option is gone (rect only) and that dragging the tile up and enlarging it fills a whole 607×540 area, then switch back and confirm the desktop layout is untouched. The unit tests cover the geometry, not the eyeball.
- ⏸ Distribution & packaging is DEFERRED (creator ruling 2026-10-26) — do not pick it up until
we are close to v1. The creator's reasons: the remaining programming tasks are far from
release, and a complete UX redesign is about to start — so packaging/signing/updater/route
decisions would chase scope that is about to move. Nothing distribution-related is urgent now.
Frozen: TASK 48 items 6-8, the signing decision, the updater choice, and the route contradiction
(
ai.mdsays Store route DEAD → direct + Steam;TASKS.md/TASKS/task-48-…/this file still say Store MSIX + Store IAP). That contradiction is to be settled in ONE distribution sweep at the revisit, not patched piecemeal in the meantime. Detail:TASKS.md→ Open items → the ⏸ TASK 48 bullet. - Nothing else is queued for llamacasty — the creator queues work.
Open (operational)
- Follow-up (not fixed — out of scope for TASK 61): the web source block's geometry rows in
Controls/LeftPanel.xaml(theSelectedElement.IsWebSourcepanel, ~lines 387-402) have the identical shape and the identical defect as the webcam's did — the Y/H fields stretch to fill the row. Same one-line-per-field fix as TASK 61, when the creator wants it. - ✅ FIXED in TASK 63: the border-colour swatches now carry a 1px
BorderBrush="#2a3a5e", so the black (#000000) and dark swatches are visible against the dark menu (#16213e). - Follow-up spotted while doing TASK 63 (not fixed — out of scope for that change): the theme has
no implicit
Buttonstyle, so every plain<Button>in the app still renders with the light WPF system template (Controls/LeftPanel.xaml×7,Controls/CameraPickerDialog.xaml×2). The border picker's...button was one of them and is gone; the rest are still there. A theme-level implicitButtonstyle would fix them all at once — that is a creator-queued task, not a silent edit. - GOG Galaxy launcher shows "offline" (2026-10-21) — GOG's own overnight outage, NOT Windows. GOG
put
www.gog.combehind a maintenance page (503) and their Fastly services forauth.gog.com/api.gog.com/remote-config.gog.comreturn500 "Fastly error: unknown domain"; the page itself says "Galaxy Launcher will also be down." Window: 00:00–08:11 local on 2026-10-21 — the Wayback snapshot ofwww.gog.com/en/at 06:56 UTC is HTTP 200 with the full live storefront.status.gog.comis NXDOMAIN globally. Local exoneration chain: genuineGOG sp. z o.o → DigiCertcert (no MITM), local DNS == Google's authoritative answers, real Fastly POP headers, and GOG's own non-Fastly servers still answering. Nothing to fix locally — wait for GOG. Galaxy's logs (incl. the rotated ones) show no API-status failures between Oct 10 and Oct 20. Diagnosis recipe + thewebfetch-is-not-an- independent-egress trap:MyMistakes.md→ 2026-10-21 GOG Galaxy "offline". Galaxy 2.0 logs live inC:\ProgramData\GOG.com\Galaxy\logs\(NOT%LOCALAPPDATA%). ⚠️ that folder also holds a 2.7 GBcef.log(since Jul 13) — disk hygiene, see TASK 55. - verify.sh's known-failure whitelist is too loose (confirmed twice 2026-10-16): require EVERY failure
line to be whitelisted, and add
MasterLimiter_CapsTheLiveMix_OnThePipe+RealMouseDrag_OnTheLayerList_PersistsTheReorderto the list. - A pre-existing stash is still sitting there:
stash@{0}= "WIP on main:0464593Compositor: fast-path opaque 1:1 when source fills canvas" (NOT this session's; do not drop blindly). - The judder reproduction take in the FAILING geometry (vertical 1080p60 first) is still outstanding — no fix until a take names the stage.
- ⛔ Sudo password rotation pending (user; then update both
CREDENTIALS.mdpassword lines). - ✅ TASK 56 secret scan — DONE 2026-10-22, CLEAN. 432 reachable commits (all branches, 35
tags, reflog, stash) + 63 dangling commits + the worktree: 0 real secrets. 4 rule hits, all
false positives (
README.md:79= theyour-client-secretdoc placeholder;TokenStoreTests.cs:22= a 9-char test dummy).CREDENTIALS.md/MARCOM.md/Helpers/OAuthCredentials.cswere never tracked. ⚠️ the repo was already public (anonymous GET → 200, APIprivate = false) when the scan ran — the gate came late, but nothing leaked. Method + verdict:TASKS/task-56-secret-scan.md. - TASK 55 disk hygiene: slice 1 (log rotation) shipped 2026-10-22 — see the At-a-glance bullet.
Slices 2 (temp alert-clip cleanup) + 3 (low-disk guard before recording) are open. (The GOG
Galaxy
cef.logat 2.7 GB is NOT ours.)
Tests
- Last full run: 438/438 passed, 0 warnings (2026-10-22 — after TASK 48 slice 2's
manifest guard; the run before was 437/437 after slice 3's
StorePackagingTests, then 436/436 after TASK 55 slice 1'sAppLogRotationTestsand 435/435 after TASK 63). The one failure seen earlier in the session wasLayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder, which passes in isolation (re-run: 3/3) — the known real-mouse flake, not a regression. - Known flaky-by-environment (all pass in isolation):
AudioPipelineTests.Mix_HonorsProviderGains…,MasterLimiter_CapsTheLiveMix_OnThePipe,LayerReorderPersistenceTests.RealMouseDrag…,Round_Clip_Corner….- ⚠️
LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorderis NOT "passes in isolation" any more. During this session it FAILED ALONE on a clean tree at58b9a7d(the vv work stashed) with the same "Expected: ImgC / Actual: ImgA" — i.e. it is an environment/real-mouse flake, not a regression from the vv work — and it PASSES in the full-suite run (429/429). Treat it as environment-dependent, and don't chase it as a regression without stashing first.
- ⚠️
Secrets / paths (do not re-hunt)
- Layout DB:
%APPDATA%\ytLlive\ytLlive.db(SQLite, full-rewrite per save). Auth:%APPDATA%\ytLlive\ytLlive.auth(DPAPI). Startup log:%APPDATA%\ytLlive\startup.log(23MB — now CAPPED at 5 MB with one rolled copy, TASK 55). - Recordings land in
C:\Users\gramp\Downloads\recordings\(ty-<date>-<time>-<ms>-<seq>.mp4; a duplicate name gets a-2suffix). - Conversation history:
~/.local/share/opencode/opencode.db, tablesession_message— creator turns aretype='user'with text indata.text; my turns aretype='assistant'with reasoning AND the rendered reply concatenated intocontent[0].text. The reply marker's verbatim string is recorded inMyMistakes.md. - LAN credentials:
CREDENTIALS.md(gitignored) — ⚠️ stale for HA: it says192.168.50.144, the real Home Assistant is192.168.50.145(homeassistant.local, HAOS 18.2, Core 2026.10.1, SSHgramps/einstein,/configroot-owned).gorditois.144. Fix this file when next editing it. - Google Cloud OAuth project number
198374416003, owned byllamachile.shop@gmail.com— verify athttps://console.cloud.google.com/apis/credentials?project=198374416003.
Open (operational) — officerFriendly / PS5 "DNS errors" (2026-10-17, off-repo)
- Root cause: a ~43 h-wrong system clock on officerFriendly ×
dnssec = true. Pi 400, no RTC hardware at all, healthy oscillator (−7.39 ppm). Journal shows +54 min, +7 h, +42.9 h steps.pihole-FTL.db: 1,688,396dnssec=3rows on 10-11, 839,276 on 10-12 vs ≤23 other days, hitting PSN endpoints = the PS5's "DNS errors". KSK-rollover theory retracted. - Pending creator decision (do not apply unilaterally): tighten
/etc/systemd/timesyncd.conf.d/lan.conftoPollIntervalMinSec=16/PollIntervalMaxSec=64/ConnectionRetrySec=8/SaveIntervalSec=30, and/or add a DS3231 RTC (i2c-toolsalready installed). - LAN DNS routing vs creator intent: DHCP still hands out
.26+.1(clients query Pi-hole directly) whereas the creator wants everything →.1with BBR forwarding. Alsodnssec = trueon Pi-hole duplicates dnscrypt-proxy'srequire_dnssec = true. Both offered-for-veto, not done. - Router is the DHCP server (ASUS ROG GT-BE98 Pro
.1) — Pi-hole.26is DNS only, itsdhcp.leasesis 0 bytes.