Codex 대 Claude 코드. 여기서 중요한 것은 단 하나의 절대적인 승자를 가리는 것이 아니라, 매일 믿고 사용할 수 있는 작업 방식을 선택하는 것입니다. 두 제품 모두 리포지토리를 검토하고, 여러 파일을 편집하며, 명령을 실행하고, 테스트를 수행하고, 패치를 설명할 수 있습니다. 두 도구 간의 실질적인 차이는 작업을 위임하는 방식, 에이전트를 제어하는 빈도, 검토할 수 있는 증거의 양, 그리고 각 도구가 기존 개발 환경에 얼마나 잘 부합하는지에 나타납니다.
통제된 4가지 작업으로 구성된 저장소 테스트에서 Codex는 100점 만점에 98점을, Claude Code는 99점을 기록했습니다. 두 모델 모두 핵심 작업을 완료했습니다. Claude Code는 더 광범위한 검토와 경계 사례 커버리지를 보인 반면, Codex는 우리 테스트 환경에서 더 좁은 범위 내에서 요구되는 결과에 도달하는 경우가 많았으며, 실행 수준에서 더 강력한 증거를 제시했습니다. 소규모 Python 테스트 환경에서 1점 차이는 전체적인 승자를 가릴 만한 근거가 되지 않습니다.
나머지 워크플로우를 특정 코딩 에이전트에 묶여 있게 하고 싶지 않은 개발자는 GlobalGPT를 별도의 다중 모델 및 다중 모달 레이어로 추가할 수 있습니다. GlobalGPT는 GPT 5.6, Claude Opus 5, GPT Image 2 등 100개 이상의 최상위 모델을 하나의 대시보드에 통합합니다. 또한, 이 GlobalGPT CLI, MCP 및 Skill 경로는 코덱스(Codex)나 Claude 코드에서 제2의 의견 수렴, 계획 수립, 문서화 또는 기타 지원되는 모델을 위해 활용할 수 있으며, 이 과정에서 네이티브 코딩 호스트는 리포지토리 수정 및 테스트에 대한 통제권을 유지합니다.

이 비교 분석은 공식 계획 정보, 실제 저장소 작업, 완벽하게 확장 가능한 출력 결과, 그리고 명확하게 분류된 커뮤니티 경험을 종합하여 이루어졌습니다. 그 목적은 독립 개발자가 구독 방식의 접근 권한, 추가 크레딧, API 과금 등의 복잡한 요소에 혼란을 겪지 않고 주된 코딩 도구를 선택할 수 있도록 돕는 데 있습니다.
Codex와 Claude 코드 비교 한눈에 보기
| 결정 요인 | 코덱스 | 클로드 코드 |
|---|---|---|
| 핵심 저장소 관련 업무 | 지원되는 모든 Codex 환경에서 내용을 읽고, 편집하고, 명령을 실행하며, 변경 사항을 확인합니다. | 명령어 읽기, 편집, 실행 및 변경 사항 확인을 위한 대화형 터미널 에이전트 |
| 테스트에서 확인된 스타일 | 구현 및 버그 수정 측면에서 더욱 간결해졌습니다. | 저장소 분석, 테스트 및 검토 범위 면에서 더욱 철저함 |
| 저장소 이해 | 동결된 작업에 대한 기능적 연결 | |
| 코드 검토 | 중요도가 더 높은 유효한 결함 두 건을 발견하고 수정했습니다. | 재현 가능한 문제를 추가로 보고했으며, 20건 중 19건을 20건 중 18건으로 수정했습니다. |
| 측정된 속도 | 혼재된 결과; 각 환경 간의 유사성이 충분하지 않아 단일 우승자를 가리기 어려웠다 | |
| 소비자용 보급형 제품군 | 관련 ChatGPT 플랜을 통해 월 $20 | Claude Pro: 미국 내 월 $20 |
| 이용량이 많은 요금제 | $100 및 $200 등급 | $100에서는 최대 5배, $200에서는 최대 20배 |
이 표는 구매 결정을 위한 참고 자료일 뿐, 모델 순위표가 아닙니다. 모델 설정, 저장소, 권한 구성 또는 작업 사양이 다르면 결과가 달라질 수 있습니다. 이미 특정 제품을 사용하고 계신다면, 동일한 성공 명령어를 사용하고 품질 재시도가 없는, 자체 코드베이스의 제한된 작업을 기준으로 비교하는 것이 가장 좋습니다.
제어된 테스트 프로필
첫 번째 유효한 결과이며, 평가 기준은 동일하게 고정되어 있습니다. 막대 그래프는 각 과제의 만점을 기준으로 정규화되었습니다.
이 그림은 1점 차가 어디서 비롯되었는지를 보여줄 뿐, 작은 경기를 종합 순위로 확대 해석하는 것은 아닙니다.
코덱스와 Claude 코드가 실제로 무엇인지
Codex와 Claude Code는 단순히 모델명이 아닌 에이전트 제품입니다. 그 기반이 되는 코딩용 AI 모델 모델도 중요하지만, 이를 둘러싼 프레임워크 역시 에이전트가 어떤 파일을 볼 수 있는지, 어떤 명령을 실행할 수 있는지, 승인 절차가 어떻게 진행되는지, 컨텍스트가 어떻게 유지되는지, 그리고 작업이 끝난 후 어떤 증거가 남는지 등을 결정합니다. 모델의 평판만을 비교하는 것은 개발자가 얻는 경험의 상당 부분을 간과하는 것입니다.
Codex는 명령줄, IDE, 데스크톱 및 클라우드 기반 워크플로를 아우릅니다. 이러한 폭넓은 지원 덕분에 직접적인 로컬 협업은 물론, 범위가 더 제한된 업무 위임에도 적합합니다. Claude Code는 지원되는 통합 기능과 폭넓은 사용자 지정 옵션을 갖춘 대화형 터미널 워크플로를 중심으로 설계되었으며, 이는 코딩 시 Claude 사용 안내 해당 워크플로우에 대해 보다 폭넓게 소개합니다. 일부 개발자에게는 터미널에서 에이전트가 작동하는 모습을 지켜보는 것만으로도 안심이 됩니다. 반면 다른 개발자들에게는 끊임없는 대화보다는 최종 diff, 테스트 결과, 감사 추적이 더 중요한 산출물입니다.
이러한 구분은 명목상 강력한 모델을 사용하는 두 가지 테스트가 서로 다른 결과를 보이는 이유도 설명해 줍니다. 호스트는 지침이 어떻게 제시될지, 도구가 어떻게 호출될지, 그리고 언제 사람이 행동을 승인해야 하는지를 결정합니다. 이러한 테스트 환경을 무시한 커뮤니티 간 비교는 제품 수준의 행동을 모델 수준의 진리로 오해할 수 있습니다.
- 모델 추론 및 생성 기능을 제공합니다.
- 에이전트 하네스 파일, 명령어, 컨텍스트, 승인 및 복구 기능을 제어합니다.
- 사용자의 작업 계약 범위, 성공 여부 확인, 그리고 에이전트가 언제 중단해야 하는지를 결정합니다.

업무 흐름과 통제: 권한 위임인가, 지속적인 지도인가?
Codex와 Claude 코드 중 어느 것이 더 유용한지에 대한 질문은 대개 “어느 쪽이 더 나은 코드를 작성하는가?”가 아니라 “어떻게 작업하고 싶은가?”입니다. 명확하고 범위가 정해진 작업은 정확한 목표, 허용된 범위, 검증 명령과 함께 위임할 수 있습니다. 모호한 리팩토링의 경우, 논의와 중간 점검을 거치고, 변경이 너무 많이 진행되기 전에 담당자의 방향을 재조정할 기회를 갖는 것이 도움이 됩니다.
요구 사항이 지속적으로 변화하거나 아키텍처에 대한 판단이 아직 논의 중인 상황에서는 지속적인 조정이 유용합니다. 반면, 에이전트가 저장소의 지침만으로도 해결될 수 있는 사안에 대해 반복적으로 결정을 요청할 경우 이는 비용으로 작용합니다. 작업 계약이 안정적인 상황에서는 자율적 실행이 유용합니다. 그러나 에이전트가 검증되지 않은 가정을 하거나 명확한 롤백 경로 없이 범위를 확장할 경우 이는 위험 요소가 됩니다.
2026년 4월 13일자 레딧(Reddit)의 한 상세한 보고서에 따르면, 테스트 케이스가 약 2,800개인 약 80,000줄 규모의 파이썬 및 타입스크립트 프로젝트에서 Claude Code를 사용한 시간은 약 100시간, Codex를 사용한 시간은 20시간이었다. 작성자는 Claude를 더 빠르고 상호작용이 활발하지만 더 많은 관리가 필요한 반면, Codex는 더 느리고 신중한 방식이라고 평가했습니다. 이 보고서는 프로젝트 및 경험적 맥락을 포함하고 있어 유난히 유용하지만, 여전히 한 개발자의 워크플로우를 반영한 것에 불과합니다.

