# task-682.1 완료 보고서: ThreadAuto 파이프라인 리팩토링 (5→2단계)

## SCQA

**S**: ThreadAuto 콘텐츠 파이프라인이 5단계(angle→structure→writing→hooking→review)로 운영 중이며, review 0점 반복, JSON 파싱 실패, pipeline hang 문제가 발생하고 있다.

**C**: 에이전트 미팅에서 5단계 과잉, review 점수제 폐기, 6→3타입 축소, 규칙 기반 검증으로 전환이 만장일치 합의되었으나, 구현체가 없는 상태였다.

**Q**: 2단계(generate→validate) 파이프라인으로 전환하여 LLM 호출을 1회로 줄이고, 규칙 기반 검증으로 안정성을 확보할 수 있는가?

**A**: `two_stage_pipeline.py` + `validate_rules.py` + `whitelist_config.py` 3개 모듈을 신규 생성하고 `pipeline.py`에 "2stage" 모드를 추가 완료. pytest 73건 전체 통과, pyright 0 errors. LLM 호출 1회 + 순수 코드 검증으로 기존 5회 호출 대비 80% 호출 절감. 일일 50회 hard cap, drop+알림, 이중 게시 트랙 등 안전장치 구현 완료.

---

## 생성/수정 파일

### 신규 생성 (3개)
- `/home/jay/projects/ThreadAuto/content/whitelist_config.py` — 화이트리스트 29+2개, 검증 상수, 안전장치 설정
- `/home/jay/projects/ThreadAuto/content/validate_rules.py` — 규칙 기반 검증 모듈 (LLM 호출 없음)
- `/home/jay/projects/ThreadAuto/tests/test_two_stage_pipeline.py` — TDD 테스트 73건

### 수정 (1개)
- `/home/jay/projects/ThreadAuto/content/pipeline.py` — "2stage" 파이프라인 모드 추가

### 보존 (변경 없음)
- `/home/jay/projects/ThreadAuto/content/five_stage_pipeline.py` — 기존 파이프라인 보존

---

## 구현 상세

### 1. 파이프라인 구조: 5→2단계
- **generate**: 타입별(empathy/insight/cardnews) 통합 프롬프트 1회 LLM 호출
- **validate**: 순수 코드 기반 pass/fail (JSON 스키마, 글자수, 금칙어, 구조 체크)
- fail 시 1회 재생성 → 재실패 시 drop + Telegram 알림

### 2. 콘텐츠 타입: 6→3종
- empathy (공감), insight (인사이트), cardnews (카드뉴스)
- 확장 구조: `GENERATE_SYSTEM_PROMPTS` dict에 프롬프트 추가 + `validate_rules`에 규칙 추가

### 3. 안전장치
- `ContentDroppedError`: 재생성 실패 시 drop + Telegram 알림 (사일런트 실패 방지)
- `DailyLimitExceededError`: 일일 50회 hard cap 초과 시 즉시 중단
- 로깅: 생성시간, pass/fail, 재생성 여부, drop 사유 기록
- CLI 타임아웃 600초 + 재시도 1회

### 4. 게시 이중 트랙
- `is_auto_publish()`: AUTO_PUBLISH_WHITELIST(29개) → 자동 게시
- CONDITIONAL_WHITELIST(eg-112, eg-120): 수치 언급 없을 때만 자동 게시
- 그 외 → 검수 트랙 (Telegram 미리보기 + 승인)
- 화이트리스트 하드코딩 (LLM 분류 금지)

### 5. 검증 규칙 (validate_rules.py)
- JSON 스키마: 필수 필드 존재 + 타입 체크
- 글자수: 텍스트 100~300자, 슬라이드 30~80자
- 금칙어: "보장합니다", "확실히", "무조건", "최대", "최소"
- 구조: 첫 줄 15자 이내, 마지막 줄 CTA 키워드 존재

---

## 테스트 결과

### test_two_stage_pipeline.py: 73 passed, 0 failed
- TestWhitelistConfig: 10건 통과
- TestValidateRules: 14건 통과
- TestTwoStagePipelineInit: 2건 통과
- TestTwoStagePipelineGenerate: 8건 통과
- TestCallClaude: 7건 통과
- TestParseJsonResponse: 8건 통과
- TestAutoPublish: 8건 통과 (parametrize 포함)
- TestCheckForbiddenWords: 16건 통과 (parametrize 포함)

### pyright: 0 errors, 0 warnings
- 4개 파일 모두 타입 체크 통과

### black + isort: 포맷 준수

---

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **카드뉴스 슬라이드 str 타입 미지원** — validate_rules가 dict만 처리하여 str 슬라이드 실패 → str/dict 모두 지원하도록 수정 (validate_rules.py:177-187)
2. **check_conditional_whitelist 비조건부 토픽 반환값 오류** — 조건부 목록에 없는 토픽에 False 반환 → True 반환으로 수정 (validate_rules.py:63)
3. **_check_daily_limit 테스트 mock 불일치** — 직접 인스턴스 변수 참조 → get_daily_call_count() 메서드 사용으로 수정 (two_stage_pipeline.py:401-405)

### 범위 외 미해결 (2건)
1. **기존 test_five_stage_pipeline.py 2건 실패** — 범위 외 사유: 이전 작업에서 `five_stage_pipeline.py`의 MAX_FULL_RETRIES(1→2), timeout(120→600) 변경 시 테스트 미갱신. 본 작업에서 five_stage_pipeline.py를 수정하지 않았으므로 수정 범위 외.
   - `test_max_retries_constants`: MAX_FULL_RETRIES=2 vs 테스트 기대값 1
   - `test_call_claude_timeout`: timeout=600 vs 테스트 기대값 120
2. **⚠️ 기존 테스트 실패 1건 (본 작업 범위 외)**: `test_cta_linebreak.py::TestFactDbContainsBusinessPage::test_fact_db_contains_business_page` — fact_db.md에 '사업단 페이지' 표기 부재 관련. 본 작업과 무관.

---

## QC 셀프 체크리스트

- [x] 1. 다른 파일 영향: pipeline.py에 2stage 분기 추가 (기존 로직 변경 없음)
- [x] 2. 엣지 케이스: 빈 content, 잘못된 content_type, 일일 상한 초과, 조건부 화이트리스트
- [x] 3. 작업 지시 일치: 5→2단계, 6→3타입, 안전장치, 이중 트랙, CLI 유지 모두 구현
- [x] 4. 에러 처리: ContentDroppedError, DailyLimitExceededError, CLI timeout/retry
- [x] 5. 테스트 커버리지: 73건 (init, generate, validate, CLI, JSON parse, auto-publish, forbidden words)
- [x] 6. 이슈 해결: 3건 자체 해결, 1건 범위 외 명시
