---
name: codex-review-pingpong
description: Use after `verifying-test-coverage` passes (commit-direct gate) or after `planning-before-work` produces a plan (pre-implementation gate). Runs Codex CLI cross-review with forced `[위험|경고|안전]` labels, ping-pongs up to 3 rounds; round-between edits apply automatically (gate-internal exception to CLAUDE.md approval gate). Skip one-or-two-line tweaks, formatting/doc-only edits, or build/IDE meta-file-only changes.
---

# Codex 핑퐁 리뷰

## Overview

두 종류 게이트로 자동 호출되어 Codex CLI(`gpt-5.5`, `model_reasoning_effort=high`,
`service_tier=fast`, `--sandbox read-only`)와 `[위험|경고|안전]` 라벨 강제 포맷으로
독립 교차검토를 수행한다.

- **(a) commit-direct 게이트**: `verifying-test-coverage` 통과 직후, `git add` 직전.
- **(b) pre-implementation 게이트**: `planning-before-work` 가 plan 을 도출한 직후,
  코드 작성 시작 직전.

Claude 자체 평가와 Codex 평가에 **둘 다 [위험]이 0건** 일 때 게이트가 열려 다음 흐름
(commit 또는 구현) 으로 진입한다. 남은 [경고]는 게이트 여는 라운드에서 **한 번만**
보고하고 [경고]만으로는 라운드를 더 열지 않는다 — [경고]는 주관적 자문이라 0으로
수렴하지 않으므로 종료 조건에서 배제한다(§3). 최대 3라운드 안에 [위험] 미해소면
사람에게 에스컬레이션해 결정을 넘긴다. 책임 범위는 "외부 모델 한 명과의 독립 교차검토"
한 가지로 한정한다.

**라운드 사이 자동 적용**: 핑퐁 사이 코드/계획 수정을 사용자 승인 없이 적용한다.
단일 진실은 CLAUDE.md `### 승인 게이트` "명시적 예외" 표 — 본 스킬은 그 표에
등재된 항목으로 동작하며, 표에 없는 추가 자동화는 단독 도입하지 않는다.

## 상태기계 (요약)

진입·라운드 루프·종료·에스컬레이션의 정본 요약 — 상세 조건은 아래 각 섹션이 소유한다.

```
  진입: (a) commit-direct [coverage 후, git add 앞] / (b) pre-implementation [plan 후, 코드 앞]
     │
     ▼
  스킵 게이트(§언제호출) ──충족──▶ 한 줄 보고 후 게이트 OPEN (핑퐁 없음)
     │ 미충족
     ▼
  ┌─▶ Round N/3 ── codex 호출  ∥  Claude 자체 평가 (§1 ∥ §2, 병렬)
  │      │
  │      ▼  §3 합의 판정: 양쪽 [위험] 0?
  │      ├─ 아니오 ─▶ [위험] 자동수정(승인 없이, §5) ─▶ 카운터 +1 ─┐
  │      └─ 예 ─▶ 게이트 OPEN ─▶ [경고] 1회 보고 ─▶ 👤 승인 ─▶ 다음 흐름
  └────────────────────────(N<3)────────────────────────────────┘
         │ N=3 미해소 / 포맷 2회 실패 / codex 실패
         ▼
  👤 에스컬레이션(§6) ── 사용자 항목별 결정
         ├─ 1건이라도 "적용" ─▶ +1 라운드
         └─ 전부 "무시" ─▶ 합의 간주 ─▶ 👤 최종 승인 ─▶ 다음 흐름

  종단(에이전트 파일): pass / escalated / fail.
```

## 언제 호출

- **호출 (a) commit-direct**: 코드/설정 변경 → 회귀 테스트 통과 →
  `verifying-test-coverage` 통과 직후, `git add` 제안 직전. 본 게이트를 통과하지
  않으면 `git add` 흐름을 진행하지 않는다.
- **호출 (b) pre-implementation**: `planning-before-work` 가 산출한 plan 본문 +
  영향 파일 목록을 입력으로 본 게이트를 호출한다. 통과 전까지는 실제 코드 작성
  (Edit/Write) 을 시작하지 않는다.
