Some checks failed
ci/woodpecker/pr/ci Pipeline failed
Invert the delivery verdict from negative to positive evidence. Previously, success was declared by the ABSENCE of a draft snippet on a prompt line: if the `❯|^>|│ >` glyph matched nothing (busy-receiver draft on an unmatched line, or wrong-pane drift), an UNSUBMITTED message read as "✓ delivered" exit 0 — a silent worker->lead relay stall (filed by UC-LEAD, PR #3046: three review verdicts reported delivered but never surfaced for ~50 min). Fix: success now requires POSITIVE evidence — either the queued banner, or the REPL input box located AND clear of the message tail. If the input box cannot be located, status is `unconfirmed` -> exit 2 + stderr ("could not confirm submission ... may be UNDELIVERED"). The near-dead `*)` indeterminate default also flips from silently returning 0 to exit 2. Bracketed-paste and double-Enter delivery mechanics are unchanged; queued/draft/delivered semantics are preserved, only the failure-mode default direction changes. Adds `test-send-message-verdict.sh`: 3 real tmux-pane fixtures (delivered / unconfirmed-glyphless / draft) locking the fail-loud verdict logic, and upgrades `test-send-message-socket.sh` fixtures from a glyphless bash prompt to `❯`-prompt REPLs so the patched binary can read delivery positively. Reproduce-first evidence (baseline vs patched, glyphless-pane fixture): baseline: rc=0, stdout "✓ delivered to =noglyph" (silent false positive) patched: rc=2, stderr "could not confirm submission ... may be UNDELIVERED" Test results after port: test-send-message-verdict.sh -> PASS=3 FAIL=0 test-send-message-socket.sh -> ok Firewall: grep -niE 'jason|woltje|jarvis' on changed files = 0 hits; tools/quality/scripts/verify-sanitized.sh -> sanitization gate passed. shellcheck: 1 pre-existing SC2034 finding (unused loop var `attempt`, present identically in baseline) carried through; 0 new findings. Part of #891
79 lines
2.8 KiB
Bash
Executable File
79 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR=$(cd -- "$(dirname -- "$0")" && pwd)
|
||
SEND_MESSAGE="$SCRIPT_DIR/send-message.sh"
|
||
AGENT_SEND="$SCRIPT_DIR/agent-send.sh"
|
||
SOCKET="mosaic-test-$RANDOM-$$"
|
||
TARGET="target-$RANDOM"
|
||
DEFAULT_TARGET="default-target-$RANDOM"
|
||
TMPDIR=$(mktemp -d)
|
||
trap 'tmux -L "$SOCKET" kill-server >/dev/null 2>&1 || true; tmux kill-session -t "$DEFAULT_TARGET" >/dev/null 2>&1 || true; rm -rf "$TMPDIR"' EXIT
|
||
|
||
fail() {
|
||
echo "FAIL: $*" >&2
|
||
exit 1
|
||
}
|
||
|
||
require_tmux() {
|
||
command -v tmux >/dev/null 2>&1 || fail "tmux is required"
|
||
}
|
||
|
||
capture_named() {
|
||
tmux -L "$SOCKET" capture-pane -t "=$TARGET:0.0" -p
|
||
}
|
||
|
||
capture_default() {
|
||
tmux capture-pane -t "=$DEFAULT_TARGET:0.0" -p
|
||
}
|
||
|
||
require_tmux
|
||
|
||
tmux -L "$SOCKET" new-session -d -s "$TARGET" -c "$TMPDIR" 'PS1="❯ " exec bash --noprofile --norc -i'
|
||
tmux new-session -d -s "$DEFAULT_TARGET" -c "$TMPDIR" 'PS1="❯ " exec bash --noprofile --norc -i'
|
||
|
||
"$SEND_MESSAGE" -L "$SOCKET" -t "=$TARGET" -m "named socket hello" >/tmp/send-message-named.out
|
||
sleep 0.2
|
||
capture_named | grep -qF "named socket hello" || fail "send-message.sh did not deliver to named socket"
|
||
if capture_default | grep -qF "named socket hello"; then
|
||
fail "send-message.sh leaked named-socket message to default tmux server"
|
||
fi
|
||
|
||
"$AGENT_SEND" -L "$SOCKET" -S "tester:source" -s "=$TARGET" -m "agent socket hello" >/tmp/agent-send-named.out
|
||
sleep 0.2
|
||
capture_named | grep -qF "[tester:source ->" || fail "agent-send.sh did not include preamble"
|
||
capture_named | grep -qF "agent socket hello" || fail "agent-send.sh did not deliver to named socket"
|
||
if capture_default | grep -qF "agent socket hello"; then
|
||
fail "agent-send.sh leaked named-socket message to default tmux server"
|
||
fi
|
||
|
||
# Concurrency: parallel senders on one server must not cross-deliver or drop.
|
||
# Locks the unique-per-invocation paste buffer (a fixed buffer name raced:
|
||
# load overwrote load, -d deleted underneath — messages swapped between panes).
|
||
CONC_N=5
|
||
for i in $(seq 1 "$CONC_N"); do
|
||
tmux -L "$SOCKET" new-session -d -s "conc-$i" -c "$TMPDIR" 'PS1="❯ " exec bash --noprofile --norc -i'
|
||
done
|
||
pids=()
|
||
for i in $(seq 1 "$CONC_N"); do
|
||
"$SEND_MESSAGE" -L "$SOCKET" -t "=conc-$i" -m "CONCPAYLOAD-${i}-END" >/dev/null &
|
||
pids+=($!)
|
||
done
|
||
for pid in "${pids[@]}"; do
|
||
wait "$pid" || fail "concurrent send-message.sh invocation exited non-zero"
|
||
done
|
||
sleep 0.2
|
||
for i in $(seq 1 "$CONC_N"); do
|
||
pane=$(tmux -L "$SOCKET" capture-pane -t "=conc-$i:0.0" -p)
|
||
printf '%s' "$pane" | grep -qF "CONCPAYLOAD-${i}-END" \
|
||
|| fail "concurrent send dropped payload for pane conc-$i"
|
||
for j in $(seq 1 "$CONC_N"); do
|
||
[ "$j" = "$i" ] && continue
|
||
if printf '%s' "$pane" | grep -qF "CONCPAYLOAD-${j}-END"; then
|
||
fail "concurrent send cross-delivered payload $j to pane conc-$i"
|
||
fi
|
||
done
|
||
done
|
||
|
||
echo "ok - named tmux socket send tools"
|