---
task_id: task-2553
type: context
scope: task
created: 2026-05-11
updated: 2026-05-11
status: completed
---

# 맥락 노트: task-2553

**task**: task-2553

---

## 결정 근거

### 핵심 결정 1: OWNER PAT trigger-only doctrine 예외 (단일 함수 한정)
- 회장 dec_1 (2026-05-11) 승인. bot trigger 0/5 실증 / OWNER trigger 10/10 실증으로 trigger gap 확정.
- 대안 기각: 별도 GitHub App (sender.type=='Bot' 동일 분류로 trigger 미작동 가능성 매우 높음, 검증 비용 대비 ROI 음수).
- doctrine 예외 범위: **단 1개 함수에서만 OWNER PAT 사용**. merge/approve/push/close/reopen은 전부 BOT_GITHUB_TOKEN.

### 핵심 결정 2: 신규 모듈 단일 책임 분리 (`owner_trigger_pat.py`)
- `merge_queue_executor.py`에 합치지 않음 → 보안 경계 명확화 + 정적 검사 용이.
- 외부 부수효과는 모두 callable 주입 (gh_runner, audit_writer, decision_writer) — 기존 anu_v2 패턴 일관.
- 허용 body `/gemini review`만 (strict equality). 다른 body는 fail-fast (정적 차단).

### 핵심 결정 3: dedupe key = (pr_number, head_sha)
- update-branch로 head SHA가 바뀌면 기존 dedupe stale → 새 head는 새 trigger 가능.
- audit log (jsonl append-only) lookup으로 중복 판정. sqlite 불필요 (로컬 파일 단순).

### 3 Step Why 자문 결과
- **1st Why** — 왜 이 설계가 필요한가? → A: OWNER PAT을 단 1개 함수에 격리해야 다른 권한 사용을 정적으로 차단 가능. 모듈 분리 = 보안 경계 = 코드 리뷰 표면 최소화.
- **2nd Why** — 왜 A가 최선의 접근인가? → B: 기존 `merge_queue_executor`는 BOT_GITHUB_TOKEN 전용으로 설계됨. OWNER PAT 로직을 섞으면 token leak / 경계 흐림. 분리하면 token loader / redaction / endpoint allowlist를 모두 한 파일에 집중 가능.
- **3rd Why** — 왜 B가 다른 대안보다 나은가? → C: 대안 = `merge_queue_executor` 내부 메서드 추가. 단점: 1) BOT/OWNER 토큰 두 종이 한 클래스에 공존 → 호출 실수 시 OWNER PAT으로 merge 호출 위험. 2) 회장 §명시 "단일 책임"에 위배. 3) regression test의 보안 경계 어설션이 복잡해짐.
- **결론**: A-B-C 논리 일관. 신규 모듈 분리 채택.

## 참조 자료

- task 명세: `memory/tasks/task-2553.md`
- 사전조사 결과: `memory/events/task-2552.owner_trigger_policy_decision.json`
- token scope risk: `memory/events/task-2552.token_scope_risk_matrix.md`
- 기존 anu_v2 패턴: `anu_v2/merge_queue_executor.py` (callable 주입 + BOT_GITHUB_TOKEN process-local injection)
- regression 위치: `tests/regression/` (기존 패턴 따름)

## 주의사항

- **token value 절대 출력/로그 금지**: audit에는 `token_present: bool` 또는 `token_hash: sha256[:12]`만 기록.
- **comment body는 strict equality `/gemini review`** (앞뒤 공백/대소문자 변형 모두 fail-fast).
- **endpoint allowlist 강제**: `gh api ... POST /repos/{owner}/{repo}/issues/{pr}/comments` 외 호출 0.
- **OWNER PAT은 본 모듈 외 import 금지**: 다른 모듈에서 `os.environ["OWNER_GEMINI_TRIGGER_PAT"]` 접근 시도 정적 grep 검증.
- **production token 발급 X**: 본 task는 코드 로직 + fixture only. 실제 token 주입은 회장 별도 단계.
- **dedupe stale 조건**: head_sha 변경 시 기존 (pr, old_head) 엔트리는 무효, (pr, new_head) 신규 trigger 가능.
