# task: engine.py ARG_MAX 초과 에러 수정

## 문제
`/home/jay/workspace/services/multimodel-bot/engine.py`의 `call_codex()`와 `call_claude()`가 프롬프트를 CLI 인자로 직접 전달하고 있어서, 장시간 토론(50분+) 시 컨텍스트가 OS의 ARG_MAX 제한(~2MB)을 초과하여 `[Errno 7] Argument list too long` 에러 발생.

## 수정 대상
파일: `/home/jay/workspace/services/multimodel-bot/engine.py`

### 1. call_codex() (line 144~183)
**현재 코드 (문제):**
```python
cmd = ["codex", "exec", "-c", 'model="gpt-5.2-codex"', prompt]
proc = await asyncio.create_subprocess_exec(
    *cmd,
    stdout=asyncio.subprocess.PIPE,
    stderr=asyncio.subprocess.PIPE,
    cwd="/home/jay/workspace",
)
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout)
```

**수정 방향:**
- prompt를 CLI 인자에서 제거하고, stdin으로 전달
- codex CLI는 prompt 자리에 `-`를 넣거나 생략하면 stdin에서 읽음 (공식 문서: "If not provided as an argument (or if `-` is used), instructions are read from stdin")
```python
cmd = ["codex", "exec", "-c", 'model="gpt-5.2-codex"', "-"]
proc = await asyncio.create_subprocess_exec(
    *cmd,
    stdin=asyncio.subprocess.PIPE,
    stdout=asyncio.subprocess.PIPE,
    stderr=asyncio.subprocess.PIPE,
    cwd="/home/jay/workspace",
)
stdout, stderr = await asyncio.wait_for(
    proc.communicate(input=prompt.encode("utf-8")), timeout=timeout
)
```

### 2. call_claude() (line 191~227)
**현재 코드 (문제):**
```python
cmd = ["/home/jay/.local/bin/claude", "-p", prompt, "--output-format", "text", "--model", "sonnet"]
```

**수정 방향:**
- `-p` 뒤의 prompt를 제거하고, stdin으로 전달
- claude CLI는 `-p` 모드에서 prompt 인자가 없으면 stdin에서 읽음
```python
cmd = ["/home/jay/.local/bin/claude", "-p", "--output-format", "text", "--model", "sonnet"]
# ... (code_analysis 분기 등 기존 로직 유지)
proc = await asyncio.create_subprocess_exec(
    *cmd,
    stdin=asyncio.subprocess.PIPE,
    stdout=asyncio.subprocess.PIPE,
    stderr=asyncio.subprocess.PIPE,
    cwd=cwd,
    env=env,
)
stdout, stderr = await asyncio.wait_for(
    proc.communicate(input=prompt.encode("utf-8")), timeout=timeout
)
```

## 주의사항
- 기존 에러 핸들링(timeout, FileNotFoundError, auth 체크 등) 그대로 유지
- code_analysis 분기(`--allowedTools` 등) 그대로 유지
- shell=True 사용 금지 (보안)
- `call_gemini()`은 HTTP API 호출이므로 이 이슈 해당 없음 — 수정 불필요

## 추가 요구사항 3: call_codex() 모델 분기 기능

`call_codex()`에 `model` 파라미터를 추가하여 호출 시 모델을 선택할 수 있게 한다.

**기본값**: `gpt-5.2-codex`
**사용 가능 모델**: `gpt-5.2-codex` (깊은 토론), `gpt-5.1-codex-mini` (간단한 합의)

```python
async def call_codex(prompt: str, timeout: int = 600, model: str = "gpt-5.2-codex") -> str:
    cmd = ["codex", "exec", "-c", f'model="{model}"', "-"]
    ...
```

**호출부(codex_bot.py)도 model 파라미터를 전달받을 수 있도록 수정:**
- codex_bot.py의 `handle_codex_message()`에서 `call_codex(context_prompt, model=model)` 형태로 호출
- model 값은 외부에서 전달 (기본값 gpt-5.2-codex 유지)

## 추가 요구사항 4: 에러 메시지에 시스템 프롬프트 노출 방지

현재 에러 시 `stderr_text[-300:]`을 그대로 사용자에게 보여줘서 시스템 프롬프트가 노출된다.

**수정:**
- usage limit 에러 감지: stderr에 "usage limit" 또는 "hit your" 포함 시 → `"⚠️ Codex 사용량 한도 초과. 잠시 후 다시 시도해주세요."` 반환
- 그 외 에러: stderr에서 프롬프트 내용을 제거하고 마지막 에러 라인만 추출하여 반환
  - 예: `stderr_text.split('\n')` 후 "ERROR:" 또는 "error" 포함된 라인만 필터링

## 완료 후
- 문법 오류 없는지 python3 -c "import ast; ast.parse(open('engine.py').read())" 검증
- 변경 내용 보고
