20d59fae
docs(e2e): say what the bell leg's cleanup and its zero-OSC check actually do
a73x 2026-08-15 21:28
Commit message
test/e2e.sh
| Old | New | ||
|---|---|---|---|
| @@ -806,10 +806,17 @@ cleanup() { | |||
| 806 | # ...and its other half: the paste capture and the file nvim wrote, which | 806 | # ...and its other half: the paste capture and the file nvim wrote, which |
| 807 | # IS that scenario's assertion rather than a log beside it. | 807 | # IS that scenario's assertion rather than a log beside it. |
| 808 | rm -f "$OUT.paste" "$OUT.paste.err" "$OUT.paste.log" "$OUT.pasted.txt" | 808 | rm -f "$OUT.paste" "$OUT.paste.err" "$OUT.paste.log" "$OUT.pasted.txt" |
| 809 | # ...and the bell leg's five: the four the other side-channel legs have, | 809 | # ...and the bell leg's five, plus the daemon capture and socket, since |
| 810 | # plus the daemon capture, since this leg runs a daemon of its own. The | 810 | # that leg runs a daemon of its own. |
| 811 | # daemon capture is rm'd here and never mid-suite, so the leak sweep above | 811 | # |
| 812 | # still has it to read. | 812 | # All six are ALSO rm_swept mid-suite on success, which is not a conflict: |
| 813 | # rm_swept banks a capture's LEAK verdict into $LEAKBANK before deleting | ||
| 814 | # it, and the sweep above reads the bank for everything that no longer | ||
| 815 | # exists. So the daemon capture's verdict survives its own deletion, and | ||
| 816 | # this line is the backstop for the runs where that rm_swept never ran — | ||
| 817 | # the failing ones, which are exactly the runs somebody is looking at. The | ||
| 818 | # tp1 leg sweeps its own daemon capture the same way (see its rm_swept), | ||
| 819 | # so this is that leg's convention rather than a new one. | ||
| 813 | rm -f "$SOCK24" "$OUT.d21.d" \ | 820 | rm -f "$SOCK24" "$OUT.d21.d" \ |
| 814 | "$OUT.bell" "$OUT.bell.err" "$OUT.bell.log" "$OUT.bell.sh" | 821 | "$OUT.bell" "$OUT.bell.err" "$OUT.bell.log" "$OUT.bell.sh" |
| 815 | # M14 handoff. The shim, both runtime dirs (each holding its daemon's | 822 | # M14 handoff. The shim, both runtime dirs (each holding its daemon's |
| @@ -3046,20 +3053,27 @@ ok "a paste into nvim keeps its indentation" | |||
| 3046 | # attaching there is then told about. On a fresh daemon nothing sets a | 3053 | # attaching there is then told about. On a fresh daemon nothing sets a |
| 3047 | # title and nothing copies, so neither OSC has an occasion to be built. | 3054 | # title and nothing copies, so neither OSC has an occasion to be built. |
| 3048 | # 2. The zero-OSC check below, which is what turns that argument into a | 3055 | # 2. The zero-OSC check below, which is what turns that argument into a |
| 3049 | # measurement. With no `ESC]` anywhere in the capture, every BEL in it | 3056 | # measurement. With no `ESC]` anywhere in the capture, no BEL in it can |
| 3050 | # is a bare bell — there is no sequence left for one to be terminating. | 3057 | # be terminating a sequence. |
| 3051 | # | 3058 | # |
| 3052 | # The session's own OSC 133 marks are BEL-terminated too and do not reach | 3059 | # That leaves one way a BEL could arrive with no `ESC]` in front of it, which |
| 3053 | # here, because the engine consumes them into cmd_state rather than | 3060 | # check 2 would NOT catch: as painted cell content, since paint.zig writes |
| 3054 | # forwarding bytes. That is not an assumption either: check 2 would see them. | 3061 | # row.bytes verbatim. It cannot arise here — ghostty-vt executes C0 rather |
| 3062 | # than storing it, and this session paints a prompt, an echo and BELLDONE — | ||
| 3063 | # but the two checks above are what make the count unambiguous, not a proof | ||
| 3064 | # that no other path to a BEL exists. | ||
| 3055 | "$MUXD" run --sock "$SOCK24" --shell /bin/sh > "$OUT.d21.d" 2>&1 & | 3065 | "$MUXD" run --sock "$SOCK24" --shell /bin/sh > "$OUT.d21.d" 2>&1 & |
| 3056 | D21PID=$! | 3066 | D21PID=$! |
| 3057 | wait_sock "$SOCK24" "$OUT.d21.d" "bell daemon socket never appeared" | 3067 | wait_sock "$SOCK24" "$OUT.d21.d" "bell daemon socket never appeared" |
| 3058 | 3068 | ||
| 3059 | # Five rings in ONE printf, which is one write and therefore one pty read and | 3069 | # Five rings in ONE printf, which is one write and so in practice one pty read |
| 3060 | # one drain. Split across two writes they would be two chunks and two frames | 3070 | # and one drain — the line discipline is not going to split five bytes short of |
| 3061 | # — correctly, since coalescing is per drain — so the single printf is what | 3071 | # a full output buffer, but that is a property of the read side rather than |
| 3062 | # makes "one" the right answer rather than a number that depends on timing. | 3072 | # anything the single write guarantees. Split across two writes they would be |
| 3073 | # two chunks and two frames, correctly, since coalescing is per drain; the | ||
| 3074 | # single printf is what makes "one" the right answer here. A split would show | ||
| 3075 | # up as `2 bells ... want exactly 1`, so read that as a chunking accident | ||
| 3076 | # before reading it as lost coalescing. | ||
| 3063 | # | 3077 | # |
| 3064 | # Emitted by a FILE, never typed, for the M12 reason spelled out on the | 3078 | # Emitted by a FILE, never typed, for the M12 reason spelled out on the |
| 3065 | # clipboard leg: the shell echoes what is typed, so a needle that could | 3079 | # clipboard leg: the shell echoes what is typed, so a needle that could |