← Commit history

Document the three-layer taskbar oracle and the four icon bugs it caught, including the title-less page that makes a window invisible to all branding

John Lauer ·afd6a25b4c · ·parent b091420
1 file changed +51
dev-skills/pup-bridge-debug/SKILL.md+51
@@ -284,3 +284,54 @@ change** and every live window rebuilds its button.   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.++## Build a taskbar ORACLE before touching icon code (2026-07-20)++Every icon regression in this file was found by eye, days late, by the user. A taskbar audit that+can actually FAIL takes about ten minutes to build and catches them in seconds. Three layers, each+catching a class the others miss:++1. **Structural** (`Shell_TrayWnd` via UIA): enumerate taskbar buttons, assert+   `branded_buttons == sessions` and `raw-Chrome buttons == 0`. Any button still named "Google+   Chrome for Testing" is an unbranded pup window. The count check catches duplicate sessions.+2. **Deterministic category**: read each `Adom.Pup.<sid>.<cat>.<gen>` key's `IconResource` and+   compare against the category derived from that session's own tab URLs. Get the URLs from+   `browser_list_tabs` PER SESSION - `browser_list_windows` returns a single `url` field, and using+   it graded a correct mixed window as a failure.+3. **Pixel** (crop each button's rect, measure it): assert the Adom teal tile is present. This is the+   layer that catches a white or generic tile, which is invisible to layers 1 and 2 because the+   registry can be perfectly correct while Windows paints something else entirely.++**Do not try to tell the five category glyphs apart from pixels.** Three attempts failed: whole-tile+RMS put every category within 1-4 units of every other (the identical teal tile is ~85% of the+pixels), and a glyph-mask IoU tripped over the dark-teal window body all five share, plus+anti-aliasing. It always answered "wiki" while looking like it worked. Layer 2 already establishes+category deterministically; layer 3 only needs to answer "is this our tile at all".++**Guard the oracle against passing vacuously.** The first run reported PASS with zero sessions, and a+later one graded results measured after the desktop had disconnected. An audit that cannot+distinguish "nothing is wrong" from "nothing was measured" is worse than none. Assert+`sessions > 0` and ping the desktop first; report INVALID, never PASS.++### What the oracle found within minutes, that eyeballing had missed for days++- A window whose page has **no `<title>`** never got its `(session: <id>)` marker, because the+  injector's guard was `if (document.title && ...)`. AD resolves pup windows by that suffix, so such+  a window is INVISIBLE to every branding call - identity, category flip, overlay and jump list all+  fail with "No visible window with title containing (session: ...)". This is the single biggest+  cause of "the icon is stale / never updates", and plenty of app routes serve a title-less shell.+- **Category was only recomputed when a tab VERB ran**, never when a page finished navigating. A tab+  is `about:blank` while its navigation is in flight, so opening two tabs back-to-back cached the+  wrong category in `_lastCat` and froze the icon there forever. Fixed by rechecking on+  `framenavigated` (debounced).+- **Never cache a category whose stamp did not land.** `_lastCat` was set before the re-stamp was+  confirmed, so an exhausted retry loop permanently suppressed every future attempt.+- **Reclaim adopted windows mid-launch**, before their own session registered, yielding two sessions+  for one window (8 sessions, 7 buttons). Fixed with a launch-in-flight skip plus a two-strike rule:+  only adopt a window seen unowned on two consecutive sweeps.++### Also worth knowing++`bridge_install` + `restart_bridge` kills pup's detached Chromes (recovery then reports every PID+dead and drops all sessions). Re-open test windows after any bridge upgrade, and do not read a+post-restart empty taskbar as an icon bug.