feat(isolation): implement Phase 1-3 session isolation with stop purge and resume safety

This commit is contained in:
2026-07-10 12:24:35 +09:00
parent 35068f7a9e
commit 768cfe5c6d
6 changed files with 451 additions and 62 deletions
@@ -148,7 +148,7 @@ fi
# purge 대상 UUID 를 워크스페이스 격리해서 해결 (P0-C — 전역 참조 금지)
PURGE_UUID=""
if [ "$PURGE" = "1" ] && [ -n "$TARGET_CWD" ]; then
PURGE_UUID=$(find_workspace_uuid "$TARGET_CWD" "$AGENT" || true)
PURGE_UUID=$(find_workspace_uuid "$TARGET_CWD" "$AGENT" "$SESSION_NAME" || true)
fi
NOW_ISO=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
@@ -167,7 +167,7 @@ fi
# 를 알아서 시도하므로 tmux 생사와 무관하게 동작.
CAPTURED_UUID=""
if [ "$CAPTURE_ID" = "1" ] && [ -n "$TARGET_CWD" ]; then
CAPTURED_UUID=$(capture_conversation_id "$AGENT" "$TARGET_CWD" || true)
CAPTURED_UUID=$(capture_conversation_id "$AGENT" "$TARGET_CWD" "$SESSION_NAME" || true)
if [ -n "$CAPTURED_UUID" ]; then
echo "captured conversation id: $CAPTURED_UUID"
else
@@ -270,6 +270,23 @@ if captured and not purge:
target['resumable'] = True
# --purge-conversation: 워크스페이스 격리된 UUID 의 디스크 artifact 만 삭제 (P0-C)
# T6: stop-purge 시 격리 디렉터리 청소 및 경로 가드
iso = target.get('isolation')
if purge and iso:
iso_root = iso.get('root')
iso_uuid = iso.get('uuid')
if iso_root and iso_uuid:
ws_abs = os.path.abspath(ws) if ws else ""
expected_homes_dir = os.path.join(ws_abs, '.mam', 'agent_homes')
expected_iso_root = os.path.join(expected_homes_dir, iso_uuid)
if (os.path.abspath(iso_root) == os.path.abspath(expected_iso_root) and
os.path.abspath(iso_root).startswith(os.path.abspath(expected_homes_dir) + os.sep)):
if os.path.isdir(iso_root):
shutil.rmtree(iso_root)
print(f"purged isolated home: {iso_root}", flush=True)
else:
print(f"WARN: isolated home path check failed: {iso_root}", flush=True)
if purge and purge_uuid:
if agent == 'claude':
key = ws.replace('/', '-').replace('_', '-')