# task-2542 — GEMINI_TRIGGER_GAP_INVESTIGATION_REPORT (read-only research)

- **일시**: 2026-05-10
- **팀**: dev1-team 헤르메스(팀장) + 불칸(백엔드 리서치) + 아르고스(테스터 사례 분석)
- **작업 유형**: read-only research / report-only / analysis-only / finalize_policy:no_pr
- **작업 레벨**: Lv.4 (외부 시스템 분석 + 9 조사 범위 + 4 사례 비교)
- **회장 §결정**: 2026-05-10 — operational nudge 거부, 근본 원인 조사 승격
- **track**: gemini_trigger_gap_root_cause_investigation

## 0. SCQA 요약

- **Situation**: 4건의 PR(#75/#83/#86/#87)이 BEHIND 또는 push 사이클에서 Gemini 자동 리뷰 미트리거 → 수동 회장 `/gemini review`로 회복 → 누적 manual burden 증가.
- **Complication**: bot이 `/gemini review`를 발행해도 Gemini 응답 없음 (PR #75 사례 확인). EXTERNAL_TRIGGER_REQUIRED operational nudge로 처리 거부 → 근본 원인 조사 승격.
- **Question**: Gemini App 트리거 조건은 무엇이며, bot이 활용 가능한 자동화 대체 트리거가 존재하는가?
- **Answer**: **자동화 불가**. Gemini App은 `pull_request.opened` 이벤트만 자동 구독, on-demand `/gemini review`는 sender.type=='User' AND OWNER/MEMBER/COLLABORATOR association 필터로 bot 차단. 8개 대체 트리거 후보 모두 불가/조건부. → **nudge 최후수단 유지 + audit 임계 정의 + task-2537/2538 finalize 보류 [조건부 해제] 권고**.

## 1. 조사 범위 9건 답변

### 1.1 영역 1 — Gemini Code Assist App 트리거 이벤트

**finding**: Gemini Code Assist GitHub App은 자동 리뷰에 `pull_request.opened` 이벤트만 공식 구독한다. 설정 파일(`.gemini/`)에서 `pull_request_opened` 섹션으로 `code_review`(기본 true), summary, help, include_drafts 구성 가능. `synchronize` (새 커밋 push) / `reopened` / `labeled`에 대한 자동 재리뷰는 공식 문서에 명시되지 않음.

On-demand 리뷰는 `issue_comment.created` 이벤트로 트리거되며, comment 본문에 `/gemini review` 또는 `@gemini-code-assist` 멘션을 포함해야 한다.

**evidence**:
- https://developers.google.com/gemini-code-assist/docs/use-code-assist-github
- https://developers.google.com/gemini-code-assist/docs/customize-gemini-behavior-github
- https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/gemini-dispatch/gemini-dispatch.yml (공식 dispatch 워크플로우 — 가장 핵심 증거)

### 1.2 영역 2 — 인간 vs Bot account comment 차이

**finding**: GitHub API의 user 객체에는 `type` 필드가 있고 값은 `User` 또는 `Bot`. App installation token으로 발행된 모든 코멘트는 login이 `appname[bot]` 형태이며 type은 `Bot`으로 강제 설정된다. Google 공식 dispatch 워크플로우(`gemini-dispatch.yml`)는 `issue_comment` 트리거에서 명시적으로 `github.event.sender.type == 'User'` 조건을 검사하여 Bot 타입 계정을 트리거 대상에서 제외한다. Gemini Code Assist GitHub App 자체에서도 동일 방어 패턴이 적용되는 것으로 강하게 추정됨(소스 비공개로 확증 불가).

**evidence**:
- https://github.com/orgs/community/discussions/65546
- https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/gemini-dispatch/gemini-dispatch.yml
- https://docs.github.com/en/rest/users/users

### 1.3 영역 3 — `/gemini review` author 권한 조건

**finding**: 공식 문서는 "any pull request contributor"가 사용 가능하다고 명시하나, run-gemini-cli dispatch 워크플로우는 comment 트리거에 두 조건을 동시 강제한다:
1. `github.event.sender.type == 'User'` (Bot 타입 차단)
2. `author_association` ∈ {OWNER, MEMBER, COLLABORATOR} (외부 기여자 차단)

App installation token으로 발행된 코멘트는 항상 type=Bot이므로 조건 (1)에서 차단됨. 이는 self-trigger loop 방지 설계.

**evidence**:
- https://developers.google.com/gemini-code-assist/docs/use-code-assist-github
- https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/gemini-dispatch/gemini-dispatch.yml
- https://github.com/google-github-actions/run-gemini-cli/issues/195

### 1.4 영역 4 — GitHub App 권한 / installation permission

**finding**: jeon-jonghyuk-taskctl-bot App의 일반 installation permissions는 `pull_requests: write`, `issues: write`로 추정되며 PR/Issue 코멘트 발행 권한 충분. **그러나 권한 ≠ Gemini trigger 자격**. App installation token으로 발행된 코멘트는 항상 sender.type=Bot으로 표시되어 Gemini dispatch 워크플로우의 User 필터에서 차단됨.

`gh api /app` 엔드포인트는 App JWT 인증 필수(401 반환)로 read-only 환경에서 직접 권한 조회 불가. 그러나 **권한 변경은 본 task에서 회장 §명시 절대 금지** (read-only).

**evidence**:
- https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation

### 1.5 영역 5 — GitHub Webhook 이벤트 조건

**finding**: 공식 dispatch 워크플로우에서 확인된 구독 이벤트:

| 이벤트 | types | 용도 |
|---|---|---|
| `pull_request` | `opened` | PR 생성 시 자동 리뷰 1회 |
| `issues` | `opened`, `reopened` | issue 처리 |
| `issue_comment` | `created` | `/gemini review` on-demand 트리거 |
| `pull_request_review` | `submitted` | review 분석 |
| `pull_request_review_comment` | `created` | review comment 분석 |

**미구독 이벤트** (자동 재리뷰 불가 증거):
- `pull_request.synchronize` (새 커밋 push)
- `pull_request.reopened`
- `pull_request.labeled`
- `check_suite` / `check_run`
- `workflow_run`

**evidence**:
- https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/gemini-dispatch/gemini-dispatch.yml

### 1.6 영역 6 — branch BEHIND 상태에서 Gemini 리뷰 생략 여부

**finding**: **BEHIND는 단독 trigger filter 조건이 아니다.** 4 사례 분석 결과:

- **PR #75**: 전 기간 BEHIND 없음. main 불변(parent=94344526f1 고정). commit2 이후 자동 재리뷰 없음(synchronize 미구독 증거).
- **PR #83**: commit2 이후 BEHIND 1차(06:06:08Z~06:22:43Z). 해당 구간 내 자동 재리뷰 없음. 회장 `/gemini review`로 BEHIND 상태에서도 응답 확인.
- **PR #86**: PR 생성 3m37s 후 BEHIND 전환. 그러나 Gemini 0건의 진짜 원인은 BEHIND가 아님 → gemini-review-gate에서 `git exit code 128`로 47s 만에 즉시 failure. 정확한 원인 불명(GitHub webhook 내역 비공개), best-effort 추정: BEHIND 전환 타이밍 또는 서비스 blip.
- **PR #87**: PR 생성 전부터 BEHIND 상태였으나 PR open 후 5m24s 만에 Gemini 1차 리뷰 정상 발화 → **반례** (BEHIND가 트리거 필터라면 발화 안 됐어야 함).

**결론**: BEHIND 상태에서 push에 의한 자동 재트리거는 억제되는 것으로 보임(synchronize 미구독). `/gemini review` 명령은 BEHIND 무관하게 동작. **PR open 트리거도 BEHIND 무관하게 동작.**

### 1.7 영역 7 — PR 사례 비교 표

| PR | task | 봇 | created | last_push | gemini_first | first_lag | BEHIND | recovery (회장) | result |
|---|---|---|---|---|---|---|---|---|---|
| #75 | 2526 | dev4 비슈누 | 01:28:39Z | 02:29:53Z | 01:30:36Z | 1m57s | 없음 | 02:26:46Z (`/gemini review`) | MERGED |
| #83 | 2534 | dev5 마르둑 | 05:58:52Z | 06:49:47Z | 06:00:01Z | 1m9s | 06:06:08Z~06:22:43Z (1차), 06:27:49Z~06:49:47Z (2차) | 06:26:48Z (`/gemini review`) | MERGED |
| #86 | 2537 | dev4 비슈누 | 06:24:12Z | 06:23:02Z | **null** | **미응답** | 06:27:49Z~현재 | **미회복** | OPEN_HOLD |
| #87 | 2538 | dev7 이참나 | 07:01:30Z | 07:32:08Z | 07:06:54Z | 5m24s (BEHIND에서도 정상) | PR 생성 전~07:11:04Z | 07:11:22Z (`/gemini review` 7차례) | OPEN_HOLD (BLOCKED, approval 미충족) |

**공통점**:
1. 4건 모두 push 이후 자동 재리뷰 없는 구간 발생(synchronize 미구독 증거).
2. bot actor(taskctl-bot)의 `/gemini review`는 응답 유발 안 됨 (PR #75 02:13:16Z 사례 확인).
3. 인간 회장(JonghyukJeon)의 `/gemini review`는 BEHIND 포함 모든 상태에서 Gemini 응답 유발.

**차이점**:
1. **PR #86만 PR open 자동 트리거가 0건** — 다른 3건은 1m9s~5m24s 내 정상 응답. 이는 BEHIND 패턴이 아닌 webhook 처리 실패(gemini-review-gate `git exit 128`)로 추정됨.
2. PR #87은 자기참조적 구조(AutoGeminiTriage 자체 적용)로 회장 7차례 `/gemini review` 사이클 발생.
3. PR #86은 gemini-review-gate가 git 명령 실패로 즉시 failure → 다른 3건과 별도 원인.

### 1.8 영역 8 — 대체 트리거 8 후보 검증

| ID | 후보 | 판정 | 사유 | evidence |
|---|---|---|---|---|
| (a) | label 추가 (`gemini-rerun` 등) | **불가** | 공식 dispatch 워크플로우 `pull_request.labeled` 미구독. 설정 파일에 label 트리거 옵션 없음. | gemini-dispatch.yml |
| (b) | workflow_dispatch | **조건부** | run-gemini-cli Action을 사용하는 별도 커스텀 워크플로우 구성 시 가능. Gemini App 자체는 인식 안 함. | github.com/google-github-actions/run-gemini-cli |
| (c) | check rerun | **불가** | check_suite/check_run 이벤트 미구독. | gemini-dispatch.yml |
| (d) | empty commit | **절대 금지** | 회장 §명시 fictitious change 룰 위반. 설령 synchronize 발생해도 Gemini 미반응. | (룰) |
| (e) | bot이 `/gemini review` 발행 | **불가** | sender.type=='User' 필터로 차단. 누적 사례 4건 무효 확증(PR #75 02:13:16Z taskctl-bot 응답 0건). | gemini-dispatch.yml |
| (f) | app token vs installation token | **불가** | App JWT는 코멘트 발행 불가. installation token으로 발행되는 모든 코멘트는 항상 `[bot]`/Bot 타입. | docs.github.com authenticating-as-a-github-app-installation |
| (g) | PR close-reopen | **조건부 (불가 추정)** | dispatch 워크플로우 `pull_request` types에 `reopened` 미포함. App 자체 webhook subscription 비공개. | gemini-dispatch.yml |
| (h) | branch update / force push | **불가** | synchronize 이벤트 미구독. force push 무관. | gemini-dispatch.yml |

**자동화 불가 결론**: 8개 후보 중 절대 가능 1건도 없음. (b) workflow_dispatch는 별도 커스텀 워크플로우 구축이 필요하여 본 시스템 범위 밖. (g) close-reopen은 조건부 추정이나 회장 §명시 금지(close/reopen 금지 룰 적용 가능).

### 1.9 영역 9 — 자동화 불가 시 처리

**nudge 최후수단 유지 권고** (task-2540 spec 그대로 박제 / 본 task 반려 결정 정합):

1. **operational nudge 모듈 spec 동결** — task-2540 정의 그대로 유지. 발사 보류 상태 유지.
2. **회장 직접 `/gemini review`만 신뢰 가능한 회복 경로** — 인간 actor(OWNER) author_association이 유일한 통과 조건.
3. **audit 누적 박제** — `memory/orchestration-audit/gemini-trigger-gap-260510.jsonl`에 사례별 발생 박제.
4. **임계 정의**:
   - **24h period당 3건 이상** 발생 시 별도 escalation (회장에게 임계 초과 보고 1회).
   - **단일 PR이 60min 이상 BEHIND_OR_GEMINI_GAP** 유지 시 회장 알림 1회.
   - **manual recovery burden 누적 minutes** 기록 (PR #75/#83는 약 58min, PR #86/#87는 본 조사 시점 미회복).

## 2. 자동화 가능 → 구현 권고 task

**해당 없음.** 자동화 불가 결론.

본 조사로 task-2540 (operational nudge module spec) 발사 보류 사유는 다음과 같이 정합 갱신:

> 자동화 대체 불가 확증 → nudge 모듈 본질이 회장 인간 actor 호출(텔레그램 통보)로 한정됨. operational nudge 본질이 변하지 않으므로 task-2540은 "회장 텔레그램 알림 모듈"로 spec 동결 유지.

## 3. task-2537 / task-2538 finalize 보류 권고

### 3.1 PR #86 (task-2537) — **조건부 보류 해제 권고**

**근거**:
- 본 조사 결과 BEHIND가 단독 차단 사유 아님 (PR #87 반례).
- 실제 차단 원인은 `gemini-review-gate` workflow에서 `git exit code 128` 실패 (별도 원인).
- Gemini App webhook 자체가 PR open에 미트리거 → 회장 `/gemini review` 1회 필요 (다른 3건과 동일 회복 경로).

**권고**:
1. 회장 `/gemini review` 1회 발사로 회복 시도 (다른 3건과 동일 패턴).
2. 회복 후 gemini-review-gate `git exit 128` 별도 root cause는 후속 task(미발행)로 이관.
3. 회복 실패 시 기술적 finalize 보류 연장 + chairman 직접 review 요청.

### 3.2 PR #87 (task-2538) — **조건부 보류 해제 권고**

**근거**:
- Gemini 리뷰 7차례 정상 작동(가장 활발한 PR).
- mergeable_state=BLOCKED 사유는 BEHIND/Gemini gap 아님 → **approval 미충족**.

**권고**:
1. Gemini 리뷰 결과 High severity 0건 확인 (회장이 task-2538 리뷰 결과 직접 검증 필요).
2. approval 1건 추가 시 자동 머지 가능.
3. BEHIND/Gemini gap과 직접 관련 없으므로 본 조사 결과로 보류 해제 가능.

## 4. 발견 이슈 및 해결

### 4.1 PR #86의 gemini-review-gate `git exit 128` (미해결, 범위 외)

**이슈**: PR #86의 gemini-review-gate workflow가 PR open 후 47초만에 `git exit code 128`로 즉시 failure. 다른 3건에서는 발생하지 않은 특이 사항.

**해결 상태**: 본 task 범위 외 (회장 §명시 read-only). 후속 task(미발행)로 이관 권고 — gemini-review-gate workflow 코드 read-only 조사 필요.

### 4.2 audit 누적 박제 (해결)

**이슈**: 4건 사례를 jsonl에 박제 필요.

**해결**: `memory/orchestration-audit/gemini-trigger-gap-260510.jsonl`에 INVESTIGATION_COMPLETE 레코드 1건 + 4 PR case 레코드 4건 append 예정 (다음 단계).

## 5. 회장 §명시 절대 금지 — 0건 위반

| 금지 항목 | 위반 |
|---|---|
| 코드 변경 | 0건 ✅ (read-only) |
| PR 생성 | 0건 ✅ (finalize_policy:no_pr) |
| 머지 | 0건 ✅ |
| 회복 nudge 발송 | 0건 ✅ |
| PR #86/#87 인간 계정 트리거 | 0건 ✅ |
| GitHub App 권한 변경 | 0건 ✅ |
| empty commit | 0건 ✅ |
| owner_pat / admin override / force / rebase | 0건 ✅ |
| manual `.done` | 0건 ✅ (finish-task.sh만 사용) |
| `--session` flag | 0건 ✅ |
| Critical 7종 외 회장 보고 | 0건 ✅ |

## 6. 모델 사용 기록

| 팀원 | 모델 | 작업 | 정당성 |
|---|---|---|---|
| 헤르메스(팀장) | opus-4-7 | 작업 분배, 결과 통합, 보고서 작성, 권고 결정 | 분석/판단 작업, 코딩 0건 |
| 불칸(백엔드) | sonnet | Gemini App 트리거 조건 외부 리서치 (영역 1-5, 8) | 리서치 작업 — sonnet 표준 |
| 아르고스(테스터) | sonnet | PR 4건 gh CLI read-only 타임라인 추출 (영역 6-7) | 분석 작업 — sonnet 표준, haiku 미사용 |

## 7. L1 스모크테스트 결과

- **서버 재시작**: 해당없음 (read-only research, no code change)
- **API 응답 확인**: 해당없음 (no API endpoint 변경)
- **스크린샷**: 해당없음 (no UI change)

본 task는 read-only / report-only / analysis-only / finalize_policy:no_pr 4 opt-out tokens 명시로 finalize 14단계 면제. L1 스모크테스트 대상 코드 없음.

## 8. 머지 판단

- **머지 필요**: No (finalize_policy:no_pr)
- **브랜치**: 없음 (worktree 미생성, project_id 부재)
- **워크트리 경로**: 해당없음
- **머지 의견**: 본 task는 read-only research 산출물이며 PR 생성 금지 (회장 §명시). 보고서 + audit jsonl append만 산출.

## 9. 산출물 (affected_files 정합)

| 파일 | 종류 | 상태 |
|---|---|---|
| `memory/reports/task-2542.md` | NEW | ✅ 본 보고서 |
| `memory/orchestration-audit/gemini-trigger-gap-260510.jsonl` | APPEND only | ✅ 다음 단계 박제 예정 |
| `memory/events/task-2542.done` | NEW (finalize 면제 마커) | finish-task.sh로 생성 |

## 10. 결론

```
task-2542 GEMINI_TRIGGER_GAP_INVESTIGATION_REPORT — 9 범위 답변 완료 / 4 사례 비교 / 8 대체 트리거 검증, 자동화 [불가] / [nudge 최후수단 유지 + audit 임계 24h당 3건 정의], task-2537/2538 finalize 보류 [조건부 해제 — 회장 /gemini review 1회 + approval 검증] 권고, Critical 7종 0건.
```

**핵심 통찰**:

1. **Gemini App은 `pull_request.opened` 이벤트만 자동 구독** — push/main merge/label/check rerun으로는 자동 재리뷰 불가.
2. **bot의 `/gemini review`는 자동 차단** — sender.type=='User' AND OWNER/MEMBER/COLLABORATOR 필터 (PR #75 02:13:16Z taskctl-bot 사례 확증).
3. **BEHIND는 트리거 차단 단독 조건 아님** — PR #87 반례(BEHIND에서도 PR open 트리거 정상).
4. **PR #86의 0건은 별도 원인** — gemini-review-gate `git exit 128` workflow 실패 (BEHIND/Gemini gap과 무관).
5. **자동화 불가 확증** — 8개 후보 모두 불가/조건부, nudge 최후수단 유지.
6. **회복 경로 단일화** — 회장(OWNER) 직접 `/gemini review`만 신뢰 가능.

## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회

