# autoresearch 인증 방식 수정: SDK 직접호출 → claude -p CLI 래퍼

## 목표
autoresearch 시스템이 Anthropic Python SDK를 직접 호출하는 대신, `claude -p` CLI를 통해 모델을 호출하도록 수정.

## 배경
- task-1104.1에서 OAuth 인증(`anthropic.Anthropic(auth_token=...)`) 적용했으나, Anthropic API가 OAuth를 지원하지 않아 401 에러 발생
- **현재 실제 동작하는 인증**: Claude Code CLI(`claude -p`)가 내부적으로 OAuth 토큰을 처리하여 API 호출 성공
- 검증 완료: `env -u CLAUDECODE claude -p "Say hello" --output-format text` → 정상 응답

## 수정 대상 파일

### 1. `scripts/autoresearch/skill_executor.py`
**현재 (잘못된 방식)**:
```python
client = anthropic.Anthropic(auth_token=token)
response = client.messages.create(model=..., messages=...)
```

**수정 방향**:
```python
import subprocess, os, json

def call_claude(prompt: str, model: str = "claude-sonnet-4-6", max_tokens: int = 4096, system: str = None) -> str:
    """claude -p CLI를 통해 모델 호출"""
    env = os.environ.copy()
    env.pop("CLAUDECODE", None)  # 중첩 세션 방지

    cmd = ["claude", "-p", prompt, "--output-format", "text", "--model", model, "--max-turns", "1"]
    if system:
        cmd.extend(["--system-prompt", system])

    result = subprocess.run(cmd, capture_output=True, text=True, env=env, timeout=120)
    if result.returncode != 0:
        raise RuntimeError(f"claude -p failed: {result.stderr}")
    return result.stdout.strip()
```

- `load_auth()` 함수: 제거 또는 deprecated 처리 (더 이상 불필요)
- `_create_client()` 함수: 제거 또는 deprecated 처리
- `execute_skill()`: `call_claude()` 래퍼 사용으로 변경

### 2. `scripts/autoresearch/mutator.py`
- `generate_mutation()` 내부의 `client.messages.create()` → `call_claude()` 호출로 변경
- 모델: `claude-sonnet-4-6` (mutation용)

### 3. `scripts/autoresearch/judge.py`
- `judge_output()` 내부의 `client.messages.create()` → `call_claude()` 호출로 변경
- 모델: `claude-haiku-4-5-20251001` (judge용, 비용 절감)

### 4. 공통 래퍼 위치
- `call_claude()` 함수는 `scripts/autoresearch/skill_executor.py`에 두거나, 새 파일 `scripts/autoresearch/claude_runner.py`를 생성하여 공용화
- mutator.py, judge.py, skill_executor.py 모두 이 래퍼를 import

## 주요 요구사항

1. **`CLAUDECODE` 환경변수 반드시 해제**: `env.pop("CLAUDECODE", None)` — 안 하면 "중첩 세션" 에러
2. **`--output-format text`**: JSON이 아닌 텍스트 출력
3. **모델 분리 유지**: mutation/execution = Sonnet, judge = Haiku
4. **토큰 카운팅**: `claude -p`는 토큰 사용량을 직접 리턴하지 않음 → `--output-format json` 옵션이 있으면 사용, 없으면 chars/4 추정으로 대체
5. **타임아웃**: subprocess 호출에 적절한 timeout 설정 (120초)
6. **에러 처리**: subprocess 실패 시 stderr 내용 포함한 에러 raise
7. **기존 테스트 호환**: 기존 테스트가 mock으로 동작하는 경우 mock 대상을 `call_claude`로 변경

## 테스트

1. **단위 테스트**: `call_claude()` 래퍼의 subprocess mock 테스트
2. **기존 테스트 수정**: `anthropic.Anthropic` mock → `call_claude` mock으로 변경
3. **통합 테스트(선택)**: 실제 `claude -p` 호출 1회 테스트 (모델: haiku, 간단한 프롬프트)
4. 기존 테스트 전체 통과 확인

## 제거 대상 (task-1104.1에서 추가했던 코드)
- `load_auth()` 함수 → 불필요 (claude -p가 인증 처리)
- `_create_client()` 함수 → 불필요
- `auth` 파라미터 (각 함수에서) → 불필요
- `anthropic` 패키지 import → call_claude 래퍼만 사용하면 불필요

## 산출물
1. 수정된 코드 파일들
2. `memory/reports/task-1108.1.md` — 완료 보고서
3. 테스트 전체 통과 확인

## 주의사항
- `claude -p` 호출 시 `--max-turns 1` 필수 (도구 사용 없이 단순 응답만)
- autoresearch runner.py 등 다른 파일에서 auth/api_key 전달하는 부분도 정리
- changelog.py의 토큰 분리 기록 로직은 유지 (chars/4 추정이라도)