# Phase 1: 보리스 게이트 시스템 — 기반 인프라 구축

## 배경
교차검증 풀스택 워크플로우 3문서 승인 완료 (task-1837).
Phase 1 한정승인: 기반 인프라(gate_instructions.py + affected_files + batch_id + 레벨 자동 추정)만 구현.

## 3문서 참조 경로
- 계획서: `memory/plans/cross-verification-workflow/plan.md`
- 맥락노트: `memory/plans/cross-verification-workflow/context-notes.md`
- 체크리스트: `memory/plans/cross-verification-workflow/checklist.md`

---

## 구현 항목 4건

### 1. gate_instructions.py 신규 생성

**파일**: `/home/jay/workspace/prompts/gate_instructions.py`

레벨별 게이트 지시 텍스트를 딕셔너리로 관리하는 모듈.

```python
GATE_INSTRUCTIONS = {
    0: {
        "g1": "",  # 스킵
        "g2": "셀프 QC: 구문 에러, 기본 기능 확인.",
        "g3": "즉시 머지.",
    },
    1: {
        "g1": "",  # 스킵
        "g2": "셀프 QC: 구문 에러, 기본 기능 확인.",
        "g3": "즉시 머지.",
    },
    2: {
        "g1": "affected_files에 명시된 파일 확인. 다른 팀과 겹침 없는지 확인.",
        "g2": "팀 테스터 또는 마아트 QC 수행. 기능 테스트 필수.",
        "g3": "머지 전 main 최신화 필수. git merge main --no-edit 실행 후 머지.",
    },
    3: {
        "g1": "3문서 필수. Codex 사전 검증 PASS 필요. affected_files 교차 분석.",
        "g2": "Gemini PR 리뷰 + 마아트 독립 검증. 두 검증 모두 PASS 필요.",
        "g3": "충돌 감지 시 Gemini 집중 리뷰. 시맨틱 충돌 분석.",
    },
    4: {
        "g1": "3문서 필수 + Agent 미팅 만장일치 + Codex 사전 검증 PASS.",
        "g2": "Gemini PR 리뷰 + 마아트 QC + 로키 레드팀 투입. 전체 PASS 필요.",
        "g3": "전팀 완료 대기 + Graduated Auto-Gate (L1→L2→L3) 통과 필수.",
    },
}

def get_gate_instructions(level: int) -> dict:
    """레벨에 해당하는 게이트 지시를 반환."""
    return GATE_INSTRUCTIONS.get(level, GATE_INSTRUCTIONS[0])

def format_for_prompt(level: int) -> str:
    """프롬프트에 삽입할 게이트 지시 문자열을 생성."""
    gates = get_gate_instructions(level)
    lines = []
    if gates["g1"]:
        lines.append(f"[G1 설계 게이트] {gates['g1']}")
    if gates["g2"]:
        lines.append(f"[G2 구현 게이트] {gates['g2']}")
    if gates["g3"]:
        lines.append(f"[G3 머지 게이트] {gates['g3']}")
    return "\n".join(lines)
```

### 2. dispatch.py에 affected_files 필드 추가

**파일**: `/home/jay/workspace/dispatch.py`

**수정 내용:**

(A) task 파일 파싱 시 `affected_files:` 필드 읽기:
- task 파일 내 `affected_files:` 라인이 있으면 쉼표 구분 파일 목록으로 파싱
- 예: `affected_files: server.py, InsuWikiView.js, knowledge_extractor_v2.py`

(B) 겹침 감지 로직:
- task-timers.json에서 현재 "running" 상태인 task들의 affected_files를 수집
- 새 task의 affected_files와 겹치는 파일이 있으면 경고 메시지 출력
- 경고 형식: `⚠️ 파일 겹침 감지: {파일명} — {task_id}({team})에서 수정 중`
- 경고만 하고 위임은 계속 진행 (블로킹하지 않음)

(C) Lv.2 이상에서 affected_files 미기재 시 경고:
- 작업 레벨이 2 이상인데 affected_files가 없으면 경고
- 경고 형식: `⚠️ Lv.2+ 작업에 affected_files 미기재. 파일 겹침 감지 불가.`

(D) task-timers.json에 affected_files 필드 저장:
- task 시작 시 affected_files를 task-timers.json 엔트리에 포함

### 3. dispatch.py에 batch_id 필드 추가

**파일**: `/home/jay/workspace/dispatch.py`

**수정 내용:**

(A) `--batch` 옵션 추가:
- `python3 dispatch.py --team dev1 --task-file ... --batch <batch_id>`
- batch_id는 아누가 병렬 위임 시 수동 지정 (예: `batch-20260415-dashboard`)
- batch_id 미지정 시: 단독 작업으로 간주 (batch_id = None)

(B) task-timers.json에 batch_id 필드 저장

(C) batch 완료 조회 함수:
```python
def check_batch_completion(batch_id: str) -> dict:
    """batch_id에 해당하는 모든 task의 완료 여부를 반환."""
    # task-timers.json에서 해당 batch_id의 task들을 조회
    # 전체 완료 여부 + 미완료 task 목록 반환
    return {"complete": bool, "total": int, "done": int, "pending": [task_ids]}
```

### 4. 레벨 자동 추정 경고

**파일**: `/home/jay/workspace/dispatch.py`

**수정 내용:**

(A) 자동 추정 로직:
- affected_files 개수 >= 3 → 최소 Lv.2 권장
- affected_files에 server.py 포함 → 최소 Lv.2 권장 (대형 파일)
- task 설명에 "구조 변경", "분할", "아키텍처", "migration" 포함 → 최소 Lv.3 권장

(B) 경고 표시:
- 아누가 지정한 레벨 < 자동 추정 레벨 시:
- `⚠️ 레벨 재확인 권장: 지정 Lv.{n} < 자동 추정 Lv.{m} (사유: {reason})`
- 경고만 하고 위임은 계속 진행

(C) gate_instructions.py 연동:
- dispatch 시 레벨에 해당하는 게이트 지시를 팀장 프롬프트에 자동 삽입
- `from prompts.gate_instructions import format_for_prompt` 호출
- 프롬프트 끝에 게이트 지시 블록 추가

---

## affected_files
dispatch.py, prompts/gate_instructions.py (신규)

## 검증 시나리오

1. **gate_instructions 동작**: Lv.2 task 위임 → 팀장 프롬프트에 "[G1 설계 게이트] affected_files에 명시된 파일 확인..." 포함 확인
2. **affected_files 겹침 감지**: 팀A가 server.py 수정 중(running) → 팀B에 server.py 수정 위임 → "⚠️ 파일 겹침 감지: server.py" 경고 출력
3. **affected_files 미기재 경고**: Lv.2 task에 affected_files 없이 위임 → 경고 출력
4. **batch_id 완료 추적**: --batch batch-test로 3팀 위임 → 3팀 모두 .done → check_batch_completion("batch-test") = complete
5. **레벨 자동 추정**: Lv.1로 위임했으나 affected_files 5개 → "⚠️ 레벨 재확인 권장" 경고

## 주의사항
- dispatch.py는 핵심 인프라. 기존 기능 깨뜨리지 않도록 주의.
- 새 옵션(--batch)은 기존 옵션과 호환되어야 함 (옵션 미지정 시 기존 동작 그대로).
- gate_instructions.py는 신규 파일이므로 import 실패 시 graceful fallback (게이트 지시 없이 기존대로 동작).
- task-timers.json 스키마 변경 시 기존 엔트리와 호환 유지 (새 필드는 optional).
