← Commit history

doctrine: the birth measured to one frame (2.0.641), ab clear raises+activates, first-show park, no minimized birth, cold-birth stamp

John Lauer ·aad35e9004 ·1mo ago ·parent aee3a87
2 files changed +41−4
dev-skills/pup-bridge-dev/SKILL.md+7−4
@@ -348,10 +348,13 @@ R1 never visually pop / cover the user's work · R2 the window is reachable (tas were set after a pup window opened off-screen behind a live taskbar button for the second time in one day: *"you need to allow a user to open a pup window immediately if they want to."* -**R1 on the EXTENSION lane (2.0.630+): the extension API refuses off-screen bounds and refuses `state:"minimized"`-combined with bounds, so the ext-lane birth is `chrome.windows.create({url: birth.html?token, focused:false,-state:"minimized"})`, bound by the `PUPBIRTH-<token>` title, then shown at the bottom with `SWP_NOOWNERZORDER` and-fitted. The 50 ms move budget is recorded as 0 on this lane. The CDP-lane text below still holds for lane:"cdp".**+**R1 on the EXTENSION lane (2.0.641): the extension API refuses off-screen bounds, so the ext-lane birth is+`chrome.windows.create({url: birth.html?token, focused:false, state:"normal"})`, bound by the `PUPBIRTH-<token>`+title. The birth watcher catches the hwnd while it is still invisible, stamps the thread tile natively, and calls+`Host::park_on_first_show`, which bottoms the window in the same instant Chrome first shows it and holds it there+for 300 ms (busy for the first 100 ms). Measured residual: one frame at most. The 50 ms move budget is recorded+as 0 on this lane. See `pup-user-foreground` "The birth, measured to one frame". The CDP-lane text below still+holds for lane:"cdp".**  **R1 BIRTH IT OFF-SCREEN, PARK IT ON-SCREEN WITHIN 50ms — UNCONDITIONALLY (revised 2026-08-22, v2.0.276).** `Target.createTarget` is created at `-32000,-32000`, then IMMEDIATELY moved by `Browser.setWindowBounds`
dev-skills/pup-user-foreground/SKILL.md+34
@@ -343,3 +343,37 @@ unless the user has foregrounded it themselves. that once is too much") and the "warn first" toasts as a substitute for a background open (John: "i hate all these ab toasts... if you can truly figure out opening background pup windows, it generally solves the problem"). A toast is for the moment pup NEEDS the user (a password), not an apology for a window it should never have raised.+++## The birth, measured to one frame (2.0.635 to 2.0.641, 2026-09-19)++After 2.0.634 the 0.5 s sampler still caught a pup window on top about one run in three. A z-watch thread+(`spawn_zwatch` in `open_window_ext`, polling every 15 ms from before the extension creates the window, logging+the hwnd, its title, whether it is the foreground, and `pup_core::last_log()`) plus millisecond log timestamps+named every remaining raise. Read these before touching the birth again:++1. **ab's `desktop_clear_window_attention` RAISES AND ACTIVATES.** Every newborn became the FOREGROUND window for+   40-80 ms about a second after "jump list committed": that was `activity::clear_attention` on the open and+   navigate paths (adom-bridge#199, confirmed as an activation, not only a z1). pup's own paths now never call+   it; `clear_attention_later` stops the flash natively (`FlashWindowEx FLASHW_STOP`, `Host::stop_flash`) 2.5 s+   later, and only when the window is not the foreground. The raise path (`window.rs`) still uses ab's verb,+   because there the raise is the point.+2. **Chrome's first show puts the window ON TOP no matter what you did while it was hidden.** A `HWND_BOTTOM`+   while invisible did not survive the show. The only defense is speed: `Host::park_on_first_show` spins on+   `IsWindowVisible` at 100 us, bottoms in the same instant, then re-bottoms in a busy loop for 100 ms and at+   1 ms for 300 ms total, unless the user has made it the foreground. The birth watcher calls it the moment it+   catches the invisible window (after the native stamp). Residual: at most ~30 ms on top, which is the time+   Chrome's UI thread takes to process the request during its first paint. One composed frame at worst.+3. **`ShowWindow(SW_SHOWNOACTIVATE)` on a window that is already visible re-raises it** (19 ms, every birth).+   `show_at_bottom_no_activate` only shows a window that is hidden or minimized.+4. **No minimized birth.** The minimized create still showed the window on top for 140-250 ms before its+   minimize, and the restore surfaced it again. The worker creates `{focused:false, state:"normal"}` on the birth+   page and pup parks it as in (2). Same for the cold lane's first window.+5. **The stock icon on a cold birth was the birth watcher expiring.** It lives 4 s and was armed BEFORE the+   cold launch; Chrome took longer to start, so the cold window was never stamped before its first show and wore+   the Chrome-for-Testing icon until the deferred navigate. It is armed after the launch now, and there is a+   stamp-at-bind backstop. A warm birth was always stamped before its first show; a cold one is too now.++The gate passed 4 of 4 on 2.0.641 (ConfRoomROG) and the z-watch episodes are all under one frame. The+instrumentation stays in: the log now carries ms timestamps, and the z-watch lines are the first thing to read+when anyone says a window appeared.