Huny's Dev Blog
huny.dev

Cloudflare Codex harness 실험 공개: 복구·중복 실행·인증 점검

11월 9일 공개된 실험적 Codex harness의 저장·복구 경계를 살펴본다. 요청 중복과 외부 부작용, 인증·세션 소유권, 로컬 모델 호출 비용을 구분해 점검한다.

Hun Jang
Hun Jang Nov 10, 2026

재시작 뒤 복구되는 에이전트 실행 기록과 외부 작업의 경계를 표현한 생성형 이미지. 실제 서비스 화면은 아니다.

Cloudflare가 11월 9일 공개한 실험적 Codex harness는 코딩 에이전트의 실행 상태를 Durable Object에 남기는 예제다. Codex의 Rust 턴 처리 코드를 WebAssembly 환경에 맞게 수정해 실행하고, 대화·파일·완료된 모델 및 도구 결과를 저장해 중단 후 복구한다. 장시간 작업을 서버리스 환경에 올리려는 개발자에게 유용하지만, 도입 판단은 무엇을 저장하고 어느 작업이 다시 실행되는지부터 시작해야 한다. 공식 발표

전체 Codex CLI를 Workers에 옮긴 것은 아니다

이번 CodexHarness는 SDK에서 바로 가져다 쓰는 정식 공개 클래스가 아니라, 내부 SDK API를 사용하는 예제 코드다. 현재 기본 도구는 영속 Workspace의 UTF-8 파일 읽기와 쓰기다. Linux 셸, Git 명령, 저장소의 빌드·테스트 도구가 필요한 팀은 별도 Container harness 경로를 검토해야 한다. 이름이 같아도 실행 환경과 복구 범위가 다르다. Codex harness 가이드

Container harness는 실제 코딩 CLI를 컨테이너에서 돌리고 Durable Object가 세션을 관리한다. 다만 컨테이너가 사라지면 마지막 파일시스템 스냅샷 이후 수정은 유실될 수 있다. 기본 동작은 진행 중 작업을 unanswered로 정리하며, 처음부터 재시도하는 옵션은 외부 동작까지 안전하게 반복할 수 있을 때만 쓰도록 안내한다. 컨테이너 방식으로 바꾼다고 모든 파일과 프로세스가 자동 보존되는 것은 아니다. Container harness의 복구 조건

복구는 네 가지 저장 책임으로 나뉜다

Wasm 커널에는 다음 효과와 대기 중인 도구 호출을 가리키는 작은 체크포인트가 들어간다. 큰 데이터는 다음 저장 구성 요소에 나뉘어 남는다.

  • Tasks: 모델·도구 단계의 실행 결과를 기록한다. 완료된 단계는 복구할 때 기록을 재사용한다.
  • Sessions: 사용자 입력, 모델 응답, 도구 출력을 보관하고 모델에 보낼 문맥을 압축한다.
  • Streams: 작업별 이벤트를 순서대로 저장해 연결이 돌아왔을 때 재생한다.
  • Workspace: Durable Object의 SQLite에 파일을 저장한다.

따라서 운영 검증도 ‘채팅 기록이 다시 보인다’에서 끝내면 안 된다. 작업 상태, 도구 결과, 이벤트 순서, 파일 내용이 각각 맞는지 확인해야 한다. UI가 복원됐어도 특정 파일 쓰기나 외부 요청이 어디까지 끝났는지는 별도 문제다. 예제 README의 저장 구조

요청 중복과 외부 부작용 중복은 따로 막는다

예제의 submit()은 프롬프트가 영속적으로 접수되면 반환한다. 모델 작업의 완료를 뜻하지 않는다. 같은 요청을 재전송할 때 operationId를 유지하면 새 작업을 만들지 않고 accepted: false를 반환한다. 이후 snapshot()으로 queued, running, completed, failed를 확인할 수 있다. 접수와 상태 조회

소스의 #performEffect()는 모델·도구 호출을 단계 단위로 기록한다. 이미 기록된 결과를 다시 쓰는 경우와, 처리 도중 끊겨 호출을 다시 하는 경우가 구분된다. 이 구조만으로 외부 API의 ‘정확히 한 번 실행’이 보장되지는 않는다. 단계 실행 소스

예를 들어 도구를 확장해 이슈를 만드는 경우를 생각해 보자.

  1. 외부 서비스가 이슈 생성을 완료한다.
  1. 결과를 실행 기록에 저장하기 전에 연결이나 프로세스가 끊긴다.
  1. 복구 과정에서 미완료로 보이는 도구 단계가 다시 실행된다.

