feat(issue-50): create --onboard waits for the onboarding job to end (A)
The handshake only said the agent saw the prompt (#23). create_session.sh now waits, after `started`, for the onboarding job to reach a terminal status and makes that its own result, so the orchestrator learns it from create's exit (MULTI_AGENT_RULES §6) instead of guessing from herdr's agent_status: - lib_py/delegation/wrapper.py: `wait-terminal` (completed|error|cancelled, `timeout` after --timeout, `missing` when the record is gone; stops with its caller via --watch-pid) and `onboard-exit` (completed 0, error or cancelled 44, timeout or missing 45). bash branches on the printed answer. - lib.sh: delegate_wait_terminal / delegate_onboard_exit, thin calls. - create_session.sh: `onboarding completed: job <id> (<n>s)` on stdout, or `last_visible_status: onboarding-<status>` on the row, the reason on stderr and `exit 44` / `exit 45` after `trap - EXIT` - the session is kept, as for a missing handshake. The "no started" path (error, exit 0 before) now ends with 44. MAM_ONBOARD_WAIT_S (default 600, floor 1) bounds the wait. - worktree_prepare.sh: 44/45 pass through with "session and worktree kept". - create SKILL.md exit table (44, 45) and the knob; the #42 inventory follows. - tests/conftest.py: --onboard is the default, so ~60 sandbox create tests reach the new wait. The mock herdr now acts as the agent for create's onboarding prompt - it runs the publish commands the prompt names through the real publish_event.py - and MAM_ONBOARD_WAIT_S=3 caps a test that turns that off (MAM_MOCK_ONBOARD_HANDSHAKE=0 -> 44, `started` -> 45). The delegate-job wrapper's prompt has another shape and is never answered. - tests/test_issue50_onboard.py: the decision tables, create in the sandbox (0 / 44 / 45, session kept, row note, trap window), the knob's integer rule, worktree_prepare's pass-through. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
40293841e7
commit
c29c5b2142
9 files changed
+367
-14
No files matched your search
@@ -19,6 +19,8 @@
|
||||
# 4 = agent-sessions.yaml append failure
|
||||
# 42 = agent TUI never became ready and the process is gone
|
||||
# 43 = rollback could not kill the herdr session; it is still running (#23)
|
||||
# 44 = the onboarding job ended with error (or was cancelled); the session is kept (#50)
|
||||
# 45 = the onboarding job did not end within MAM_ONBOARD_WAIT_S; the session is kept (#50)
|
||||
set -euo pipefail
|
||||
|
||||
_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
@@ -316,6 +318,21 @@ for s in d.get('herdr_sessions', []):
|
||||
PYEOF
|
||||
}
|
||||
|
||||
# _mark_row_note <note>
|
||||
# Issue #50: last_visible_status only. The row stays `running` with its
|
||||
# delegate_job_id: the session is alive and the job record is the evidence.
|
||||
_mark_row_note() {
|
||||
local note="$1"
|
||||
[ "${ROW_APPENDED:-0}" = "1" ] || return 0
|
||||
atomic_dump_yaml "$AGENT_SESSIONS_YAML" SESSION_NAME="$SESSION_NAME" ROW_NOTE="$note" <<'PYEOF' || true
|
||||
name = os.environ['SESSION_NAME']
|
||||
for s in d.get('herdr_sessions', []):
|
||||
if s.get('name') == name:
|
||||
s['last_visible_status'] = os.environ['ROW_NOTE']
|
||||
break
|
||||
PYEOF
|
||||
}
|
||||
|
||||
# Trap for rolling back/cleaning up herdr session if script exits due to error
|
||||
cleanup_herdr_on_error() {
|
||||
local exit_code=$?
|
||||
@@ -698,12 +715,38 @@ If you delegate any part of it with multi-agent-mux-delegate-job submit, add --p
|
||||
esac
|
||||
JOB_TERMINALIZED=1
|
||||
fi
|
||||
# Issue #50: the handshake only said the agent saw the prompt. Wait for the
|
||||
# onboarding itself to end; its result is this script's exit code, so the
|
||||
# orchestrator learns it from create (MULTI_AGENT_RULES §6) instead of
|
||||
# guessing from herdr's agent_status. A job marked `error` just above is
|
||||
# terminal and returns at once.
|
||||
ONBOARD_WAIT_S=$(mam_int_knob MAM_ONBOARD_WAIT_S 600 1)
|
||||
ONBOARD_T0=$(date +%s)
|
||||
ONBOARD_STATUS="$(delegate_wait_terminal "$DELEGATE_JOB_ID" "$ONBOARD_WAIT_S")"
|
||||
ONBOARD_STATUS="${ONBOARD_STATUS:-missing}"
|
||||
# Trigger immediate priority reconcile cycle asynchronously
|
||||
# Issue #21 phase 2 (A8): the control root's reconcile/watchdog, never the
|
||||
# (unreviewed) copy in a worktree --workspace; identical paths by default.
|
||||
(bash "$SKILL_DIR/multi-agent-mux-monitor/scripts/reconcile.sh" --once >/dev/null 2>&1 &) || true
|
||||
WD_PID=$(start_watchdog "$DELEGATE_JOB_ID" "$WORKSPACE_ROOT")
|
||||
echo "watchdog PID: $WD_PID"
|
||||
case "$ONBOARD_STATUS" in
|
||||
completed)
|
||||
echo "onboarding completed: job $DELEGATE_JOB_ID ($(( $(date +%s) - ONBOARD_T0 ))s)"
|
||||
;;
|
||||
*)
|
||||
# The session is kept, as for a missing handshake above: the row says
|
||||
# what happened and the exit code tells the caller. The trap is cleared
|
||||
# first - a non-zero exit must not roll a live session back.
|
||||
_mark_row_note "onboarding-$ONBOARD_STATUS"
|
||||
echo "ERROR: onboarding $ONBOARD_STATUS for '$SESSION_NAME': job $DELEGATE_JOB_ID; the session is kept" >&2
|
||||
trap - EXIT
|
||||
case "$(delegate_onboard_exit "$ONBOARD_STATUS")" in
|
||||
44) exit 44 ;;
|
||||
*) exit 45 ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# Clear cleanup trap as registration was fully successful
|
||||
trap - EXIT
|
||||
|
||||
Reference in new issue
Block a user