# task-930.1: output-review.py — Champion/Challenger 핵심 엔진

## 설계서
- **반드시 먼저 읽을 것**: `/home/jay/workspace/memory/specs/skill-eval-self-learning-design.md` (v1.2)
- 특히 Section 3 (Champion/Challenger 모델), Section 6 (플로우), Section 8 (안전장치)

## 구현 범위

### 1. output-review.py (scripts/output-review.py, ~100줄 목표)

스킬 아웃풋의 자가 평가 파이프라인 메인 스크립트. 두 가지 모드:

**초회 모드 (--init)**:
1. 같은 인풋으로 아웃풋 A, B 두 개 생성 요청 (외부에서 전달받음)
2. eval-axes.json에서 해당 스킬의 평가 축 로드
3. 평가 축 기준으로 A vs B 비교 → 더 나은 쪽 선택
4. (사업용 스킬) WebSearch로 온라인 전문가 벤치마킹 → 부족점 도출 → 개선사항 생성
5. (시스템용 스킬) cross-model 검증 자리 표시 (Phase 2에서 연동, 지금은 스킵 가능)
6. 개선점 반영한 최종 아웃풋 생성 요청
7. Delta 검증: 개선 전 선택본 vs 최종본 비교. 역행 시 개선 전 선택본이 챔피언 (fallback)
8. champions/{skill-name}.json에 챔피언 저장
9. learnings.jsonl에 개선사항 저장 (source: champion-battle, skill_name 포함)

**일상 모드 (--compare)**:
1. 새 아웃풋(챌린저)을 입력받음
2. champions/{skill-name}.json에서 챔피언 로드
3. eval-axes.json에서 평가 축 로드
4. 비교 순서 랜덤화 (random.shuffle)
5. 평가 축 기준으로 챔피언 vs 챌린저 비교
6. 챌린저 승리 시: 챔피언 교체 + 이유를 learnings에 저장
7. 챔피언 승리 시: 버림 + (선택적) 미달 시 개선 재생성 트리거 (max 2회)
8. 전적 업데이트 (consecutive_wins/losses 카운트)

**성과 기반 갱신 로직**:
- champion.json에 `consecutive_defenses`, `consecutive_losses`, `reinit_count_this_month` 필드
- 5연속 방어 → status: "stable"
- 3연속 교체 → status: "unstable" → 재초기화 플래그
- reinit_count >= 2 (월) → status: "manual_intervention_required"
- 30일간 미실행 (last_used 체크) → 재초기화 대상

### 2. champions/ 디렉토리 구조

**champions/{skill-name}.json 스키마**:
```json
{
  "skill_name": "satori-cardnews",
  "skill_type": "business",
  "champion_output": "... (아웃풋 내용 또는 파일 경로)",
  "eval_axes_used": ["훅 강도", "시각 밸런스", ...],
  "created_at": "2026-03-25T...",
  "last_used": "2026-03-25T...",
  "status": "active",
  "consecutive_defenses": 0,
  "consecutive_losses": 0,
  "reinit_count_this_month": 0,
  "month_reset_date": "2026-04-01",
  "init_method": "full_benchmark",
  "benchmark_source": "online_expert | cross_model | graceful_degradation"
}
```

**champions-archive/{skill-name}/ 디렉토리**:
- 교체/만료된 챔피언을 타임스탬프 파일명으로 보존
- 예: `champions-archive/satori-cardnews/2026-03-25T001030.json`

### 3. graceful degradation
- WebSearch 결과가 부실하면 (결과 0건 또는 관련성 낮음 판단)
- A/B 선택본을 그대로 챔피언으로 세움
- benchmark_source: "graceful_degradation"으로 기록

## 제약사항
- 파일 위치: `scripts/output-review.py`
- champions/ 위치: `memory/skill-learning/champions/`
- champions-archive/ 위치: `memory/skill-learning/champions-archive/`
- learnings.jsonl 위치: `memory/skill-learning/learnings.jsonl` (2팀이 스키마 담당, 여기서는 append만)
- eval-axes.json 위치: `skills/shared/eval-axes.json` (2팀이 생성, 여기서는 읽기만)
- **절대경로 금지**: 환경변수 또는 상대경로 사용
- **~100줄 목표**: 모듈화. 헬퍼 함수는 별도 모듈로 분리 가능

## 테스트
- 초회 모드: 가상 스킬로 A/B 비교 → 챔피언 생성 확인
- 일상 모드: 챔피언 로드 → 비교 → 교체/유지 확인
- 성과 기반: 5연속 방어 → stable, 3연속 교체 → unstable 확인
- graceful degradation: 빈 벤치마킹 → fallback 확인
