# MoAI-ADK Phase 2 코드화 지시서

작성일: 2026-03-31
작성자: 페이토 (CRO 카피라이터 → 기술 지시서 역할)
대상 에이전트: 마아트, 헤르메스

---

## 파일 경로 맵 (WORKSPACE_ROOT = /home/jay/workspace)

| 지시서 표기 | 절대 경로 | 비고 |
|---|---|---|
| `qc_verify.py` | `/home/jay/workspace/teams/shared/qc/qc_verify.py` | 기존 파일 수정 (dev1 복사본: teams/dev1/qc/) |
| `team_prompts.py` | `/home/jay/workspace/prompts/team_prompts.py` | 기존 파일 수정 |
| `.claude/feature_flags.json` | `/home/jay/workspace/.claude/feature_flags.json` | Phase 0b에서 생성 완료 |
| `scripts/analyze_ab.py` | `/home/jay/workspace/scripts/analyze_ab.py` | [NEW] P2-3에서 생성 |
| `logs/ab_results.jsonl` | `/home/jay/workspace/logs/ab_results.jsonl` | [NEW] P2-3 데이터 수집 |
| `QC-RULES.md` | `/home/jay/workspace/teams/shared/QC-RULES.md` | 기존 파일 수정 |

---

## 개요

Phase 2는 MoAI-ADK 시스템의 품질 신뢰성과 모델 운영 효율을 높이는 3개 태스크로 구성된다.
Week 3~8에 걸쳐 순차·병렬 실행하며, 각 태스크는 독립 feature flag로 격리된다.

| 태스크 | 코드 | DRI | 기간 | 데드라인 |
|---|---|---|---|---|
| TRUST 5 태그 | P2-4 | 마아트 | Week 3 | 4/27 |
| 모델 매핑 테이블 | P2-5 | 헤르메스 | Week 4 | 5/4 |
| haiku 전용화 A/B | P2-3 | 마아트 | Week 4-8 | 5/31 |

---

## 선행 조건

- Phase 1 완료 확인 필수: P1-1, P1-2, P1-7 feature flag 모두 `ON` 상태
- 통합 테스트 INT-01 ~ INT-07 전체 통과
- 위 조건 미충족 시 Phase 2 착수 금지. 마아트·헤르메스 착수 전 상태 확인 후 보고

---

## Task 1: P2-4 TRUST 5 태그

**DRI:** 마아트
**수정 파일:** `qc_verify.py`
**데드라인:** 2026-04-27
**feature_flag:** `trust5_tagging_enabled`

### 구현 방법

`qc_verify.py`의 최종 결과 JSON에 `trust_summary` 키를 추가한다.
`trust_summary`는 TRUST 5차원 각각에 대해 연결된 verifier 목록과 통과/실패 상태를 담는다.

출력 JSON 스키마 예시:

```json
{
  "trust_summary": {
    "Tested":     { "verifiers": ["test_runner", "tdd_check"],          "passed": true  },
    "Readable":   { "verifiers": ["style_check", "pyright_check"],      "passed": true  },
    "Unified":    { "verifiers": ["scope_check"],                       "passed": false },
    "Secured":    { "verifiers": ["schema_contract"],                   "passed": true  },
    "Trackable":  { "verifiers": ["data_integrity", "file_check"],      "passed": true  },
    "_independent": { "verifiers": ["api_health"], "note": "TRUST 외 독립 실행" }
  }
}
```

### verifier → TRUST 5차원 매핑 테이블

| verifier | TRUST 차원 | 비고 |
|---|---|---|
| test_runner | Tested | |
| tdd_check | Tested | |
| style_check | Readable | |
| pyright_check | Readable | |
| scope_check | Unified | |
| schema_contract | Secured | |
| data_integrity | Trackable | |
| file_check | Trackable | |
| api_health | (독립) | TRUST 5 외, _independent 버킷 |

매핑 불일치율 기준: **<3%** (전체 실행 건 대비 매핑 오류 건수)

### 구현 세부 지침