저희가 직접 측정한 결과에서는 명확한 승자를 가릴 수 없었습니다. Claude는 처음 두 과제를 더 빨리 완료한 반면, Codex는 나머지 두 과제를 더 빨리 완료했습니다. 또한 Claude는 CLI 인증 경로를 사용할 수 없게 되자 서브에이전트 대체 방식을 사용했기 때문에, 두 시스템의 실행 경로는 실험실 환경에서 동일하게 재현되지 않았습니다. 따라서 신중한 결론은 속도가 과제, 선택된 모델, 노력 설정, 맥락 및 호스트에 따라 달라진다는 것이며, 어느 한 제품이 항상 더 빠르다고 단정할 수는 없다는 점입니다.
저장소 이해 및 컨텍스트 관리
리포지토리를 이해한다는 것은 단순히 폴더 이름을 짓는 것 이상의 의미를 지닙니다. 유용한 에이전트는 데이터가 파일 간에 어떻게 이동하는지 추적하고, 변경을 제한하는 계약 사항을 파악하며, 테스트를 찾아내고, 증상과 그 원인을 구분하며, 잘못된 계층을 수정할 경우의 위험을 설명할 수 있어야 합니다. 철저한 맵은 숨겨진 불일치를 드러낼 수 있고, 간결한 맵은 개발자가 더 빠르게 안전한 구현 결정을 내릴 수 있도록 도와줍니다.
읽기 전용 T1 과제에서 두 에이전트 모두 20점 만점에 20점을 획득했으며, 답변을 리포지토리에 근거를 두었습니다. Claude Code는 더 철저하여 추가적인 계약 불일치 사항을 찾아냈습니다. Codex는 더 간결하면서도 관련 파일, 위험 요소 및 구현 계획을 정확히 파악했습니다. 어느 한 방식이 자동으로 더 우수하다고 할 수는 없습니다. 철저함은 익숙하지 않은 마이그레이션이나 감사 과정에서 도움이 되며, 간결함은 개발자가 이미 아키텍처를 잘 알고 있고 핵심에 집중된 변경 계획을 원할 때 유용합니다.
T1 · 제어된 저장소 테스트
익숙하지 않은 저장소를 변경하기 전에 그 내용을 파악하십시오
아키텍처를 매핑하고, 데이터 흐름을 추적하며, 우선순위 기능의 위험 요소를 파악하되, 파일 변경은 하지 마십시오.
아키텍처: 모델, 리포지토리, 서비스, 그리고 연결되지 않은 시간 유틸리티. 주요 위험 요소: 정의되지 않은 우선순위 의미론, 호환성, 순서, 유효성 검사, 범위 불일치.
리뷰어의 의견: 간결하고, 사실에 근거하며, 해당 결정에 충분한 근거를 제공한다.
3개의 레이어와 하나의 고아 모듈. 사이클 없음; 의존성 주입 최소화. 또한 식별자 할당, 비대칭 오류 계약, 그리고 부족한 테스트 커버리지가 드러났다.
리뷰어의 의견: 동일한 읽기 전용 계약 조건을 충족하면서도 더 철저합니다.
Codex 출력 결과 전체 보기
완전하게 정제된 첫 번째 유효한 출력
## 아키텍처
이 패키지는 표준 라이브러리만 사용하는 소규모 파이썬 패키지로, 다음 네 가지 기능 계층으로 구성되어 있습니다:
- **데이터 모델:** [`Job`]()은 `identifier`, `name`, `owner`를 포함하는 불변 데이터 클래스입니다. `Job.to_dict()`는 `dataclasses.asdict()`를 통해 이를 직렬화합니다.
- **리포지토리:** [`JobRepository`]()는 식별자를 키로 사용하여 메모리 내 사전(dictionary)에 작업을 저장합니다. 데이터베이스나 영구 저장 기능은 없습니다.
- **서비스:** [`SchedulerService`]()는 식별자 할당, 입력 정규화, 생성, 목록 표시 및 삭제를 담당합니다.
- **시간 유틸리티:** [`next_daily_run()`]()는 다음 실행 시간을 계산하지만, 이를 `Job`, `SchedulerService` 또는 `JobRepository`로 가져오거나 연결하는 코드는 없습니다.
- **공개 API:** [`scheduler.__init__`]()는 `SchedulerService`만 노출합니다.
리포지토리 이름과는 달리, 현재 작업(job)에는 스케줄링 정보가 포함되어 있지 않으며 실행 대기열도 없습니다. 따라서 우선순위는 저장된 메타데이터와 목록 표시 순서에는 영향을 줄 수 있지만, 시스템을 상당히 확장하지 않는 한 실제 작업 실행에는 영향을 미칠 수 없습니다.
## 생성 및 목록 표시 데이터 흐름
`SchedulerService.create_job(name, owner)`를 통한 생성:
1. [`create_job()`]()은 공백만으로 구성된 이름을 거부합니다.
2. `name`과 `owner`의 공백을 제거한 후, 서비스의 `_next_identifier`를 사용하여 변경 불가능한 `Job` 객체를 생성합니다.
3. [`JobRepository.save()`]()는 객체를 `_jobs[job.identifier]`에 저장합니다.
4. 서비스는 `_next_identifier`를 증가시키고 동일한 `Job`을 반환합니다.
`SchedulerService.list_jobs()`를 통한 목록 조회:
1. [`list_jobs()`]()는 `repository.all()`로 직접 위임합니다.
2. [`JobRepository.all()`]()은 사전 키를 숫자 순으로 정렬합니다.
3. 따라서 작업은 일정이나 우선순위 순서가 아닌, 식별자/생성 순서(오름차순)로 반환됩니다.
## 작업 우선순위의 영향을 받을 가능성이 있는 파일
필수:
- [`scheduler/models.py`](): priority 필드와 기본값을 추가합니다. `to_dict()`는 `asdict()`를 사용하므로 이 필드를 자동으로 포함합니다.
- [`scheduler/service.py`](): 우선순위를 수락하고 유효성을 검사한 후 `Job`으로 전달합니다.
- [`tests/test_scheduler.py`](): 기본값, 명시적 값, 유효하지 않은 값, 직렬화된 값 및 정렬 동작을 테스트합니다.
조건부:
- [`scheduler/repository.py`](): 우선순위가 목록의 순서를 제어하기 위한 목적으로만 사용되는 경우에만 `all()`을 변경합니다. 동점 상황은 `identifier`와 같은 결정론적 보조 키로 처리해야 합니다.
- [`scheduler/__init__.py`](): 우선순위가 공개 열거형(enum) 또는 값 객체가 되는 경우에만 업데이트합니다.
- [`README.md`](): 허용되는 값, 기본값 및 정렬 규칙을 문서화하십시오.
영향을 받지 않을 것으로 예상됨:
- `scheduler/time_rules.py`: 이 파일의 유일한 심볼은 제공된 datetime을 처리할 뿐이며, 작업이나 목록과 아무런 관련이 없기 때문입니다.
## 주요 위험 요소
- **정의되지 않은 의미론:** 코드에는 값이 클수록 우선순위가 높은지, 작은 값이 우선순위가 높은지, 어떤 값이 유효한지, 또는 우선순위가 목록 순서에 영향을 미치는지에 대한 선례가 전혀 없습니다.
- **호환성:** `Job` 또는 `create_job()`에 필수 인수를 추가하면 현재 테스트에 있는 `create_job("Daily report", "Alex")`와 같은 기존 호출 코드가 작동하지 않게 됩니다. 기본값을 지정하면 해당 호출은 유지됩니다.
- **위치 기반 생성자 문제:** `Job`은 현재 `SchedulerService.create_job()`에서 위치 기반으로 생성됩니다. 필드 배치나 향후 위치 기반 호출 시 잘못된 값이 조용히 할당될 수 있으므로, 키워드 기반 생성자가 더 안전할 것입니다.
- **순서 변경:** `JobRepository.all()`에서 식별자 순서를 변경하면 기존 동작이 달라집니다. 우선순위가 동일한 경우 안정적인 동점 처리 기준이 필요합니다.
- **유효성 검사 모호성:** 제한 없는 Python 값을 허용하면 문자열, 부울 값 또는 임의의 정수가 포함될 수 있으며, 이를 일관되게 비교하기 어렵습니다.
- **실행 범위 불일치:** 디스패처나 실행 큐가 없습니다. 우선순위에 따라 어떤 작업이 먼저 실행되는지 결정한다는 주장은 현재의 어떤 심볼로도 지원되지 않습니다.
- **메모리 내 제한:** `_jobs`는 단순한 인스턴스 사전(dictionary)이므로, 다른 모든 작업 필드와 마찬가지로 우선순위도 프로세스가 종료되면 사라집니다.
## 구현 및 유효성 검사 계획
1. 먼저 계약(contract)을 정의합니다: 표현 방식, 허용되는 값, 기본값, 우선순위 방향, 동점 처리 방식, 그리고 목록 순서에 영향을 미치는지 여부.
2. `Job`에 `priority`를 추가하며, 가급적 하위 호환성이 보장되는 기본값을 설정한다.
3. `SchedulerService.create_job()`을 기본값이 설정된 우선순위 매개변수로 확장하고, 이를 검증한 후 키워드 인수를 사용하여 `Job`을 생성한다.
4. 나열 순서가 우선순위를 반영하는 경우, `JobRepository.all()`을 우선순위 순으로 먼저 정렬한 후 식별자 순으로 정렬되도록 변경합니다. 그렇지 않은 경우 리포지토리 정렬 순서는 변경하지 않습니다.
5. 다음 항목에 대한 테스트를 추가합니다:
- 기존의 두 인자 생성 방식.
- 명시적 우선순위 유지.
- 기본 우선순위.
- 유효하지 않은 유형 및 범위 외 값.
- `Job.to_dict()` 출력.
- 다중 우선순위 목록 정렬 순서.
- 동일한 우선순위에 대한 안정적인 정렬 순서.
- 기존 빈 이름 처리 동작.
6. 정확한 공개 계약 내용을 README에 반영하십시오.
7. `python3 -m unittest discover -s tests -v` 명령어로 전체 오프라인 테스트 스위트를 실행합니다.
## 검증 완료
- 기준 테스트 스위트: **테스트 2개 통과**.
- 리포지토리 전체 심볼 검색 결과, `next_daily_run()`이 분리되어 있으며 기존 우선순위 심볼이 없는 것이 확인되었습니다.
- 변경된 파일: **없음**.
- 기능 구현: 요구 사항에 따라 **실시되지 않음**.
> **결론 + 결정**
>
> 우선순위가 메타데이터나 나열 순서에 불과하다면 변경 사항은 미미합니다. 주로 `models.py`, `service.py`, `repository.py` 및 테스트가 해당됩니다. 구현 전에, 우선순위가 단순히 작업을 설명하는 것인지, 아니면 `list_jobs()`의 순서를 변경하는 것인지, 그리고 값의 척도, 기본값, 방향 및 동점 처리 규칙을 결정해야 합니다.Claude 코드 출력 전체 보기
첫 번째 유효한 출력을 그대로 포함하는 완전한 핸드오프 기록
# T1 실행 기록 — 알 수 없는 저장소 파악
## 실행 매개변수
| 필드 | 값 |
| --- | --- |
| 작업 | `T1` |
| 고정 프롬프트 | `01-prompts/T1.md` |
| 고정 프롬프트 SHA-256 | `a571ff15c2502ec29b172ae2e77dd9ab0caca2869b91f9468d47571434d16c17` |
| 실행 단위 | 격리된 Claude 서브에이전트, `general-purpose`, 새로운 컨텍스트 |
| 격리 방법 | **서브에이전트 폴백** (문서화된 다운그레이드 — `results/isolation-decision.md` 참조) |
| 할당된 깨끗한 사본 | `runtime/workspaces/T1` |
| Claude 코드 버전 | `2.1.220` |
| 모델 설정 | `claude-opus-5` |
| start_utc | `2026-07-28T10:27:31Z` |
| end_utc | `2026-07-28T10:28:32Z` |
| 소요 시간 | 61초 (T2–T4와 동시 실행; 정확한 지연 시간 측정이 아님) |
| 시도 횟수 | 1 |
| 상태 | `valid` |
| 수동 개입 | 없음 |
## Safe 도구 요약
`date`, `find`, `ls`, `wc`, `stat`, `grep`, 작업 공간 파일 7개에 대한 `Read`, `python3 -V`,
`python3 -m unittest discover -s tests -v`. 모든 읽기 작업은 할당된 작업 공간 내에서만 수행됨.
네트워크 접속 없음, 설치 없음, 쓰기 작업 없음.
## 오프라인 검사 결과
`python3 -m unittest discover -s tests -v` → 테스트 2개, OK (종료 코드 0).
워크스페이스 외부에서 코디네이터가 재확인함: `results/checks/T1-public.txt` 참조.
## 패치
없음. `results/T1/patch.diff`는 비어 있으며, `diff -ru 02-fixture runtime/workspaces/T1`
명령은 차이점을 반환하지 않습니다. 이 작업은 파일을 변경하지 않고 검사해야 했으며, 이는
단순히 확인된 사항일 뿐 명시적으로 주장된 것은 아닙니다.
## 정제된 오류
복구 가능한 셸 오류 1건: 초기 `grep` 명령에서 따옴표로 묶이지 않은 `--include=*.py` 패턴을 사용했으므로
셸이 글로브 처리를 시도했습니다. 패턴을 따옴표로 묶어 다시 실행하니 성공했습니다. 결과에는 영향을 미치지 않았습니다.
## 표시된 출력(원문 그대로)
### 1. 이 저장소의 내용
`local-scheduler-1.0.0`(`fixture-manifest.json`)이라는 이름의 독립형 파이썬 표준 라이브러리 피처로, MIT 라이선스를 따르며 네트워크나 프로덕션 의존성이 없습니다(`README.md`, `"network_required": false`). 크기가 매우 작습니다: 소스/문서 파일 8개와 매니페스트를 합쳐 총 103줄입니다. 사용된 인터프리터는 **Python 3.9.6**입니다. `pyproject.toml`, `setup.py`, CI 구성, 린터 또는 타입 체커 구성은 없습니다. 선언된 유일한 워크플로는 `python3 -m unittest discover -s tests -v`입니다(`README.md`).
### 2. 아키텍처
세 개의 레이어와 하나의 독립 모듈로 구성되어 있으며, 모두 `scheduler/` 아래에 위치합니다:
| 레이어 | 파일 | 심볼 | 역할 |
|---|---|---|---|
| 패키지 파사드 | `scheduler/__init__.py` | `__all__ = ["SchedulerService"]` | `SchedulerService`만 재수출하며, `Job`, `JobRepository` 및 `time_rules`는 공개 인터페이스의 일부가 아님 |
| 도메인 모델 | `scheduler/models.py` | `Job` (`@dataclass(frozen=True)`) | `identifier: int`, `name: str`, `owner: str` 필드를 가진 불변 값 객체이며, `to_dict()` 메서드는 `asdict(self)`로 구현됨 |
| 지속성 | `scheduler/repository.py` | `JobRepository` | `identifier`를 키로 하는 메모리 내 `dict`; `save`, `get`, `all`, `delete` |
| 애플리케이션 서비스 | `scheduler/service.py` | `SchedulerService` | 유효성 검사, 식별자 할당, 오케스트레이션: `create_job`, `list_jobs`, `delete_job` |
| 고아 | `scheduler/time_rules.py` | `next_daily_run` | 반복 계산 — **어디에서도 임포트되지 않음** |
의존성 방향은 명확하고 단방향입니다: `service.py`는 `.models`와 `.repository`에서 가져오고, `repository.py`는 `.models`에서 가져오며, `models.py`는 `dataclasses`만 가져옵니다. 순환 의존성은 없습니다. 의존성 주입이 존재하지만 최소한으로 사용됩니다 — `SchedulerService.__init__(self, repository=None)`은 `self.repository = repository or JobRepository()`를 수행하므로, 테스트 시 가짜 리포지토리를 대입할 수 있습니다.
현재 `scheduler/time_rules.py`는 사멸된 코드입니다. 전체 디렉토리 트리에서 `time_rules`와 `next_daily_run`을 grep으로 검색해 본 결과, 해당 파일의 정의와 `fixture-manifest.json`의 `expected_files`에 나열된 항목만이 검색되었습니다. 이 파일은 배포되었으나 실제로는 연결되지 않은 상태입니다.
### 3. 데이터 흐름
**작업 생성** — `SchedulerService.create_job(name, owner)`:
1. 가드: `if not name.strip(): raise ValueError('name is required")`. 이것이 시스템 내 *유일한* 유효성 검사입니다 — `owner`는 절대 확인되지 않으므로, 빈 소유자도 허용됩니다.
2. 생성: `Job(self._next_identifier, name.strip(), owner.strip())` — 위치 기반 생성이며, 두 문자열 모두 공백을 제거하여 정규화됩니다.
3. 저장: `self.repository.save(job)`, 이는 `self._jobs[job.identifier] = job`을 수행하고 작업 인스턴스를 반환합니다.
4. 카운터 증가: `self._next_identifier += 1` — 저장 *후*에 수행되므로, 예외가 발생하더라도 카운터는 소비되지 않은 상태로 남습니다.
5. `Job` 인스턴스 반환 (서비스는 리포지토리의 반환 값이 아닌 자체 로컬 `job`을 반환합니다).
식별자 할당은 리포지토리가 아닌 **서비스** 내에서 이루어집니다(`SchedulerService.__init__` 내의 `self._next_identifier = 1`). 이는 중요한 경계점입니다. 이미 작업이 포함된 리포지토리를 주입하면, 새로 생성된 서비스가 번호 매기기를 1부터 다시 시작하기 때문에 기존 작업들이 아무런 경고 없이 덮어쓰이게 됩니다.
**작업 나열** — `SchedulerService.list_jobs()`는 `JobRepository.all()`을 그대로 전달하는 함수이며, 이 함수는 `[self._jobs[key] for key in sorted(self._jobs)]`를 반환합니다. 따라서 정렬 순서는 **정수 식별자 기준 오름차순**이며, 현재 이는 삽입 순서와 일치합니다. 호출할 때마다 새로운 리스트가 생성되지만, `Job` 객체들은 공유 참조입니다. `Job`이 고정(frozen)되어 있기 때문에 안전합니다.
**삭제** — `SchedulerService.delete_job(identifier)`는 `JobRepository.delete`로 위임되는데, 이는 기본값이 없는 `self._jobs.pop(identifier)`와 동일하므로, 따라서 ID가 누락된 경우 `KeyError`를 발생시킵니다. 이는 동일한 조건에서 `None`을 반환하는 `JobRepository.get`과 일관성이 없습니다.
**이 경로들에 대한 테스트 커버리지** — `tests/test_scheduler.py`에는 정확히 두 가지 테스트 케이스가 있습니다: `test_create_and_list_jobs`(`job.identifier == 1` 및 `[job] == service.list_jobs()`를 검증)와 `test_blank_name_is_rejected`입니다. 두 테스트 모두 현재 트리에서는 통과합니다.
### 4. 작업 우선순위 추가로 영향을 받을 가능성이 있는 파일
확실성 순서대로 나열하면 다음과 같습니다:
1. **`scheduler/models.py`** — 확실함. `Job`에 `priority` 필드가 필요합니다. 데이터클래스가 `frozen=True`이고 필드가 위치 기반이므로, 새 필드에는 기본값(예: `priority: int = 0`)을 가져야 하거나, 기존 세 필드 뒤에 배치되어야 합니다. 그렇지 않으면 기존의 모든 위치 매개변수 구성이 깨집니다. `to_dict()`는 수정할 필요가 없습니다. `asdict(self)`가 해당 필드를 자동으로 인식하므로, 이는 코드 변경이 아닌 명시되지 않은 직렬화 계약의 변경에 해당합니다.
2. **`scheduler/service.py`** — 확실합니다. `create_job`에는 `priority` 매개변수가 필요하며, 13행의 `Job(...)` 위치 기반 생성자에 이를 전달해야 합니다. 우선순위가 유효성 검사(범위, 열거형 멤버십)를 거친다면, 해당 조건문은 기존 `name.strip()` 검사 바로 옆에 위치해야 합니다. 목록을 우선순위 순으로 정렬해야 한다면, 저장소를 단순한 저장소로 유지하고 싶을 경우 `list_jobs`에 정렬 로직을 배치해야 합니다.
3. **`scheduler/repository.py`** — 가능성이 높음. `JobRepository.all()`의 `sorted(self._jobs)`는 딕셔너리의 *키*, 즉 식별자를 기준으로 정렬합니다. 우선순위 순서로 목록을 표시하려면 이를 `(-job.priority, job.identifier)`와 같은 키를 기준으로 값을 정렬하도록 변경하거나, 별도의 정렬된 액세서를 추가해야 합니다. 동점 처리 방식을 암묵적으로 남겨두지 마십시오. 딕셔너리의 삽입 순서는 의존할 수 있는 안정적인 계약이 아닙니다.
4. **`tests/test_scheduler.py`** — 확실함. 기본 우선순위, 명시적 우선순위, 정렬, 유효하지 않은 우선순위 거부 등에 대한 새로운 테스트 케이스. 기존의 `assertEqual([job], service.list_jobs())`는 *동일한* 객체를 비교하므로 필드 추가 후에도 정상 작동하지만, 새로 생성된 `Job` 리터럴을 비교하는 경우에는 작동하지 않을 것입니다.
5. **`README.md`** — 우선순위 의미론(범위의 어느 쪽이 우선하는지, 기본값 등)을 어디에든 명시해야 할 경우, 수정될 가능성이 높습니다.
6. **`scheduler/__init__.py`** — `SchedulerService`와 함께 우선순위 열거형이나 상수를 내보내야 하는 경우에만 수정됩니다.
7. **`fixture-manifest.json`** — 새로운 모듈 파일을 추가하는 경우에만 해당됩니다. 이 파일의 `expected_files` 배열은 명시적인 목록이므로 변경될 수 있습니다.
8. **`scheduler/time_rules.py`** — *절대* 수정해서는 안 됩니다. 우선순위는 반복성과 무관하며, 이 모듈은 연결되어 있지 않습니다.
### 5. 주요 위험 요소
- **정렬 규칙은 명시되지 않은 동작 변경입니다.** `JobRepository.all()`은 현재 식별자 오름차순 정렬을 보장하며, `list_jobs`도 이를 상속받습니다. 이 보장에 의존하는 모든 소비자는 재정렬로 인해 오류가 발생합니다. 명확히 결정하십시오: `list_jobs()`의 의미가 변경되는 것인지, 아니면 새로운 `list_jobs_by_priority()`가 함께 추가되는 것인지? 전자가 더 위험한 선택이며, 기존 테스트인 `test_create_and_list_jobs`는 회귀 현상(요소가 하나뿐인 리스트)을 포착하기에는 너무 취약합니다.
- **정렬 방향은 실제로 모호합니다.** "우선순위 1'은 시스템에 따라 관례적으로 *가장 높음*을 의미하기도 하고 *가장 낮음*을 의미하기도 합니다. 이 저장소에는 이를 명확히 하는 내용 — 주석, docstring, README 문구 등 —이 전혀 없습니다. 규칙을 정하고, `models.py`에 문서화한 다음, 정렬 방향이 명확히 고정되도록 최소 세 가지 서로 다른 우선순위를 사용하여 테스트에 반영하십시오.
- **동점 처리 방식이 불안정합니다.** 두 작업의 우선순위가 같더라도 결과는 여전히 결정론적이어야 합니다. 파이썬의 `sorted`는 안정적이지만, 안정성은 입력 순서 자체가 정의되어 있을 때만 유용합니다. 항상 `identifier`를 명시적인 보조 키로 포함시키세요.
- **Frozen-dataclass 필드 순서.** `Job`은 세 개의 위치 기반 필드를 가진 `@dataclass(frozen=True)`이며, `service.py:13`에서 위치 기반으로 생성됩니다. `priority`를 마지막 위치 이외의 곳에 삽입하거나 기본값을 지정하지 않는 것은 호환성을 깨는 변경 사항이며, 기존 두 개의 테스트만으로는 이 문제가 명확하게 드러나지 않을 수 있습니다.
- **`to_dict()` 계약 확장.** `asdict(self)`는 모든 필드를 반영합니다. `priority`를 추가하면 `models.py`의 메서드 본문에 눈에 띄는 수정 없이도 모든 직렬화된 페이로드가 변경됩니다. 정확한 딕셔너리 형식을 확인하는 모든 코드는 작동하지 않게 됩니다.
- **Python 3.9.6 제약 조건.** `@dataclass(slots=True)`(3.10 이상) 및 `kw_only=True`(3.10 이상)를 사용할 수 없으며, PEP 604의 `int | None` 어노테이션은 `from __future__ import annotations`가 없으면 런타임에 오류가 발생합니다. 우선순위를 열거형(enum)으로 모델링할 경우, `enum.StrEnum`은 3.11 이상에서만 지원되므로 사용할 수 없습니다. 이 중 어느 하나라도 이 인터프리터에서 피처(fixture)를 작동하지 않게 만듭니다.
- **식별자 할당이 잘못된 계층에 위치해 있습니다.** `SchedulerService._next_identifier`는 서비스가 ID 생성을 담당하는 반면, 저장소는 리포지토리가 관리함을 의미합니다. 우선순위 관련 작업으로 인해 두 번째 리포지토리 구현이나 사전 로드된 피처가 필요해질 경우, 이러한 분할로 인해 ID 충돌이 발생하고 작업이 덮어쓰일 수 있습니다.
- **비대칭적인 오류 처리 방식.** `JobRepository.get`은 조회에 실패할 경우 `None`을 반환하는 반면, `JobRepository.delete`는 `KeyError`를 발생시킵니다. 우선순위와 관련된 새로운 조회 기능은 우연히 이러한 불일치를 물려받기보다는 의도적으로 하나의 규칙을 선택해야 합니다.
- **유효성 검사 누락의 선례.** `create_job`은 `name`을 유효성 검사하지만 `owner`는 검사하지 않습니다. `priority`에 대해 이러한 느슨한 기준을 그대로 적용해서는 안 됩니다. 유효성 검사가 이루어지지 않은 우선순위는 정렬 키로 전파되어, 호출 지점이 아닌 `sorted`의 깊은 내부에서 `TypeError`를 발생시킬 수 있습니다(예: `int`와 `None`을 비교하는 경우).
- **사망 코드 함정.** `scheduler/time_rules.py`는 스케줄링 로직처럼 보이기 때문에 수정 유혹을 받을 수 있습니다. 이 파일은 어디에서도 임포트되지 않으며, 자체 docstring에서도 버그를 인정하고 있습니다. 즉, UTC 기준으로 경과 시간 24시간을 더하고 "일광 절약 시간제 전환 시 현지 실시간을 조정"합니다. 이 파일을 수정해도 테스트 대상 시스템에 눈에 띄는 영향은 전혀 없으므로, 여기에 쏟는 노력은 낭비이며, 이를 대상으로 작성된 테스트는 출시된 버전의 어떤 부분도 검증하지 못합니다.
- **허술한 안전망.** 테스트는 두 개뿐이며, CI, 린터, 타입 검사도 없습니다. 직접 작성한 코드 외에는 회귀 현상을 잡아낼 수단이 전혀 없습니다. 기존 테스트 모음을 '게이트'가 아닌, 불충분한 기본 커버리지로 간주하십시오.
### 6. 구현 계획 (실행되지 않음)
1. **먼저 의미론을 문서화하여 확정하십시오.** 우선순위 유형(`int` 대 열거형), 유효 범위, 기존/미지정 작업에 대한 기본값, 정렬 방향. 이를 `scheduler/models.py`의 `Job` 클래스에 docstring으로 기록하십시오. 이는 모든 계층이 이미 의존하고 있는 유일한 위치입니다.
2. **모델을 확장합니다.** `scheduler/models.py`의 `Job` 클래스에 `priority: int = 0`을 *마지막* 필드로 추가하되, `service.py:13`과의 위치 호환성을 유지하고 `to_dict()`는 변경하지 않습니다.
3. **서비스 전반에 이를 반영하세요.** `SchedulerService.create_job`에 기본값이 설정된 `priority` 매개변수를 추가하고, 기존 `name.strip()` 검증 조건 옆에 유효성 검사를 추가한 후(기존 오류 유형과 일치하도록 `ValueError`를 발생시킴), 이를 `Job` 생성자에 전달하세요.
4. **목록 제공 방식을 명시적으로 결정합니다.** 권장되는 저위험 옵션: `JobRepository.all()`은 식별자 순서로 정렬된 기본 기능으로 그대로 두고, 별도로 우선순위 순서로 정렬된 액세서리를 추가합니다. 대신 `list_jobs()`의 의미가 변경되어야 한다면, `JobRepository.all()`의 이해식을 수정하여 `identifier`를 동점 처리 기준으로 포함하는 명시적인 복합 키로 값을 정렬하고, `README.md`에 변경 사항을 기록하십시오.
5. **`scheduler/__init__.py`를 동기화**하는 것은 공개 열거형이나 상수가 도입된 경우에만 수행하십시오.
6. **`scheduler/time_rules.py`는 수정하지 마십시오**. 또한, 동일한 변경 사항에서 `fixture-manifest.json`의 `expected_files`가 업데이트되지 않는 한 파일을 추가하지 마십시오.
### 7. 검증 계획
- **먼저 기준 상태를 확인합니다.** 수정하기 전에 `python3 -m unittest discover -s tests -v`를 실행하여 2개의 테스트가 통과되는지 확인하십시오. 저는 이미 이 작업을 수행했으며, 테스트는 문제없이 통과되었습니다.
- **회귀 테스트 게이트.** 기존 테스트 두 개는 수정 없이도 여전히 통과되어야 합니다. 만약 `test_create_and_list_jobs`를 수정해야 한다면, 이는 변경 사항이 호환성을 깨고 있다는 신호일 뿐, 테스트를 수정해야 할 이유는 아닙니다.
- **`tests/test_scheduler.py`의 새로운 테스트 케이스:**
- 기존 두 개의 인자를 사용하는 시그니처로 `create_job`이 호출될 때의 기본 우선순위 (하위 버전 호환성 검증).
- `create_job` → `list_jobs`를 거치는 명시적인 우선순위 왕복 테스트.
- **세 개 이상의** 서로 다른 우선순위를 가진 정렬 시 전체 목록을 검증 — 이것이 정렬 방향을 확정합니다.
- 동점 처리: 우선순위가 동일한 두 작업은 식별자 오름차순으로 반환됩니다.
- 유효하지 않은 우선순위는 `ValueError`를 발생시키며, 이는 이름이 비어 있는 경우와 동일합니다.
- `to_dict()`는 예상된 값을 가진 `priority`를 포함합니다.
- 주입된 리포지토리 경로: `SchedulerService(repository=fake)`는 여전히 우선순위를 올바르게 할당하며, `repository or JobRepository()` 연결 지점을 활용합니다.
- **호환성 확인.** 특히 Python 3.9.6에서 모든 것이 정상적으로 실행되는지 확인합니다. `slots=`, `kw_only=`, PEP 604 연합(unions)의 단순 사용, `StrEnum`은 허용되지 않습니다.
- **인벤토리 확인.** `fixture-manifest.json`을 다시 읽고, 디스크상의 파일 세트가 여전히 `expected_files`와 일치하는지 확인합니다.
- **결정성.** 테스트 스위트를 두세 번 실행합니다. 딕셔너리 반복 순서와 관련된 버그는 간헐적으로 나타날 수 있습니다.
- **정리 상태.** `PYTHONDONTWRITEBYTECODE=1`을 설정하여 실행하면, `__pycache__` 디렉터리가 매니페스트에 비해 추적되지 않은 편차로 나타나지 않습니다.
Fixture의 제한 사항: 이는 소규모의 오프라인 Python 저장소였습니다. Claude는 CLI OAuth가 만료된 후 서브에이전트 대체 방식을 사용했기 때문에, 격리 상태와 토큰 가시성이 동일하지 않았습니다.
이 결과는 대규모 모노레포나 일주일 동안 진행되는 자율 세션에서의 성능을 입증하는 것은 아닙니다. 이번 테스트 환경은 의도적으로 규모를 작게 잡고 통제된 조건에서 진행되었습니다. 실제 평가를 진행하려면 읽기 전용 프롬프트부터 시작하십시오. 각 도구에 호출 경로를 매핑하고, 변경될 파일 이름을 지정하며, 테스트를 식별하고, 해결되지 않은 가정을 나열하도록 요청한 후, 편집을 허용하십시오.
구현 방식, 패치 범위 및 버그 수정
여러 파일을 대상으로 한 작업
서로 다른 설계 선택에 따라 동일한 통과 결과가 나타날 수 있습니다. T2 테스트에서 두 제품 모두 30/30을 기록하며 ‘frozen hidden’ 유효성 검사기를 통과했습니다. Claude Code는 하나 이상의 경계에 유효성 검사를 배치하고, 더 광범위한 직접 모델 및 임계값 테스트를 추가했습니다. Codex는 계약을 충족하는 더 작은 규모의 서비스 중심 구현 방식을 사용했습니다.
독립 개발자에게 있어 이는 진정한 타협의 문제입니다. 검증 범위를 넓히면 여러 경로를 통해 객체가 생성될 때 불변 조건을 보호할 수 있습니다. 반면, 하나의 서비스가 의도된 진입점일 경우 패치 크기를 줄이면 회귀 발생 가능성을 줄이고 검토 시간을 단축할 수 있습니다. 올바른 답은 변경된 줄 수나 테스트를 개별적으로 계산하는 것이 아니라, 리포지토리의 소유권 규칙에 따라 결정됩니다.
T2 · 제어된 저장소 테스트
여러 파일에 걸쳐 우선순위 기능을 구현합니다
동결된 동작을 추가하고, 호환성을 유지하며, 공개 및 숨겨진 검사 항목을 모두 통과합니다.
불변 모델에 우선순위를 부여하고, 서비스 경계에서 유효성을 검증하며, 리포지토리 내 순서를 유지했습니다. 7개의 공개 테스트와 고정된 숨겨진 유효성 검사기 모두 통과했습니다.
리뷰어의 의견: 모든 고정된 행동 양상을 충족시킨, 서비스 중심의 소규모 구현 방식.
서비스 경계와 불변 모델 모두에서 우선순위가 검증되었으며, 리포지토리 필터링 기능이 유지되었고, 임계값 커버리지가 추가되었습니다. 14개의 공개 테스트와 숨겨진 검증기가 모두 통과했습니다.
리뷰어의 의견: 기능 점수 면에서의 이점은 없으면서도, 직접 모델 및 임계값 모델의 적용 범위가 더 넓어졌다.
Codex 출력 결과 전체 보기
완전하게 정제된 첫 번째 유효한 출력
예약 작업 우선순위 기능을 구현했습니다. 변경된 파일: - [scheduler/models.py](./scheduler/models.py:5) — 직렬화된 `priority`를 추가했으며, 기본값은 `0`입니다. - [scheduler/service.py](./scheduler/service.py:11) — 식별자 순서를 유지하면서 유효성 검사, 저장 및 `list_jobs(min_priority=0)` 필터링 기능을 추가했습니다. - [tests/test_scheduler.py](./tests/test_scheduler.py:16) — 기본값, 직렬화, 저장, 경계, 유효하지 않은 값 및 필터링에 대한 커버리지 테스트를 추가했습니다. 실행된 테스트: ```text python3 -m unittest discover -s tests -v 7개의 테스트 실행 — OK ``` **결론:** 동결된 작업이 완료되었으며 검증되었습니다. **결정 사항:** 없음.
Claude 코드 출력 전체 보기
첫 번째 유효한 출력을 그대로 포함하는 완전한 핸드오프 기록
# T2 실행 기록 — 다중 파일 우선순위 기능 ## 실행 매개변수 | 필드 | 값 | | --- | --- | | 작업 | `T2` | | 고정 프롬프트 | `01-prompts/T2.md` | | 고정 프롬프트 SHA-256 | `8476a56034c4e719b97ee4081b32b4c73efd45feafe1bda9d477c83cb8fdb698` | | 실행 단위 | 격리된 Claude 서브에이전트, `general-purpose`, 새로운 컨텍스트 | | 격리 방법 | **서브에이전트 폴백** (문서화된 다운그레이드 — `results/isolation-decision.md` 참조) | | 할당된 깨끗한 사본 | `runtime/workspaces/T2` | | Claude 코드 버전 | `2.1.220` | | 모델 설정 | `claude-opus-5` | | start_utc | `2026-07-28T10:27:52Z` | | end_utc | `2026-07-28T10:29:33Z` | | 소요 시간 | 101초 (T1, T3, T4와 동시 실행; 정확한 지연 시간 측정이 아님) | | 시도 횟수 | 1 | | 상태 | `valid` | | 수동 개입 | 없음 | ## 안전 도구 요약 `date`, 할당된 작업 공간 내에서의 `Read`/`Edit`/`Write`만 허용, `grep`, `python3 -m unittest discover`, `python3 -m compileall`, 인라인 `python3 -c` 스모크 테스트. 네트워크 없음, 설치 없음, 표준 라이브러리만 사용. ## 변경된 파일 `scheduler/models.py`, `scheduler/repository.py`, `scheduler/service.py`, `tests/test_scheduler.py`. 추가되거나 제거된 파일이 없으므로 `fixture-manifest.json`은 정확한 상태를 유지합니다. 전체 패치: `results/T2/patch.diff`. ## 오프라인 검사 결과 태스크 러너에서 보고한 내용: | 검사 | 결과 | | --- | --- | | `python3 -m unittest discover -s tests -v` (기준, 변경 전) | 2개 통과, 0개 실패 | | `python3 -m compileall -q scheduler tests` | 문제 없음 | | 인라인 스모크 테스트 (레거시 3-인자 구문, 키워드/위치 기반 임계값, `to_dict`) | 통과 | | `python3 -m unittest discover -s tests -v` (최종) | **14개 통과, 0개 실패** | 워크스페이스 외부에서 코디네이터가 독립적으로 재검증한 결과: | 검사 | 종료 | 결과 | | --- | --- | --- | | 공개 테스트 모음 (`results/checks/T2-public.txt`) | 0 | 14개 테스트, OK | | 숨겨진 검증기 `03-checks/test_t2_hidden.py` (`results/checks/T2-hidden.txt`) | 0 | 2개 테스트, OK | 숨겨진 검증기는 초기화된 피처 복사본에 대해 실패(종료 코드 1)하며, 이는 통과 결과가 의미 있음을 확인해 줍니다. `results/checks/validator-controls.md`를 참조하십시오. ## 골드 맵 동작 커버리지 `03-checks/gold-map.json`에 명시된 5가지 필수 동작이 모두 충족됩니다: | 필수 동작 | 증거 | | --- | --- | | 우선순위 기본값 0 | `Job.priority: int = MIN_PRIORITY`; `create_job(..., priority=MIN_PRIORITY)`; `test_priority_defaults_to_zero` | | 0부터 9까지의 정수 범위 | `validate_priority`는 정수가 아니거나 범위를 벗어난 값을 거부합니다; `test_out_of_range_priority_is_rejected`, `test_non_integer_priority_is_rejected` | | 직렬화된 우선순위 | `asdict`를 통한 `to_dict()`; `test_priority_appears_in_serialized_output`는 정확한 딕셔너리를 검증합니다 | | 최소 우선순위 필터링 | `list_jobs(min_priority=0)` → `JobRepository.all(min_priority)`; `test_filter_is_inclusive_of_the_threshold` | | 식별자 정렬 순서 | 기존 `sorted(self._jobs)` 이해식 내부에서 필터 적용; `test_filter_preserves_ascending_identifier_order` | ## 오류 정리 없음. 테스트 실행에서 발생한 `__pycache__` 잔여물은 태스크 러너에 의해 제거되었으며, 코디네이터 스윕을 통해 작업 공간이 깨끗한 것으로 확인되었습니다. ## 표시된 출력 (원문 그대로) 로컬 스케줄러 피처의 모델, 리포지토리 및 서비스 계층 전반에 걸쳐 예약된 작업에 정수형 `priority` 필드를 추가하고, 필터링된 목록을 제공했습니다. **`scheduler/models.py`** — 모듈 상수 `MIN_PRIORITY = 0` / `MAX_PRIORITY = 9`와 재사용 가능한 `validate_priority(priority)` 함수를 추가했습니다. 이 함수는 정수가 아니거나 0~9(포함) 범위를 벗어난 값에 대해 `ValueError`를 발생시킵니다. `bool`은 `int`의 서브클래스임에도 명시적으로 거부되므로, `True`가 우선순위 1로 처리되는 것을 방지합니다. 고정된 `Job` 데이터 클래스에는 기본값이 지정된 후행 필드 `priority: int = MIN_PRIORITY`가 추가되어 기존 3개 인자 생성자가 계속 작동하도록 했으며, 유효성 검사기를 호출하는 `__post_init__` 메서드가 추가되어 어떤 경로를 통해서도 유효하지 않은 우선순위가 생성될 수 없도록 했습니다. `to_dict()`는 `asdict(self)`로 유지되었으므로, 우선순위는 직렬화 출력에 필드 순서대로 자동으로 표시됩니다. **`scheduler/repository.py`** — `JobRepository.all()`은 선택적 `min_priority`를 받아 기존 `sorted(self._jobs)` 이해식 내에서 필터링하므로, 필터링 후 다시 정렬할 필요 없이 이미 이를 제공하던 동일한 단일 코드 경로를 통해 식별자 오름차순 정렬이 보장됩니다. 기본 인수는 기존 호출자에 대해 이전의 인자 없음 동작을 유지합니다. 스토리지 자체에는 변경이 필요하지 않았습니다. 리포지토리는 전체 `Job` 인스턴스를 저장하므로, 우선순위는 유지되며 `save`/`get`/`all`을 통해 왕복 전달됩니다. **`scheduler/service.py`** — `create_job`은 선택적 후행 `priority` 인자(기본값 0)를 받아들이며, `Job`을 생성하기 전에 이를 유효성 검사하므로, 기존 빈 이름 검사와 동일한 `ValueError` 계약에 따라 서비스 경계에서 오류가 발생합니다. `list_jobs(min_priority=0)`는 리포지토리에 위임합니다. 정렬과 필터링은 중복되지 않고 한 곳에서 처리됩니다. **`min_priority` 유효성 검사에 대한 설계 참고 사항:** 정수형으로 타입 검사가 이루어지지만, 의도적으로 0–9 범위로 제한하지 않습니다. 0–9 규칙은 작업이 저장할 수 있는 값을 제한합니다. 임계값은 쿼리 매개변수이며, 예를 들어 `min_priority=10`을 거부하면 유효한 "일치하는 항목 없음" 쿼리가 오류로 변환될 수 있습니다. 우선순위가 9인 작업이 없을 때 `list_jobs(min_priority=9)`가 `[]`를 반환하는 경우는 테스트를 통해 검증되었습니다. `scheduler/time_rules.py` 파일은 검토했으나 수정하지 않았습니다. 이 파일에 문서화된 일광 절약 시간제 전환은 기존에 설정된 동작이며, 이번 작업의 범위 밖이고, 이를 변경하는 것은 본 작업과 무관한 동작 변경이 되었을 것입니다. 파일이 추가되거나 제거된 것이 없으므로 `fixture-manifest.json`은 정확한 상태를 유지합니다(프로그래밍 방식으로 검증됨). ### 테스트 커버리지 추가 기본값 0; `JobRepository`를 통한 스토리지 왕복; `to_dict()` 출력의 우선순위; 경계값 0 및 9 허용; 범위 외 값 −1/10/100 거부; 비정수 `"3"`/`3.5`/`None`/`True`는 거부됨; 모델 수준 직접 유효성 검사; 필터링되지 않은 나열 순서; 식별자 오름차순 순서를 유지하는 필터링된 나열; 포괄적 임계값; 빈 결과; 비정수 `min_priority`는 거부됨.
Fixture의 제한 사항: 이는 소규모의 오프라인 Python 저장소였습니다. Claude는 CLI OAuth가 만료된 후 서브에이전트 대체 방식을 사용했기 때문에, 격리 상태와 토큰 가시성이 동일하지 않았습니다.
예외적인 상황에서 발생하는 버그 수정
T3는 일광 절약 시간제 관련 스케줄링 결함을 테스트했습니다. 두 에이전트 모두 30/30을 기록했으며, 봄과 가을에 실시된 동일한 숨겨진 점검을 통과했습니다. Claude 코드는 모호하거나 생략된 현지 시간, 단순 입력, 그리고 며칠에 걸친 롤오버에 대한 명시적인 커버리지를 추가했습니다. Codex는 달력 일자 변경 범위를 더 좁게 조정했으며, 동결된 계약을 통과했습니다.
라이브러리가 광범위하게 재사용되거나 스케줄링 오류로 인한 비용이 클 경우, 더 광범위한 경계 사례 테스트를 수행하면 신뢰도를 높일 수 있습니다. 결함이 명확하게 격리되어 있고 팀이 동작 변화를 최소화하고자 할 때는 국소적인 변경이 바람직합니다. 실무적인 검토 질문은 “누가 더 많이 썼는가?”가 아닙니다. 패치가 명시된 근본 원인을 해결하고, 주변 계약을 유지하며, 위험한 경계를 검증하는지 여부입니다.
T3 · 제어된 저장소 테스트
일광절약시간제(DST) 전환 시 매일의 일정 조정을 수정합니다
봄과 가을의 계절이 바뀌는 시기에도 요청된 뉴욕식 벽시계 시간을 유지하십시오.
근본 원인: 구현 과정에서 UTC 기준 24시간이 추가되었습니다. 수정 사항: 현지 달력 기준으로 하루를 앞당겼습니다. 동결된 봄 및 가을 점검 모두 통과했습니다.
리뷰어의 의견: 더 좁은 범위의 수정안이 동결된 계약안을 그대로 통과시켰다.
봄, 가을, 누락되거나 모호한 현지 시간, 단순 입력, 그리고 며칠에 걸친 롤을 다뤘습니다. 회귀 테스트 범위를 확대한 후, 동결된 숨겨진 검사 두 가지 모두 통과했습니다.
리뷰어의 의견: 예외 사례에 대한 포괄적인 커버리지; 고정된 평가 기준에 따른 동일한 기능 점수.
Codex 출력 결과 전체 보기
완전하게 정제된 첫 번째 유효한 출력
일광 절약 시간제(DST) 수정 사항을 적용했습니다. 변경된 파일: - [scheduler/time_rules.py](./scheduler/time_rules.py) - [tests/test_time_rules.py](./tests/test_time_rules.py) 변경 사항: - UTC 기준 24시간 대신 현지 달력 기준으로 하루를 앞당깁니다. - 뉴욕의 일광 절약 시간제(봄/가을)에 대한 회귀 테스트를 추가했습니다. - 경과한 UTC 간격이 각각 23시간과 25시간인지 확인했습니다. 검증 결과: - 단위 테스트: 4개 통과. - 메모리 내 구문 검사: 7개의 Python 파일이 통과했습니다. - Python이 할당된 작업 공간 외부로 캐시를 리디렉션하기 때문에 바이트코드 컴파일이 차단되었습니다. 외부 파일에 대한 쓰기 작업은 발생하지 않았습니다. **결론:** `next_daily_run`은 이제 일광 절약 시간제(DST) 전환 시에도 요청된 실제 시간을 유지합니다. 별도의 결정이 필요하지 않습니다.
Claude 코드 출력 전체 보기
첫 번째 유효한 출력을 그대로 포함하는 완전한 핸드오프 기록
# T3 실행 기록 — DST 버그 수정
## 실행 매개변수
| 필드 | 값 |
| --- | --- |
| 작업 | `T3` |
| 고정 프롬프트 | `01-prompts/T3.md` |
| 고정 프롬프트 SHA-256 | `3fee50d0230f27f8d6dd7f12e050fa3f0b7f5fb77d9559361fee96e5f1a47307` |
| 실행 단위 | 격리된 Claude 서브에이전트, `general-purpose`, 새로운 컨텍스트 |
| 격리 방법 | **서브에이전트 폴백** (문서화된 다운그레이드 — `results/isolation-decision.md` 참조) |
| 할당된 깨끗한 사본 | `runtime/workspaces/T3` |
| Claude 코드 버전 | `2.1.220` |
| 모델 설정 | `claude-opus-5` |
| start_utc | `2026-07-28T10:28:05Z` |
| end_utc | `2026-07-28T10:30:03Z` |
| 소요 시간 | 118초 (T1, T2, T4와 동시 실행; 정확한 지연 시간 측정이 아님) |
| 시도 횟수 | 1 |
| 상태 | `valid` |
| 수동 개입 | 없음 |
## Safe 도구 요약
`date`, 지정된 작업 공간 내에서의 `읽기`/`편집`만 허용, `python3 -m unittest discover`,
`python3 -m compileall`, 메모리 내 음성 대조군 실행, 매니페스트 무결성 검사.
표준 라이브러리만 사용 (`datetime`, `zoneinfo`, `unittest`). 네트워크 연결 없음, 설치 없음.
## 변경된 파일
`scheduler/time_rules.py` (`next_daily_run`의 본문 및 docstring만 수정),
`tests/test_scheduler.py` (`NextDailyRunTests` 추가, 테스트 8개, `_elapsed` 헬퍼 추가;
기존 테스트는 수정되지 않음). 다른 모듈은 수정되지 않았으며, 파일도 추가되지 않았습니다. 전체 패치:
`results/T3/patch.diff`.
## 오프라인 검사 결과
태스크 실행기가 보고한 내용:
| 검사 | 결과 |
| --- | --- |
| `python3 -m unittest discover -s tests -v` | **10개 통과, 0개 실패** (기존 2개 + 신규 8개) |
| `python3 -m compileall -q scheduler tests` | 정상 |
| `fixture-manifest.json` 대비 매니페스트 무결성 | 누락 0개, 예상치 못한 항목 0개 |
| 네거티브 컨트롤: 메모리 내에서 패치된 시드 구현, `NextDailyRunTests`만 | 8개 실행, **예상대로 5개 실패**, DST 테스트 2개 포함 |
워크스페이스 외부에서 코디네이터가 독립적으로 재검증함:
| 검사 | 종료 | 결과 |
| --- | --- | --- |
| 공개 테스트 모음 (`results/checks/T3-public.txt`) | 0 | 10개 테스트, OK |
| 숨겨진 검증기 `03-checks/test_t3_hidden.py` (`results/checks/T3-hidden.txt`) | 0 | 테스트 2개, OK |
숨겨진 검증기는 초기 상태의 피처 복사본에 대해 실패합니다(종료 코드 1).
`results/checks/validator-controls.md`를 참조하십시오.
## 골드 맵 동작 커버리지
`03-checks/gold-map.json`에 명시된 4가지 필수 동작이 모두 충족되었습니다:
| 필수 동작 | 증거 |
| --- | --- |
| 실제 시계 시간 유지 | 단순 로컬 실제 시계에 증분이 적용되고, 시간대가 재연결됨; 모든 일광 절약 시간(DST) 테스트에서 검증됨 |
| 봄 시간 변경 처리 | `test_spring_forward_keeps_requested_hour` — 09:30 시간 유지, 오프셋 `-04:00`, 경과 시간 23시간 |
| 가을 시간 변경 포함 | `test_fall_back_keeps_requested_hour` — 09:30 시간 유지, 오프셋 `-05:00`, 경과 시간 25시간 |
| IANA 시간대 사용 | 표준 라이브러리의 `ZoneInfo("America/New_York")` |
필수 테스트 세트 외에도, 실행기는 PEP 495의 두 가지 경계 사례 — 봄 시간 변경으로 인해
건너뛴 실제 시간과 가을 시간 변경 중 모호한 실제 시간 — 뿐만 아니라 각 전환 시점을
넘나드는 7일 롤오버 및 단순 입력 처리 동작까지 모두 테스트했습니다.
## 정제된 오류
두 건의 자체 유발 테스트 어설션 실패: 동일한
`tzinfo`를 공유하는 두 날짜/시간에 대해 `following - previous` 연산을 수행하면 순수 월간 시계가 차감되어, 경과 시간 어설션이 1일로 판정되어 실패했습니다.
구현은 올바랐으나 어설션이 잘못되었습니다. 두 피연산자를 먼저 UTC로 변환하는 `_elapsed`
헬퍼를 사용하여 수정했습니다. 툴, 임포트 또는 환경 관련 오류는 없었습니다.
실행 후 `__pycache__` 아티팩트가 제거되었습니다.
## 표시된 출력 (원문 그대로)
**재현 방법**
2024년 일광 절약 시간제(DST) 전환 전후의 양쪽 끝에 `America/New_York` 날짜/시간을 지정하여 `scheduler/time_rules.py::next_daily_run`을 호출했습니다:
```
2024-03-09T09:30:00-05:00 -> 2024-03-10T10:30:00-04:00 # 시간 편차 +1
2024-11-02T09:30:00-04:00 -> 2024-11-03T08:30:00-05:00 # 시간 편차 -1
```
현지 시간 09:30에 요청된 작업이 일광 절약 시간제 시작 후 10:30에, 일광 절약 시간제 종료 후 08:30에 실행되었습니다.
**근본 원인**
시드된 구현에서는 "daily"를 고정된 절대 기간으로 처리했습니다:
```python
elapsed = previous_run.astimezone(timezone.utc) + timedelta(hours=24)
return elapsed.astimezone(previous_run.tzinfo)
```
먼저 UTC로 변환하면 `timedelta(hours=24)`는 정확히 24시간의 경과 시간을 나타냅니다. 그러나 IANA 시간대에서의 현지 달력 상 하루는 일광 절약 시간제 시작일(spring-forward)에는 23시간, 종료일(fall-back)에는 25시간이므로, 일정한 24시간 오프셋을 적용하면 요청된 실제 시각에서 필연적으로 1시간 차이가 발생합니다.
**수정 방법** (`scheduler/time_rules.py`)
일일 반복은 달력 규칙이므로, 이제 증분 값을 순수한 현지 실제 시간에 적용한 후, 그 뒤에 시간대를 다시 연결합니다:
```python
tzinfo = previous_run.tzinfo
naive_next = previous_run.replace(tzinfo=None) + timedelta(days=1)
if tzinfo is None:
return naive_next
candidate = naive_next.replace(tzinfo=tzinfo, fold=0)
return candidate.astimezone(timezone.utc).astimezone(tzinfo)
```
이 방법이 올바른 이유:
- 단순 값에 대한 실제 시계 연산은 오프셋과 무관하므로, 요청된 시:분은 구조상 그대로 유지됩니다; `zoneinfo`는 새로운 날짜에 적용되는 UTC 오프셋을 제공합니다(검증 결과: 일광 절약 시간제 시작 후 `-04:00`, 종료 후 `-05:00`, 각각 실제 경과 시간 23시간 및 25시간).
- `fold=0`에 UTC 왕복 처리를 더하면, 순수한 실제 시간 연산으로는 정의되지 않는 두 가지 경계 사례를 처리할 수 있습니다. PEP 495에 따르면, *건너뛴* 실제 시간 (2024-03-10 02:30)은 `fold=0`일 때 전환 전 오프셋을 가지므로, 왕복 처리를 통해 특정 시점을 명시하지 않는 datetime을 반환하는 대신 실제 시점인 03:30 EDT로 정규화됩니다. *모호한* 실제 시간(2024-11-03 01:30)은 임의적으로 처리되는 대신, 첫 번째 발생 시점(EDT)으로 결정론적으로 해결됩니다.
- 단순한 입력은 기존 의미(단순히 +1 캘린더 일)를 유지합니다. 호출자에게 새로운 `tzinfo` 요구 사항이 부과되지 않습니다.
변경 범위는 좁게 유지되었습니다. `next_daily_run`의 본문/docstring만 변경되었습니다. `service.py`, `models.py`, `repository.py` 및 `__init__.py`는 변경되지 않았으며, 새로운 파일도 추가되지 않았고, 피처 매니페스트는 여전히 정확히 일치합니다(누락되거나 예상치 못한 파일이 없음). 표준 라이브러리만 사용되었습니다(`datetime`, `zoneinfo`, `unittest`).
**회귀 테스트** (`tests/test_scheduler.py`, 새로운 `NextDailyRunTests`, 8개 테스트)는 다음을 다룹니다: 평상시 안정성, 일광 절약 시간제 시작(시간 + 오프셋 + 23시간 경과), 일광 절약 시간제 종료(시간 + 오프셋 + 25시간 경과), 각 전환 시점을 아우르는 7일 롤, 건너뛴 실제 시간, 모호한 실제 시간, 그리고 단순 입력.
기록해 둘 만한 두 가지 사항이 있습니다. 첫째, 초기 경과 시간 어설션에서는 `following - previous`를 사용했습니다. 파이썬은 공유된 `tzinfo`를 무시하고 순수 벽시계를 뺀 값을 계산하므로, 두 경우 모두 1일을 반환하여 테스트가 실패했습니다. 구현은 올바랐고 어설션이 잘못된 것이었습니다. 두 피연산자를 모두 UTC로 변환하는 `_elapsed` 헬퍼를 사용하여 수정했습니다. 둘째, 시드된 구현체의 메모리 내 복사본을 대상으로 `NextDailyRunTests`를 재실행하여 테스트가 실제로 원래 결함을 포착하는지 확인했습니다. 8개 중 5개가 실패했으며, 여기에는 두 가지 일광 절약 시간(DST) 테스트도 포함되었습니다. 버그가 있는 버전에서 통과한 세 가지 사례(평일, 건너뜀, 모호한 경우)는 회귀 결함을 포착하기보다는 동작을 문서화하는 것에 가깝습니다. 건너뜀/모호한 사례가 우연히 일치하는 이유는 +24시간의 절대적 시프트가 우연히 동일한 정규화된 순간에 해당하기 때문입니다.
Fixture의 제한 사항: 이는 소규모의 오프라인 Python 저장소였습니다. Claude는 CLI OAuth가 만료된 후 서브에이전트 대체 방식을 사용했기 때문에, 격리 상태와 토큰 가시성이 동일하지 않았습니다.
코드 검토 품질 및 수동 검증
코드 검토 작업은 기능 구현과는 다른 기술을 요구합니다. 유능한 검토자는 재현 가능한 문제를 찾아내고, 그 영향도를 평가하며, 정확한 코드 경로를 제시하고, 실제 결함과 추측에 기반한 경고를 구분해야 합니다. 문제를 수정할 때는 또 다른 테스트가 필요합니다. 패치로 인해 새로운 회귀 현상이 발생해서는 안 됩니다.
Claude Code는 T4에서 가장 뚜렷한 우위를 보였습니다. 이 팀은 미리 설정된 검토 대상 두 가지를 포함해 독립적으로 재현 가능한 5가지 발견 사항을 보고했으며, 20점 만점에 19점을 획득했습니다. Codex는 유효한 고위험 결함 두 가지를 보고하고 수정했으나, 미리 설정된 두 가지 결함에 대해서는 언급하지 않아 20점 만점에 18점을 획득했습니다. Codex의 발견 사항은 오탐이 아니었으며, 관찰된 차이는 기본적인 정확성보다는 검토 범위의 폭에 기인한 것이었습니다.
T4 · 제어된 저장소 테스트
재현 가능한 결함을 찾아내고, 신뢰도가 가장 높은 문제를 수정하십시오
테스트 케이스를 검토하고, 실제 결함을 재현하며, 허용된 수정 사항을 적용한 후, 회귀 테스트를 통해 해당 동작이 제대로 반영되었음을 입증하십시오.
1. 높음 — 기존 작업이 감지되지 않은 채 덮어쓰일 수 있습니다. 2. 중간 — 일일 실행 일정이 일광 절약 시간제 전환 시기에 따라 어긋났습니다. 검증 결과: 테스트 4개 통과, 실패 0개.
리뷰어의 의견: 중요도가 높은 유용한 문제점들이 발견되었고 집중적인 수정 작업이 이루어졌으나, 두 가지 우선 검토 대상은 놓쳤습니다.
D1 DST 드리프트 · 높음 D2 단순 시간대 획득 · 중간 D3 식별자 충돌 · 높음 D4 삭제 누락 시 KeyError 발생 · 중간 D5 소유자 유효성 검사 미실시 · 낮음
리뷰어의 의견: 재현된 오탐이 전혀 없는, 더 광범위한 검토 범위; 계약에 따른 두 가지 발견 사항은 수정되지 않았습니다.
Codex 출력 결과 전체 보기
완전하게 정제된 첫 번째 유효한 출력
## 조치 필요 사항 1. **높음 — 기존 작업이 사용자 모르게 덮어쓰일 수 있음** - 근거: [service.py](./scheduler/service.py:8)의 식별자 초기화와 [repository.py](./scheduler/repository.py:9)의 사전 대체가 결합된 경우. - 영향: 기존 리포지토리가 있는 상태에서 서비스를 생성하면 식별자 `1`이 재사용되어 저장된 작업이 대체되고 데이터 손실이 발생할 수 있습니다. - 최소 재현 방법: `Job(1, ...)`을 저장하고, `SchedulerService(repository)`를 생성한 다음, 다른 작업을 생성합니다. 수정 전에는 새로운 작업만 남아 있었습니다. - 수정: 리포지토리에 존재하는 가장 높은 식별자부터 다음 식별자를 초기화합니다. - 회귀 테스트: [test_scheduler.py](./tests/test_scheduler.py:22). 2. **중간 — 일일 실행 일정이 일광 절약 시간제 전환 시점에 어긋남** - 증거: [time_rules.py](./scheduler/time_rules.py:4)에서 계산 방식 수정. - 영향: 09:00에 예약된 일일 작업이 봄 일광 절약 시간제 전환 후 10:00에 실행되었습니다. - 최소 재현 조건: `2026-03-07 09:00 America/New_York` 이후의 다음 실행 시간을 계산해 보세요. 수정 전 결과는 `2026-03-08 10:00`이었습니다. - 수정 사항: 경과한 UTC 시간 24시간 대신 현지 달력 상의 하루를 추가했습니다. - 회귀 테스트: [test_scheduler.py](./tests/test_scheduler.py:33). ## 변경된 파일 - [scheduler/service.py](./scheduler/service.py) - [scheduler/time_rules.py](./scheduler/time_rules.py) - [tests/test_scheduler.py](./tests/test_scheduler.py) ## 검증 - 수정 전 두 회귀 테스트 모두 실패한 것으로 확인되었습니다. - 각 테스트는 해당 수정 후 통과했습니다. - `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -v` - 결과: **4개 테스트 통과, 0개 실패**. - 생성된 Python 캐시 아티팩트는 남아 있지 않습니다. ## 결론 및 결정 - **결론:** 확인된 두 결함 모두 수정되었으며, 집중적인 회귀 테스트를 통해 검증되었습니다. - **필요한 결정:** 없음.
Claude 코드 출력 전체 보기
첫 번째 유효한 출력을 그대로 포함하는 완전한 핸드오프 기록
# T4 실행 기록 — 테스트 및 코드 검토
## 실행 매개변수
| 필드 | 값 |
| --- | --- |
| 작업 | `T4` |
| 고정 프롬프트 | `01-prompts/T4.md` |
| 고정 프롬프트 SHA-256 | `5e69546007ea776f40b3d334ddb75671ff684c151c77551bad27de3b0fdce640` |
| 실행 단위 | 격리된 Claude 서브에이전트, `일반 목적`, 새로운 컨텍스트 |
| 격리 방법 | **서브에이전트 폴백** (문서화된 다운그레이드 — `results/isolation-decision.md` 참조) |
| 할당된 깨끗한 사본 | `runtime/workspaces/T4` |
| Claude 코드 버전 | `2.1.220` |
| 모델 설정 | `claude-opus-5` |
| start_utc | `2026-07-28T10:28:22Z` |
| end_utc | `2026-07-28T10:32:17Z` |
| 소요 시간 | 235초 (T1–T3와 동시 실행; 정확한 지연 시간 측정값 아님) |
| 시도 횟수 | 1 |
| 상태 | `유효` |
| 수동 개입 | 없음 |
동결된 프롬프트에 포함된 조건문 — "동결된 실행 구성이 수정을 허용하는 경우
수정하라" — 는 코디네이터가 `00-control/run-config.json` 및
`00-control/safety-policy.json`에서 코디네이터에 의해 해결되었으며, 이 설정들은 격리된 피처 사본 작성을 허용합니다. 러너에게는
수정 작업이 허용된다는 지시가 전달되었습니다. 러너에게는 어떠한 제어 파일도 표시되지 않았습니다.
## 안전한 도구 요약
`date`, 할당된 작업 공간 내에서의 `Read`/`Edit`/`Write`만 허용, `grep`,
`python3 -m unittest discover`, `python3 -m compileall`, 스크래치 사본을 사용한 빈 실행,
매니페스트 존재 여부 확인. 네트워크 없음, 설치 없음, 표준 라이브러리만 사용.
## 변경된 파일
`scheduler/time_rules.py` (수정됨), `scheduler/service.py` (수정됨),
`tests/test_scheduler.py` (수정됨, 테스트 2개 추가), `tests/test_time_rules.py` (추가됨, 테스트 5개).
전체 패치: `results/T4/patch.diff`.
## 오프라인 검사 결과
태스크 실행기가 보고한 내용:
| 검사 | 결과 |
| --- | --- |
| `python3 -m unittest discover -s tests -v` | **9개 통과, 0개 실패, 0개 건너뜀** (기준 2) |
| `python3 -m compileall -q scheduler tests` | 통과 |
| `expected_files` 대비 매니페스트 존재 여부 확인 | 8개 모두 존재 |
| 복원된 원래 구현에 대한 vacuity 실행 | 5개 실패, 4개 통과, 예상대로 |
워크스페이스 외부에서 코디네이터가 독립적으로 재확인한 결과:
| 확인 항목 | 종료 상태 | 결과 |
| --- | --- | --- |
| 공개 테스트 모음 (`results/checks/T4-public.txt`) | 0 | 테스트 9개, 정상 |
점수 산정 대상이 아닌 참고용 교차 확인: T3 숨겨진 검증기도 이
워크스페이스에서 통과합니다(종료 코드 0). 이는 T4가 동일한 `next_daily_run` 결함을 독립적으로 수정했기 때문입니다.
`results/checks/validator-controls.md`를 참조하십시오.
## 골드맵 결함 커버리지
`03-checks/gold-map.json`은 T4 점수 산정을 위해 두 개의 결함을 시드합니다. 두 결함 모두 발견되었습니다:
| 시드된 결함 | 발견됨 | 보고됨 |
| --- | --- | --- |
| 소유자 미지정(blank owner) 허용 | 예 | **D5**, `scheduler/service.py:11,13`, 심각도 낮음(Low), 보고됨 및 의도적으로 수정되지 않음 |
| 누락된 식별자 삭제 시 `KeyError` 발생 | 예 | **D4**, `scheduler/repository.py:19` → `service.py:22`, 심각도 Medium, 보고되었으나 의도적으로 수정되지 않음 |
설정된 결함 세트 외에도 세 건의 추가 결함이 보고되었습니다. 오탐은 없습니다:
- **D1** — `next_daily_run`의 일광 절약 시간(DST) 편차. 이는
`03-checks/seeded-defects.md`에 나열된 세 번째 결함입니다(T4가 아닌 T3로 평가되었으나, 실제 시드된 버그입니다).
- **D2** — `next_daily_run`에 전달된 단순 입력값이 호스트의 시간대를 자동으로 반영하여
시간대를 고려한 datetime 값을 반환합니다. 실제 문제이며 호스트에 따라 달라집니다. 코디네이터가 피처 소스 코드를 대조하여 확인했습니다.
- **D3** — 서비스와 주입되거나 공유된 리포지토리 간의 식별자 충돌로 인해
알 수 없는 덮어쓰기가 발생합니다. 실제: `SchedulerService._next_identifier`는 항상 1부터 시작하지만
`JobRepository.save`는 보호되지 않은 딕셔너리 할당입니다. T1은 원본 피처에서 동일한
취약점을 독립적으로 식별했습니다.
오탐지 수: **0**. 러너는 또한 피처에 네트워크, I/O, 역직렬화, 하위 프로세스 또는 자격 증명 노출이
없음을 지적하며 보안 발견 사항이 없음을 올바르게 보고했습니다.
## 기록할 가치가 있는 편차
고정된 프롬프트는 "신뢰도가 가장 높은 두 가지 결함"에 대한 테스트와 수정 사항을 요청했습니다.
러너는 골드 맵에 미리 설정된 두 결함인 D4와 D5 대신 D1/D2(하나의 수정, 동일한 함수)와 D3를 선택했습니다. 그가 밝힌 이유는 타당합니다. D4와 D5는 모두 명시되지 않은 API
계약에 의존하므로, 이를 수정하는 것은 추측에 불과할 것입니다. 탐지 크레딧에는 영향을 미치지 않습니다. 두 시드 결함 모두
파일, 줄 번호, 심각도, 영향도 및 재현 정보를 포함하여 발견되었습니다. 적용된 수정 사항은 실제
결함에 대한 것이며, 공백 검사를 통해 그 타당성이 입증되었습니다.
## 정제된 오류
`tzinfo`를 공유하는 날짜/시간에 대해 실제 시간(wall-clock)과 절대 시간(absolute-time)을 뺀 결과 발생한 두 건의 자체 유발 테스트 실패가 있었습니다.
이를 수정하고 재검증했습니다. 도구 또는 환경 오류는 없었습니다. 실행 후 `__pycache__`
잔여물이 제거되었습니다.
## 표시된 출력 (원문 그대로)
### 결함 보고서
**D1 — `scheduler/time_rules.py:10-11` — 일일 스케줄이 일광 절약 시간제(DST) 적용 시 1시간씩 어긋남 — 심각도: 높음**
`next_daily_run`은 달력 날짜를 앞당기는 대신 UTC 왕복 시간을 통해 24시간의 *경과* 시간을 추가합니다. 일일 작업은 실제 시계 시간으로 정의되므로, 일광 절약 시간제를 적용하는 시간대에서는 전환일 이후부터 모든 작업이 1시간 일찍 또는 늦게 무음으로 실행되며, 이 오류는 지속됩니다(각 실행 시 이동된 시간을 기준으로 재설정됨). 문서 문자열 자체에서도 이러한 동작을 인정하고 있습니다.
```
prev = datetime(2024, 3, 9, 9, 0, tzinfo=ZoneInfo("America/New_York"))
next_daily_run(prev) # -> 2024-03-10 10:00:00-04:00, 예상값 09:00-04:00
prev = datetime(2024, 11, 2, 9, 0, tzinfo=ZoneInfo("America/New_York"))
next_daily_run(prev) # -> 2024-11-03 08:00:00-05:00, 예상 09:00-05:00
```
**D2 — `scheduler/time_rules.py:10-11` — 단순 입력값은 시스템의 로컬 시간대를 자동으로 적용합니다 — 심각도: 중간**
동일한 두 줄입니다. `naive` 형식의 datetime에 `.astimezone(timezone.utc)`를 적용하면 시스템 로컬 시간을 가정하며, `.astimezone(None)`은 `aware` 형식의 datetime을 반환합니다. 나입(naive) 값을 입력으로 받으면 타임존을 인식하는 값을 반환하므로, 결과는 호출자의 다른 나입 값들과 비교할 수 없으며(비교 시 `TypeError` 발생), 결과는 호스트의 `TZ`에 따라 달라집니다.
```
next_daily_run(datetime(2024, 1, 1, 9, 0))
# -> datetime(2024, 1, 2, 9, 0, tzinfo=timezone(timedelta(hours=8), 'CST')) # 호스트에 따라 다름
```
**D3 — `scheduler/service.py:8,13,15` (pre-fix) — 식별자 충돌 시 저장된 작업이 무통보로 삭제됨 — 심각도: 높음**
ID 카운터는 `SchedulerService`별로 관리되었으며, 주입된 리포지토리의 내용을 무시하고 항상 1부터 시작했습니다. 공유 리포지토리를 사용하는 두 번째 서비스나 미리 채워진 리포지토리를 사용하는 서비스는 ID 1을 다시 할당했습니다. `JobRepository.save`는 딕셔너리 할당 연산이므로, 기존 작업이 오류 없이 덮어쓰여졌습니다. 데이터 손실.
```
repo = JobRepository()
SchedulerService(repo).create_job("야간 백업", "Alex") # ID 1
SchedulerService(repo).create_job("Payroll export", "Blake") # 다시 id 1
repo.all() # -> [Job(1, 'Payroll export', 'Blake')] — Alex의 작업이 사라졌습니다
```
**D4 — `scheduler/repository.py:19` → `scheduler/service.py:22` — `delete_job`이 알 수 없는 ID에 대해 `KeyError`를 발생시킵니다 — 심각도: 중간**
`delete`는 기본값 없이 `dict.pop`을 사용하는 반면, 같은 그룹의 `get`(13행)은 해당 항목이 없을 때 `None`을 반환합니다. 이러한 불일치로 인해 `SchedulerService.delete_job`을 통해 원시 `KeyError`가 누출되는데, 호출 측에서 이를 포착하기는 어려울 것입니다. 재현 방법: `SchedulerService().delete_job(999)` → `KeyError: 999`. 수정 방안은 `pop(identifier, None)` 또는 명시적인 도메인 예외를 던지는 것입니다. 올바른 계약(무작위 무작위 작업 vs. 유형 지정 오류)은 소유자의 API 결정 사항이므로 의도적으로 수정하지 않았습니다.
**D5 — `scheduler/service.py:11,13` — owner 필드 유효성 검사 누락 — 심각도: 낮음**
`name`은 공백 여부를 검사하지만 `owner`는 검사하지 않습니다: `create_job("ok", " ")`는 `owner=''`를 저장합니다. 두 매개변수 모두 보호 조치 없이 `.strip()`을 호출하므로, `None`이 `AttributeError: 'NoneType' object has no attribute 'strip'` 오류로 노출되며, 이는 API가 잘못된 입력에 대해 일반적으로 사용하는 `ValueError`와는 다릅니다. 수정하지 않음 — 의도된 소유자 계약이 피처 어디에도 명시되어 있지 않습니다.
**보안:** 발견된 사항 없음. 이 피처에는 네트워크, I/O, 역직렬화, 서브프로세스 또는 자격 증명 노출 지점이 없으며, 저장소는 프로세스 내 딕셔너리입니다.
**테스트 커버리지 격차:** 이번 실행 전까지 `scheduler/time_rules.py`와 `scheduler/repository.py`의 테스트 커버리지는 0%였습니다. 시드된 두 테스트는 서비스의 정상 경로만 검증했습니다.
### 테스트 및 수정 사항 적용
신뢰도가 가장 높은 두 가지 결함은 **D1/D2**(동일한 함수, 하나의 수정)와 **D3**이었습니다.
**수정 사항 1 — `scheduler/time_rules.py`:** UTC 왕복 연산을 `previous_run + timedelta(days=1)`로 대체했습니다. Python은 인식 가능한 datetime에 대해 실제 시간 연산을 수행하며, `zoneinfo`는 새로운 실제 시간을 기반으로 UTC 오프셋을 지연적으로 재해결합니다. 따라서 09:00은 그대로 09:00으로 유지되는 반면, 오프셋은 `-05:00 → -04:00`으로 올바르게 변경됩니다. 이를 통해 D1과 D2가 함께 수정되었습니다: 단순 입력값은 이제 그대로 유지되며, 현지 시간대는 절대 추론되지 않습니다. 도달 불가능한 경우와 모호한 경우 간의 전환 시간대 처리에 대해서는 tzinfo의 접합 규칙을 따르도록 문서화되어 있습니다.
**수정 사항 2 — `scheduler/service.py`:** 인스턴스별 `_next_identifier` 카운터를 제거했습니다. 이제 식별자는 생성 시점에 리포지토리 상태에서 `max(기존 ID, 기본값=0) + 1`로 할당됩니다. 이는 공유 리포지토리와 미리 채워진 리포지토리 모두에 대해 올바른 방식입니다. 장단점: 생성 시마다 O(1) 대신 O(n)이 소요되지만, 딕셔너리 기반의 메모리 내 저장소에는 허용 가능한 수준이며, 기록 대상 저장소를 인식할 수 없는 카운터보다 정확성이 보장됩니다.
**테스트 — `tests/test_time_rules.py` (신규, 5개 테스트):** 봄 시간 변경 및 가을 시간 변경 시 실제 시간 보존, 해당 전환 기간 동안 23시간/25시간의 절대 경과 시간, UTC 오프셋 재설정, ‘naive-stays-naive’ 규칙, 그리고 단순한 UTC 날짜 전진. IANA 데이터베이스가 없으면 깔끔하게 건너뜁니다.
**테스트 — `tests/test_scheduler.py` (확장, 테스트 2개 추가):** 하나의 저장소를 공유하는 두 서비스는 서로 다른 ID를 발급하고 두 작업 모두를 유지해야 합니다. ID 1과 7이 미리 채워진 저장소를 사용하는 서비스는 ID 8을 발급하고 기존 작업을 그대로 유지해야 합니다.
**결함 확인:** 임시 복사본에 원래 구현을 모두 복원하고 테스트 모음을 다시 실행했습니다. 새로운 테스트 5개 모두 실패했으며(`FAILED (failures=5)`), 수정된 코드에서는 모두 통과했습니다. 테스트가 결함을 확실히 포착하고 있습니다.
실행 중 한 가지 수정 사항: 초안에서는 경과한 DST 시간을 `result - previous`로 확인했는데, 두 피연산자가 동일한 tzinfo를 공유할 경우 Python은 이를 실제 시간 연산으로 평가하여 `24h`로 해석했고, 이로 인해 테스트가 실패했습니다. 이제 확인 조건에서 빼기 연산을 수행하기 전에 UTC로 변환하도록 수정했습니다. 실패 원인은 수정 사항이 아니라 제 테스트에 있었습니다.
### 담당자 참고 사항
`fixture-manifest.json`은 변경되지 않았으므로, `tests/test_time_rules.py`는 `expected_files`에 나열되지 않은 정당한 새 파일입니다. 특정 파일 세트를 정확히 준수해야 하는 검사가 있다면 매니페스트를 업데이트하십시오. 또한 D4/D5는 보고되었으나 의도적으로 수정하지 않았습니다. 두 문제 모두 피처 어디에도 명시되지 않은 API 계약 결정(삭제 시 누락 세미언틱, 소유자 유효성 검사 규칙)에 달려 있으므로, 그중 하나를 선택하는 것은 수정이라기보다는 추측에 불과했을 것입니다.
Fixture의 제한 사항: 이는 소규모의 오프라인 Python 저장소였습니다. Claude는 CLI OAuth가 만료된 후 서브에이전트 대체 방식을 사용했기 때문에, 격리 상태와 토큰 가시성이 동일하지 않았습니다.
어느 점수라도 사람의 검토를 대체할 수는 없습니다. 에이전트 중 하나가 수리를 완료한 후에는 변경된 인터페이스, 예상치 못한 파일 범위, 누락된 부정 테스트, 권한 또는 명령어 이력, 롤백 경로를 점검해야 합니다. 확신에 찬 설명은 재현 가능한 테스트를 대신할 수 없습니다.
권한, 샌드박싱 및 운영 안전성
코딩 에이전트는 비공개 코드를 읽거나, 셸 명령을 실행하거나, 여러 파일을 수정하거나, 외부 도구를 호출할 수 있습니다. 따라서 권한 설계는 제품 품질의 중요한 요소입니다. 여기서 고려해야 할 사항은 어떤 작업에 승인이 필요한지, 에이전트가 기본적으로 어떤 항목에 접근할 수 있는지, 위험한 작업이 얼마나 명확하게 미리 표시되는지, 그리고 개발자가 그 결과로 발생한 변경 사항을 확인할 수 있는지 여부입니다.
승인 요청 횟수가 적다고 해서 무조건 더 낫다고 생각해서는 안 됩니다. 인증 정보나 프로덕션 연결이 없는 독립된 환경에서는 마찰을 최소화하는 것이 유용합니다. 하지만 배포 스크립트, 실제 고객 데이터, 또는 광범위한 클라우드 권한과 연결된 저장소에서는 동일한 방식이 위험할 수 있습니다. 반대로, 승인 절차가 지나치게 많으면 안전한 자동화가 비실용적으로 변할 뿐만 아니라, 사용자가 요청 내용을 읽지 않고 무턱대고 승인하도록 유도할 수 있습니다.
이번 테스트에서는 실제 운영 시스템이나 배포 과정을 거치지 않았으며, 유효성 검증을 위한 사람의 개입도 없이 새로 생성된 로컬 사본만을 사용했습니다. 따라서 이 테스트는 두 제품의 상대적인 보안성을 평가한 것이 아니라, 안전한 조건 하에서 작업 완료 여부를 평가한 것입니다. 중요한 업무에 두 도구 중 하나를 사용하기 전에, 먼저 읽기 전용 권한으로 시작하고, 허용되는 디렉터리와 명령어를 정의하며, 변경 내역을 검토하고, 복구 가능한 환경에서 객관적인 검증을 수행하십시오.
- 읽기 전용 아키텍처로 시작하거나, 그렇지 않으면 위험을 감수해야 합니다.
- 범위와 결과를 확실히 이해한 명령만 승인하십시오.
- 인증 정보, 프로덕션 데이터 및 배포 액세스 권한은 평가판 외부에 보관하십시오.
- 결과를 승인하기 전에 diff, 테스트 결과 및 명확한 롤백 경로를 제출해야 합니다.
MCP, 기술, 프로젝트 지침 및 사용자 정의
두 생태계 모두 확장할 수 있지만, ‘확장’이라는 용어를 동의어로 취급해서는 안 됩니다. 프로젝트 지침은 에이전트에게 리포지토리 내에서 어떻게 행동해야 하는지 알려줍니다. 재사용 가능한 스킬(Reusable Skills)은 반복 가능한 워크플로우나 전문 지식을 패키지화한 것입니다. MCP는 호스트를 외부 도구나 데이터에 연결합니다. 후크(Hooks)와 명령어(commands)는 개발 루프의 특정 단계를 자동화할 수 있습니다. 한 계층에서 뛰어난 성능을 보이는 제품이 다른 계층의 기능을 일대일로 모두 갖추고 있지 않을 수도 있습니다.
구매 시 고려해야 할 핵심은 통합 로고가 있는지 여부가 아닙니다. 실제로 사용하는 호스트 환경에서 해당 연결을 설치하고, 인증하고, 승인받으며, 실행할 수 있는지 여부입니다. 또한 오류 발생 시 그 원인을 파악하기 쉬운 방식이어야 합니다. 대화형 모드에서는 작동하지만 무인 세션에서는 승인을 기다리는 MCP 서버도 여전히 유용하지만, 이를 ‘마찰 없는 자동화’라고 묘사해서는 안 됩니다.
재사용 가능한 지침에도 비슷한 주의사항이 있습니다. 지침 문서가 길다고 해서 반드시 준수된다는 보장은 없으며, 지나치게 복잡한 규칙 세트는 맥락을 흐리거나 모순을 야기할 수 있습니다. 저장소 지침은 간결하고, 테스트 가능하며, 코드와 밀접하게 연계되도록 작성해야 합니다. 필수 검증 명령어, 보호 대상 영역, 스타일 규칙, 그리고 에이전트가 작업을 중단하고 확인을 요청해야 하는 시점을 명시하십시오.
- 프로젝트 지침: 저장소별 규칙 및 검증 명령어.
- 기술: 재사용 가능한 절차 또는 전문 지식 패키지.
- MCP: 외부 도구 및 데이터와의 연동.
- 후크와 명령어: 정의된 워크플로 이벤트를 중심으로 한 자동화.
Codex 대 Claude 코드의 가격 및 사용 제한
클린 소비자 요금제 비교는 월 $20부터 시작됩니다. 관련 $20 ChatGPT 요금제를 통해 Codex 이용 권한이 포함되며, Claude Pro는 미국에서 월 $20이며 Claude Code가 포함됩니다. 두 요금제 모두 $100 및 $200의 대용량 소비자 요금제를 제공합니다. 정가가 비슷하다고 해서 용량이 동일한 것은 아닙니다.
Claude Max 5x의 월 이용료는 $100이며, Max 20x의 월 이용료는 $200입니다. “5x” 및 “20x”라는 명칭은 보장된 코딩 작업 수를 의미하기보다는 Pro 요금제와 비교한 세션당 사용량을 나타냅니다. Claude와 Claude Code는 세션 및 주간 한도를 공유합니다. 컨텍스트 길이, 첨부 파일, 모델 선택 및 기능 사용 여부에 따라 할당량이 소진되는 속도가 달라질 수 있습니다.

