# MoAI-ADK 도입 맥락노트

> **목적**: 왜 이 순서인지, 왜 이 방법인지, 미팅에서 나온 근거를 기록한다.
> 추측이 아닌 실제 미팅 발언과 합의 내용만 기록한다.
> 소스: task-1285.1-meeting-cycle1.md ~ cycle10.md (2026-03-31 완료)

---

## 1. 배경: 왜 MoAI-ADK를 분석했는가

MoAI 시스템 운영 중 누적된 3가지 문제를 해결하기 위해 10개 도입 항목을 선별했다.

1. **토큰 낭비**: 작업 난이도와 무관하게 항상 full 프롬프트를 로딩 → 단순 작업에도 ~3,000토큰 소비
2. **안전성 부재**: 읽기/쓰기 에이전트가 구분 없이 worktree에 접근 → 읽기 전용 작업이 메인 트리를 오염할 위험
3. **QC 사각지대**: 코드 수정 후 pyright/ruff 검증이 수동 또는 미실행 → 결함이 QC를 통과하는 사례 발생

이 3가지는 Cycle 1 논의의 전제였으며, 모든 우선순위 판단의 기준이 되었다.
(Cycle 1에서 로키가 "비용 절감과 품질 향상을 동시에 달성하는 유일한 항목"이라고 hooks P1 상향 근거를 설명할 때 명시된 문제의식)

---

## 2. 우선순위 결정 근거 (P1/P2/P3/P4 분류 이유)

### P1 최종 3건: (1) Progressive Disclosure, (2) 읽기/쓰기 격리, (7) hooks 자동 강제

**초기 제안 vs 최종 결정 차이:**

| 항목 | 초기 제안 | 최종 | 변경 근거 |
|---|---|---|---|
| (3) haiku 전용화 | P1 | P2 | Cycle 1. 로키+프로메테우스: "P1에 넣기엔 A/B 검증 기간(4주)이 필요하다. 단기 투입 불가." |
| (7) hooks 자동 강제 | P2 후보 | P1 | Cycle 1. 로키: "비용 절감과 품질 향상을 동시에 달성하는 유일한 항목." 헤르메스+오딘 동의 후 P1 상향 |

**P1 선발 기준 (Cycle 10 프로메테우스 3 Whys):**
- P1 = 일상 운영에 즉시 영향 (토큰 절감 + 안전성)
- P2 = 품질 개선 (QC 강화, 시간 필요)
- P3 = 코드 수정 없이 사전 설계만 (Cycle 5에서 "준비 항목(Ready Queue)"으로 정의)
- P4 = 외부 의존(ADK 로드맵) 또는 P1/P2 효과 검증 후 의미 있는 항목

### P4 하향 항목들

| 항목 | 하향 근거 | 재논의 트리거 |
|---|---|---|
| (6) @MX 태그 | Cycle 1. 헤르메스·오딘·로키 3명 동시 제안: "자연어 분류 불가능 + 메인 트리 오염 위험". 3인 합의. | (7)hooks 4주 운영 데이터 확보 후 |
| (8) Context Search | Cycle 1. Google ADK 네이티브 기능 대기. 자체 구현 시 중복 | ADK 네이티브 기능 릴리즈 후 |
| (9) Agent Teams API | Cycle 1. Google ADK 로드맵 의존. API 안정화 전 구현 불가 | API 90%+ 커버 후 |
| (10) Task 파일 구조 자동 생성 | P3/P4 병행. P3는 네이밍 규칙만. P4는 구조 자동 생성 | P3 완료 후 |

### P3 상향: (10) Task 파일 표준화

Cycle 5에서 로키가 "P3을 채울 이유 없다"며 반대했으나, 프로메테우스가 타협안 제시.
- "코드 수정 없이 사전 설계만" 조건 충족 시 P3 진입 허용
- 네이밍 규칙(P3)과 구조 자동 생성(P4)을 분리하여 합의 달성

---

## 3. 핵심 설계 결정과 근거

