fix: address round 2 review findings from issue #81

- Move atomic mv inside gardener loop so reply is only claimed when a
  matching needs_human session exists (fixes reply-loss regression)
- Delay rm of claimed file until after successful injection in both
  supervisor and gardener (OOM/SIGKILL leaves file recoverable)
- Fix matrix_listener ack message: 'next poll' instead of 'next supervisor poll'

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-17 22:59:05 +00:00
parent bfe0c09b5c
commit 63e60de9d6
3 changed files with 30 additions and 31 deletions

View file

@ -66,23 +66,24 @@ fi
# ── Inject human replies into needs_human dev sessions (backup to supervisor) ─
HUMAN_REPLY_FILE="/tmp/dev-escalation-reply"
_gr_claimed="/tmp/dev-escalation-reply.gardener.$$"
if [ -s "$HUMAN_REPLY_FILE" ] && mv "$HUMAN_REPLY_FILE" "$_gr_claimed" 2>/dev/null; then
for _gr_phase_file in /tmp/dev-session-"${PROJECT_NAME}"-*.phase; do
[ -f "$_gr_phase_file" ] || continue
_gr_phase=$(head -1 "$_gr_phase_file" 2>/dev/null | tr -d '[:space:]' || true)
[ "$_gr_phase" = "PHASE:needs_human" ] || continue
_gr_issue=$(basename "$_gr_phase_file" .phase)
_gr_issue="${_gr_issue#dev-session-${PROJECT_NAME}-}"
[ -z "$_gr_issue" ] && continue
_gr_session="dev-${PROJECT_NAME}-${_gr_issue}"
tmux has-session -t "$_gr_session" 2>/dev/null || continue
# Atomic claim — only take the file once we know a session needs it
_gr_claimed="/tmp/dev-escalation-reply.gardener.$$"
[ -s "$HUMAN_REPLY_FILE" ] && mv "$HUMAN_REPLY_FILE" "$_gr_claimed" 2>/dev/null || continue
_gr_reply=$(cat "$_gr_claimed")
rm -f "$_gr_claimed"
for _gr_phase_file in /tmp/dev-session-"${PROJECT_NAME}"-*.phase; do
[ -f "$_gr_phase_file" ] || continue
_gr_phase=$(head -1 "$_gr_phase_file" 2>/dev/null | tr -d '[:space:]' || true)
[ "$_gr_phase" = "PHASE:needs_human" ] || continue
_gr_issue=$(basename "$_gr_phase_file" .phase)
_gr_issue="${_gr_issue#dev-session-${PROJECT_NAME}-}"
[ -z "$_gr_issue" ] && continue
_gr_session="dev-${PROJECT_NAME}-${_gr_issue}"
tmux has-session -t "$_gr_session" 2>/dev/null || continue
_gr_inject_msg="Human reply received for issue #${_gr_issue}:
_gr_inject_msg="Human reply received for issue #${_gr_issue}:
${_gr_reply}
@ -91,20 +92,19 @@ Instructions:
2. Continue your work based on their input.
3. When done, push your changes and write the appropriate phase."
_gr_tmpfile=$(mktemp /tmp/human-inject-XXXXXX)
printf '%s' "$_gr_inject_msg" > "$_gr_tmpfile"
tmux load-buffer -b "human-inject-${_gr_issue}" "$_gr_tmpfile" || true
tmux paste-buffer -t "$_gr_session" -b "human-inject-${_gr_issue}" || true
sleep 0.5
tmux send-keys -t "$_gr_session" "" Enter || true
tmux delete-buffer -b "human-inject-${_gr_issue}" 2>/dev/null || true
rm -f "$_gr_tmpfile"
_gr_tmpfile=$(mktemp /tmp/human-inject-XXXXXX)
printf '%s' "$_gr_inject_msg" > "$_gr_tmpfile"
tmux load-buffer -b "human-inject-${_gr_issue}" "$_gr_tmpfile" || true
tmux paste-buffer -t "$_gr_session" -b "human-inject-${_gr_issue}" || true
sleep 0.5
tmux send-keys -t "$_gr_session" "" Enter || true
tmux delete-buffer -b "human-inject-${_gr_issue}" 2>/dev/null || true
rm -f "$_gr_tmpfile" "$_gr_claimed"
rm -f "/tmp/dev-renotify-${PROJECT_NAME}-${_gr_issue}"
log "${PROJECT_NAME}: #${_gr_issue} human reply injected into session ${_gr_session} (gardener)"
break # only one reply to deliver
done
fi
rm -f "/tmp/dev-renotify-${PROJECT_NAME}-${_gr_issue}"
log "${PROJECT_NAME}: #${_gr_issue} human reply injected into session ${_gr_session} (gardener)"
break # only one reply to deliver
done
# ── Fetch all open issues ─────────────────────────────────────────────────
ISSUES_JSON=$(codeberg_api GET "/issues?state=open&type=issues&limit=50&sort=updated&direction=desc" 2>/dev/null || true)