docs: add VERSIONS.md, resolve C-6 stop_session usage/comments drift, and prune LOG.md

This commit is contained in:
2026-08-17 09:39:21 +09:00
parent 5ed39f899b
commit ac97550e13
8 changed files with 856 additions and 186 deletions
@@ -1,28 +1,28 @@
#!/usr/bin/env bash
# stop_session.sh — multi-agent-mux-stop 의 부속 스크립트
# Usage:
# bash stop_session.sh --session <name> [--agent claude|agy] \
# [--mode soft|hard] [--purge-conversation] [--yes]
# bash stop_session.sh --session <name> [--agent claude|agy|hermes|cline] \
# [--reason <reason>] [--purge-conversation] [--yes]
#
# mode:
# soft — YAML 을 status=archived 로 마크, herdr 세션은 그대로 둠 (P1-A:
# terminated 는 herdr 가 실제로 죽은 상태에만 사용)
# hard — herdr kill-session + YAML status=terminated
# --purge-conversation: --mode hard 일 때만. 삭제 대상 세션의 *워크스페이스에
# 격리된* conversation artifact 만 삭제 (P0-C). 전역
# agent_identities 를 참조하지 않음. resume 불가.
# 동작: 항상 graceful stop 입니다. send-keys 로 정상 종료를 유도하고
# (미종료 시 SIGTERM → SIGKILL 폴백), kill 직전에 이 워크스페이스의
# conversation id 를 row 에 확정 기록해 다음 resume 이 tier-1(race-free)
# 으로 복원되게 합니다. status 는 running -> stopped 로 전이합니다.
# 멱등: 이미 stopped 면 no-op + exit 0.
#
# Stop extension (Option A — stop 확장, 새 6번째 스킬 없이 stop 의미론 흡수):
# --capture-id — kill 직전에 이 워크스페이스의 conversation id 를 row 에 확정
# 기록 (claude_session_id_own / agy_conversation_id_own) →
# 다음 resume 이 tier-1(race-free) 로 복원. find_workspace_uuid
# 재사용 (per-row -> workspace-scoped disk scan -> cache).
# --reason R — 상태 전이 사유 (stop_reason). 기본값 manual_stop.
# --graceful — kill-session 즉시 종료 대신 send-keys 로 정상 종료 유도 →
# 3초 대기 → 미종료 시 kill-session(SIGTERM) → 5초 → SIGKILL.
# 위 세 옵션 중 하나라도 주면 STOP 모드: status 가 terminated 가 아니라 stopped
# 로 전이 (running -> stopped). 멱등: 이미 stopped 면 no-op + exit 0.
# 옵션 미지정 시 기존 hard/soft 동작 그대로 (backward compatible).
# 옵션:
# --session <name> — 대상 세션 (필수)
# --agent <type> — claude | agy | hermes | cline
# (미지정 시 세션명 접미사로 추론; 추론 실패 시 exit 2)
# --reason <reason> — 상태 전이 사유 (stop_reason). 기본값 manual_stop
# --purge-conversation — 디스크의 conversation artifact 까지 삭제.
# status=terminated, resumable=false 로 전이하며
# resume 불가. --yes 없이는 확인 프롬프트(exit 3)
# --yes — --purge-conversation 의 확인 프롬프트 생략
#
# 폐지된 옵션: --mode / --capture-id / --graceful 는 각각 exit 2 로 거부됩니다.
# graceful 종료와 id 캡처는 이제 무조건 수행되며, soft/hard 모드
# 구분은 --purge-conversation 유무로 대체되었습니다.
#
# Exit codes:
# 0 = success (or already-stopped no-op) | 1 = YAML not found / not registered
@@ -38,11 +38,20 @@ source "$_lib_sh"
usage() {
cat <<EOF
Usage: $0 --session <name> [--agent claude|agy] [--purge-conversation] [--yes] [--reason <reason>]
Usage: $0 --session <name> [--agent claude|agy|hermes|cline] [--reason <reason>]
[--purge-conversation] [--yes]
Stop arguments:
--reason <reason> — stop_reason field (default: manual_stop)
(idempotent: stopping an already-stopped session is a no-op with exit 0)
Arguments:
--session <name> — target session name (required)
--agent <type> — claude | agy | hermes | cline
(inferred from the session-name suffix when omitted)
--reason <reason> — stop_reason field (default: manual_stop)
--purge-conversation — also delete on-disk conversation artifacts;
status becomes terminated and resume is impossible
--yes — skip the --purge-conversation confirmation prompt
Stop is always graceful and always captures the conversation id.
(idempotent: stopping an already-stopped session is a no-op with exit 0)
EOF
}
@@ -154,7 +163,7 @@ if herdr has-session -t "$SESSION_NAME" 2>/dev/null; then
LAST_STATUS=$(herdr capture-pane -t "$SESSION_NAME" -p -S -10 2>/dev/null | tr '\n' ' ' | head -c 500 || true)
fi
# --capture-id: kill 직전에 conversation id 를 해결 (process/jsonl 이 아직 살아있을 때).
# 캡처: kill 직전에 conversation id 를 해결 (process/jsonl 이 아직 살아있을 때).
# find_workspace_uuid 가 tier-1(row) -> tier-2(workspace-scoped disk scan) -> tier-3(cache)
# 를 알아서 시도하므로 herdr 생사와 무관하게 동작.
CAPTURED_UUID=""
@@ -163,13 +172,13 @@ if [ "$CAPTURE_ID" = "1" ] && [ -n "$TARGET_CWD" ]; then
if [ -n "$CAPTURED_UUID" ]; then
echo "captured conversation id: $CAPTURED_UUID"
else
echo "WARN: --capture-id requested but no conversation id resolved (nothing on disk yet)"
echo "WARN: no conversation id resolved before stop (nothing on disk yet)"
fi
fi
delegate_publish_event "$DELEGATE_JOB_ID" progress "terminating"
# --graceful: send-keys 로 정상 종료 유도 → 폴백 체인 (SIGTERM → SIGKILL).
# graceful 종료: send-keys 로 정상 종료 유도 → 폴백 체인 (SIGTERM → SIGKILL).
graceful_stop() {
local pane_pid exitkey
pane_pid=$(herdr list-panes -t "$SESSION_NAME" -F '#{pane_pid}' 2>/dev/null | head -1 || true)
@@ -254,7 +263,7 @@ if not purge:
if last_status:
target['last_visible_status_at_termination'] = last_status
# --capture-id: 항상 captured UUID 기록 (purge가 아닐 때만)
# 항상 captured UUID 기록 (purge 가 아닐 때만)
if captured and not purge:
if agent == 'claude':
target['claude_session_id_own'] = captured