### 3.1 Progressive Disclosure 3단계 (summary/standard/full)

**결정 내용:**
- `build_prompt(disclosure_phase: str = "full", ...)` 파라미터로 3단계 제어
- Cycle 4에서 파라미터명 확정: 로키가 "disclosure_phase 비직관적"이라 지적 → `prompt_detail: Literal["brief", "normal", "verbose"]`로 수정 제안했으나, Cycle 9 오딘이 코드 예시에서 `disclosure_phase` 명칭 사용하여 최종 확정
- summary 모드: 상한 600토큰, full 대비 15~25%
- standard 모드: 상한 1,800토큰, full 대비 40~60%
- full 모드: 상한 없음 (~3,000), 기존 대비 delta < 5%

**Phase A만 P1 한정 근거 (Cycle 2 로키 지적):**
- 로키: "Phase C(동적 모드 전환) 기술 실현 가능성이 미검증"
- 합의: Phase A(3단계 구조 구현)만 P1. Phase C는 Phase A 운영 후 데이터 기반으로 재논의

**비율 검증 방식 채택 근거 (Cycle 8 로키 지적):**
- 원안: 절대 토큰 수로 검증
- 로키: "빌드 환경/팀별 토큰 수가 달라서 절대값 고정은 의미 없다"
- 수정: full 대비 비율로 검증 (summary: 15~25%, standard: 40~60%)

### 3.2 hooks auto-fix 영구 비활성화

**결정**: PostToolUse hooks에서 pyright+ruff 실행. auto-fix 옵션 영구 비활성화.

**3 Whys 검증 결과 (Cycle 2):**
1. auto-fix가 에이전트 모르게 코드를 변경한다
2. 에이전트가 변경되지 않은 코드를 기준으로 판단하게 된다
3. 잘못된 전제 위에 작성된 보고서가 QC를 통과할 수 있다

→ "에이전트 판단 근거 오염"이 핵심 위험. auto-fix는 편의 기능이 아니라 판단 오염 경로.

**hooks 실패 시 심각도 2단계 (Cycle 4):**
- critical (exit 2): 작업 중단
- standard (exit 1): 경고 + 계속
- 최대 재시도: 2회 (Cycle 2에서 3회로 제안, Cycle 4에서 2회로 수정)

**circuit breaker 판정 키: `(tool, error_code, file_path)` 3-튜플 (Cycle 9):**
- 기각된 대안들: 에러 메시지 전체 해시(라인번호 변화로 같은 에러를 다르게 판정), 에러 타입만(다른 파일의 동일 코드를 같다고 판정), 라인번호 포함 4-튜플(코드 수정 시 라인 이동으로 우회)
- 채택 근거: pyright(`reportXxx`)와 ruff(`EXXX`/`FXXX`) 에러 코드 체계가 달라 `tool` 구분 필수 (Cycle 9 로키 지적)
- 연속 3회 동일 키 = halt, warning=15회, critical=30회

### 3.3 TRUST 5 태그 방식

**결정**: QC-RULES.md 본문 구조는 변경하지 않고, `qc_verify.py`의 `build_result()` 출력에 `trust_summary` JSON 필드만 추가.

**"분류 연극" 비판과 해소 (Cycle 3 로키):**
- 로키: "TRUST 5 차원(Tested/Readable/Unified/Secured/Trackable)으로 QC-RULES.md 전체를 재구조화하면 기존 verifier 로직 전부 재작성. 이건 QC 개선이 아니라 분류 연극."
- 프로메테우스 타협안: "문서 구조 변경 없이 출력 태그만 추가. verifier 9종과 TRUST 5차원 매핑 테이블만 작성."
- 채택 근거: 기존 QC 로직 보존 + 외부 집계 시 TRUST 5 차원으로 분류 가능

**매핑 불일치율 기준**: 3% 미만 (Cycle 8 DoD에 포함)

### 3.4 haiku 전용화 A/B 테스트