외부 서비스의 중복 방지 장치가 없으면 같은 이슈가 두 개 생길 수 있다. 아래는 이런 도구를 추가할 때의 권장 설계다.

  • 사용자 요청을 처음 접수할 때 안정적인 작업 ID를 만들고 재전송에도 유지한다.
  • 각 외부 작업에 별도 멱등성 키를 부여한다. 하나의 요청에 외부 작업이 여러 개라면 요청 ID만 공유해서는 부족하다.
  • 응답을 못 받았다고 곧바로 다시 만들지 말고, 같은 키나 업무 식별자로 이미 완료됐는지 먼저 확인한다.
  • 중복 실행을 막을 수 없는 작업은 자동 재시도 대상에서 빼고, 확인 대기 상태를 둔다.

이 권고는 예제에 이슈 생성 기능이 있다는 뜻이 아니다. 기본 파일 도구를 외부 업무 도구로 확장할 때 필요한 경계다.

배포 전에 인증과 세션 소유권부터 붙인다

공식 가이드는 예제 라우트에 인증이 없다고 명시한다. 로컬 데모를 공개 주소에 그대로 배포하면 안 된다. HTTP 요청과 WebSocket 연결을 모두 검사하고, 로그인한 사용자가 해당 세션에 접근할 권한이 있는지도 확인해야 한다. 예제 배포 주의

Cloudflare의 라우팅 문서는 HTTP의 onBeforeRequest, WebSocket의 onBeforeConnect에서 요청을 차단할 수 있도록 설명한다. 클라이언트가 보낸 세션 이름을 그대로 신뢰하지 말고, 서버에서 사용자 신원에 맞는 객체를 선택하거나 소유권을 검사한다. 문서 속 인증 함수의 자리표시 코드는 실제 토큰 검증으로 교체해야 한다. 인증과 객체 접근 제어

운영에서는 사용자 A의 세션 이름을 사용자 B가 넣어 봤을 때 거부되는지도 시험해야 한다. 프롬프트 제출만 막고 대화 조회·파일 읽기·이벤트 구독은 열어 두는 누락을 함께 점검한다.

로컬 실행도 비용과 승인 설계를 확인한다

예제의 로컬 개발은 모델까지 오프라인으로 실행한다는 뜻이 아니다. 공식 가이드는 로컬에서도 계정의 원격 Workers AI를 사용한다고 안내한다. 모델 어댑터는 도구 승인 요청을 지원하지 않으므로, 민감한 업무 도구를 추가할 때 사람의 승인 절차를 별도로 설계해야 한다. 실행 조건과 모델 제한

AI Gateway의 Unified Billing을 쓰는 경우 선불 크레딧 구매에 5% 수수료가 붙으며, 드물게 잔액이 음수가 되면 저장된 결제수단에 청구될 수 있다. 개발 테스트에도 사용할 모델, 호출 예산, 중단 조건을 먼저 정한다. 기존 공급자 키를 쓰는 경로와 Cloudflare 크레딧을 쓰는 경로의 청구 대상도 구분해야 한다. Unified Billing 과금 안내

첫 검증은 작은 파일 작업으로 제한한다

다음은 운영 도입 전에 수행할 권장 실험이다. 실제 고객 데이터나 외부 변경 권한 없이 시작한다.

  1. 버전을 고정한다. 예제 커밋, SDK 의존성, Rust/Wasm 도구 체인을 함께 기록한다. 내부 API를 쓰므로 서로 다른 시점의 코드 조각을 섞지 않는다.
  1. 작은 파일을 쓰고 다시 읽는다. 예상 경로와 내용이 일치하는지 확인한다. 반복 쓰기는 기존 파일을 바꿀 수 있으므로 테스트 경로를 분리한다.
  1. 완료 후 새로고침한다. 같은 세션에서 대화와 파일이 남는지 확인한다.
  1. 진행 중 중단을 시험한다. 완료된 단계와 진행 중 단계의 재실행 여부, 모델 호출 횟수, 최종 파일 내용을 대조한다.
  1. 동일 요청을 재전송한다. 같은 작업 ID로 새 작업이 추가되지 않는지 확인한다. 사용자가 의도적으로 시작한 새 작업에는 새 ID를 쓴다.
  1. 접근 거부를 시험한다. 로그인하지 않은 접속과 다른 사용자의 세션 접근이 HTTP·WebSocket 양쪽에서 막히는지 확인한다.

검증 결과에는 접수 성공, 작업 완료, 복구 성공을 따로 남기는 것이 좋다. 이번 예제의 가치는 에이전트 루프와 영속 상태를 연결하는 구현을 살펴볼 수 있다는 데 있다. 실제 서비스에 적용할 때는 그 위에 외부 작업의 멱등성, 사용자별 접근 제어, 비용 한도를 완성해야 한다.

확인 범위

2026년 11월 9일 Cloudflare 공식 발표·가이드와 공개 예제 소스를 확인해 작성했다. 문서와 저장소는 변경될 수 있으므로 실제 도입 시 같은 커밋의 전체 예제를 기준으로 다시 확인해야 한다. 이 글에서는 SDK 설치·빌드, Cloudflare 배포, 모델 API 호출, 장애 주입이나 과금 실험을 수행하지 않았다. 위 목록은 실행 결과가 아닌 검증 계획이다.

추천 글