1. `TRUST_MAP` 딕셔너리를 모듈 레벨 상수로 정의한다.
2. `feature_flag: trust5_tagging_enabled` 가 `False`이면 기존 결과 JSON을 그대로 반환한다 (하위 호환).
3. 각 차원의 `passed` 값은 해당 차원 내 모든 verifier가 통과한 경우에만 `true`로 설정한다.
4. `api_health`는 `_independent` 버킷에 별도 보관하며 TRUST 차원 점수에 영향을 주지 않는다.

### 테스트

```
tests/test_trust_tagging.py
```

- 9종 verifier 각각이 올바른 차원에 매핑되는지 단위 테스트
- `trust_summary` 키 존재 여부 및 스키마 유효성 검사
- `api_health`가 `_independent`에만 포함되는지 확인
- feature_flag `OFF` 시 기존 JSON 변경 없음 확인
- 매핑 불일치율 시뮬레이션: 100건 중 오류 ≤2건

### DoD (Definition of Done)

- [ ] `trust_summary` 키가 모든 qc_verify 결과 JSON에 포함됨
- [ ] TRUST_MAP 상수 정의 완료
- [ ] 매핑 불일치율 <3% 검증 통과
- [ ] feature_flag 토글 테스트 통과
- [ ] PR 리뷰 승인 + CI 그린

---

## Task 2: P2-5 모델 매핑 테이블

**DRI:** 헤르메스
**수정 파일:** `team_prompts.py`
**데드라인:** 2026-05-04
**feature_flag:** `model_map_enabled`

### MODEL_MAP 상수 정의

`team_prompts.py` 모듈 레벨에 다음 상수를 추가한다:

```python
MODEL_MAP = {
    "팀장":      {"default": "opus",   "설계": "opus"},
    "백엔드":    {"default": "sonnet", "아키텍처": "opus"},
    "프론트엔드": {"default": "sonnet"},
    "UX/UI":    {"default": "sonnet", "에셋생성": "haiku"},
    "테스터":    {"default": "haiku",  "테스트설계": "sonnet"},
    "QC":       {"default": "haiku"},
    "git":      {"default": "haiku"},
    "보안리뷰":  {"default": "opus"},
    "_updated": "2026-03-31",  # staleness 추적용 메타키
}
```

`_updated` 메타키는 마지막 수동 갱신 날짜를 ISO 8601 형식으로 기록한다.

### _build_cowork_section() 통합 방법

`_build_cowork_section()` 함수 내에서 `MODEL_MAP`을 순회하여 모델 가이드 텍스트를 자동 생성한다.

생성 규칙:
- 키 앞에 `_`가 붙은 항목(메타키)은 출력에서 제외한다
- `default` 외 추가 컨텍스트 키가 있으면 "역할 / 컨텍스트: 모델" 형식으로 병기한다
- 결과 텍스트 예시:

```
[모델 가이드]
- 팀장: opus (설계: opus)
- 백엔드: sonnet (아키텍처: opus)
- 프론트엔드: sonnet
- UX/UI: sonnet (에셋생성: haiku)
- 테스터: haiku (테스트설계: sonnet)
- QC: haiku
- git: haiku
- 보안리뷰: opus
```

### staleness 경고

- `_updated` 날짜와 현재 날짜 차이가 **7일 초과** 시 경고 로그를 출력한다.
- 경고 메시지 형식: `[WARNING] MODEL_MAP이 {n}일 경과했습니다. 최신 모델 정책을 확인하세요.`
- 경고는 로그에만 기록하며 실행을 중단하지 않는다.

### 테스트

```
tests/test_model_map.py
```

- `MODEL_MAP` 키 목록 및 필수 역할 존재 여부 단위 테스트
- `_build_cowork_section()` 출력 텍스트에 모든 역할이 포함되는지 확인
- 메타키(`_updated`, `_*`)가 출력 텍스트에 노출되지 않는지 확인
- staleness 7일 초과 시 경고 메시지 발생 확인
- staleness 7일 이하 시 경고 없음 확인
- feature_flag `OFF` 시 기존 `_build_cowork_section()` 동작 유지 확인

