# QA — ObesityTriangulate-Kor (2026-05-29)

## 검수 결과: PASS

### 1. AST parse 검증

모든 Python 파일이 syntax error 없이 parse됨.

| 파일 | 결과 |
|------|------|
| main.py | PASS |
| app.py | PASS |
| triangulation/__init__.py | PASS |
| triangulation/ontology.py | PASS |
| triangulation/grid.py | PASS |
| triangulation/lawlor.py | PASS |
| triangulation/mvmr.py | PASS |
| triangulation/mediation.py | PASS |
| triangulation/bias.py | PASS |
| triangulation/designs.py | PASS |
| triangulation/report.py | PASS |

### 2. 데이터 로드 검증

```
effect rows: 52        (목표 ≥30 ✓)
interventions: 15      (목표 10+ ✓)
outcomes: 32           (목표 25+ ✓)
IARC obesity-related cancers: 13   (목표 12 ✓ — 12 IARC + 1 thyroid_MTC context)
unique (intervention, outcome) pairs: 20
designs used: ['BMI_MR', 'DIO_animal', 'RCT', 'bariatric_natural', 'multivariable_MR', 'observational', 'within_subject_crossover']   (6+1 designs ✓)
```

### 3. CLI 실행 검증

| 명령 | 결과 |
|------|------|
| `python3 main.py --help` | PASS (argparse 정상 출력) |
| `python3 main.py --summary` | PASS |
| `python3 main.py --grid` | PASS (20 pairs ranked by concordance) |
| `python3 main.py --pair "semaglutide" "CV death"` | PASS (concordance=0.878, Lawlor=8.33/10) |
| `python3 main.py --mediation "semaglutide" "CV death"` | PASS (curated 70% mediated, product method) |
| `python3 main.py --mvmr "bariatric_RYGB" "obesity_related_cancer_IARC12"` | PASS (BMI/WHR/BF% conditional 분리) |
| `python3 main.py --designs "tirzepatide" "sarcopenia"` | PASS (4 cards 추천, factorial 포함) |
| `python3 main.py --discordant --top 5` | PASS (IF×CV, lifestyle, thyroid 등 진단) |
| `python3 main.py --pair "semaglutide" "CV death" --report /tmp/r.md` | PASS (9.5KB markdown 저장) |
| `python3 main.py --pair "semaglutide" "CV death" --report /tmp/r.json` | PASS (JSON 직렬화) |

### 4. 디스클레이머 검증

| 파일 | 디스클레이머 키워드 ("임상의사결정") |
|------|----|
| README.md | ✓ 맨 위 |
| app.py | ✓ st.warning() |
| main.py | ✓ DISCLAIMER_SHORT 모든 명령 출력 |
| triangulation/report.py | ✓ 모든 리포트 상단 |

### 5. 의존성 fallback 검증

- streamlit 미설치 시 main.py 작동 ✓ (sys.path 명시적 추가, streamlit import는 app.py에만)
- statsmodels 미설치 시 MVMR 작동 ✓ (numpy 없이 manual 3x3 matrix inverse)
- python-docx 미설치 시 markdown fallback ✓ (report.to_docx)
- plotly 미설치 시 Streamlit st.bar_chart / st.dataframe로 fallback ✓
- pandas만 필요 (Streamlit이 어차피 요구)

### 6. 핵심 기능 5개 매핑

| 요구 기능 | 구현 위치 | 상태 |
|----------|----------|------|
| 1. 6-design ingest + 온톨로지 (10 iv × 25+ outcome, IARC 12) | data/* + triangulation/ontology.py | ✓ 52 rows, 15 iv, 32 outcomes, 13 IARC |
| 2. 6-design grid + MVMR + mediation | grid.py, mvmr.py, mediation.py | ✓ concordance, Lawlor, product+difference methods |
| 3. discordance bias 진단 + bariatric IV | bias.py | ✓ taxonomy 7×N, preference-IV 2SLS |
| 4. 8 design 카드 | designs.py | ✓ 8 templates, 우선순위 기반 추천 |
| 5. 리포트 (HTA/규제/KASMBS/OpenClaw) | report.py | ✓ docx/md/json export |

### 7. Streamlit app 구조

7개 탭: Grid / Pair Detail / Mediation / MVMR / Discordance / Designs / Report
사이드바: outcome 카테고리 필터, intervention 필터, CSV 업로드.
디스클레이머: st.warning 상단 고정.

### 8. 알려진 한계

- 효과 추정치는 데모 큐레이션 (일부 source_url은 placeholder)
- statsmodels 없이는 MVMR-Egger / MR-PRESSO 등 advanced sensitivity 불가
- python-docx 미설치 환경에서는 markdown fallback (docx 직접 export 불가)
- intermittent_fasting × CV death 같은 emerging area는 outcome 정의가 unstable

## 재현

```bash
cd "/Users/sangjoonpark/claude daily project/2026 metabolic daily idea/projects/2026-05-29-2-obesity-triangulate-kor"
python3 main.py --summary
python3 main.py --grid
python3 main.py --pair "semaglutide" "CV death"
python3 main.py --mediation "semaglutide" "CV death"
python3 main.py --discordant --top 5

# Streamlit (optional)
pip install streamlit pandas
streamlit run app.py
```