- **Skip** (어느 하나라도 충족 시 자동 스킵, 한 줄 보고만):
  - **변경 라인 ≤ 10 AND 새 분기 0 AND 시그니처 변경 0 AND 외부 caller 0** (외과적 리네이밍·메서드 통합·상수 치환의 전형). `git diff --shortstat` 기준.
  - 1~2줄 단순 수정, 오타, 포맷팅 변경
  - 문서(`.md`) 단독 변경
  - 빌드/IDE 메타파일(`.gradle-local`, `.settings`, `bin/`, `build/`)만 변경된 경우
  - 사용자가 명시적으로 "리뷰 생략" 또는 "그냥 add" 또는 "plan 검증 생략" 요청
- **commit-direct 중복 회피**: 직전에 pre-implementation 게이트가 합의 통과했고
  구현 diff 가 plan 의 "영향 범위" 섹션 안에 머문 경우(파일 목록 일치 + 라인이 plan 예상 범위 내),
  commit-direct 게이트는 자동 스킵한다. 한 줄 보고:
  `commit-direct 핑퐁 스킵 (pre-implementation 통과 + diff 가 plan 영향범위 내)`.
  diff 가 plan 범위를 벗어나면(스코프 크리프) 정상 호출.
- **사용자 우선**: 사용자가 명시적으로 "핑퐁 돌려라" / "검증해" 요청 시 위 임계값을
  무시하고 호출한다.
- **재호출**: ping-pong 중 코드/계획 수정이 발생하면 같은 변경 세트로 다음 라운드만
  진행한다. 코드 게이트의 경우 `verifying-test-coverage` 부터 다시 시작하지 않는다
  (라운드 수정이 새 분기를 만들었다면 그때만 재실행).

## 1. Codex 호출 명령

기본 명령 (모델/추론/티어 옵션 고정). 코드 게이트는 cwd 의 변경분(`git diff HEAD`),
계획 게이트는 plan 본문 + 영향 파일 목록을 동봉한다.

**입력 전달 규칙** (게이트별 분기):
- **commit-direct (코드 게이트)**: stdin heredoc 인라인 강제. 코드 diff 는 매 라운드
  바뀌는 폭이 작고, 임시 파일에 쓸 가치보다 인라인이 단순.
- **pre-implementation (plan 게이트)**: plan 본문을 cwd 의
  `.codex-skill-work/<티켓키>_<작업명>.md` (예: `TICKET-123_example-task.md`;
  티켓 키 없으면 `<작업명-kebab>.md`) 에 `Write` 로 **최초 1회만** 저장하고(파일 끝에
  라벨 강제 포맷·정의 블록 동봉), codex 호출 시 `... < .codex-skill-work/<그 파일>`
  로 redirect 동봉. **고정명(`plan-v1.md`) 금지** — 직전 태스크 잔재가 남아
  Read-before-Write 실패·의도치 않은 덮어쓰기를 유발하므로 태스크별 고유명으로 쓴다.
  라운드 사이 변경은 **같은 파일을 in-place `Edit` 로 델타만 갱신** — 라운드마다
  `_v2` 같은 새 버전 파일을 `Write` 하지 않는다(full 본문 재기재가 그 자체로 컨텍스트
  블로트라 파일 redirect 의 이점을 상쇄한다). 채팅에는 변경 요약 1~3줄만 출력,
  풀본문 채팅 재출력 금지. 이유: plan 본문을 매 라운드 채팅·codex heredoc 양쪽에
  인라인 반복하면 메인 컨텍스트가 비대해진다.
- 본 완화는 plan 게이트 한정. commit-direct 의 stdin heredoc 강제는 그대로다.

공통 프롬프트 본문(라벨 강제 포맷)을 stdin 또는 redirect 로 흘려보낸다.

```bash
# (a) commit-direct — stdin heredoc 인라인 (코드 diff 동봉)
codex exec -C . \
  -c model=gpt-5.5 \
  -c model_reasoning_effort=high \
  -c service_tier=fast \
  --sandbox read-only \
  - <<'EOF'
다음 [코드 변경] 을 한국어로 검토해줘.

출력은 반드시 다음 한 줄 포맷의 항목 목록으로만 작성한다 (서두/총평/마무리 멘트 금지):

[위험] <파일:라인 또는 식별자> — <한 줄 근거>
[경고] <파일:라인 또는 식별자> — <한 줄 근거>
[안전] <파일 또는 영역> — <한 줄 근거>

라벨 정의는 §1 기준. 지적할 게 없는 영역은 [안전] 한 줄로만. 세 라벨 외 출력 금지.
EOF
```

