W3 fix lane proof (branch w3-fix, dry run port 7094, headless bundled Chromium, 2026-10-11)
- 0 dryrun:
tools/mac-dryrun.sh 7074 ~/trc-lighting/wt-fix against another worktree's server exits 2 and prints "stale pid 55828 cwd /Users/gregspero/trc-lighting/unstable"; a second start on 7094 reuses its own pid 20428 (exit 0). Launch now uses the absolute dll path so the command line names the worktree.
- 1 desk rail: 1536x864 document 1866 -> 1536 wide; rail 8-1528, set list strip 1111-1396, Screen 2 button 1404-1519, GO 64x44. 1366x768: rail 8-1358, peer 1240-1349, GO 56x44. Set list strip = name button (opens picker) + Back + GO. Nudge, half, double moved into an Adjust pop-up (4 x 44x44, Escape and outside tap close it). scrollTo(900,900) and a 900 px wheel leave scrollX/scrollY 0 (was 330 px).
- 1 lock: html and body overflow hidden + overscroll none on desk, screen 2 and phone; pinScroll() in controls.js resets any page scroll on all three.
- 2 screen 2 1920x1080: document 1947 -> 1920 wide; peer label "Screen 1 not open" 117 px, scrollWidth 117 = clientWidth, right edge 1912; ellipsis + min-width 0 as a guard.
- 3 phone: set list block 130 -> 44 px, one row (name, Back, GO). 844x390 shows 2 full rows of 4 tiles (was 1). With no set lists (stubbed) the block is hidden, 0 px, both orientations.
- 4 camera pill: "No camera" now ld-state neutral (grey); kill red stays for blackout only on that pill.
- 5 fan: with 4 washes picked the Colour card shows "Fan colour across these" (374x44); one tap opens the Effect card, focus lands on Fan, the Fan column is outlined for 1.4 s; no element overflows the column.
- Every page, all five viewports: scrollWidth = viewport width, scrollHeight = viewport height, 0 targets under 44 px, 0 text under 12 px, 0 console errors, 0 elements past the viewport edge.
- tools/regress-v2.sh 7094: GREEN 14 passed.
- Shots: v2-shots/fix-desk.png, fix-desk-1366.png, fix-screen2.png, fix-phone-p.png, fix-phone-l.png.
- Rebased onto two-screen 0436a1e (tutorial). Help pages updated to the new Screen 2 label and grey camera tag;
node wwwroot/help/check-controls.mjs http://127.0.0.1:7094: 106 of 106 controls resolve. Proof and regress rerun after the rebase: all clean, GREEN 14.
- Commits on w3-fix: 1d049c3 (dry-run guard), 9e346cd (fixes 1-5), 21bd912 (help wording). Not pushed.
Judge-1 full list (second commit series)
- A footer: rail overflow hidden, #peerBtn flex none, timeline name shrinks (min-width 0); the desk set list strip has no read column, and the GO title carries "Ready / Build a set list on screen 2". documentElement.scrollWidth 1536 at 1536; #peerBtn right 1519 (gate <= 1528); at 1366 right 1349. Adjust pop-up is now fixed-position above the rail, so the rail clip cannot cut it (1536: 723,736 to 925,794).
- B toasts: desk and screen 2 top 64, right 16. Desk 1536 toast 1310,64 to 1520,104 and 1366 1140,64 to 1350,104, both clear of #pads. Screen 2 1681,64 to 1904,106, clear of every tile. Phone bottom calc(90px + safe area): 390x844 toast bottom 754, 844x390 bottom 300, clear of .ph-bot in both.
- C cap: KEY cap 5, Off tapped while POST /api/inhibit was stubbed to reply {"ok":true} with no inhibits. The cap button still reads 5, the editor still has 5 pressed, and an error toast says "KEY cap not changed: the desk did not confirm it. Try again." A thrown request reverts and toasts the same way.
- D phone set list: nothing renders with no set list (hidden, 0 px, both orientations); one 44 px row under the family chips otherwise.
- E screen 2 peer: "Screen 1 not open" 117 px, scrollWidth = clientWidth, min-width 0 + ellipsis guard.
- F phone BPM: phone.html starts at "---" until /api/tempo answers (then 120 on the dry run).
- G fan: one tap from the Colour card, labelled "Fan colour across these" (see above).
- H network: 0 responses >= 400 and 0 failed requests on desk 1536, desk 1366, screen 2 1920, phone 390x844 and 844x390; 0 console errors.
- Rerun after these: regress-v2 GREEN 14, check-controls 106 of 106.
Gate re-proof after the lead's merge of 21bd912 (items B, C, F, H, I)
- B toasts (fired with toast() on each page): desk 1536 at 1421,64 to 1520,104 and 1366 at 1251,64 to 1350,104, both outside #pads. Screen 2 at 1800,64 to 1904,106, outside the wall and every tile. Phone 390x844 at 146,714 to 244,754 and 844x390 at 373,260 to 471,300, both outside .ph-bot.
- C cap with POST /api/inhibit stubbed to 500: the KEY pill reads cap 5 before and after, the editor stays on 5, and the toast says "KEY cap not changed: the desk did not answer. Try again."
- F phone BPM: with /api/tempo, /api/status and /api/events held for 3 s, the page reads "---" at 0.8 s and 120 after the replies.
- H network, responses >= 400 plus failed requests per page: desk 1536 0, desk 1366 0, screen 2 1920 0, phone 390x844 0, phone 844x390 0. Console errors were 0 everywhere. No quiet404 lookup returned 404 on this server, so there are none to name.
- I blackout, 900 ms mouse hold: the desk server reads on=true and the button reads Release, and both are unchanged 600 ms later. A second tap sets on=false. The phone behaves the same and a second tap releases it. Screen 2 also reads on=true and unchanged; its release is a second hold (by design), which sets on=false. Fix: the desk now ignores the click that ends a hold that fired. A flag is set in boFire and cleared by the next pointerdown, or 400 ms after pointerup. The phone (it releases on pointerdown) and screen 2 (it releases on a hold) have no click handler that could land after the hold.
- regress-v2 GREEN 14.