# task-611.1 완료 보고서 (SCQA)

**작성**: 라(Ra, dev3-team장) | **일시**: 2026-03-16 10:05

---

## S — Situation

`/home/jay/workspace/services/multimodel-bot/engine.py`의 `call_codex()`와 `call_claude()` 함수가 LLM 프롬프트를 CLI 인자로 직접 전달하는 구조로 구현되어 있었다.

## C — Complication

장시간 토론(50분+) 후 누적된 컨텍스트가 OS의 ARG_MAX 제한(~2MB)을 초과하여 `[Errno 7] Argument list too long` 에러가 발생한다. CLI 인자 방식으로는 이 한계를 구조적으로 우회할 수 없다.

## Q — Question

`call_codex()`와 `call_claude()`를 stdin 방식으로 전환하여 ARG_MAX 한계를 제거하되, 기존 에러 핸들링(timeout, FileNotFoundError, auth 체크, code_analysis 분기)을 그대로 유지할 수 있는가?

## A — Answer

두 함수를 모두 stdin 전달 방식으로 수정 완료. `proc.communicate(input=prompt.encode("utf-8"))`로 프롬프트를 전달하여 CLI 인자 길이 제한을 완전히 우회. pyright 에러 0건(engine.py), black/isort 통과, pytest 27/27 통과.

---

## 수정 내용

### 1. call_codex() (engine.py:144~183)

| 항목 | 변경 전 | 변경 후 |
|------|---------|---------|
| cmd 마지막 인자 | `prompt` | `"-"` (stdin 플래그) |
| stdin | 없음 | `asyncio.subprocess.PIPE` |
| communicate | `proc.communicate()` | `proc.communicate(input=prompt.encode("utf-8"))` |

### 2. call_claude() (engine.py:191~228)

| 항목 | 변경 전 | 변경 후 |
|------|---------|---------|
| cmd | `[..., "-p", prompt, ...]` | `[..., "-p", ...]` (prompt 제거) |
| stdin | 없음 | `asyncio.subprocess.PIPE` |
| communicate | `proc.communicate()` | `proc.communicate(input=prompt.encode("utf-8"))` |

### 3. call_gemini() — 수정 없음
HTTP API 호출 방식이므로 ARG_MAX 이슈 미해당.

---

## 발견 이슈 및 해결

### 자체 해결 (3건)

1. **`_make_mock_process` helper `input=` 처리 불가** — `async def _communicate()` → `AsyncMock(return_value=...)`로 교체
   - 상세: `test_engine.py:18-31` 수정. `proc.communicate(input=...)` 호출 시 `TypeError` 발생하던 문제 해결. 영향 범위: TestCallCodex 6건, TestCallClaude 1건 = 총 7개 테스트

2. **`_make_timeout_process` 동일 문제** — `async def _communicate()` → `AsyncMock(side_effect=asyncio.TimeoutError())`로 교체
   - 상세: `test_engine.py:35-46` 수정

3. **`test_call_codex_passes_prompt_to_subprocess` 어설션 오류** — "prompt가 CLI args에 있어야 함" → "prompt가 CLI args에 없어야 하고 stdin으로 전달되어야 함"으로 수정
   - 상세: `test_engine.py:431-445`. 기존 assertion: `assert "함수 작성해줘" in all_args` (구 방식 검증) → 신규: `assert "함수 작성해줘" not in all_args` + `assert "-" in all_args` + `mock_proc.communicate.assert_called_once_with(input=...)`

<details>
<summary>상세 수정 내역 (클릭하여 펼치기)</summary>

#### 이슈 1+2: _communicate() keyword argument 오류
- 발견 경위: `pytest tests/test_engine.py` 실행 시 7개 실패 확인
- 원인: `_communicate()`가 `**kwargs` 없이 `proc.communicate(input=...)` 호출을 받으려 함
- 수정: `AsyncMock`으로 교체하면 `input=` 키워드 인자 자동 처리, call 기록도 가능
- 검증: 7개 실패 → 0개

#### 이슈 3: stdin 전환 후 test assertion 불일치
- 발견 경위: `test_call_codex_passes_prompt_to_subprocess` FAILED
- 원인: 구 방식(CLI args에 prompt) 검증 코드가 신 방식(stdin) 구현과 불일치
- 수정: stdin 전달 방식에 맞게 3개 assertion으로 재작성
- 검증: PASS 확인

</details>

---

## 검증 결과

| 항목 | 결과 | 증거 |
|------|------|------|
| Python 문법 | PASS | `ast.parse()` 오류 없음 |
| black 포맷 | PASS | `black --check`: 2 files unchanged |
| isort | PASS | 이상 없음 |
| pyright (engine.py) | 0 errors | `pyright engine.py`: 0 errors, 0 warnings |
| pytest (test_engine.py) | 27/27 PASS | 0.37s |
| pytest (전체 서비스) | 248/248 PASS | 0.87s |
| 기존 테스트 회귀 | 없음 | scripts/tests: 827 PASS |

⚠️ 기존 테스트 실패 3건 (본 작업 범위 외):
- `tests/test_group_chat.py::TestLoadPersonas::test_org_loads_expected_count`
- `tests/test_group_chat.py::TestLoadPersonasFromOrg::test_parses_centers`
- `tests/test_group_chat.py::TestLoadPersonasFromOrg::test_excludes_planned_teams`
→ `test_group_chat.py`는 변경된 파일 목록에 없음. organization-structure.json 변경에 의한 기존 회귀로 추정. 본 작업 범위 외.

---

## QC 자동 검증 결과

```json
{
  "task_id": "task-611.1",
  "overall": "FAIL (file_check: events/.done 미생성, finish-task.sh 이후 PASS 예정)",
  "summary": "5 PASS, 1 FAIL, 3 SKIP, 1 WARN",
  "test_runner": "PASS (248 passed)",
  "style_check": "PASS (black+isort OK)",
  "tdd_check": "PASS",
  "pyright_check": "WARN (test_engine.py: 28건 reportMissingImports — sys.path.insert 패턴 기존 이슈, engine.py 자체는 0건)",
  "data_integrity": "PASS"
}
```

---

## 생성/수정 파일

- `services/multimodel-bot/engine.py` — call_codex/call_claude stdin 전환
- `services/multimodel-bot/tests/test_engine.py` — mock helper 수정, stdin 어설션 업데이트
