Bluetape Skills Part 3: 중단된 작업 흐름을 안전하게 복구하는 방법

Part 2에서는 $bluetape-workflow가 작업을 분류하고, 승인된
계획을 행동·증거·실패 대응 체크리스트로 검증하는 과정을 설명했다. 이 방식은 빠뜨린 검증 관문을 찾는 데
효과적이지만, 작업이 길어지고 여러 네이티브 하위 에이전트가 나뉘어 움직이면 체크리스트만으로 답하기 어려운 질문이
생긴다.
한 에이전트가 한동안 응답하지 않는다면 계산이 오래 걸리는 중일까, 아니면 멈춘 걸까? 새 세션이 작업을 이어받을 때 이전 에이전트의 결과를 어디까지 믿어야 할까? 일부 실행 단위가 끝났다는 보고만으로 전체 작업을 완료해도 될까? 작업 원장이 손상됐다면 멀쩡해 보이는 마지막 줄부터 다시 시작해도 될까?
Bluetape Skills 1.1.0은 2026년 7월 14일 공개됐으며, 이 질문을 다루기 위해 2단계 네이티브 작업 흐름
런타임을 추가했다. 핵심은 새
조정기를 하나 더 두는 것이 아니다. Codex 주 세션이 수행한 네이티브 조정 결과를 검증 가능한
상태로 남기고, 중단 뒤에도 그 상태를 읽어 이어 갈지, 실행 단위를 교체할지, 별도 복구 작업을 만들지 판단하는
데 있다.
왜 복구 가능한 작업 흐름이 필요했나
섹션 제목: “왜 복구 가능한 작업 흐름이 필요했나”작업이 한 세션에서 끝날 때는 대화 내용만으로도 진행 상황을 대략 파악할 수 있다. 하지만 작업 시간이 길어지고 실행 단위가 여러 개로 갈라지면 설명과 실제 상태가 쉽게 어긋난다. 에이전트가 “완료했다”고 말했어도 필수 검사가 실행되지 않았을 수 있고, 파일은 바뀌었지만 그 파일이 승인된 쓰기 범위 안에 있는지 확인하지 않았을 수도 있다.
침묵을 곧바로 실패로 판단하는 것도 위험하다. 큰 빌드나 외부 응답을 기다리는 동안에는 새 메시지가 없어도 정상적으로 작업 중일 수 있다. 반대로 생존 신호가 계속 들어온다는 이유만으로 진척이 있다고 볼 수도 없다. 살아 있다는 신호와 완료에 가까워졌다는 증거는 서로 다른 정보다.
교체 과정에는 더 까다로운 문제가 있다. 멈춘 에이전트를 새 에이전트로 바꾼 뒤 이전 에이전트가 늦게 결과를 보내면, 그 결과가 현재 상태를 덮어쓰지 못하도록 막아야 한다. 세션을 넘길 때도 이전 소유자와 새 소유자가 동시에 같은 작업을 수정하면 안 된다. 어느 쪽이 현재 기록 권한을 가졌는지 분명해야 한다.
그래서 복구 가능한 작업 흐름에는 단순한 작업 목록보다 더 많은 정보가 필요하다. 전체 작업과 실행 단위의 현재 상태, 소유권 세대, 생존 여부 관찰, 교체 관계, 구성 요소별 검사와 증거, 작업 원장의 검증 결과가 함께 남아야 한다. 그래야 다음 세션이 과거 대화를 추측하지 않고 현재 상태에서 다시 시작할 수 있다.
문서형 체크리스트에서 네이티브 런타임으로
섹션 제목: “문서형 체크리스트에서 네이티브 런타임으로”1.0.0의 체크리스트 계약은 작업마다 수행할 행동, 남겨야 할 증거, 실패했을 때 멈출 조건을
정의했다. 1.1.0은 이 원칙을 없애지 않는다. 오히려 여러 실행 단위가 움직이는 동안에도 같은 원칙을 적용할 수
있도록 상태 기록 계층을 더했다.
공개 배포 묶음에는 매니페스트 버전 1.1.0,
생존 확인 계약,
구성 계약,
작업 원장 검증 규칙과 보호된 CLI가 함께 들어 있다. 매니페스트는 전체 작업과 실행 단위의 상태, 관찰 주기, 교체 횟수,
완료 조건을 고정한다. 계약은 각 상태를 어떤 명령으로 바꿀 수 있는지와 그때 필요한 증거를 정의한다.
여기서 런타임은 작업을 대신 실행하는 스케줄러가 아니다. .bluetape 아래의 작업 흐름 상태를 기록하고
검증하는 계층이다. 네이티브 하위 에이전트를 만들고 메시지를 보내며 기다리거나 중단하는 동작은 여전히 Codex 주
세션이 맡는다. 런타임은 주 세션이 실행 전에 남긴 의도와 실행 뒤 관찰한 제한된
증거를 정해진 상태 전이로 기록한다.
이 구분 덕분에 “명령을 기록했다”와 “네이티브 동작이 실제로 실행됐다”를 혼동하지 않는다. CLI가
lane-start를 기록했다고 에이전트가 생성된 것은 아니다. 주 세션이 네이티브 생성 동작을 수행하고 그 결과를
직접 읽은 뒤에야 startup-ack을 남길 수 있다. 침묵은 확인 응답이 아니다.
전체 작업과 실행 단위는 어떻게 움직이나
섹션 제목: “전체 작업과 실행 단위는 어떻게 움직이나”run은 승인된 전체 작업을 나타내고, lane은 그 안에서 한 에이전트나 주 세션이 맡은 제한된 실행 단위다.
아래 그림의 왼쪽은 하나의 전체 작업을 여러 실행 단위로 나누고 결과를 모으는 구조를 보여 준다. 오른쪽에서는
실행 단위 하나가 정상 실행과 복구·교체를 거치는 흐름을 따라간다.