```bash
# (b) pre-implementation — 파일 redirect 동봉 (plan 본문)
codex exec -C . \
  -c model=gpt-5.5 \
  -c model_reasoning_effort=high \
  -c service_tier=fast \
  --sandbox read-only \
  - < .codex-skill-work/<티켓키>_<작업명>.md   # ↑ §1 에서 저장한 실제 파일명으로 치환
```

> plan 파일(§1 의 `<티켓키>_<작업명>.md`) 끝에 라벨 강제 포맷·라벨 정의 블록을 박아 둔다 — codex 가
> 파일 내용 그대로를 prompt 로 받는다. 파일은 (1) plan 본문 + (2) 라벨 포맷 지시
> 두 부분으로 구성하며, 라운드 사이엔 (1) plan 본문만 in-place `Edit` 한다.

라벨 정의 (양 게이트 공통):
- [위험] 머지 또는 구현 시작 전에 반드시 고쳐야 하는 결함 (버그/보안/회귀/
  데이터 무결성, 계획 게이트에서는 누락된 영향분석·잘못된 전제·범위 폭주 포함)
- [경고] 진행 가능하지만 개선 권고 (가독성/네이밍/마이너 리팩터, 계획 게이트에서는
  단계 분해 누락·테스트 전략 빈약 등). 가급적 적극적으로 잡는다.
- [안전] 변경/계획이 의도대로 구성됐고 결함이 없는 부분

옵션 의미:
- `model=gpt-5.5` — 본 게이트의 고정 리뷰 모델.
- `model_reasoning_effort=high` — 정적 분석 깊이 충분 (xhigh 한 단계 아래; fast 큐와 호환되어 hang 회피).
- `service_tier=fast` — 처리 속도 우선 (핑퐁 허들 최소화).
- `--sandbox read-only` — 외부 모델은 절대 파일을 수정하지 않는다.

호출 전 채팅에 `Round N/3 — Codex 호출 + Claude 자체 평가 병렬 진행` 한 줄 보고.

## 2. Claude 자체 평가

Codex 호출과 **별도로**, Claude 자체도 동일 라벨 체계로 본인 변경을 분류한다.
이는 ping-pong 의 한 쪽 입장이며, Codex 응답을 보기 전에 작성해 편향을 줄인다.

작성 규칙:
- 같은 한 줄 포맷(`[라벨] 식별자 — 근거`) 사용
- 자기 변경에 대한 비판도 [위험]/[경고] 로 솔직히 표시
- 추측 회피, 실제 코드/diff 근거만

**§1 의 codex 호출과 병렬 실행**: Claude 자체 평가는 변경 diff 또는 plan 본문만
입력으로 받으므로 Codex 응답을 기다릴 필요가 없다. 매 라운드 §1 codex 호출과
본 §2 자체 평가는 동시에 시작하고, 두 응답이 모두 도착한 시점에 §3 합의 판정으로
넘어간다. 직렬 실행은 무의미한 대기 시간을 만든다.

## 3. 합의 판정

| Claude | Codex | 결과 |
|---|---|---|
| 양쪽 [위험] 0건 | 양쪽 [위험] 0건 | **합의(게이트 OPEN)** → 남은 [경고]는 **최종 결과 요약에 선택 항목으로 보고만** (자동 반영 없음) → **사용자 승인** → 다음 흐름 |
| 어느 쪽이라도 [위험] 1건 이상 | — | Claude 가 즉시 자동 수정 (승인 없이) → **다음 라운드에서 그 수정을 재검토** |

**종료는 `[위험] 0` 으로만 판정한다.** [위험] 이 0건이면 [경고] 가 몇 건이든
다음 라운드 없이 즉시 게이트를 OPEN 한다. [경고] 는 주관적 자문(가독성/네이밍/
마이너 리팩터)이라 재검토(codex 재호출)하면 AI 가 새 트집을 무한히 만들어내
0 으로 수렴하지 않는다 — 그래서 **오직 [위험]만 확인용 다음 라운드를 유발**하며,
이것이 조기 종료의 핵심이다. [경고] 는 게이트 여는 라운드의 최종 요약에 한 번
보고하고 사용자가 승인 단계에서 취사한다(자동 반영·재검토 없음). 같은 라운드에
[위험]과 [경고]가 섞이면 [위험]만 고쳐 다음 라운드로 가고, [경고]는 게이트가
OPEN 되는 라운드에서 일괄 보고한다.

