fix(issue-6): fail-closed registry timeout and TUI turn handshake
- Introduce finalize_unfinished in multi-agent-mux-delegate-job for fail-closed atomic transitions - Enforce CAS dispatch_token and attempt_id pinning across engine, CLI, and lifecycle scripts - Integrate Herdr wait_for_agent_idle turn handshake to prevent prompt loss and race conditions - Resolve bash 3.2 set -u empty array expansion compatibility in lib.sh - Preserve Issue #5 R2 contract in CAS transition engine (engine.py, publish_event.py, service.py) - Add comprehensive regression suites (test_issue6_fail_closed.py, test_issue6_turn_handshake.py) - Bump lockstep framework and skills to v4.4.1 across lib.sh, eager.py, VERSIONS.md, 8 SKILL.md - Synchronize documentation (IMPROVEMENTS.md, MESSAGING.md, state-transitions.md, task.md, phase5-e2e.md) - Unanimous PASS achieved across 4 reviewer team leaders (Claude, Codex, OpenCode, Grok) Closes #6
This commit is contained in:
1 parent
7b761be7b8
commit
ec61511699
51 files changed
+3477
-293
No files matched your search
@@ -142,6 +142,29 @@ sys.exit(7)
|
||||
|
||||
TARGET_CWD=$(printf '%s' "$MAPPED_DATA" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("cwd",""))')
|
||||
DELEGATE_JOB_ID=$(printf '%s' "$MAPPED_DATA" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("job_id",""))')
|
||||
DELEGATE_JOB_TOKEN=""
|
||||
DELEGATE_JOB_ATTEMPT=""
|
||||
if [ -n "$DELEGATE_JOB_ID" ]; then
|
||||
local_info=$(python3 -c "
|
||||
import sys, json, os
|
||||
jid = '$DELEGATE_JOB_ID'
|
||||
reg_dir = os.environ.get('MAM_JOBS_DIR', '.mam/jobs')
|
||||
p = os.path.join(reg_dir, f'{jid}.json')
|
||||
if os.path.exists(p):
|
||||
try:
|
||||
with open(p) as f:
|
||||
d = json.load(f)
|
||||
tok = d.get('dispatch_token', '')
|
||||
att = d.get('attempt_id', d.get('iteration', 1))
|
||||
print(f'{tok} {att}')
|
||||
except Exception:
|
||||
pass
|
||||
" 2>/dev/null || true)
|
||||
if [ -n "$local_info" ]; then
|
||||
DELEGATE_JOB_TOKEN=$(echo "$local_info" | awk '{print $1}')
|
||||
DELEGATE_JOB_ATTEMPT=$(echo "$local_info" | awk '{print $2}')
|
||||
fi
|
||||
fi
|
||||
|
||||
# 멱등성: STOP 모드에서 이미 stopped 인 세션이고 purge 가 아닐 때만 no-op + exit 0
|
||||
if [ "$STOP_MODE" = "1" ] && [ "$PURGE" != "1" ]; then
|
||||
@@ -190,7 +213,7 @@ if [ "$CAPTURE_ID" = "1" ] && [ -n "$TARGET_CWD" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" progress "terminating"
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" progress "terminating" "$DELEGATE_JOB_TOKEN" "$DELEGATE_JOB_ATTEMPT"
|
||||
|
||||
# graceful 종료: send-keys 로 정상 종료 유도 → 폴백 체인 (SIGTERM → SIGKILL).
|
||||
graceful_stop() {
|
||||
@@ -239,7 +262,7 @@ if [ "$PURGE" = "1" ] && [ "$HERDR_ALIVE" = "1" ]; then
|
||||
echo " Refusing registry removal — records preserved (no state was modified)." >&2
|
||||
echo " Diagnose the stuck TUI (herdr session attach '$SESSION_NAME'), then re-run" >&2
|
||||
echo " stop_session.sh --purge-conversation --yes (retry is safe/idempotent)." >&2
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" cancelled "purge aborted: session still alive; no state was modified"
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" cancelled "purge aborted: session still alive; no state was modified" "$DELEGATE_JOB_TOKEN" "$DELEGATE_JOB_ATTEMPT"
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
@@ -319,7 +342,7 @@ else:
|
||||
print(f"updated: {name} status={target['status']}", flush=True)
|
||||
PYEOF
|
||||
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" cancelled "session stopped by operator before job completion"
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" cancelled "session stopped by operator before job completion" "$DELEGATE_JOB_TOKEN" "$DELEGATE_JOB_ATTEMPT"
|
||||
|
||||
echo
|
||||
echo "=== stop complete ==="
|
||||
|
||||
Reference in new issue
Block a user