### DoD (Definition of Done)

- [ ] `MODEL_MAP` 상수 `team_prompts.py` 모듈 레벨에 정의 완료
- [ ] `_build_cowork_section()` 자동 생성 텍스트 검증 통과
- [ ] staleness 7일 경고 동작 확인
- [ ] feature_flag 토글 테스트 통과
- [ ] PR 리뷰 승인 + CI 그린

---

## Task 3: P2-3 haiku 전용화 A/B

**DRI:** 마아트
**데드라인:** 2026-05-31 (4주 A/B + 최대 1주 연장)
**feature_flag:** `haiku_ab_enabled`

### A/B 설계

| 구분 | 설명 |
|---|---|
| 실험군 (A) | QC 요청 50% → haiku |
| 대조군 (B) | QC 요청 50% → sonnet |
| 층화 추출 | 작업 레벨 Lv.1 / Lv.2 / Lv.3 별 균등 분배 |
| 재검증 | 주 1회 sonnet으로 실험군 20% 재검증 |
| 통계 기법 | Fisher's exact test |
| 유의 수준 | α = 0.05 |
| 최소 표본 | n > 150 (각 군) |

### 분기 구현 방법

1. `feature_flag: haiku_ab_enabled` 가 `True`일 때 A/B 로직 활성화.
2. 각 QC 요청 진입 시 작업 레벨(Lv.1/2/3)을 식별한다.
3. 레벨별 버킷 카운터를 기반으로 50:50 균등 배정 (층화 추출).
4. 배정 결과(`haiku` 또는 `sonnet`)를 요청 메타데이터에 기록한다.
5. 매주 월요일 00:00 KST 기준으로 실험군 요청의 20%를 sonnet으로 재검증 스케줄 등록.

```
# 의사 코드
def assign_model(task_level: str) -> str:
    if not feature_flags.get("haiku_ab_enabled"):
        return "sonnet"  # 기본값
    bucket = stratified_counter[task_level] % 2
    stratified_counter[task_level] += 1
    return "haiku" if bucket == 0 else "sonnet"
```

### 데이터 수집

수집 항목 (요청당 1행):

| 컬럼 | 설명 |
|---|---|
| `request_id` | 고유 요청 ID |
| `assigned_model` | haiku / sonnet |
| `task_level` | Lv.1 / Lv.2 / Lv.3 |
| `fnr` | False Negative Rate (0~1) |
| `is_recheck` | sonnet 재검증 여부 (bool) |
| `timestamp` | ISO 8601 |

저장 위치: `logs/ab_results.jsonl` (JSONL 형식, 1행 1레코드)

### 분석 스크립트

```
scripts/analyze_ab.py
```

- 입력: `logs/ab_results.jsonl`
- Fisher's exact test 수행 (실험군 vs 대조군 FNR 비교)
- 출력: p-value, 95% CI, 판정 결과
- 실행 방법: `python scripts/analyze_ab.py --input logs/ab_results.jsonl`

### 판정 기준

| 조건 | 판정 | 조치 |
|---|---|---|
| FNR < 15% AND p < 0.05 | **채택** | haiku 전용화 진행 (`haiku_ab_enabled` → 상시 ON) |
| FNR ≥ 15% OR p ≥ 0.05 | **기각** | sonnet 유지, 실험 종료 |
| n ≤ 150 (4주 경과) | **연장** | 최대 1주 추가 수집 후 재판정 |

### 테스트

```
tests/test_ab_split.py
tests/test_ab_analysis.py
```

- 층화 추출 균등 분배 검증 (Lv.1/2/3 각 레벨별 ±2% 오차 허용)
- feature_flag `OFF` 시 전량 sonnet 배정 확인
- `logs/ab_results.jsonl` 스키마 유효성 검사
- Fisher's exact test 계산 결과 검증 (목 데이터 사용)
- 판정 로직 단위 테스트 (채택/기각/연장 3가지 케이스)