**대상 확정 (Cycle 3):**
- 적용: 테스터 서브에이전트 + QC 위임 Task tool의 model 파라미터
- 제외: 팀장 Opus 자체, qc_verify.py verifier (팀장은 고급 판단 필요, verifier는 일관성 필요)

**층화 추출 채택 근거 (Cycle 3):**
- 원안: 홀짝 배분
- 로키: "홀짝은 작업 난이도 편향 발생. 어려운 작업이 한 그룹에 몰릴 수 있다."
- 수정: 작업 레벨 기반 층화 추출 (각 레벨에서 50:50 배분)

**Fisher's exact test 채택 근거 (Cycle 9):**
- 기각된 대안들: t-test (연속 변수용, FNR 비율에 부적합), chi-squared (n~150 수준에서 기대 빈도 5 미만 셀 발생 가능)
- 채택 근거: 소표본(n~150)에서 정확한 p-value 계산. 2x2 분할표(haiku/sonnet × FN/TN) 직접 확률 계산
- 검정 설계: α=0.05, power≥0.80, n>150 (그룹당 75건)
- 원안 n>100에서 n>150으로 상향 이유: sonnet FNR=5%, haiku FNR=20%(15%p 차이) 탐지에 그룹당 75건 필요. n>100(그룹당 50건)으로는 검정력 0.60 수준

**sonnet FNR 기준선 추가 (Cycle 9 로키 지적):**
- "QC 패스율 72%는 FNR이 아니다. FNR 측정에는 gold standard(인간 리뷰)가 필요하다."
- 수정: Week 0 기준선 측정에 "최근 30건 QC PASS 산출물을 인간/opus 재검증" 항목 추가

### 3.5 기준선 Phase 0a/0b 분리