**핑퐁 사이 사용자 승인은 없다**. 사용자 허들은 **합의 후 최종 결과 1회** 만.
이 게이트의 가치는 핑퐁 속도이며, 매 라운드 승인은 가치를 훼손한다.

**합의 후 최종 결과 요약**의 출력 형식·템플릿은 §7 이 단일 진실이다.

사용자가 (a) 승인 → 다음 흐름 진입 / (b) 수정 요청 → Claude 재핑퐁 또는 직접 반영 /
(c) 중단 → 흐름 종료.

## 4. 라운드 카운터 / 종료 조건

- **최대 3라운드**. 카운터는 Codex 호출 1회당 +1.
- 라운드 종료 시점에 채팅에 `Round N/3` 표시.
- 종료 조건:
  - (a) 양쪽 [위험] 0건 → 게이트 통과 (남은 [경고]는 최종 요약에 보고만) → §7 보고 후 종료.
    첫 라운드부터 [위험] 0 이면 **1라운드에서 종료**된다. [경고]는 라운드를 늘리지 않는다.
  - (b) 3라운드 종료 시 [위험] 미해소 → §6 에스컬레이션
  - (c) Codex 응답이 라벨 포맷을 어김 → **같은 라운드 내 1회만 재요청**,
    그래도 실패면 즉시 §6 에스컬레이션
  - (d) Codex CLI 호출 실패 (네트워크/exit code ≠ 0) → 한 줄 사용자 보고 후
    **사용자에게 재시도/스킵 결정 요청**. Claude 단독으로 스킵하지 않는다.
    (`codex` CLI 자체 설치 여부는 사용자 환경 전제로 검증하지 않는다.)

## 5. ping-pong 중 코드/계획 수정 절차 (자동 적용)

라운드 사이 자동 적용은 **[위험] 해소 한정**이다 ([경고]는 §3 대로 게이트 OPEN
라운드에 보고만, 자동 반영·재검토 없음). [위험] 해소를 위해 Claude 가 코드 또는
plan 본문을 수정해야 할 때:

1. **변경 한 줄 요약** 채팅 출력 (예: `자동 적용: log.debug raw ci + @Slf4j 제거`)
2. **즉시 적용** (코드: `Edit`/`Write`, plan: markdown 직접 편집). 사용자 승인 없음.
3. 코드 게이트면 영향 범위 단위 테스트 자동 재실행 — green 이어야 다음 라운드.
   여러 모듈/테스트 클래스가 영향 범위에 포함되면 Bash 호출을 **병렬**로
   디스패치한다 (예: `./gradlew :A:test :B:test` 단일 호출, 또는 모듈이 분리되어
   있으면 별도 Bash 툴 호출 2개를 동시에). plan 게이트는 본 단계 자체를 스킵
   (실행 코드가 아직 없음). 컴파일/테스트 실패 시 즉시 추가 수정 (승인 없이).
   같은 실패 2회 반복 → §6 에스컬레이션.
4. 다음 라운드 Codex 호출 (방금 고친 [위험]을 재검토). [위험]이 0으로 떨어지면
   §3 대로 다음 라운드 없이 게이트 OPEN — 남은 [경고]는 최종 요약에 보고만.

예외 — 다음 경우에는 자동 적용을 멈추고 §6 에스컬레이션으로 전환:
- 같은 라운드에서 컴파일/테스트 실패가 2회 반복
- 수정 범위가 본래 변경 세트의 영향 파일 목록을 벗어남 (스코프 크리프)
- Codex 가 동일 [위험] 항목을 라운드 1·2 에서 같은 근거로 반복 지적 (해소가 안 됨)

## 6. 에스컬레이션 포맷

