# .done 감지 → 자동 머지 시스템

## 목표
.done 파일 감지 → 보고서 분석 → 자동 머지 → 테스트 → .done.clear 처리를 **완전 자동화**하는 스크립트 개발.
추가로 전체 프로세스를 문서화(spec 문서) 한다.

## 배경
- 현재: 아누(개발실장)가 대화 중 수동으로 .done 감지 → 머지 수행
- 문제: 대화 없으면 .done이 쌓이고, 머지가 지연됨
- 기존 도구: report_parser.py (머지 감지), worktree_manager.py (머지 실행) — 이미 있으나 연결 안 됨

## 프로젝트 경로
`/home/jay/workspace/` (dev_workspace)

## 작업 상세

### 1. auto_merge.py 신규 개발

`/home/jay/workspace/scripts/auto_merge.py` — 핵심 스크립트

#### 동작 흐름:

```
1. memory/events/*.done 스캔
2. 각 .done 파일에 대해:
   a. .done.clear 원자적 생성 시도 (open('x') — 중복 방지)
      - FileExistsError → 이미 처리 중, 스킵
   b. .done JSON 파싱 → task_id, team_id 추출
   c. 보고서 읽기: memory/reports/{task_id}.md
   d. report_parser.py로 분석 → merge_needed, merge_branch 추출
   e. merge_needed=true인 경우:
      i.  프로젝트 경로 확인 (보고서에서 추출 또는 task 메타에서)
      ii. worktree_manager.py finish --action merge 실행
      iii. 머지 성공 시:
           - 프로젝트 테스트 실행 (pytest, 있으면)
           - 테스트 성공 → 성공 로그
           - 테스트 실패 → 머지 revert + 에스컬레이션
      iv. 머지 충돌 시:
           - 에스컬레이션 (아누에게 통보)
   f. merge_needed=false인 경우:
      - 완료 로그만 기록
   g. .done → .done.clear rename (이미 원자적으로 생성했으므로 .done만 삭제)
   h. 결과를 merge-log.json에 기록
3. 처리 결과 요약 → cokacdir --cron으로 아누에게 통보
```

#### 핵심 함수:

```python
class AutoMerger:
    """자동 머지 시스템"""

    def __init__(self, workspace_path: str = "/home/jay/workspace"):
        self.workspace = Path(workspace_path)
        self.events_dir = self.workspace / "memory" / "events"
        self.reports_dir = self.workspace / "memory" / "reports"
        self.merge_log = self.workspace / "memory" / "merge-log.json"

    def scan_done_files(self) -> list[Path]:
        """미처리 .done 파일 스캔"""
        ...

    def try_claim(self, done_file: Path) -> bool:
        """원자적 .done.clear 생성으로 처리 선점"""
        ...

    def parse_done(self, done_file: Path) -> dict:
        """JSON 파싱 → task_id, team_id"""
        ...

    def analyze_report(self, task_id: str) -> dict:
        """report_parser.py로 보고서 분석 → merge_needed, branch"""
        ...

    def execute_merge(self, project_path: str, task_id: str, team_id: str) -> dict:
        """worktree_manager.py finish --action merge 실행"""
        ...

    def run_tests(self, project_path: str) -> dict:
        """프로젝트 테스트 실행 (pytest)"""
        ...

    def revert_merge(self, project_path: str) -> bool:
        """머지 실패 시 되돌리기 (git reset --hard HEAD~1)"""
        ...

    def escalate(self, task_id: str, reason: str) -> None:
        """아누에게 에스컬레이션 통보 (cokacdir --cron)"""
        ...

    def log_result(self, task_id: str, result: dict) -> None:
        """merge-log.json에 결과 기록"""
        ...

    def run(self) -> dict:
        """메인 실행: 스캔 → 처리 → 결과"""
        ...
```

#### CLI 인터페이스:

```bash
# 자동 실행 (cron용)
python3 scripts/auto_merge.py

# 특정 task만 처리
python3 scripts/auto_merge.py --task-id task-391.1

# 드라이런 (실제 머지 없이 분석만)
python3 scripts/auto_merge.py --dry-run

# 에스컬레이션된 건 수동 처리
python3 scripts/auto_merge.py --force-merge task-391.1
```

### 2. merge-log.json 형식

```json
{
  "entries": [
    {
      "task_id": "task-391.1",
      "timestamp": "2026-03-07T15:30:00+09:00",
      "merge_needed": true,
      "action": "auto_merged",
      "project": "/home/jay/projects/ThreadAuto",
      "branch": "task/task-391.1-dev1",
      "test_result": "pass",
      "duration_seconds": 12.5,
      "status": "success"
    },
    {
      "task_id": "task-392.1",
      "timestamp": "2026-03-07T15:35:00+09:00",
      "merge_needed": true,
      "action": "escalated",
      "project": "/home/jay/projects/ThreadAuto",
      "branch": "task/task-392.1-dev2",
      "reason": "merge_conflict",
      "status": "escalated"
    }
  ]
}
```

