← Commit history

Update 3 file(s)

John Lauer ·38a6620cf6 ·1mo ago ·parent be176fb
3 files changed +37−8
CLAUDE.md+4−1
@@ -105,7 +105,10 @@ build hung every vault verb on John's laptop and cost 14 saved logins. `tools/ab   pup's Chrome for a COLD lane, then samples the top-of-screen window twice a second through ab while it does a cold   open, two navigates, two warm opens and a navigate. PASS only when ZERO samples have a pup Chrome window on top,   counted by PROCESS (a 40-char title can lose the "Chrome for Testing" suffix and hide a window that sat on top for-  28 s). INVALID (exit 2) if any step fails or fewer than 3 windows exist at the end. This is the gate for John's+  28 s), and since 2.0.665 by pup browser PID (the process command line names `pup-profiles`, sampled every 5 s):+  on a box where the user runs their own Chrome, counting by image name blamed pup for the user's windows+  (arav-rog and AdomLapper, 2026-09-20). The gate force-kills pup's browser, so the auto-mode classifier refuses+  it on the user's own laptop; run it on CRR or winvm. INVALID (exit 2) if any step fails or fewer than 3 windows exist at the end. This is the gate for John's   goal ("stop shoving windows in front of me"); the first PASS ever was 2.0.634 on ConfRoomROG. - `tools/jumplist-ralph.py --target <box>`: every jump-list task fired THROUGH ab's taskrun shim with the   link's exact target and arguments, effect asserted in the window. Added 2026-09-06 after the Rust port
dev-skills/pup-user-foreground/SKILL.md+7
@@ -192,6 +192,13 @@ not be acted on and arrived with the window rather than ahead of it. Now: the to the warning reaches the screen first. An AI should prefer the toast ALONE and let the human click it, rather than raising at all, whenever the task can wait for them. +**A HUMAN caller gets no toast (2.0.665).** The taskbar button's relaunch command reaches the same verb+(`pup_focus_window` as caller `user-taskbar-menu`), and on 2026-09-20 John saw "pup: user-taskbar-menu needs+this window on your screen" twice while the jump-list gate fired it on his laptop: a warning to the human+about the human's own click. `window::raise` now checks `USER_CALLERS`; a human caller is raised at once,+captioned, with no toast and no 1.2 s wait, and the response says `toasted:false`. The `raise_for_user`+path (jump-list tasks that resolve a window themselves) never toasted.+ ## The birth grace may override FLAGS, never INPUT (2.0.584, John 2026-09-15)  R6's birth grace (8 s, no granted raise) skipped BOTH user signals inside the shared primitive, on the
tools/foreground-proof.sh+26−7
@@ -16,11 +16,17 @@ S="${TMPDIR:-/tmp}/fgproof-$$"; mkdir -p "$S" lw() { timeout 25 $AB desktop_list_windows '{}' 2>/dev/null; } top() { lw | python3 -c " import sys,json-d=json.load(sys.stdin); o=d.get('output',d)-if isinstance(o,str): o=json.loads(o)-w=(o.get('data') or o).get('windows') or []-t=[x for x in w if not x.get('minimized') and x.get('kind')=='normal']; t.sort(key=lambda x: x.get('z',999))-print(((t[0].get('image') or '?')+'|'+(t[0].get('title') or '')[:40]) if t else 'none')"; }+try:+    d=json.load(sys.stdin); o=d.get('output',d)+    if isinstance(o,str): o=json.loads(o)+    w=(o.get('data') or o).get('windows') or []+    t=[x for x in w if not x.get('minimized') and x.get('kind')=='normal']; t.sort(key=lambda x: x.get('z',999))+    print((str(t[0].get('pid') or '?')+'|'+(t[0].get('image') or '?')+'|'+(t[0].get('title') or '')[:40]) if t else 'none')+except Exception: print('?')"; }+# 2.0.665: the judge counts a sample only when the top window's PID belongs to a pup browser (command line names+# pup-profiles), sampled every 5 s. On a box where the user runs their own Chrome, counting by image name blamed+# pup for the user's windows (arav-rog, 2026-09-20).+puppids() { timeout 25 $AB run_script "{\"interpreter\":\"powershell\",\"scriptB64\":\"$(printf '%s' '(Get-CimInstance Win32_Process | Where-Object { $_.Name -eq "chrome.exe" -and $_.CommandLine -match "pup-profiles" } | ForEach-Object { $_.ProcessId }) -join ","' | base64 -w0)\",\"reason\":\"Sampling pup browser pids for the foreground gate\"}" 2>/dev/null | python3 -c "import sys,json; t=sys.stdin.read(); d=json.loads(t[t.index('{'):]); print((d.get('stdout') or '').strip())" 2>/dev/null; } if [ -z "$PIN" ]; then PIN=$(lw | python3 -c " import sys,json d=json.load(sys.stdin); o=d.get('output',d)@@ -45,6 +51,7 @@ timeout 120 $AB shell_execute "{\"command\":\"powershell -NoProfile -EncodedComm timeout 60 $AB desktop_bring_to_front "{\"hwnd\":$PIN,\"reason\":\"foreground proof: pin a non-pup window in front\"}" >/dev/null 2>&1; sleep 2 echo "top before: $(top)" (for i in $(seq 1 240); do echo "$(date +%H:%M:%S) $(top)"; sleep 0.5; done > "$S/samples" 2>&1) & SP=$!+(for i in $(seq 1 60); do puppids; sleep 5; done > "$S/puppids" 2>&1) & PP=$! mark() { echo "$(date +%H:%M:%S) ===== $*" >> "$S/marks"; } FAILS=0 # a step must SUCCEED: a window that never opens trivially never surfaces, and that must not read as a pass@@ -59,8 +66,20 @@ step "navigate A again" pup_navigate    '{"window":"fgp-a","url":"https://exampl step "warm open B"      pup_open_window '{"window":"fgp-b","url":"https://example.org/"}' step "warm open C"      pup_open_window '{"window":"fgp-c","url":"https://example.com/"}' step "navigate C"       pup_navigate    '{"window":"fgp-c","url":"https://example.org/"}'-mark "done"; sleep 3; kill $SP 2>/dev/null; wait 2>/dev/null-BAD=$(grep -cE "^[0-9:]+ chrome\.exe\|" "$S/samples"); TOTAL=$(grep -c . "$S/samples")   # by PROCESS: a 40-char title can lose the "Chrome for Testing" suffix (2.0.632 missed a listing window on top for 28 s)+mark "done"; sleep 3; kill $SP $PP 2>/dev/null; wait 2>/dev/null+BAD=$(python3 - "$S/samples" "$S/puppids" <<'PYJ'+import sys+pids=set()+for l in open(sys.argv[2]): pids.update(x.strip() for x in l.strip().split(',') if x.strip().isdigit())+bad=0+for l in open(sys.argv[1]):+    parts=l.split(' ',1)+    if len(parts)<2: continue+    top=parts[1].strip(); pid=top.split('|',1)[0]+    if pid in pids: bad+=1+print(bad)+PYJ+); TOTAL=$(grep -c . "$S/samples")   # by pup PID (see puppids); image-name counting blamed the user's own Chrome OPEN=$(timeout 60 $AB pup_my_windows '{}' 2>/dev/null | python3 -c " import sys,json try: print(json.load(sys.stdin).get('count') or 0)