fix(issue-9,14): bound the R1 grace by the wall clock and keep other ls failures unknown

Round-2 review of d5a191c (planner-reviewer-claude-01, planner-reviewer-codex-01).

- delegate wrapper: the R1 idle grace and the broker_unavailable re-check
  counted only their sleeps against TIMEOUT, so python/herdr probe time plus
  fresh disk heartbeats let a job run far past --timeout (55 s for a 20 s
  budget in the new test). Both loops now end at START_TIME + TIMEOUT read
  off the clock on every pass; heartbeats extend only the idle window, and
  the herdr probe is cut off at the deadline (_within_deadline)
- document the window policy d5a191c actually implements: an agent with no
  evidence is closed ~2 x IDLE_TIMEOUT after its last wire event (Issue #6
  promised IDLE_TIMEOUT + 5 s) and heartbeats may be ~2 x IDLE_TIMEOUT apart;
  correct the claim that publish_event records a heartbeat on disk before
  the wire publish - it records right after the publish attempt
- shim ls: every failed `agent list` other than a structured
  server_not_running now exits nonzero with a "state unknown" diagnostic
  instead of reaching the list parser, where an error document on stdout
  read as an empty list and let drift A terminate live rows
- tests: stdout variants for down and unrelated errors, reconcile keeping
  herdr_confirmed False on an unrelated failure, and a wall-clock upper bound
  under continuous heartbeats and slow probes; the three new checks fail on
  d5a191c
- VERSIONS.md v4.4.2: items 3 and 6 and the test count (19)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HCGpJXhSZasJLU38ksDghe
This commit is contained in:
GodopuandClaude Opus 5 committed 2026-09-13 01:53:57 +09:00
1 parent d5a191c47c
commit 952657efb4
5 files changed
+221 -77

No files matched your search

+10 -1
View File
@@ -1249,7 +1249,9 @@ except Exception:
# error.code == "server_not_running" means "down". A successful list can
# legitimately contain that text (an agent named server_not_running-codex),
# and reading it as "down" made reconcile terminate every live row on that
# server. Any other failure falls through to the unknown path below.
# server. Any other failed call is "unknown": it exits nonzero below
# without its output ever reaching the list parser, so an error document on
# stdout cannot pass for an empty list either.
_ls_err=$(mktemp 2>/dev/null || echo "/tmp/mam_ls_err_$$")
_ls_rc=0
_ls_raw="$(_real_herdr agent list 2>"$_ls_err")" || _ls_rc=$?
@@ -1281,6 +1283,13 @@ print(down)
echo "no server running (herdr session ${_sess:-default})" >&2
exit 1
fi
if [ "$_ls_rc" -ne 0 ]; then
# Unknown, never empty: keep the nonzero status and word the diagnostic
# so it matches none of reconcile.sh's empty-server phrases ("no server
# running", "no sessions", "failed to connect").
echo "herdr agent list returned rc=$_ls_rc (herdr session ${_sess:-default}); state unknown" >&2
exit 1
fi
printf '%s\n' "$_ls_raw" | \
MAM_LS_FORMAT="$format" MAM_REAL_HERDR="$REAL_HERDR" MAM_LS_SESSION="$_sess" \
TZ=UTC LC_ALL=C python3 -c '