Claude의 선택적 사용 크레딧은 활성화 시 포함된 사용량 이후에도 적격 작업을 계속할 수 있게 해주며, 해당 크레딧은 표준 API 요율에 따라 별도로 청구됩니다. API 키 인증 역시 별도의 청구 방식입니다. 두 방식 중 어느 하나를 “무제한”이라고 부른다면 실제 한계 비용을 간과하게 될 것입니다.

Codex 역시 포함된 소비자 요금제 사용량, 사용 가능한 구매 크레딧, API 청구액을 별도로 구분합니다. 로컬 메시지와 클라우드 채팅은 5시간의 사용 한도 범위를 공유하며, 주간 한도가 적용될 수도 있습니다. CLI 로그에 표시된 토큰 필드는 5시간 기준 백분율, 구독 크레딧 금액 또는 API 청구액으로 직접 변환할 수 없습니다.
가끔씩 혼자 코딩을 할 때는 양쪽 모두에서 $20 티어가 합리적인 시작점입니다. 긴 컨텍스트가 포함된 일상적인 리포지토리 작업의 경우 더 높은 사용량 티어를 선택하는 것이 타당할 수 있지만, 이는 실제 리셋 횟수와 작업 소비량을 관찰한 후에야 결정해야 합니다. 고강도 병렬 작업의 경우 더욱 세심한 주의가 필요합니다. 더 큰 티어를 선택한다고 해서 컨텍스트를 관리하고, 작업을 분할하며, 판단력이 많이 필요한 작업에 비용이 많이 드는 추론 자원을 할당해야 할 필요성이 사라지는 것은 아닙니다.
‘Codex 대 Claude 코드’ 비교 테스트 결과
두 에이전트가 실행되기 전에, 네 가지 영어 프롬프트, 공개 파이썬 픽스처, 객관식 문제, 채점 기준표, 그리고 ‘첫 번째 유효 결과’ 규칙을 고정해 두었습니다. 과제는 낯선 저장소 이해, 다중 파일 기능, DST 버그 수정, 수정 사항을 포함한 코드 검토로 구성되었습니다. 유효한 결과에는 사람의 개입이 없었으며, 점수는 낮지만 유효한 출력의 경우 더 높은 점수를 얻기 위해 재실행할 수 없었습니다.
Codex는 원시 JSONL을 사용하여 격리된 CLI 프로세스를 실행했으며, CLI에서 생성된 토큰 필드는 그대로 유지했습니다. 동료의 Claude CLI OAuth 세션이 만료되었기 때문에, Claude Code는 새로운 서브에이전트 컨텍스트를 가진 코디네이터를 사용했습니다. 우리는 깨끗한 감사 사본에서 Claude의 패치를 재구성한 후, 공개 및 숨겨진 검사를 다시 실행했습니다. 이를 통해 신뢰할 수 있는 실질적인 증거를 확보할 수 있었으나, 완전히 동일한 격리 환경이나 모델 제어 표면은 확보하지 못했습니다.
| 작업 | 코덱스 | 클로드 코드 | 유계 해석 |
|---|---|---|---|
| T1: 저장소 이해 | 20/20 | 20/20 | 동점: 간결한 접근법 대 철저한 접근법 |
| T2: 다중 파일 기능 | 30/30 | 30/30 | 기능적 연계; 서로 다른 검증 및 테스트 범위 |
| T3: DST 수리 | 30/30 | 30/30 | 둘 다 통과했습니다. 좁은 패치 대 넓은 가장자리 커버리지 |
| T4: 점검 및 수리 | 18/20 | 19/20 | Claude 코드는 검토 범위가 더 넓은 것으로 나타났다 |
통제된 시험 · 고정된 평가 기준
코덱스 98/100 대 Claude 코드 99/100
1점 차이는 보편적인 승리 신호가 아닙니다. 유용한 차이는 과제에 따라 다릅니다.
| 의사결정 영역 | 관측된 결과 | 실용적인 읽기 |
|---|---|---|
| 저장소 이해 | 무승부 · 각 20/20 | Claude는 더 상세했고, Codex는 더 간결했다. |
| 다중 파일 기능 | 무승부 · 각 30/30 | 둘 다 비공개 검사를 통과했으며, Claude는 더 광범위한 테스트를 추가했습니다. |
| 일광절약시간제(DST) 오류 수정 | 무승부 · 각 30/30 | Claude는 더 많은 가장자리를 덮었고, Codex는 더 좁은 패치를 사용했습니다. |
| 점검 및 수리 | Claude 19/20; 코덱스 18/20 | Claude에서는 재현성이 더 높은 결함이 발견되었습니다. |
| 측정된 속도 | 혼합 | Claude가 T1/T2를 이끌었고, Codex가 T3/T4를 이끌었다. |
공개 사항: 프로ンプ트와 피처는 동일하지만, 격리 경로는 다릅니다. 이 소규모 테스트 결과를 모든 리포지토리, 모델 계층 또는 자율 세션에 일반화해서는 안 됩니다.
이 테스트 환경은 규모가 너무 작아 대규모 저장소, 모든 언어, 모든 모델 계층 또는 장시간의 자율 실행 세션에 대한 성능을 평가하기에는 한계가 있습니다. 총 점수 차가 1점인 결과는 “두 가지 모두 성공했으나 검토 범위에 차이가 있다’는 의미로 해석하는 것이 가장 적절하며, 이를 보편적인 순위 평가로 보아서는 안 됩니다.
실제 사용자들의 후기—그리고 이를 얼마나 신뢰해야 할까
커뮤니티 피드백은 프로젝트, 작업, 모델, 노력 수준, 기간 등의 정보가 포함될 때 가치가 있습니다. 반면, 단순히 특정 제품이 “더 똑똑해 보인다”거나 “훨씬 빠르다”는 내용만 담은 게시물은 설득력이 떨어집니다. 사용자마다 비교하는 대상(리포지토리, 구독 등급, 프롬프트, 확장 기능, 감독 수준 등)이 다르기 때문입니다.
위의 레딧 사례를 통해 볼 때, 상호작용에는 상충 관계가 존재함을 알 수 있습니다. 즉, 빠르고 대화형인 방식은 더 많은 주의를 요구할 수 있는 반면, 신중하게 실행하는 방식은 더 느리게 느껴질 수 있지만 수정할 부분이 적습니다. 우리의 통제된 테스트는 해당 계정의 사례와 부분적으로만 겹칩니다. 이 테스트에서는 유효한 실행에서 속도가 제각각이었고 사람의 개입이 전혀 없었기 때문에, ‘지속적인 관리’ 주장을 입증할 수 없습니다. 바로 이 때문에 커뮤니티 증거와 통제된 증거는 서로 혼합하지 않고 함께 제시되어야 합니다.
X 하네스에 대한 논평은 두 번째로 유용한 점을 지적합니다. 즉, 코딩 결과는 단순히 모델 레이블에만 국한된 것이 아니라 전체 시스템에 속한다는 것입니다. 두 게시물 모두 설문조사 데이터로 취급되어서는 안 됩니다. 이 게시물들을 활용하여 자신의 실험에서 다룰 질문들—개입 횟수, 차이 크기, 테스트 품질, 잘못된 가정으로부터의 회복 등—을 파악하십시오.
Codex 및 Claude 코드를 GlobalGPT로 확장하기
GlobalGPT는 다중 모델, 다중 모달 작업 공간, 네이티브 리포지토리 에이전트를 대체하는 것은 아닙니다. 이 도구의 실질적인 역할은 기존 호스트 기능을 확장하는 데 있습니다. 즉, Codex나 Claude Code가 리포지토리 접근, 셸 명령어, 테스트 및 승인 업무를 계속 담당하는 동안, 제2의 의견 수렴, 계획 검토, 문서 검토 또는 특수한 출력 처리를 위해 사용 가능한 다른 에이전트 모델을 활용하는 것입니다.
GlobalGPT는 다음을 위한 공식 CLI 가이드를 발행합니다. 코덱스 그리고 클로드 코드, 그리고 Cursor도 마찬가지입니다. 안전한 T5 통합 테스트에서 CLI는 두 비교 대상 환경 모두에서 동일한 정지된 작업을 완료했습니다. 또한 Codex에서는 읽기 전용 MCP 모델 목록 호출을 검증했으며, GlobalGPT 스킬을 설치, 로드 및 사용했습니다.
GlobalGPT 통합 · 채점 점수에서 제외됨
두 워크플로우 모두에서 CLI가 검증되었으며, Codex에서 MCP와 Skill이 검증되었습니다.
이는 통합 경로를 측정하는 것이지, GlobalGPT가 두 가지 고유 코딩 인자 중 하나를 대체하는지 여부를 측정하는 것이 아닙니다.
| 경로 | 코덱스 환경 | Claude 동료 달리기 행사 |
|---|---|---|
| GlobalGPT CLI | gpt-5.6-sol 및 gpt-5.6-luna로 검증됨 | 동일한 동결된 작업으로 검증됨 |
| MCP | 상호작용이 가능한 읽기 전용 모델 목록이 검증되었습니다. | 실행 중에는 연결되지 않음 |
| 기술 | 설치, 로딩 및 테스트 완료 | 설치되었으나 통화 중단 시에는 사용되지 않음 |
| 무인 MCP | 승인 제한 사항 확인됨 | 테스트되지 않음 |
통합 관련 증거 전체 보기
# GlobalGPT 통합 테스트 요약 # # 범위 T5는 GlobalGPT 통합을 측정하며, 네이티브 Codex 코딩 점수에서는 제외됩니다. Yukie는 사용되지 않았습니다. ## 모델 잠금 및 준비 상태 - 모델 A: `gpt-5.6-sol` - 모델 B: `gpt-5.6-luna` - 두 모델 모두 라이브 모델 목록에 표시되었습니다. - 두 경량 준비도 프로브 모두 유효하고 구문 분석 가능한 텍스트를 반환했습니다. - 모델은 공식 T5A 및 T5B 출력 호출 전에 잠금 처리되었습니다. ## 공식 CLI 결과 | 작업 | 모델 | 상태 | 소요 시간 | 프롬프트 토큰 수 | 완성 토큰 수 | 필수 제목 수 | |---|---|---|---:|---:|---:|---:| | T5A | gpt-5.6-sol | 유효 | 27초 | 2,116 | 1,207 | 6/6 | | T5B | gpt-5.6-luna | 유효 | 14초 | 2,116 | 1,441 | 6/6 | 두 공식 호출 모두 `glbgpt exec`를 통해 동일한 고정된 영어 제품 기획 과제를 사용했으며, 영어로만 표시되는 출력을 반환했고, 어떠한 인증 정보도 노출하지 않았습니다. 품질 재실행은 발생하지 않았습니다. ## MCP 결과 - `codex mcp list` 명령어 실행 결과 `globalgpt`가 활성화된 것으로 나타났습니다. - 비상호작용형 Codex 세션에서 `mcp__globalgpt__glbgpt_list_models`를 탐지하고 호출을 시도했으나, 무인 MCP 승인이 불가능하여 호출이 취소되었습니다. 안전 설정은 완화되지 않았습니다. - 활성 대화형 Codex 세션은 동일한 읽기 전용 GlobalGPT MCP 도구를 성공적으로 호출하여 9개의 채팅 모델을 수신했습니다. - 결과: 대화형 MCP 액세스는 확인되었으며, 무인 비대화형 MCP 실행에는 여전히 승인 제한이 적용됩니다. ## 스킬 결과 - GlobalGPT 및 GlobalGPT 코딩 스킬은 번들된 CLI 스킬 패키지에 대한 링크를 통해 Codex 스킬 디렉터리에 설치되었습니다. - GlobalGPT 스킬을 로드하여 구성 세션 확인, 라이브 모델 선택, 준비 상태, 신용 안전 옵션 및 오류 처리를 수행했습니다. - 결과: 활성 Codex 워크플로우에 설치 및 실행되었습니다. ## 제한적 결론 이번 실행을 통해 정상 작동하는 GlobalGPT CLI 호출, Codex에서 수행된 대화형 GlobalGPT MCP 읽기 전용 호출, 그리고 설치 및 사용된 GlobalGPT 스킬 경로가 검증되었습니다. 이는 모든 모델, 미디어 도구, 호스트, 계정 또는 무인 MCP 구성이 정상적으로 작동함을 입증하지는 않습니다. 또한 Yukie를 테스트하지 않으며, GlobalGPT가 Codex 또는 Claude Code를 대체한다는 주장을 뒷받침하지도 않습니다.
검증 범위: 특정 CLI 호출, 대화형 MCP 읽기 1회, 설치/사용된 스킬 경로 1개. 이는 모든 모델, 미디어 도구, 호스트 또는 무인 구성을 입증하는 것은 아닙니다.
경계가 중요합니다. 동료가 수행한 Claude 테스트에서는 Claude 측 MCP가 아닌 CLI 경로가 확인되었습니다. 해당 스킬은 그곳에 설치되어 있었지만, 중단된 통화에는 사용되지 않았습니다. 무인 Codex MCP 실행 시도에도 여전히 수동 승인이 필요했습니다. 모델 가용성과 크레딧은 현재 GlobalGPT 요금제에 따라 달라지므로, 개발자는 모든 모델이 포함되어 있다고 가정하기보다는 실제 제공 목록을 확인해야 합니다.
GlobalGPT는 이미지, 동영상, 오디오 및 안내형 에이전트 워크플로우도 다룹니다. Yukie의 ‘슬라이드’, ‘문서’, ‘이미지’ 항목은 별개의 범주에 속합니다. 이 항목들은 코딩이 필요 없는 작업을 위해 구체적인 템플릿과 단계별 브라우저 가이드를 제공합니다. 이는 프레젠테이션이나 구조화된 문서를 만들기 위해 코딩용 CLI를 여는 것보다 더 쉬울 수 있지만, 리포지토리 확인, 테스트 실행 또는 코드 검토를 대체할 수는 없습니다.
다른 워크플로 범주
유키에가 주도한 브라우저 에이전트 테스트
특정 작업에 특화된 웹 워크플로우에 유용하지만, 리포지토리 코딩 에이전트 대체 용도로는 테스트되지 않았습니다.
| 워크플로 | 기준 충족 | 첫 번째 유효한 결과 |
|---|---|---|
| 슬라이드 | 5/6 | 5장의 슬라이드로 구성된 프레젠테이션 자료가 생성되었으며, 발표자 노트는 확인할 수 없었습니다. |
| 문서 | 6/6 | 내보내기 기능과 버전 이력이 포함된 체계적인 연구 개요서. |
| 이미지 + 설명 | 5/6 | 강렬한 사각형 이미지가 표시되었으나, 필수 캡션이 누락되었습니다. |
타당한 결론: 명확한 진입점과 안내가 제공되는 다중 모드 워크플로우. 근거가 부족한 결론: 무제한 사용, 정확한 가격, 또는 Codex/Claude Code의 완전한 대체.
독립 개발자는 어떤 코딩 도구를 선택해야 할까요?
- 코덱스 선택 컴팩트한 유계 실행, 사용 가능한 표면의 조합, 또는 설정에서 제공되는 실행 증거가 여러분의 작업 방식에 부합할 때입니다.
- Claude 코드 선택 대화형 터미널 루프가 발생하거나, 사용자가 확인한 사용자 지정 기능, 혹은 당사의 테스트 환경에서 관찰된 것과 같은 광범위한 검토 동작이 더 중요해질 때입니다.
- 익숙하지 않은 저장소에는 둘 중 하나를 사용하세요 읽기 전용 아키텍처 및 위험성 검토를 거친 후에야 비로소 가능했습니다. 두 도구 모두 해당 작업을 잘 처리했습니다.
- 두 가지를 모두 적절히 활용하세요 두 번째 에이전트의 검토가 추가 구독 비용과 조정 비용을 감수할 만한 가치가 있을 때. 두 번째 도구가 작업을 무작정 반복하기보다는 diff나 계획을 검토하도록 요청하십시오.
- GlobalGPT 추가 다중 모델 라우팅이나 다중 모드 작업이 누락된 계층인 경우. 네이티브 리포지토리 작업은 코딩 호스트에서 수행하십시오.
7일간의 시험 운영은 순위표보다 더 많은 정보를 제공합니다. 실제 기능 중(단, 프로덕션 환경은 제외) 하나와 버그를 각각 하나씩 골라 검토해 보세요. 프롬프트와 성공 명령어를 고정하세요. 첫 번째 유효한 diff, 통과된 테스트, 소요 시간, 사람의 개입, 예상치 못한 범위, 그리고 해당 작업이 사용 가능한 리소스에 미친 영향을 기록하세요. 실수를 감지할 수 있고 워크플로를 지속할 수 있는 제품이 더 나은 제품입니다.
Codex 대 Claude 코드 FAQ
Codex가 Claude 코드보다 더 나은가요?
전부 그런 것은 아닙니다. 두 프로젝트 모두 저희 테스트 환경에서 제시된 네 가지 과제를 모두 완료했습니다. Claude Code는 검토 범위 면에서 앞섰고, Codex는 구현 및 버그 수정 부분에서 더 간결한 모습을 보였습니다.
대용량 저장소의 경우 어느 쪽이 더 좋을까요?
저희의 작은 도구로는 그 질문에 답할 수 없습니다. 변경을 허용하기 전에, 본인의 저장소에서 읽기 전용 아키텍처 작업으로 두 가지를 모두 평가해 보시기 바랍니다.
어떤 코딩 제제가 감독이 덜 필요한가요?
이는 작업의 명확성, 모델 설정, 저장소 지침, 그리고 원하는 상호작용 방식에 따라 달라집니다. 한 레딧 사용자가 서로 다른 감독 패턴을 보고한 바 있지만, 그 개인의 경험은 제품 전반에 적용되는 규칙은 아닙니다.
어느 쪽이 더 저렴할까요?
주요 소비자 등급은 월 $20, $100, $200으로 구분되지만, 포함된 용량 및 한도 적용 방식은 서로 다릅니다. 선택적 크레딧과 API 과금은 별도로 처리됩니다.
Claude와 Claude 코드 공유는 사용 한도가 적용되나요?
네. Claude 및 Claude Code는 연결된 Pro 또는 Max 요금제에서 공유 세션 및 주간 한도를 적용합니다.
Codex의 로컬 작업과 클라우드 작업은 제한을 공유하나요?
로컬 메시지와 클라우드 채팅은 5시간의 사용 한도가 동일하게 적용되며, 주간 한도가 적용될 수도 있습니다.
GlobalGPT가 Codex나 Claude Code를 대체할 수 있나요?
아닙니다. 추가 모델, CLI, MCP, 스킬 및 다중 모드 도구를 통해 두 워크플로우 모두를 확장할 수는 있지만, 리포지토리 접근 권한과 코딩 에이전트의 동작은 호스트 측에 그대로 유지됩니다.
두 제품 모두에서 GlobalGPT를 사용할 수 있나요?
GlobalGPT는 두 가지 모두에 대한 공식 CLI 튜토리얼을 제공합니다. 당사는 두 환경 모두에서 CLI 사용을 검증했으며, Codex에서 MCP 및 스킬 사용을 확인했습니다. 단, 무인 MCP의 경우 승인 제한이 적용됩니다.
가격, 요금제 규정, 연동 기능 및 출처 정보는 2026년 7월에 확인되었습니다. 제품 세부 정보는 변경될 수 있습니다.
GlobalGPT 열기 기존 코딩 워크플로우에 다중 모델 및 다중 모달 레이어를 추가하고 싶다면.


