a73x

3f277597

fix: tp1's daemon guard proves serving, not existing

a73x   2026-08-10 12:54

Commit message
fix: tp1's daemon guard proves serving, not existing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

test/e2e.sh
Old New
@@ -1842,7 +1842,15 @@ done
1842 # made=2/suppressed=1 on the next. Under load all three could coalesce, 1842 # made=2/suppressed=1 on the next. Under load all three could coalesce,
1843 # which would read as made=0 — the mutation's own signature. One send 1843 # which would read as made=0 — the mutation's own signature. One send
1844 # cannot coalesce with anything, so the counters below are exact. 1844 # cannot coalesce with anything, so the counters below are exact.
1845 set +e 1845 #
1846 # suppressed=0 therefore says more than "the keystroke predicted", and the
1847 # rest is worth writing down because a future edit to the input path could
1848 # take it away silently: Ctrl-\ is answered and returned on before
1849 # offerKeystroke is ever reached (client.zig:874), so the detach chord
1850 # cannot land in the counter; and Shift+PageUp has to arrive as ONE read,
1851 # because the whole-chunk mem.eql at client.zig:882 is what recognizes it —
1852 # split across two reads it matches nothing, falls through to the keystroke
1853 # path, and is both counted suppressed and forwarded to the shell as input.
1846 MUX_PREDICT_STATS=1 timeout 60 "$PTYCLIENT" --cols 80 --rows 24 \ 1854 MUX_PREDICT_STATS=1 timeout 60 "$PTYCLIENT" --cols 80 --rows 24 \
1847 --out "$OUT.tp1" --err "$OUT.tp1.err" -- \ 1855 --out "$OUT.tp1" --err "$OUT.tp1.err" -- \
1848 "$MUX" --via "$MUXD proxy --sock $SOCK13" > "$OUT.tp1.log" 2>&1 <<'EOF' & 1856 "$MUX" --via "$MUXD proxy --sock $SOCK13" > "$OUT.tp1.log" 2>&1 <<'EOF' &
@@ -1858,16 +1866,20 @@ send \x1c
1858 waitexit 15000 1866 waitexit 15000
1859 EOF 1867 EOF
1860 TP1PID=$! 1868 TP1PID=$!
1861 set -e
1862 1869
1863 # The tear goes between verb 3 (the scroll view is on screen) and verb 4; 1870 # The tear goes between verb 3 (the scroll view is on screen) and verb 4;
1864 # the fixture's "done 3" line is the barrier. Every needle above is unique 1871 # the fixture's "done 3" line is the barrier. Every needle above is unique
1865 # to its phase, which is what makes each expect sound under the no-counting 1872 # to its phase, which is what makes each expect sound under the no-counting
1866 # rule: 1873 # rule:
1867 # the first "100" is the attach snapshot's last row; 1874 # the first "100" is the attach snapshot's last row;
1868 # "60" is in the history page (54..77) and in NOTHING before it — the 1875 # "60" is in the history page (54..77) and in NOTHING before it. The
1869 # snapshot's rows are 78..100 and the client's own paints address rows 1876 # snapshot's rows are 78..100, and the escapes around them cannot spell
1870 # and column 1 only, so no cursor escape can spell it; 1877 # it either — but that is a fact about THIS session, not about the paint
1878 # code: both paint paths end with a CUP carrying the cursor's real
1879 # column (client.zig:968, :991), and a cursor at column 60 would put a
1880 # "60" in the stream. Here it cannot be: the session is cat in canonical
1881 # mode with one keystroke typed after the tear, so that column is 1 or 2
1882 # for the whole scenario, and the row half of a CUP tops out at 24;
1871 # "reconnecting" is the banner, painted once, on the tear; 1883 # "reconnecting" is the banner, painted once, on the tear;
1872 # the SECOND "100" can only be the post-resync repaint: the scroll view 1884 # the SECOND "100" can only be the post-resync repaint: the scroll view
1873 # holds 54..77, and the banner carries no digits but its own position; 1885 # holds 54..77, and the banner carries no digits but its own position;
@@ -1890,7 +1902,12 @@ wait_for "$OUT.tp1.log" "done 3" 20 || {
1890 TP1PROXY=$(proxy_pid "$SOCK13") 1902 TP1PROXY=$(proxy_pid "$SOCK13")
1891 [ -n "$TP1PROXY" ] || { echo "e2e FAIL: tp1: no proxy to tear"; exit 1; } 1903 [ -n "$TP1PROXY" ] || { echo "e2e FAIL: tp1: no proxy to tear"; exit 1; }
1892 kill -9 "$TP1PROXY" 1904 kill -9 "$TP1PROXY"
1893 kill -0 "$D13PID" || { echo "e2e FAIL: tp1 tear killed the daemon, not the proxy"; exit 1; } 1905 # The daemon must still be SERVING, which is what `kill -0` cannot tell us:
1906 # it is our own backgrounded child, so a dead one is a zombie until the
1907 # shell reaps it, and signalling a zombie succeeds. A dump answers only if
1908 # the process is alive and its accept loop is running.
1909 "$MUXD" dump --sock "$SOCK13" >/dev/null 2>&1 || {
1910 echo "e2e FAIL: tp1 tear killed the daemon, not the proxy"; exit 1; }
1894 1911
1895 set +e 1912 set +e
1896 wait "$TP1PID" 1913 wait "$TP1PID"