---
task_id: task-2509+2
type: plan
scope: task
created: 2026-05-08
updated: 2026-05-08
status: completed
---

# 계획서: task-2509+2 — automation_contracts.py 공통 계약 freeze

**task**: task-2509+2
**목표**: `utils/automation_contracts.py`에 12 타입(Critical 7 enum + 3 enum + 8 dataclass)을 freeze하고, 14건 회귀 테스트를 통과시킨다. 5 모듈 wiring 절대 금지.
**승인**: 회장 2026-05-08 직접 명령 ("task-2510-pre 명칭 폐기 → task-2509+2로 정정")
**근거**: memory/tasks/task-2509+2.md (회장 명시), memory/feedback/feedback_critical_escalation_only_260508.md

---

## 목표

후속 4 자동화 모듈(replacement_pr_runner, auto_gemini_triage, post_merge_smoke_runner, critical_escalation_reporter)이 서로 다른 enum/result/audit 형식을 만들지 않도록, 공통 계약 12종을 Python 코드로 고정한다.

산출물:
1. `utils/automation_contracts.py` — 12 타입 정의 (3 Enum + 8 dataclass + 1 helper enum)
2. `tests/regression/test_automation_contracts_2509_plus_2.py` — 회귀 테스트 14건
3. import smoke: `utils/merge_queue_executor.py`에서 `from utils.automation_contracts import ...` 가능

## 범위

### 포함 (정확히 2 파일)
- `utils/automation_contracts.py` 신규 작성
- `tests/regression/test_automation_contracts_2509_plus_2.py` 신규 작성

### 제외 (다음 페이즈 이후)
- dispatch.py wiring 금지
- merge_queue_executor 대규모 수정 금지 (import smoke 외 0)
- replacement_pr_runner 구현 금지 (task-2510)
- auto_gemini_triage 구현 금지 (task-2511)
- post_merge_smoke_runner 구현 금지 (task-2512)
- critical_escalation_reporter 구현 금지 (task-2513)
- 기존 task-2509+1 enum 이름(FORBIDDEN_PATH_INVASION 등) 재정렬 금지 — 후속 wiring task에서

## 위임 계획

- 본체 코드 + 테스트 작성: 루 (백엔드, sonnet) — 12 타입 dataclass/enum + 14 회귀 테스트 작성
- 자체 검증 + 회귀: 모리건 (테스터, sonnet) — pytest 14건 PASS 확인 + import smoke

## 검증 기준

- `utils/automation_contracts.py` 존재 + 12 타입 정의 완료
- `tests/regression/test_automation_contracts_2509_plus_2.py` 14건 PASS
- `python3 -c "from utils.automation_contracts import CriticalEscalationType, RiskLevel, GeminiStatus, AutomationDecision, ReviewGateStatus, FallbackReviewResult, ReplacementResult, GeminiTriageResult, SmokeResult, QueueAuditRecord, AutoMergeResult, EscalationPacket"` → exit 0
- `python3 -c "from utils.automation_contracts import CriticalEscalationType; from utils.merge_queue_executor import *"` → import 가능 (breaking change 0)
- effective diff == 정확히 2 파일

## Critical 7종 (회장 정확 매칭)

```
FORBIDDEN_PATH_INTRUSION
REPLACEMENT_PR_AUTO_CREATION_FAILED_FOR_CONTAMINATED_DIFF
GEMINI_REAL_BUG_REQUIRES_SCOPE_EXPANSION
BLOCK_OVERRIDE_REQUIRED_OR_REASON_INSUFFICIENT
DEPENDENCY_CYCLE_OR_SERIAL_ONLY_COLLISION
REPLACEMENT_PR_FAILED
POST_MERGE_SMOKE_FAILED
```

## 작업 순서 (Serial)

1. Codex 사전 검증 (target_dir 정정 후 재실행 → PASS 필요)
2. 루: `utils/automation_contracts.py` 작성
3. 루: `tests/regression/test_automation_contracts_2509_plus_2.py` 작성
4. 모리건: pytest 회귀 14건 PASS + import smoke
5. 마아트: 독립 검증 (Critical 게이트)
6. worktree finish → PR → Gemini 리뷰 → main merge