### 3. 프로젝트 경로 해결

.done 파일에는 프로젝트 경로가 없으므로, 다음 순서로 추출:
1. 보고서에서 프로젝트 경로 regex 추출 (`/home/jay/projects/...`)
2. task 메타 파일에서 추출 (`memory/tasks/{task_id}.md`)
3. worktree 경로에서 역추적 (`.worktrees/` 상위)
4. 못 찾으면 에스컬레이션

### 4. 에스컬레이션 통보

머지 실패/충돌/테스트 실패 시:

```bash
cokacdir --cron "task-{id} 자동 머지 실패. 사유: {reason}. 수동 처리 필요. 보고서: memory/reports/{task_id}.md" \
  --at "1m" --chat {CHAT_ID} --key {KEY}
```

### 5. cron 등록

```bash
# 1분 간격 실행 (crontab -e)
* * * * * cd /home/jay/workspace && /usr/bin/python3 scripts/auto_merge.py >> /home/jay/workspace/logs/auto_merge.log 2>&1
```

- 로그 디렉토리: `/home/jay/workspace/logs/`
- 로그 로테이션: 일별 (`auto_merge_2026-03-07.log`)

### 6. 스펙 문서 작성

`/home/jay/workspace/memory/specs/auto-merge-spec.md` 작성:

1. **현재 프로세스**: .done 프로토콜 전체 흐름 문서화
2. **자동화 프로세스**: auto_merge.py 동작 상세
3. **에스컬레이션 규칙**: 언제 자동, 언제 수동
4. **안전장치**: 원자적 선점, 머지 revert, 로깅
5. **모니터링**: merge-log.json, 일별 로그

### 7. 기존 모듈 연동

#### report_parser.py 활용:
```python
from report_parser import parse_report
result = parse_report(report_path)
merge_needed = result.get("merge_needed", False)
merge_branch = result.get("merge_branch", "")
```

#### worktree_manager.py 활용:
```python
import subprocess
result = subprocess.run(
    ["python3", "scripts/worktree_manager.py", "finish",
     project_path, task_id, team_id, "--action", "merge"],
    capture_output=True, text=True
)
```

### 8. 안전장치

- **원자적 선점**: .done.clear를 먼저 만들어 다른 프로세스와 충돌 방지
- **머지 실패 시 자동 revert**: `git merge --abort` 또는 `git reset --hard HEAD~1`
- **테스트 실패 시 머지 revert**: 머지는 성공했지만 테스트 실패 → 자동 되돌리기
- **드라이런 모드**: 실제 동작 없이 분석만 수행
- **로깅**: 모든 동작을 merge-log.json + 일별 로그에 기록
- **타임아웃**: 테스트 실행 타임아웃 300초 (초과 시 에스컬레이션)

## 수정/생성 파일 목록
1. `scripts/auto_merge.py` — 핵심 자동 머지 스크립트 (신규)
2. `memory/specs/auto-merge-spec.md` — 스펙 문서 (신규)
3. `memory/merge-log.json` — 머지 로그 (자동 생성)
4. `logs/` 디렉토리 생성

## 테스트
- scan_done_files: .done 파일 감지 테스트
- try_claim: 원자적 선점 동시성 테스트
- parse_done: JSON 파싱 정상/비정상 케이스
- analyze_report: 머지 판단 정확도 (기존 report_parser 테스트 활용)
- execute_merge: 머지 성공/충돌 시뮬레이션
- run_tests: 테스트 성공/실패/타임아웃
- revert_merge: 되돌리기 정상 동작
- escalate: 통보 발송 확인
- end-to-end: .done 생성 → 자동 머지 → .done.clear 전체 흐름

## 주의사항
- report_parser.py, worktree_manager.py는 수정하지 말 것 (기존 모듈 그대로 활용)
- cron 등록은 스크립트로 자동화하되, 실제 crontab 등록은 보고서에 명령어만 기재
- .env.keys에서 CHAT_ID, KEY 로드 (하드코딩 금지)
- 프로젝트별 테스트 명령어가 다를 수 있음 (pytest, npm test 등) — 자동 감지 또는 설정 파일

## 보고서
완료 시 `/home/jay/workspace/memory/reports/task-392.1.md`에 작성.
머지 판단 섹션: 이 작업은 dev_workspace 자체 수정이므로 머지 필요 없음 (master 직접 커밋).