---
task_id: task-2519
type: plan
scope: task
created: 2026-05-09
updated: 2026-05-09
status: completed
---

# 계획서: task-2519 — repository_policy_adapter

**task**: task-2519
**목표**: GitHub repository ruleset / branch protection / merge capability를 runtime capability layer로 표준화하여, admin override 없이 deterministic merge path 선택이 가능하도록 한다. "회장 직접 머지 fallback"을 제거한다.
**승인**: 회장 2026-05-09 직접 — Phase 2 P1 진입
**근거**: memory/tasks/task-2519.md (회장 §명시), task-2517 (canonical_workspace_resolver) 머지 완료

---

## 목표

1. `utils/repository_policy_adapter.py` 신규 작성 (1 파일)
2. `tests/regression/test_repository_policy_adapter_2519.py` 회귀 14건 PASS (1 파일)
3. expected_files 외 수정 0건 (정확히 2 파일)
4. admin override 호출 0건 (정적 차단 RuntimeError)
5. 회장 직접 머지 fallback 제거 → `AUTOMATION_CAPABILITY_GAP` 분류

## 범위

### 포함
- **RepositoryCapability** frozen dataclass (6 probe field)
- **BlockedReason** Enum (7종)
- **MergePathPlan** dataclass
- **probe_capability(owner, repo, branch="main")** — gh api 4 호출
- **classify_blocked_reason(pr, capability) → BlockedReason** — deterministic
- **select_merge_path(pr, capability, blocked_reason) → MergePathPlan** — 우선순위 매칭
- **admin override 정적 차단**: subprocess args에 `--admin` 포함 시 RuntimeError
- **auto_gemini_triage hook 인터페이스**: `triage_pr(pr_number)` 호출 가능 형태로 정의 (실제 wiring은 후속 task)
- **CLI**: --probe-capability / --pr N --json / --pr N --classify-blocked
- **회귀 테스트 14건**: probe 4 + classify 7 + merge path 3

### 제외 (다음 페이즈 이후)
- 5 모듈 본체 wiring (task-2520+)
- live pilot (task-2520)
- observability/dashboard (task-2521)
- 자동 cherry-pick (영원히 금지)
- merge_queue_executor 대규모 rewrite

## 위임 계획

- **토르 (백엔드)**: `utils/repository_policy_adapter.py` 구현 — sonnet
- **헤임달 (테스터)**: `tests/regression/test_repository_policy_adapter_2519.py` 작성 — sonnet
- **미미르/프레이야**: 본 task에 UI/UX 산출물 없음 — 비활성

순서: 토르 먼저 (모듈 인터페이스 확정) → 헤임달 (테스트 작성). 인터페이스 불일치 방지를 위해 병렬 미사용.

## 검증 기준

- `python3 -m pytest tests/regression/test_repository_policy_adapter_2519.py -v` → 14/14 PASS
- `python3 -c "from utils.repository_policy_adapter import RepositoryCapability, BlockedReason, MergePathPlan, probe_capability, classify_blocked_reason, select_merge_path; print('OK')"` → OK
- `python3 utils/repository_policy_adapter.py --probe-capability --json` → JSON 출력 (또는 dry-run mock 정상 종료)
- `git diff --stat origin/main HEAD` → 정확히 2 파일 (utils/repository_policy_adapter.py, tests/regression/test_repository_policy_adapter_2519.py)
- `grep -rn "gh pr merge --admin\|--admin" utils/repository_policy_adapter.py` → 차단 로직 외 호출 0건
- pyright 0 error
