← Commit history

Document the white-taskbar-icon root causes (unbranded AUMID, tile-bake race, icon generation) and the two state-destroying guards found alongside

John Lauer ·35e75a41a5 · ·parent 1f03442
1 file changed +46
dev-skills/pup-bridge-debug/SKILL.md+46
@@ -238,3 +238,49 @@ a dim LED but AD-core answers = process down; a **status probe won't respawn it* `browser_open_window` then poll `browser_list_windows`. Cold start stuck across several opens = concurrent-launch wedge (already fixed by `_launchInFlight`; don't spam opens). `bridge_list status:"running"` is not liveness — the **LED + browser.bridgeRunning + a real verb reply** are.++## Symptom: a pup taskbar icon is WHITE (generic document) while its siblings look right++Measured and fixed 2026-07-20 (1.9.44 -> 1.9.46). Three separate defects stacked; check them in order.++**1. The AUMID had no icon at all.** `desktop_register_app_identity` accepts an `iconPath` but only+materialises it when it ALSO builds a Start Menu shortcut. Our per-session path passes+`shortcut:false`, so every key was created with a DisplayName and a NULL `IconResource`. Measured:+129 of 129 `HKCU\Software\Classes\AppUserModelId\Adom.Pup.*` keys were unbranded.++Check it FIRST, before touching any icon file:++```powershell+Get-ChildItem "HKCU:\Software\Classes\AppUserModelId" | Where-Object { $_.PSChildName -like "Adom.Pup.*" } |+  ForEach-Object { "{0} -> {1}" -f $_.PSChildName, (Get-ItemProperty $_.PSPath).IconResource }+```++Fix: write `IconResource` ourselves with `reg add`. HKCU needs no UAC and the bridge already runs on+the desktop, so there is no AD roundtrip and no shell-approval prompt (`writeAumidIcon`).++**2. Why it was white on ONE window and fine on the others.** The per-window `Relaunch*` properties+DO brand a button, but they are a RACE against Win11 baking the tile at button creation. Win the race+and the icon is right; lose it and Windows resolves the (unbranded) AUMID and paints the generic white+page. So the same code produced correct icons on new windows and a white one on a long-lived window.+A category or icon-file theory will send you the wrong way — an inconsistent icon across identical+code usually means a race plus an unbranded fallback, not a classification bug.++**3. Fixing the resolution does NOT repair an existing button.** Win11 never re-reads a baked tile,+and a window keeps one appId for life, so 1.9.44 fixed every future button and left the already-white+one white. The ONLY repaint is a NEW appId forcing a NEW button. Hence `PUP_ICON_GEN` folded into the+appId (`Adom.Pup.<sid>.<cat>.<gen>`): **bump it whenever the icon files or the branding mechanism+change** and every live window rebuilds its button.++### Two traps found while fixing the above — both destroyed user state++- **A crash breaker must not be able to delete healthy state.** The old recovery breaker quarantined+  any session file carrying an unfinished-attempt marker, but "unfinished" is not "crashed": a normal+  restart that races the marker-clearing write leaves marks on healthy sessions, so one restart+  quarantined ALL SIX of John's windows (`Recovering 6 session(s)... Recovery complete. 0 active`).+  Replaced with a single sentinel naming the ONE session in flight, so a crash quarantines that file+  and everything else recovers. When a guard can delete user state, make it name its evidence.+- **Never sweep "stale" entries from an empty live set.** The AUMID prune compared registry keys+  against live sessions and ran right after recovery. When recovery legitimately ended with zero+  sessions, every key looked stale and the sweep deleted all of them, unbranding windows that were+  about to be re-stamped. Now it is deferred 60s AND skipped entirely when the session map is empty:+  with nothing live there is no way to tell stale from pending, so doing nothing is the right answer.