**결정 (Cycle 10 로키 최약 고리 #1 대응):**
- Phase 0a (4/1~4/3): 기준선 측정 전용. **CODE FREEZE**. DRI: 마아트
- Phase 0b (4/4~4/6): feature_flags.json 구현. DRI: 헤르메스

**분리 근거:**
- 로키: "기준선 측정 중에 코드가 변경되면 '기준선'이 아니라 '과도기 측정'이 된다. Week 0에서 feature_flags.json 구현이 시작되는데, 기준선 측정과 겹치면 이후 모든 효과 측정이 왜곡된 기준선에 의존하게 된다." (확률 40%, 영향 심각)
- 안전장치 추가: 기준선 완료 후 `git tag baseline-v1`. 이 태그 시점이 기준선의 코드 상태.
- 로키 조건부 찬성 조건 (1): "code freeze 위반 시 즉시 기준선 재측정을 트리거해야 한다."

---

## 4. 로키(DA) 핵심 지적 아카이브

로키의 반대/수정 요청이 계획을 실질적으로 보강한 사례만 기록한다.

| Cycle | 지적 내용 | 결과 |
|---|---|---|
| 1 | haiku는 P1 불가. A/B 검증 시간(4주) 필요 | haiku P2 하향, hooks P1 상향 |
| 1 | @MX 태그: 자연어 분류 불가능 + auto 모드 제거 필요 | P4 하향, auto 모드 제거 합의 |
| 2 | Phase C(동적 전환) 기술 실현 가능성 미검증 | Phase A만 P1 한정 |
| 2 | auto-fix: 3 Whys → 에이전트 판단 근거 오염 | auto-fix 영구 비활성화 |
| 3 | TRUST 5 재구조화는 "분류 연극" | 출력 태그만 추가, 문서 구조 유지 |
| 3 | MODEL_MAP은 runtime 자동 적용 안 됨, 프롬프트 텍스트 생성 시만 참조 | 오해 방지를 위해 주석 추가 합의 |
| 3 | 홀짝 배분: 작업 난이도 편향 | 층화 추출로 변경 |
| 4 | disclosure_phase 비직관적 | prompt_detail 명칭으로 수정 제안 (최종은 disclosure_phase 유지) |
| 4 | 효과 측정: "추정치가 아닌 실측" 2주 필수 | Phase 0 실측 2주 필수 확정 |
| 5 | "P3을 채울 이유 없다" | Task 파일 표준화 P3 상향 (타협안으로 통과) |
| 6 | (1)프롬프트 줄이고 (8)컨텍스트 늘리는 모순 | "프롬프트 토큰 버짓" 개념으로 해소 |
| 7 | 환경변수 킬 스위치: git 추적 불가 | feature_flags.json으로 대체 |
| 8 | 토큰 수 절대값 고정 의미 없다 | full 대비 비율 검증으로 변경 |
| 8 | hooks 회귀 기준: "산출물 diff=0"은 틀림 | "기능적 정확성"으로 변경 |
| 9 | feature_flags.json 쓰기 중 읽기 시 불완전 JSON 파싱 위험 | atomic write (.tmp + os.rename()) + JSONDecodeError 시 이전 캐시 유지 |
| 9 | circuit breaker 에러 코드: pyright와 ruff 체계가 다름 | (tool, error_code, file_path) 3-튜플로 확장 |
| 9 | sonnet FNR = 5% 가정이 검증되지 않음 | Week 0 기준선에 FNR 추정(30건 재검증) 추가 |
| 10 | 기준선 측정이 전체 프로젝트의 SPOF | Phase 0a/0b 분리, code freeze, git tag |
| 10 | 8주 타임라인에 버퍼 없음 | P2-5 Week 3→4 이동, Week 2 금 버퍼일 삽입 |
| 10 | "사람이 빠져 있다" - 에이전트가 10사이클 합의를 어떻게 이해하나 | 항목별 1-page 구현 스펙 문서(/memory/specs/adk-impl-spec-{#}.md) |

---

## 5. 기각된 대안들

| 항목 | 기각된 대안 | 기각 이유 | Cycle |
|---|---|---|---|
| 통계 검정 | t-test | FNR은 비율(이항), 연속 변수용 t-test 부적합 | 9 |
| 통계 검정 | chi-squared | n~150에서 기대 빈도 5 미만 셀 발생 가능 | 9 |
| 배분 방식 | 홀짝 배분 | 작업 난이도 편향. 어려운 작업이 한 그룹에 몰릴 수 있음 | 3 |
| TRUST 5 | QC-RULES.md 전체 재구조화 | 기존 verifier 9종 전부 재작성 필요. "분류 연극" | 3 |
| 킬 스위치 | 환경변수 | git 추적 불가. 변경 이력 관리 불가 | 7 |
| circuit breaker | 에러 메시지 전체 해시 | 라인번호 1줄 변경으로 다른 해시. 같은 에러 미탐지 | 9 |
| circuit breaker | 에러 타입만 | 다른 파일의 동일 에러 코드를 같은 에러로 오인 | 9 |
| circuit breaker | (error_code, file_path, line_number) | 코드 수정 시 라인번호 이동으로 같은 에러가 다른 키가 됨 | 9 |
| 표본 크기 | n>100 | 검정력 0.60 수준. 15%p 차이 탐지 불충분 | 9 |
| 기간 | 8주→10주 확장 | 기간 연장은 집중력 저하 + 스코프 크리프 위험 | 10 |
| @MX auto 모드 | 자연어 분류 | 분류 불가능 + 메인 트리 오염 위험 | 2 |
| hooks | auto-fix 활성화 | 에이전트 모르게 코드 변경 → 판단 근거 오염 | 2 |
| hooks 재시도 | 3회 | Cycle 4에서 2회로 수정 (과도한 재시도) | 2→4 |

---

## 6. 미래 참조 사항

### 6.1 P4 재논의 트리거 조건 (Cycle 5 합의)

| 항목 | 재논의 트리거 조건 |
|---|---|
| (6) @MX 태그 | (7) hooks 4주 운영 데이터 확보 후 |
| (8) Context Search | Google ADK 네이티브 기능 릴리즈 후 |
| (9) Agent Teams API | Google ADK API 90%+ 커버 후 |
| (10) 구조 자동 생성 | P3 네이밍 규칙 완료 후 |

### 6.2 로키 조건부 찬성 2가지 조건 (Cycle 10)

구현 단계에서 반드시 적용해야 할 조건:

1. **code freeze 위반 시 기준선 재측정**: Phase 0a(4/1~4/3) 기간 중 어떠한 코드 변경도 기준선을 무효화. 위반 발생 시 즉시 재측정 트리거.
2. **스펙 대비 구현 차이 20% 초과 시 재설계 강제**: 1-page 구현 스펙 문서 대비 실제 구현이 20%를 초과하여 이탈하면 재설계. "형식적 문서"로 전락 방지.

### 6.3 "2주 실측" → "6일 Phase 0" 축소 근거

Cycle 4에서 로키가 "효과 측정: 추정치가 아닌 실측 2주 필수"를 주장했고, 이는 합의되었다. 그러나 Cycle 10에서 타임라인 최종 확정 시, "2주 실측"은 "2주에 걸쳐 데이터를 수집"하는 것이 아니라 "기존 운영 데이터를 활용한 기준선 스냅샷"으로 재정의되었다.

축소 근거 (Cycle 10 프로메테우스 발언):
- 기준선 측정은 **이미 축적된 데이터**(task-timers.json, qc_verify 로그, 보고서)를 분석하는 것이지, 새로운 데이터를 2주간 수집하는 것이 아님
- 3일이면 QC 패스율/FNR/토큰 수/worktree 성공률을 기존 로그에서 추출 + 30건 FNR 재검증 가능
- 나머지 3일(Phase 0b)은 feature_flags 인프라 + 스펙 문서 작성

**단, "2주 실측 필수" 원칙은 A/B 테스트(P2-3)에 적용된다**: haiku vs sonnet A/B는 4주(+1주 연장) 실측 기간으로 원칙 준수.

### 6.4 구현 스펙 문서 위치

`/memory/specs/adk-impl-spec-{항목번호}.md`

각 문서에 포함해야 할 7가지 항목:
1. 목표 (1줄)
2. 수정 파일 목록
3. 핵심 로직 (pseudo-code)
4. feature_flag 이름
5. 단위 테스트 목록
6. DoD 체크리스트
7. 참조: 미팅 문서 해당 섹션 경로

### 6.4b 효과 측정 기준

| 지표 | 기준선 대비 경고 임계 | 비고 |
|---|---|---|
| QC 패스율 | 20%p 이상 하락 | 자동 알림 트리거 |
| summary/full 비율 | 15~25% 범위 이탈 | build_prompt() 내부 로깅 |
| standard/full 비율 | 40~60% 범위 이탈 | build_prompt() 내부 로깅 |
| MODEL_MAP staleness | 7일 초과 | Cycle 7에서 30일→7일로 단축 (로키 요구 아님, 마아트 제안) |
| haiku A/B FNR | FNR ≥ 15% 또는 Fisher's p ≥ 0.05 | haiku 기각 판정 기준 |

### 6.5 파일 충돌 관리 (Cycle 6)

동시 수정 위험이 높은 핫스팟 파일:
- `dispatch.py`: P1-1(PD), P1-2(격리), P2-5(MODEL_MAP), P1-7(hooks) 4개 항목
- `team_prompts.py`: P1-1, P2-5, P1-7 3개 항목

**관리 방식**: 그룹 순차 실행 (그룹A→C→D), feature branch 분리로 충돌 최소화.

### 6.6 DRI 원칙 (Cycle 8 전면 적용)

"공동 배정" 전면 폐지. 모든 항목에 단독 DRI 지정.

| DRI | 담당 항목 |
|---|---|
| 헤르메스 | (1) PD, (2) 격리, (5) MODEL_MAP, (7) hooks, feature_flags.json |
| 마아트 | (3) haiku A/B, (4) TRUST 5, 기준선 측정 |
| 오딘 | (10) Task 파일 표준화, WORKFLOW 문서 |
