fix(issue-17): a failed yes/no decision is not a "no" (review codex R1)

subscriber-up and stall-watch answered only by exit code, so a call that
could not run (module error rc 1, missing interpreter 127) read as "no":
with a subscriber that had ended 0, the error path mapped 0 to completed
and the submit ended with 0; a failed stall-watch silently skipped the
watcher.

Both now take --print: the answer is printed as yes/no and the exit code
is 0 for either. The wrapper asks with --print through _decided_yes, so a
nonzero exit, no answer or anything else is _decision_failed (ERROR line,
exit 1). Without --print the rc contract is unchanged (yes 0, no 1).

Tests: subscriber-up (direct and loop/discuss call sites) and stall-watch,
each failing by traceback, rc 127 or no answer with a subscriber that
ended 0, end the submit with 1 and the ERROR line - at 8241bd5 eight of the
nine ended with 0 (the loop/no-answer one ended with 1 through the loop's
own result and failed only on the ERROR line); yes and no keep their
branches in both paths; --print unit table; the static guard forbids an
rc-read yes/no decision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HCGpJXhSZasJLU38ksDghe
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-08 09:26:41 +09:00
1 parent 541c3febe8
commit 65b78b6ec4
3 files changed
+77 -13

No files matched your search

@@ -118,6 +118,18 @@ _decided() {
printf -v "$__var" '%s' "$__out"
}
# _decided_yes <subcommand> <args...>: a yes/no decision (asked with --print,
# so "no" is an answer and a failed call is not): returns 0 for yes, 1 for no.
_decided_yes() {
local yn
_decided yn "$@" --print
case "$yn" in
yes) return 0 ;;
no) return 1 ;;
esac
_decision_failed "$1" "answer '$yn'"
}
# _exit_for <status>: exit with the wrapper exit code for a job status.
_exit_for() {
local code
@@ -381,7 +393,7 @@ EOF
else
local sub_exit=0
wait "$sub_pid" 2>/dev/null || sub_exit=$?
if _decide subscriber-up "$sub_exit"; then
if _decided_yes subscriber-up "$sub_exit"; then
sub_ready=1
break
else
@@ -553,7 +565,7 @@ EOF
else
local sub_exit=0
wait "$sub_pid" 2>/dev/null || sub_exit=$?
if _decide subscriber-up "$sub_exit"; then
if _decided_yes subscriber-up "$sub_exit"; then
sub_ready=1
break
else
@@ -715,7 +727,7 @@ reap_subscriber() {
start_stall_watch() {
local session="$1" agent="$2" tok="${3:-}" att="${4:-}"
STALL_PID=""
_decide stall-watch "$session" "$agent" || return 0
_decided_yes stall-watch "$session" "$agent" || return 0
local args=(--job "$JOB_ID" --registry-dir "$REGISTRY_DIR" --target "${session#herdr:}"
--agent "$agent" --herdr-session "${HERDR_SESSION_NAME:-}" --watch-pid "$$")
[ -n "$tok" ] && args+=(--expect-dispatch-token "$tok")