3라운드 미합의 또는 포맷 실패 시 다음 형식으로 사용자에게 결정을 넘긴다.
**핵심 원칙**: 사용자가 파일을 열지 않고 채팅 본문만으로 결정 가능해야 한다.
카운트·라벨만 출력하면 사용자가 "왜 [위험]이지?" 추가 질문 → 추가 컨텍스트
부풀음. 차라리 핵심 근거 한 단락 + plan/diff 직접 인용을 미리 박는다.

> 결정 요청 블록의 출력 템플릿은 [references/report-formats.md](./references/report-formats.md) §6 참조.

쟁점이 4건 이상이면 상위 3건만 위 포맷으로 풀어서 보고하고, 나머지는 표로 축약
(`| # | 식별자 | 라벨 | 한 줄 요약 |`). 사용자가 "전체 보여줘" 요청 시 추가 출력.

사용자가 항목별로 "적용/무시" 결정하면 그에 따라:
- 한 건이라도 "적용" → 추가 1라운드 더 진행 (사용자 결정을 자동 반영 후 재호출).
- 전부 "무시" → 합의 통과로 간주하고 §3 의 **최종 결과 출력 + 사용자 승인** 단계로 진입.
  - commit-direct: 사용자 승인 후 `git add`.
  - pre-implementation: 사용자 승인 후 planning-before-work 의 다음 게이트(티켓)로.

본 에스컬레이션 분기는 두 게이트 모두에 동일하게 적용된다 — 3라운드 미합의 시
**최종 결정권자는 항상 사용자**이며, Claude/Codex 어느 쪽도 강행하지 않는다.

## 7. 보고 형식 (라운드별 + 합의 후)

**각 라운드 종료 직후** 한 블록으로 채팅 보고. **핵심 원칙**: 카운트만 출력하면
사용자가 핑퐁 흐름을 따라갈 수 없어 추가 질문이 발생한다 — 발견 항목의 한 줄
근거를 같이 인라인한다 (각 라벨당 상위 3건, 4건 이상은 `외 N건` 한 줄 축약).

> 라운드별 보고 블록 템플릿은 [references/report-formats.md](./references/report-formats.md) §7 참조.

라운드 사이 자동 적용 본문은 새 코드/plan 본문이 아니라 **변경 의도 한 줄 요약**
(예: `자동 적용: Step 4/5/6 에 테스트 이전 동반 항목 추가 (plan 파일 갱신)`).
풀본문은 파일에 있다 — 채팅 재출력 금지 원칙은 §1 와 동일.

**합의 통과 시 (다음 라운드가 아니라 게이트가 OPEN 되는 시점)** §3 에 따라
**최종 결과 요약 + 사용자 승인 요청** 한 블록을 추가로 출력:

commit-direct·pre-implementation 두 게이트의 최종 결과 블록 템플릿은
[references/report-formats.md](./references/report-formats.md) §7 ("합의 통과 시 최종 결과 블록") 참조.

사용자 승인 전까지 `git add` / 구현 시작 보류.

## 강제 게이트

- 본 스킬이 합의를 도출하지 못했거나 에스컬레이션 중이면 `git add` 를
  실행하지 않는다. CLAUDE.md "Git Commit" 흐름의 `verifying-test-coverage`
  통과 ↔ `git add` 사이에 삽입되는 새 게이트.
- Codex `read-only` 위반 (예: 사용자가 임시로 `workspace-write` 로 바꾸어
  실행) 시 본 스킬은 호출하지 않는다 — 외부 모델이 파일을 수정하면 본 게이트의
  "독립 검토" 전제가 무너진다.

## 다른 스킬과의 관계

- 트리거: `verifying-test-coverage` 직후 (commit-direct, `git add` 앞) /
  `planning-before-work` 직후 (pre-implementation, 코드 작성 앞).
- 통과 후에야 CLAUDE.md "Git Commit" 흐름의 `git add` 또는 plan 실행이 진행된다.
- 플러그인 `review`, `simplify` 와 책임 겹침 — CLAUDE.md 스킬 우선순위에 따라
  미사용.
- 다파일 diff 는 `review-fanout` 워크플로로 라운드 *내* 병렬 다렌즈 리뷰(정확성/회귀/스코프폭주/보안) + 독립 반박 검증을 먼저 돌린 뒤, 그 확정 발견을 본 핑퐁 라운드 입력으로 쓴다. 외부 벤더 교차검토·라운드 사이 자동적용은 본 스킬이 단일 진실.
