Merge-workspace review loop (--all-reviewer): round 1 (@8241bd5) claude grok PASS, agy NOT PASS (two static wrapper-literal tests did not follow _decided/_exit_for), codex NOT PASS (R1: a yes/no decision that could not run read as "no"); fixed in541c3feand65b78b6. Round 2 (@65b78b6) 4/4 PASS. Full suite at65b78b6on macOS / Python 3.9 / herdr 0.9.3: 1730 passed / 0 failed / 56 skipped; 18 of the skips were the uninitialized nats-docker submodule in the fresh worktree, and with it tests/test_deploy_freshness.py is 31 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
4.4 KiB
Review: Issue #17 follow-ups @ 65b78b6
- Role: Reviewer (grok)
- Identity: loop
loop-20261007T224638Z-cf1efb, snapshot/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261007T224638Z-cf1efb/2, base56d0bfda54e4f4fe1ccc138cc262edfb14cfb4a3(main still56d0bfd), head65b78b6ec44e44904afe34915563522d4631767f, treeb805d9f9e6639c7359115ea9336eac95d7ab85bc.8241bd5is an ancestor. Snapshot porcelain empty.git diff --check 56d0bfd..HEADclean. - Delta since the PASS at
8241bd5:541c3feand65b78b6, five files, +80/−16. Cumulative base..head: nine files, +267/−33. No version bump and noVERSIONS.mdedit. - Verified read-only at the snapshot. Python 3.9.6 from the follow-up worktree
.venv, bash 3.2.57, herdr 0.9.3. InheritedHERDR_*,MAM_*,MQTT_*, andWORKSPACE_ROOTwere unset.HOMEandWORKSPACE_ROOTwere the basetemp..mam.envwas not exported.startedfor this dispatch isdispatch_verifiedwith attempt-id 1.
A failed yes/no decision exits 1
wrapper.py _yes_no (:335-339) prints yes or no and returns 0 when --print is set. Without --print it returns 0 for yes and 1 for no. subscriber-up and stall-watch both take --print (:301-309) and return through _yes_no (:346-353). The module head (:15-17) says the wrapper uses --print, so a failure to decide cannot pass for no.
_decided_yes (multi-agent-mux-delegate-job:123-131) calls _decided with --print. yes returns 0, no returns 1, and any other text calls _decision_failed (:106-109), which exit 1. _decided (:112-118) already exits 1 when the command status is non-zero or stdout is empty, before that case.
The handshake uses if _decided_yes subscriber-up "$sub_exit" at :396 and :568. start_stall_watch (:730) is _decided_yes stall-watch "$session" "$agent" || return 0. A real no still returns 1, so the watcher is skipped and the subscriber "died early" branch still runs. A failed decision executes exit 1 inside _decision_failed, so that || return 0 and the if leave the wrapper at 1.
test_f_a_failed_yes_no_decision_ends_the_submit_with_1 (tests/test_issue17_item4_decisions.py:693-699) covers modes error, gone, and empty for subscriber-up on direct and loop submits, and for stall-watch on a direct submit. The stand-in subscriber exits 0 before SUBSCRIBED. Each run expects rc 1 and could not decide '<decision>'.
test_f_yes_and_no_keep_their_branches (:702-710) keeps the live branches. SUB_RC 0 stays on the yes path: "subscriber died early" is absent, and a direct submit exits 0. SUB_RC 1 takes the died-early path, and a direct submit exits 1. The direct rc 0 also shows that the later wait "$sub_pid" (:437-438), after the handshake already waited that pid, still finishes the submit on this bash 3.2.57.
test_u_yes_no_print (:713-721) checks --print stdout yes/no with rc 0, the rc form of subscriber-up still 0 or 1, stall-watch herdr:c/claude printing yes, and remote:r/claude printing no.
test_s_no_printed_decision_is_read_raw (:734-743) drops comment lines, then requires _decided_yes subscriber-up twice and _decided_yes stall-watch once, and rejects a raw _decide subscriber-up or _decide stall-watch. The comment at :725 still names _decide stall-watch. The call that runs is :730.
Frozen literals
541c3fe points tests/test_issue5_phase1_delegation.py:390 and tests/test_tier1_unit.py:847 at _decided job_status sub-status "$sub_rc". The issue5 pin also requires _exit_for "$job_status". EXIT_CODES and sub_status() stay asserted in Python (test_issue5_phase1_delegation.py:393-395).
Items already passed at 8241bd5
The herdr 0.9.3 placeholder close, the N1 docstring, the N3 PATH comment, and the printed-decision _decided / _exit_for path are absent from git diff 8241bd5 HEAD. That review recorded 305 passed (test_issue17_item4_decisions.py, test_issue33_budget.py, test_issue45_restore_unit.py) and 5 passed (tests/test_issue45_restore.py). After this review, ~/.config/herdr/config.toml mtime is still 1784456394 and the directory mtime is still 1791382452.
Tests this round
--basetemp=/tmp/518efollow.hbS1ua. tests/test_issue17_item4_decisions.py, tests/test_issue33_budget.py, tests/test_issue5_phase1_delegation.py, tests/test_tier1_unit.py: 442 passed in 472.25 s. Snapshot porcelain stayed empty. Main stayed 56d0bfd.
[VERDICT: PASS]