FROM THE WORKSHOP / 노하우
세션이 끊겼다 돌아오면 했던 일을 다시 한다 — STALE 앵커와 멱등성 스텝 레저
자동화 에이전트에게 멀티스텝 작업(빌드→업로드→스샷→출시)을 맡겼더니 세션이 API 정지로 끊겼다 살아나며 끝낸 일을 처음부터 다시 했다. 원인은 멍청함이 아니라 멱등성 부재 — 재시작 세션은 prose 로 컨텍스트를 복원하는데 글은 sub-step 완료를 기계-체크 가능하게 담지 못한다. 처방은 완료를 글이 아닌 장부(ledger)에 적고 비싼 스텝 실행 전 장부에 묻기, 위임엔 끝난 것/남은 것 STALE 앵커 못박기, 강제 훅은 observe-canary 로.
세션이 끊겼다 돌아오면 했던 일을 다시 한다 — STALE 앵커와 멱등성 스텝 레저
자동화 에이전트에게 여러 단계짜리 일(빌드 → 업로드 → 스크린샷 → 출시)을 맡겼다. 에이전트가 빌드도 하고 업로드도 하고 스크린샷까지 다 찍었다. 그런데 중간에 API가 끊겨 세션이 죽었다 살아났다. 살아난 세션은 방금 끝낸 일들을 처음부터 다시 하기 시작했다. 빌드 또 하고, 스크린샷 또 찍고, 업로드 또 하고. 사람이 보다 못해 “했던 거 또 한다”고 막았다.
이건 에이전트가 멍청해서가 아니다. “어디까지 했는지”를 기억하지 못하는 자동화의 구조적 함정이다. 그 함정과 처방.
왜 다시 하는가 — prose 는 멱등하지 않다
세션이 재시작되면 에이전트는 컨텍스트를 글(prose)로 복원한다 — 핸드오프 노트, 할일 메모. 문제는 그 글이 “빌드 완료 ✅” 같은 걸 기계가 체크할 수 있는 형태로 sub-step 단위로 담고 있지 않다는 것. 재시작된 세션은 “이미 빌드했다”를 안전하게 판정할 방법이 없으니, 가장 안전해 보이는 선택 — 다시 빌드 — 을 한다.
즉 재실행의 원인은 게으름이나 버그가 아니라 멱등성(idempotency)의 부재다. 같은 명령을 두 번 실행해도 한 번과 같아야 하는데, “빌드”는 그렇지 않고, 에이전트는 “이미 했음”을 모른다.
처방 1 — 멱등성은 글이 아니라 장부(ledger)로
각 비싼/외부 스텝을 끝낸 직후 기계가 읽을 장부에 완료를 적는다. 그리고 그 스텝을 다시 하기 전에 장부에 물어본다.
# 끝낸 직후 기록
step-done <작업ID> build "AAB vc12"
# 다시 하기 전 질의 — 이미 했으면 건너뛴다
step-check <작업ID> build && echo "이미 빌드됨, skip" || flutter build ...
키는 (작업ID, 스텝명). 장부는 로컬 + 노드 공유 채널에 동시 기록해 다른 노드가 한 완료도 인정한다. 재시작된 세션은 글을 믿지 않고 장부를 믿는다. 글과 장부가 충돌하면(글 “안 했음” vs 장부 “했음”) 장부가 이긴다.
처방 2 — STALE 앵커: 위임할 때 “끝난 것”을 못박는다
여러 단계 일을 위임하는 명령(directive)에 이미 끝난 스텝 목록과 남은 스텝 목록을 명시적으로 박는다. 사고 당시 이걸 사람이 손으로 했다:
■ 이미 DONE — 재실행 금지: ✅빌드 ✅업로드 ✅스크린샷 ✅검증
■ 각 스텝 실행 전 장부 확인, 했으면 skip / 끝나면 장부에 기록
■ 남은 건 딱 2개: (1) production 출시 (2) iOS 심사제출
효과는 즉각적이었다. 같은 세션이 이번엔 빌드·업로드·스샷을 일절 다시 안 하고, 실측으로 상태를 확인한 뒤 남은 2개만 했다. 앵커 하나가 루프를 끊었다.
처방 3 — 강제 훅 (관찰부터)
사람·에이전트가 매번 장부를 부르는 걸 잊을 수 있으니, 비싼 배포 명령을 가로채 “이 스텝 이미 했을 수 있음”을 경고하는 훅을 둔다. 단 명령을 가로막는 훅은 오탐(false positive)이 위험하므로, 처음엔 차단 없이 경고만(observe) 하고 한 노드에서 오탐률을 관찰한 뒤 점진적으로 차단으로 승격한다. 안전장치를 무인으로 전체에 강행하지 않는다.
일반화
자동화 에이전트가 여러 단계 일을 하는 중 세션이 재시작될 수 있다면(API 정지·크래시·컨텍스트 클리어), 완료 상태를 글이 아니라 기계가 체크할 수 있는 장부에 남기고, 비싼 스텝을 실행하기 전에 그 장부에 물어보라.
- 멱등성은 prose 가 아니라 ledger 로. 글은 재시작 때 다시 읽히지만 sub-step 완료를 기계-판정 가능하게 담지 못한다.
- 위임엔 STALE 앵커를. “끝난 것 / 남은 것”을 명령에 못박으면 재진입 세션이 헛돌지 않는다.
- 강제 훅은 observe-canary 로. 차단형 안전장치는 오탐 관찰 후 점진 승격, 무인 전체 강행 금지.
- 같은 노드 재시작은 로컬 장부만으로도 막힌다. 노드 간 완전성은 공유 채널 헬스에 의존하니 그건 따로 챙긴다.
가장 비싼 자동화 실수는 “실패”가 아니라 **“이미 한 일을 모르고 다시 하는 것”**이다. 비싼 일일수록, 하기 전에 “이거 이미 했나?”를 기계에게 물어보게 만들어라.