### DoD (Definition of Done)

- [ ] 층화 50:50 분기 구현 완료
- [ ] 주 1회 20% sonnet 재검증 스케줄 등록 완료
- [ ] `logs/ab_results.jsonl` 수집 파이프라인 동작 확인
- [ ] `scripts/analyze_ab.py` Fisher's exact test 정상 실행 확인
- [ ] n > 150 도달 후 판정 로직 실행 확인
- [ ] feature_flag 토글 테스트 통과
- [ ] PR 리뷰 승인 + CI 그린

---

## P1 효과 측정

Phase 2 진입 시점에 P1(P1-1, P1-2, P1-7) 기준선 대비 변화를 아래 항목으로 비교한다.

### 비교 항목

| 측정 항목 | 기준선 (P1 완료 시점) | Phase 2 완료 후 |
|---|---|---|
| QC 전체 FNR | 기록 필요 | 측정 |
| 평균 QC 응답 시간 (ms) | 기록 필요 | 측정 |
| verifier 매핑 오류율 | - | <3% (P2-4 목표) |
| 모델 가이드 텍스트 자동화율 | 0% | 100% (P2-5 목표) |
| haiku 배정 비율 | 0% | 50% (A/B 기간) |

### 보고 형식

```
[Phase 2 효과 측정 보고]
기준선 측정일: YYYY-MM-DD
보고일: YYYY-MM-DD

1. QC FNR: {기준선} → {현재} ({+/-}변화율)
2. 평균 응답 시간: {기준선}ms → {현재}ms
3. verifier 매핑 오류율: {현재}% (목표 <3%)
4. 모델 가이드 자동화: {달성 여부}
5. A/B 판정 결과: {채택/기각/진행중}
```

보고 주기: 매주 금요일 EOD, 담당 DRI가 Slack #moai-report에 게시

---

## 킬 스위치

각 태스크는 독립 feature flag로 즉시 비활성화 가능하다.

| feature_flag | 태스크 | 비활성화 효과 |
|---|---|---|
| `trust5_tagging_enabled = False` | P2-4 | trust_summary 미생성, 기존 JSON 반환 |
| `model_map_enabled = False` | P2-5 | MODEL_MAP 미적용, 기존 코섹션 유지 |
| `haiku_ab_enabled = False` | P2-3 | 전량 sonnet 배정, A/B 수집 중단 |

긴급 킬 명령 (전체 Phase 2 비활성화):

```bash
# feature_flags.yaml 또는 환경변수 일괄 설정
trust5_tagging_enabled=false
model_map_enabled=false
haiku_ab_enabled=false
```

---

## 롤백 계획

1. **P2-4 롤백:** `trust5_tagging_enabled = False` 설정 → `qc_verify.py` 이전 커밋으로 revert (git tag: `pre-p2-4`)
2. **P2-5 롤백:** `model_map_enabled = False` 설정 → `team_prompts.py` 이전 커밋으로 revert (git tag: `pre-p2-5`)
3. **P2-3 롤백:** `haiku_ab_enabled = False` 설정 → `logs/ab_results.jsonl` 보존 후 분석 중단
4. 롤백 결정 권한: DRI 또는 프로젝트 리드
5. 롤백 후 post-mortem 작성 필수 (24시간 이내)

---

## 성공 기준

Phase 2 전체 성공 판정 조건 (3개 모두 충족 시):

| # | 조건 |
|---|---|
| 1 | P2-4: verifier → TRUST 5 매핑 불일치율 <3%, CI 그린 |
| 2 | P2-5: MODEL_MAP 기반 모델 가이드 텍스트 자동 생성, staleness 경고 동작 확인 |
| 3 | P2-3: Fisher's exact test FNR <15% 채택 OR 4+1주 내 n>150 도달 후 판정 완료 |

Phase 2 완료 기준일: **2026-05-31**
최종 성공 보고서 제출: 마아트 (P2-4, P2-3) + 헤르메스 (P2-5) → 페이토에게 취합 후 리드 보고