기본 시작 흐름은 다음과 같다.
bluetape-flow.py: run-approve -> run-start -> lane-create -> lane-startCodex 주 세션: 네이티브 에이전트 생성bluetape-flow.py: startup-ack화살표가 모두 같은 실행기 안에 있는 것처럼 읽으면 안 된다. run-approve부터 lane-start까지는
bluetape-flow.py가 승인과 실행 의도를 기록한다. 그다음 주 세션이 네이티브 에이전트 도구로 에이전트를
생성한다. startup-ack은 주 세션이 실제 네이티브 결과를 관찰한 뒤 그 결과를 제한된 증거로 기록하는
단계다.
실행 단위는 pending, starting, running, suspected_stall, recovering 같은 상태를 거쳐 종료 상태로
간다. 종료 상태는 completed, failed, blocked, cancelled 중 하나다. 교체된 기존 실행 단위에는
replaced가 기록되고, 새 실행 단위는 별도의 실행 단위 ID와 에이전트 ID를 사용한다. 기존 ID만 새 에이전트에게 넘겨
마치 같은 실행이 계속된 것처럼 만들지 않는다.
새 실행 단위는 원래 할당보다 같거나 좁은 범위와 하나의 점검 지점을 받아야 한다. 기존 실행 단위와의 상위 계보도 기록한다. 교체가 끝난 뒤 이전 에이전트가 늦게 결과를 보내더라도 현재 상태를 바꿀 수 없도록 차단하는 이유다. 늦게 도착한 결과가 참고 자료가 될 수는 있어도, 현재 소유자의 검증 없이 완료 증거로 승격되지는 않는다.
실행 단위를 완료하기 전에는 주 세션이 증거를 다시 읽고, Git 상태와 브랜치 변경 사항에서 실제 변경
경로를 수집해 고정된 저장소 루트와 쓰기 범위 안에 있는지 확인한다. 빈 쓰기 범위는 “어디든 써도
된다”가 아니라 “파일을 쓰지 않는다”는 뜻이다. lane-complete를 기록한 뒤에도 필수 검사와 구성 요소별
증거가 남아 있어야 전체 작업의 완료 판정으로 넘어갈 수 있다.
생존 여부는 진척도가 아니다
섹션 제목: “생존 여부는 진척도가 아니다”Manifest의 liveness 숫자는 복구 판단에 필요한 시간 경계를 제공한다.
| 항목 | v1.1.0 기준 | 의미 |
|---|---|---|
| 관찰 간격 | 30초 | 실행 중인 네이티브 하위 에이전트 상태를 다시 확인하는 기본 간격 |
| 정체 의심 | 120초 | 유효한 침묵 유예 없이 응답하지 않을 때 정체 후보로 보는 경계 |
| 침묵 유예 최대값 | 600초 | 한 번의 유예가 보장할 수 있는 최대 침묵 시간 |
| 확인 요청 대기 | 60초 | 정체 의심 뒤 확인 요청의 응답을 기다리는 시간 |
600초는 작업 전체의 제한 시간이 아니다. 빌드나 외부 대기처럼 정당한 침묵이 필요할 때 한 번의 유예가 덮을 수 있는 최대 시간이다. 유예를 갱신하려면 새로 확인한 제한된 증거와 침묵이 필요한 이유를 함께 남겨야 한다. “아직 하는 중”이라는 같은 문장을 반복해서 유예를 무기한 늘릴 수는 없다.
120초가 지났다고 런타임이 에이전트를 곧바로 중단하지도 않는다. liveness-check는 현재 기록을 읽고 다음
행동을 권고하는 읽기 전용 판단이다. 정체 의심 상태라면 stall-record를 남기고 probe-sent를 기록한
뒤 주 세션이 네이티브 send_message 또는 에이전트 목록 확인을 수행한다. 확인 요청 대기 시간인 60초 안에 응답이
없고 정책 판정이 중단 권한을 부여했을 때만 주 세션이 네이티브 중단을 수행한다.
복구 흐름을 명령 이름만 줄이면 다음과 같다.
bluetape-flow.py: liveness-check -> stall-record -> probe-sentCodex 주 세션: 네이티브 확인 요청 -> 네이티브 중단 (권한이 있을 때)bluetape-flow.py: interrupt-result -> lane-reassign여기서도 Python과 네이티브 도구의 경계를 지킨다. probe-sent는 확인 요청을 보낼 의도를 먼저 기록한다.
실제 메시지 전송과 중단은 주 세션이 수행한다. CLI는 관찰한 결과를 interrupt-result로 남긴 뒤에만
새 실행 단위를 예약하는 lane-reassign으로 이동한다. 실행 단위 하나의 교체는 최대 한 번으로 제한된다.
생존 신호는 이 과정에서 에이전트가 살아 있음을 보여 줄 뿐이다. 변경 경로, 검사 결과, 구성 요소 검증 범위, 주 세션 검증이나 완료 증거가 아니다. 완료 판정에 생존 신호를 재사용하면 “응답 가능한 에이전트”와 “검증을 마친 작업”을 같은 상태로 취급하게 된다.
가장 약한 필수 구성 요소가 완료를 결정한다
섹션 제목: “가장 약한 필수 구성 요소가 완료를 결정한다”여러 실행 단위의 완료 보고를 합치는 것만으로는 전체 작업의 완료 여부를 알 수 없다. 한 실행 단위가 여러 구성 요소를 맡을 수도 있고, 서로 다른 실행 단위가 만든 결과가 하나의 필수 검사에서 만날 수도 있기 때문이다. 그래서 런타임은 승인된 구성을 구성 요소 단위로 기록한다.
각 구성 요소에는 다음 정보가 있다.
required: 이 구성 요소가 전체 완료를 막는 필수 항목인지 표시한다.owner_lane: 증거를 책임지는 실행 단위를 가리킨다.required_checks: 통과해야 할 검사 목록이다.dependencies: 먼저 완료돼야 할 구성 요소 ID 목록이다.evidence_refs: 작업 원장에서 확인할 수 있는 제한된 증거 참조다.coverage_state: 현재 증거가 구성 요소를 검증하는지 나타낸다.
완료 규칙은 weakest_required_component다. 전체 작업은 가장 덜 완료된 필수 구성 요소보다 앞서갈 수
없다. 예를 들어 글 작성 실행 단위와 사이트 검증 실행 단위가 모두 completed라고 보고했어도, 한국어 경로의 빌드
검사가 실패했거나 대표 이미지 증거가 비어 있다면 전체 작업은 완료할 수 없다.
| 필수 구성 요소 | 담당 실행 단위 | 필수 검사 | 증거 | 판정 |
|---|---|---|---|---|
| 한국어 글 | write-ko | 소스 링크 검사 | 있음 | 완료 가능 |
| 영어 글 | write-en | 언어별 문서 대응 | 있음 | 완료 가능 |
| 렌더링된 경로 | verify-site | 운영 빌드 | 없음 | 완료 불가 |
이 예제에서는 앞의 두 구성 요소가 준비돼도 렌더링된 경로가 가장 약하다. completion-check는 종료
상태의 실행 단위, 필수 구성 요소, 검사, 교체 계보, 증거와 주 세션 검증 중 빠진 항목을 찾는다.
누락이 하나라도 있으면 complete는 실행되지 않는다.
구성에서 구성 요소를 없애는 동작도 명시적으로 기록한다. 완료하기 어려워졌다는 이유로 필수
구성 요소를 목록에서 조용히 빼면 안 된다. topology-remove는 제거 이유를 요구하며, 다른 구성 요소가
의존하는 항목이나 아직 필요한 필수 구성 요소를 암묵적으로 삭제하지 못하게 막는다.
작업 원장으로 중단된 작업을 복구한다
섹션 제목: “작업 원장으로 중단된 작업을 복구한다”중단된 전체 작업을 복구할 때는 작업 원장이 정상인지부터 구분해야 한다. 작업 원장이 정상인 작업을 새 세션이 이어받는 경로와, 원장 연결 구조가 손상된 작업을 복구하는 경로는 서로 다르다.
정상 작업 원장은 새 소유권 세대로 이어 간다
섹션 제목: “정상 작업 원장은 새 소유권 세대로 이어 간다”먼저 읽기 전용 명령인 resume-check로 전체 작업을 재생한다. 완료되지 않은 교체 예약이 있다면 그대로
소유권을 넘기지 않고 replacement-repair로 새 실행 단위를 완성하거나 replacement-block으로 명시적으로
막아야 한다.
검사가 통과하면 resume이 새 소유자 핸들을 만들고 run_resumed 이벤트를 추가하며 소유권 세대를 1 올린다.
이전 핸들은 차단되고 제거된다. 새 세션이 이전 소유자의 자격 증명을 재사용하는 방식이 아니다. 이전
소유자와 에이전트는 최신 세대의 상태를 수정할 수 없다.
소유자 자격 증명은 명령 인자나 JSON에 넣지 않는다. 허용된 상태 루트 안에서 권한을 0600으로 제한한 소유자
파일에만 둔다. resume은 이 파일을 새로 발급하는 소유권 이전이지, 대화에서 토큰을 복사하는 인계가
아니다.
손상된 작업 원장은 별도 복구 작업으로 옮긴다
섹션 제목: “손상된 작업 원장은 별도 복구 작업으로 옮긴다”작업 원장이 손상됐다면 마지막으로 읽히는 이벤트까지만 남기고 원래 연결 구조를 계속 쓰고 싶을 수 있다. 하지만 그렇게 하면 어디까지가 원래 기록이고 어디부터가 수동으로 이어 붙인 기록인지 증명할 수 없다.
receipt-diagnose는 작업 원장을 고치지 않는 읽기 전용 진단이다. 첫 번째 손상 순번, 신뢰할 수 있는
접두 구간의 마지막 값, 매니페스트 식별자, 잠금 상태와 손상된 원장 해시를 보고한다. 이 결과로 손상 범위를
확인하되 원래 연결 구조를 잘라 내거나 편집하거나 이어 쓰지 않는다.
복구가 승인되면 recovery-run-create가 진단 체크섬과 승인 증거를 검증한다. 손상된 원본은
quarantine/ 아래에 권한 0600의 변경 불가능한 복사본으로 보존하고, 출처를 첫 이벤트에 담은 별도 작업을
만든다. 새 작업은 기존 연결 구조의 다음 순번이 아니라 독립적으로 계획한 작업이다. 제자리 마이그레이션은
지원하지 않는다.
이 구분은 복구를 조금 번거롭게 만든다. 대신 정상 작업의 소유권 이전과 손상된 기록의 재시작을 같은 동작으로 섞지 않는다. 작업 원장이 정상이면 소유권 세대를 올려 이어 가고, 손상됐으면 진단 결과와 원본을 보존한 채 새 작업으로 옮긴다.
런타임은 기록하고 Codex는 실행한다
섹션 제목: “런타임은 기록하고 Codex는 실행한다”
bluetape-flow.py는 Python으로 작성됐지만 네이티브 조정 도구를 호출하지 않는다. 에이전트 생성,
메시지 전송, 대기, 목록 확인과 중단은 Codex 주 세션의 책임이다. CLI가 이 동작을 대신했다고 설명하면
실제 실행 주체와 작업 원장 기록 주체가 뒤섞인다.
경계는 “의도를 먼저 기록하고, 네이티브 동작을 실행하고, 관찰 증거를 나중에 기록한다”로 정리할
수 있다. lane-start 뒤에는 네이티브 에이전트 생성이 있어야 하고, probe-sent 뒤에는 네이티브 확인 요청이 있어야 한다.
interrupt-result에는 주 세션이 관찰한 중단 결과만 제한된 형태로 들어간다. CLI 출력만 보고 네이티브
동작이 일어났다고 추론하지 않는다.
.bluetape 상태를 기록하는 지원 경로는 보호된 CLI인 bluetape-flow.py 하나뿐이다. 문제가 생겼다고
작업 원장이나 매니페스트 상태를 편집기로 직접 고치는 방식은 지원하지 않는다. 읽기 전용 명령도 캐시나 작업 원장을
몰래 수정하지 않는다.
증거에도 경계가 있다. 소유자 자격 증명, 비밀 정보, 원본 프롬프트, 무제한 도구 출력과 차단 정보는 작업 원장이나 보고서의 일반 JSON 필드로 받지 않는다. 런타임이 필요한 것은 네이티브 도구의 모든 대화가 아니라 다음 상태 전이를 검증할 수 있는 제한된 관찰 결과다. 이 제한이 있어야 작업 원장이 세션 대화 기록의 복사본이 되지 않고 작업 흐름 상태 원장으로 남는다.
공개 당시 1.1.0 설치와 현재 적용 절차
섹션 제목: “공개 당시 1.1.0 설치와 현재 적용 절차”이 글에서 설명한 런타임은 1.1.0에서 처음 공개됐다. 당시 버전을 재현하려면 현재 작업 사본을 덮어쓰기보다
태그를 별도 디렉터리에 얕게 복제해
검증하는 편이 안전하다.
git clone --branch v1.1.0 --depth 1 https://github.com/bluetape4k/bluetape-skills.git bluetape-skills-v1.1.0cd bluetape-skills-v1.1.0./scripts/validate.sh./scripts/install.sh --forcevalidate.sh는 공개 묶음 경계, 매니페스트 목록, 작업 흐름 계약과 함께 배포된 회귀 테스트를
검사한다. 실행에는 Bash, rg, Python 3와 uv가 필요하다. install.sh --force는 기존 정식 스킬
디렉터리를 타임스탬프가 붙은 백업으로 옮긴 뒤 새 버전을 설치한다. 로컬에서 스킬을 직접 수정했다면 강제
교체 전에 git log와 git diff로 변경 내용을 먼저 확인해야 한다.
현재 설치에는 최신 안정 태그를 사용한다. 2026년 7월 28일 기준 최신 공개 버전은 v1.2.2다.
git clone --branch v1.2.2 --depth 1 https://github.com/bluetape4k/bluetape-skills.git bluetape-skills-v1.2.2cd bluetape-skills-v1.2.2./scripts/validate.sh./scripts/install.sh --force설치 결과를 확인할 때는 현재 Codex 작업을 먼저 종료하지 않는다. 같은 작업 공간에서 새 Codex 프로세스를
별도로 실행해 새 스킬을 인식하고 자체 점검을 통과하는지 확인한 뒤 기존 프로세스를 정리한다.
code-review와 self-audit는 공개 정식 묶음 밖의 보조 스킬이므로, 해당 검토 경로나 자체 점검 관문을
사용한다면 별도로 설치해야 한다.
v1.1.0 릴리스 후보는 공개 당시 정식 스킬 14개, 테스트 133개와 하위 테스트 151개, 파일 83개의
원본·묶음 일치 검증을 통과했다고 기록돼 있다. 이 숫자는 당시의 검증 결과다. 현재 v1.2.2의 검증 수치로
해석해서는 안 된다.
언제 런타임을 사용해야 하나
섹션 제목: “언제 런타임을 사용해야 하나”모든 작업을 2단계 런타임으로 기록할 필요는 없다. 한 에이전트가 짧게 끝내는 문구 수정이나 변경 파일과 검증이 명확한 작은 작업이라면 일반 체크리스트와 Git 변경 사항만으로도 충분하다. 전체 작업과 실행 단위, 구성 정보를 만드는 비용이 실제 복구 위험보다 커질 수 있다.
반대로 다음 조건이 있다면 런타임이 남기는 상태가 도움이 된다.
- 한 세션보다 오래 걸리거나 새 세션으로 인계할 가능성이 크다.
- 여러 네이티브 하위 에이전트가 병렬 실행 단위로 움직인다.
- 에이전트 침묵과 정상적인 장기 작업을 구분해야 한다.
- 멈춘 실행 단위를 교체하고 늦게 도착한 이전 결과를 차단해야 한다.
- 여러 구성 요소의 필수 검사와 증거를 모아 전체 완료를 판정해야 한다.
- 작업 원장 손상 뒤 출처를 보존한 복구 작업이 필요하다.
선택 기준은 명령 수가 아니다. 중단 뒤 다음 세션이 대화 내용을 추측하지 않고도 현재 소유자, 실행 단위 상태, 구성 요소별 증거와 작업 원장을 읽어 안전한 다음 행동을 고를 수 있는가를 본다. 그 질문에 답하기 어렵다면 런타임을 쓸 이유가 있다. 짧고 경계가 분명한 작업이라면 체크리스트만으로 끝내는 편이 낫다.
댓글
GitHub 계정으로 의견을 남기거나 reaction을 남길 수 있습니다.