# task-2509 — merge_queue_executor: queue-head auto-merge pipeline 코드 자동화

- 작업 유형: **자동화 코드 구현 + 회귀 테스트** (정책 문서 X)
- 작업 레벨: **Lv.3+** (시스템 자동화 모듈)
- 우선순위: **★★ blocking** (회장 5 모듈 #1 우선)
- Track: **dispatch_topology_gate / merge_queue / conflict_recovery 자동화**
- parallel_policy: **serial_only**
- 일시: 2026-05-08
- 회장 결정: 2026-05-08 직접 명령 — "정책 문서화가 아니라 코드 자동화 단계로 전환"

## ⚠️ 본 task의 본질 — 회장 명시

> 이번 task의 산출물은 md 정책 문서가 아니라 **실행 가능한 코드와 회귀 테스트**다. 문서 업데이트는 부속 산출물일 뿐 완료 조건이 아니다.
> queue 선두 PR이 자동 머지 10조건 만족 시 회장 승인 없이 squash merge + post-merge smoke + 후행 stale 재검증.
> Critical 7종 발생 시에만 회장 보고.

## dependency (모두 충족 — 발사 가능)

- ✅ task-2503+1.merged (PR #57 → main `7c648edd`)
- ✅ task-2506.merged (PR #56 → main `4486ea36`)
- ✅ task-2507.merged (PR #55 → main `2cd8178b`)

## Merge Topology Gate metadata

```yaml
expected_files:
  - "utils/merge_queue_executor.py"  # 신규: 핵심 모듈 + CLI entrypoint
  - "tests/regression/test_merge_queue_executor_2509.py"  # 신규: 12 케이스 회귀

risk_area: "merge_queue / auto_merge / conflict_recovery"

dependency:
  - "task-2503+1.merged"
  - "task-2506.merged"
  - "task-2507.merged"

parallel_policy: "serial_only"

merge_queue_position: 4

stale_recheck_required: true

cherry_pick_allowed: false
```

## 실전 회귀 fixture (회장 명시)

- PR #57 → #56 → #55 queue 순차 처리 성공 사례 (2026-05-08)
- main HEAD `2cd8178b`
- PR #55 task-2507 smoke 10/10 PASS
- Critical 7종 0건
- AUTO_MERGE_SUCCESS 첫 실전 케이스

본 fixture를 회귀 테스트의 입력 데이터로 사용 — fix 후 dry-run에서 동일 결과 재현 필수.

## 필수 구현 범위 14건 (회장 §1~14)

### 1. queue head 확인
- `merge_queue_position` 기준 현재 queue 선두 PR 식별
- 선행 PR `merged` 여부 확인 (`gh pr view --json state mergedAt` + main commit grep)
- queue 선두 아니면 `WAITING_FOR_PREDECESSOR` decision 반환

### 2. origin/main fetch
- `git fetch origin`
- main HEAD SHA 기록 → audit evidence

### 3. PR branch base sync
- BEHIND 시 `git merge origin/main --no-edit` (rebase 금지, force 금지)
- conflict 시 → Critical Escalation `MERGE_CONFLICT`

### 4. effective diff 검증
- `git diff origin/main...HEAD` 결과가 `expected_files`와 정확히 일치
- 허용 파일 외 diff → `replacement_pr_runner` 대상 분기 (본 task에서는 인터페이스만, 실제 구현은 task-2510)
- replacement 자동 생성 실패 시에만 회장 보고 → Critical 7종 #2

### 5. forbidden path 검증
- forbidden path 0건 필수
- 1건 이상 → 즉시 Critical Escalation `FORBIDDEN_PATH_INVASION`

### 6. CI 상태 확인
- `gh pr view --json statusCheckRollup` → required all SUCCESS
- IN_PROGRESS → 자동 polling (max N회, exponential backoff)
- 반복 실패 → critical 분류

### 7. Gemini 상태 확인
- graphql `reviewThreads` unresolved 0 필수
- false-positive/style-only → `auto_gemini_triage` 대상 (인터페이스만)
- expected_files 안 minor fix → 자동 처리 인터페이스 (실제는 task-2511)
- expected_files 밖 수정 요구 → Critical 7종 #3

### 8. mergeStateStatus 확인
- CLEAN 필수
- BEHIND → base sync 재시도
- BLOCKED → 원인 분류 (override 필요 시 Critical 7종 #4)

### 9. HEAD SHA lock
- 검증 시작 시 head SHA 저장
- merge 직전 head SHA 재확인
- 불일치 → 자동 머지 중단 + 재검증 loop

### 10. squash merge 실행
- `gh pr merge <N> --squash --delete-branch`
- `--admin` 절대 금지 / rebase 금지 / force 금지 / required CI bypass 금지 / manual .done 금지

### 11. post-merge smoke
- `git fetch origin` + main worktree fast-forward
- task spec에 명시된 smoke command 실행
- 실패 → Critical 7종 #7

### 12. 후행 PR stale 재검증
- queue 다음 PR들의 BEHIND/conflict/diff 오염 자동 재평가
- 자동 머지 조건 만족 시 이어서 queue 처리
- Critical 7종 발생 시에만 회장 보고

### 13. audit/evidence
- `memory/events/{task_id}.merge-queue.json` (per-task)
- `memory/orchestration-audit/merge-queue.jsonl` (global append)
- 단계별 decision/sha/checks/diff/smoke 기록
- 정상 자동 처리 = evidence만, 장문 보고 X

### 14. critical_escalation_reporter 연동
회장 보고 7종 (코드 enum):
- `FORBIDDEN_PATH_INVASION`
- `EFFECTIVE_DIFF_CONTAMINATION_REPLACEMENT_FAILED`
- `GEMINI_REAL_BUG_SCOPE_EXPANSION`
- `BLOCK_OVERRIDE_REQUIRED_OR_INSUFFICIENT_REASON`
- `DEPENDENCY_CYCLE_OR_SERIAL_ONLY_CONFLICT`
- `REPLACEMENT_PR_ALSO_FAILED`
- `POST_MERGE_SMOKE_FAILURE`

본 task에서는 critical_escalation_reporter 인터페이스만 구현, 실제 모듈은 task-2513.

## 필수 회귀 테스트 12건 (회장 §1~12)

`tests/regression/test_merge_queue_executor_2509.py`:

1. queue head가 아니면 merge하지 않음 → `WAITING_FOR_PREDECESSOR`
2. queue head + 10조건 PASS → `AUTO_MERGE_ALLOWED` decision 생성
3. BEHIND 상태 → rebase 아닌 merge sync 수행 (subprocess args 검증)
4. HEAD SHA 변경 시 → 자동 머지 중단 (`HEAD_SHA_LOCK_BROKEN`)
5. effective diff != expected_files → `replacement_pr_runner` path 분기
6. forbidden path 발생 → Critical `FORBIDDEN_PATH_INVASION`
7. CI failure → 자동 머지 금지 (`CI_FAILURE_BLOCK`)
8. Gemini unresolved 존재 → `auto_gemini_triage` 또는 escalation 분기
9. mergeStateStatus != CLEAN → 자동 머지 금지
10. post-merge smoke 실패 → Critical `POST_MERGE_SMOKE_FAILURE`
11. post-merge smoke PASS → `AUTO_MERGE_SUCCESS`
12. 후행 PR stale 재검증 수행 (state machine 검증)

## CLI entrypoint (회장 명시)

`python3 utils/merge_queue_executor.py --pr <N> --dry-run`
- 출력: `AUTO_MERGE_ALLOWED` 또는 `BLOCKED_WITH_REASON: <code>` JSON
- `--no-audit` 옵션 (테스트용)
- `--task-file <path>` 옵션 (queue 선두 task spec 로드)

## 금지 행위 (회장 명시 — 절대 준수)

- 정책 문서만 작성하고 종료 금지 (산출물 = 코드 + 회귀 테스트)
- `auto_merge.py`에 임시 하드코딩 금지 (별도 모듈 `utils/merge_queue_executor.py`)
- force push 금지
- rebase 금지
- admin override 금지 (`gh pr merge --admin` 절대 X)
- manual .done 금지
- PR #52/#49/#50/#51 수정 금지
- contaminated branch 재활용 금지
- replacement PR 자동 cherry-pick 구현 금지

## allowed_resources

```yaml
allowed_resources:
  read_only_paths:
    - "memory/tasks/task-2509*"
    - "memory/feedback/feedback_critical_escalation_only_260508.md"
    - "memory/feedback/feedback_merge_topology_gate_260508.md"
    - "memory/feedback/feedback_amendment_not_enforced_260508.md"
    - "memory/events/task-2503+1*"
    - "memory/events/task-2506*"
    - "memory/events/task-2507*"
    - "memory/orchestration-audit/merge-topology-gate.jsonl"
    - "utils/merge_topology_gate.py"
    - "teams/shared/verifiers/critical_gap.py"
    - "teams/shared/verifiers/git_evidence.py"
    - "memory/task-timers.json"
    - ".env.keys"
  paths:
    - "memory/tasks/task-2509*"
    - "memory/reports/task-2509*"
    - "memory/events/task-2509*"
    - "utils/merge_queue_executor.py"
    - "tests/regression/test_merge_queue_executor_2509.py"
  forbidden_actions:
    - "auto_merge.py 임시 하드코딩"
    - "force push"
    - "rebase"
    - "admin override (gh pr merge --admin)"
    - "manual .done 생성"
    - "required CI bypass"
    - "PR #52/#49/#50/#51 수정"
    - "contaminated branch 재활용"
    - "replacement PR 자동 cherry-pick 구현"
    - "정책 문서만 작성하고 종료"
    - "expected_files 외 파일 수정"
    - "Critical 7종 외 회장 보고"
    - "amendment 무시 / mid-dispatch correction 무시"
```

## 완료 조건 (회장 명시)

1. ✅ 코드 파일 구현 (`utils/merge_queue_executor.py`)
2. ✅ 회귀 테스트 12건 PASS (`tests/regression/test_merge_queue_executor_2509.py`)
3. ✅ dry-run으로 PR #57 / #56 / #55 성공 경로 재현 (fixture)
4. ✅ 실제 queue head 후보에 `--dry-run` 결과 = `AUTO_MERGE_ALLOWED` 또는 `BLOCKED_WITH_REASON` 출력
5. ✅ Critical 7종 외 회장 보고 0건
6. ✅ Merge Topology Gate 자기참조 PASS
7. ✅ CI 11/11 SUCCESS
8. ✅ Gemini fresh evidence
9. ✅ 회장 §6 공통 금지 위반 0건
10. ✅ amendment 보호 의무 명시 + 적용 evidence

## 시스템 3문서 참조

- 정책 본체 (Critical 7종 + 자동 머지 10조건): `memory/feedback/feedback_critical_escalation_only_260508.md`
- Merge Topology Gate: `memory/feedback/feedback_merge_topology_gate_260508.md`
- amendment 보호: `memory/feedback/feedback_amendment_not_enforced_260508.md`
- composite 3종: `memory/feedback/feedback_composite_three_types_260508.md`
- 본 task fixture (실전 사례): main HEAD `2cd8178b`, PR #57/#56/#55 queue 순차 처리

## 후행 task (5 모듈 #2~#5)

- task-2510: replacement_pr_runner
- task-2511: auto_gemini_triage
- task-2512: post_merge_smoke_runner
- task-2513: critical_escalation_reporter

본 task는 5 모듈의 #1로 상위 인터페이스 정의 + 후속 모듈 hook 박제.

## goal_assertions (auto-generated)
- `python3 utils/merge_queue_executor.py --pr <N> --dry-run`
