← Commit history

pup-bridge-dev: document R6 (a newborn window's self-activation is Chrome, never the user), the implementation map for R1-R6, and the VERIFIED evidence table from the 2.0.259-261 run including John's three-vendor separate-tile test

John Lauer ·f06b6d9474 ·2mo ago ·parent 4eebe87
1 file changed +93
dev-skills/pup-bridge-dev/SKILL.md+93
@@ -387,6 +387,99 @@ AFTER his "click the flash, see nothing" bug specifically to reverse this. Two s code followed the older one, and either could be cited to justify whatever the code did. That is why this section is now the single source for placement and the others defer to it. +### R6 A NEWBORN WINDOW'S SELF-ACTIVATION IS CHROME, NEVER THE USER (v2.0.261)++R1 exposed this the day it shipped, and it is the subtlest of the set. Every user-intent check in the+bridge attributes an OS-foreground pup window to the USER — either `session._userActiveAt`, or simply+"there was keyboard/mouse input in the last 5 seconds" (`osIdleMs() < 5000`). For an established+window that is right. For a window born one second ago it is **wrong**, because a human cannot have+clicked a taskbar button that did not exist yet.++John opened ti.com while typing. Chrome self-activated the new on-screen window, the idle check saw+his keystrokes, pup concluded he had raised it, and every demotion path stood down:++```+[park] "ti-proof" (post-nav re-assert): user-foreground — hands off      <- on a window he never touched+```++So pup put an unasked-for window on top of his work and then defended it. The off-screen birth had+been hiding this the whole time: Chrome does not bother activating a window that is nowhere.++**The rule:** `session._bornAt` is stamped at creation, and for `BIRTH_GRACE_MS` (8s) an+OS-foreground pup window is attributed to Chrome and BOTTOMED, never credited to the user. Honored in+three places, and it must stay honored in all three or the flags leak in through whichever one you+forget:+- `osBottomUnlessForeground` — bottoms instead of returning `user-foreground`;+- `userIsUsingWindow` — returns false, so no demotion path stands down;+- the 15s foreground OBSERVER — skips, so it cannot stamp `_foreground`/`_userActiveAt` permanently.++**Exempt:** an explicitly granted `foreground:true` open or `pup_raise_os_window` sets+`_raiseGranted`, because that window is SUPPOSED to be in front. The grace exists only to stop+Chrome's self-activation of an *unasked-for* window being read as intent.++## How R1-R6 are actually implemented (the map, so you can change it safely)++| Piece | Where | What it does |+|---|---|---|+| `primaryWorkArea()` | `server.js` | `SystemParametersInfo(SPI_GETWORKAREA)` via one PS call, cached 5 min. Answers WITHOUT a window, which is the chicken-and-egg that pushed the old design into staging off-screen (`screen.availWidth` needs a page that does not exist yet). |+| `birthRect()` | `server.js` | Work area inset 10px on all four sides. Falls back to `10,10 1280x800` — conservative, never off-screen. |+| `createPageInNewWindow` | `server.js` | `Target.createTarget {newWindow:true, left, top, width, height}` — the window is CREATED at its final rect. |+| birth hwnd capture | same fn | `withBirthLock` + top-level window set-diff filtered to THIS profile's Chrome PIDs. No coordinate involved. If >1 window appears under the lock it **refuses to guess** and logs loudly — a wrong hwnd paints another window's badge and parks the wrong window, so late beats wrong. |+| focus handback | same fn | If `createTarget` took the foreground, hand it straight back once. Window is never moved. |+| `parkSessionWindowDirect` | `server.js` | No longer a placement gate. 3 bounded bottom attempts, then `placeOnScreen()` unconditionally. Cannot move/hide/off-screen a window when it fails. |+| `BIRTH_GRACE_MS` / `inBirthGrace()` | `server.js` | R6, above. |+| `sweepVisibility` | `server.js` | 30s BACKSTOP only. Repairs hidden and off-screen windows population-wide by owning PID. Leaves minimized alone. |++**Deleted on purpose — do not bring these back:** `moveOffScreen()` (its entire job was moving the+user's window where they cannot click it) and `zConfirmedBelow()` (it gated placement on a proof that+returned false whenever our hwnd was absent from ab's enumeration — which an off-screen window often+is, so the failure sustained itself, and it has no correct answer at all when the user has no other+windows open).++## VERIFIED — the run that closed this out (2026-08-20, pup 2.0.259-261)++Measured, not asserted. Re-run these before believing any future change to the open path.++| Claim | How it was measured | Result |+|---|---|---|+| Born on-screen, never staged | Polled the OS window list continuously *during* an open | **First sighting +1508ms, already at `10,10`, still `about:blank`** (mid-creation, pre-navigation) |+| Correct geometry | `[hwnd] birth-resolved ... born on-screen at` | `10,10 1687x999` (AdomLapper), `10,10 1900x1012` (crr, work area 1920x1032 inset 10) |+| hwnd exact under CONCURRENCY | Opened mouser.com + digikey.com **simultaneously**, then probed each claimed handle's real title via `GetWindowText` | `4266560`=Mouser, `1382102`=DigiKey, `3676722`=TI — all correct, no cross-wiring |+| hwnd exact under concurrency, HARDER (John's better test) | Opened ti.com + mouser.com + digikey.com **simultaneously, each under a DISTINCT owner thread** so each earns its own taskbar button, then probed all three handles | `5185636`=TI, `1911306`=Mouser, `4853816`=DigiKey — all correct, all at `10,10 1687x999`, three separate buttons each reading "1 running window" |+| R6: newborn is not the user | Opened ti.com while John typed, before vs after | before: `user-foreground — hands off`; after: **`bottomed`** |+| R6: user's focus survives | Foreground hwnd before vs after an open | `6761994` → `6761994`, unchanged |+| Focus handback fires | crr log | `[focus] createTarget took the foreground (460748 -> 6817858) ... handing your keyboard focus straight back`, foreground returned to `460748` |+| Backstop still works | Stranded a window at `-32000,-32000` (John's exact failure state) | pulled back to `10,10` in 50s (crr) / 85s (AdomLapper) |+| No regressions | `tools/selftest.sh` both machines | 13/13 GREEN on AdomLapper and ConfRoomROG |++**Known gap, stated rather than papered over:** on the AdomLapper re-test the `[focus]` handback line+did not appear, so it is not established whether the birth grace alone carried it or the handback+also fired. The OUTCOME was correct either way (foreground unchanged, window bottomed), but if you+are touching this path, resolve that first instead of inheriting my uncertainty.++**The strongest single test (John's, and the one to run first from now on):** open ti.com, mouser.com+and digikey.com **simultaneously, each under a different `owner` / `ADOM_AI_THREAD`**. One pass then+exercises everything that has ever broken here at once:+- three windows born concurrently (the birth lock, R1, R4),+- three DISTINCT thread tiles rather than one grouped button, so per-window identity is visible on+  glass instead of inferred from a log line,+- three different vendor favicons decoded onto the badges — and **ti.com and mouser.com are exactly+  the two that used to render generic globes** (classic BMP/DIB-in-ICO, fixed by `icoLargestDibRgba`+  in 2.0.212), so this doubles as the icon-decode regression test,+- and it stays in the user's chosen `tiles` mode, so nothing about his settings has to be disturbed+  to run it. Do NOT flip `taskbarMode` to `aumid` to get per-window icons; distinct owners is the+  production-realistic shape and leaves the user's mode alone.++Measured 2026-08-20: three buttons, `mouser vendor test` / `ti vendor test` / `digikey vendor test`,+each "1 running window", each wearing its own favicon badge (Mouser blue M, TI red Texas logo,+DigiKey red D). Red-boxed pixel evidence in shotlog channel `pup-window-fix`.++**How to re-verify in one pass:** open a window with a poller running against the OS window list and+assert the FIRST sighting is on-screen (not the final position — the final position was always right,+that is what made this bug survive so long); open two windows simultaneously and check each claimed+hwnd against `GetWindowText`; open one while typing and assert the log says `bottomed`, not+`user-foreground`.+ **Still true, still load-bearing (do not re-derive):** - `--no-startup-window` is load-bearing, but **it was never the whole focus fix** — MEASURED on   ConfRoomROG the moment R1 landed (2026-08-20). The off-screen birth was doing half the work,