# task-2486 — CI pull_request SHA payload fallback fix

- 작업 유형: **CI workflow infrastructure defect hotfix**
- 작업 레벨: **Lv.2** (workflow 1~2 파일 수정 + dry-run + 회귀)
- 위임팀: **dev1-team (헤르메스)** — 추천
- 우선순위: **★★ blocking** — task-2485 PR #47 머지, task-2472+1 PR #42 머지, task-2483 close 자동화 모두 의존
- Track: **dev_workspace**
- 일시: 2026-05-08
- 선행: task-2485 코드 PASS 박제 (CODE_PASS / MERGE_PENDING_DEPENDENCY)
- 후행: 본 task 머지 → PR #47 CI 자동 PASS → PR #47 MERGED → task-2485 MERGED_DONE → 후속 chain 자동 진행

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

> `.github/workflows/ci.yml`의 `gemini-review-gate` / `phase3-merge-gate`에서 `pull_request` 이벤트의 head SHA가 빈 값으로 들어와 required CI가 실패하는 결함을 수정한다. **stale evidence가 아니라 workflow SHA 추출 로직 결함**으로 판단됨 (재시도 5회 모두 동일 실패).

## allowed_resources

```yaml
allowed_resources:
  paths:
    - ".github/workflows/ci.yml"
    - ".github/workflows/guard.yml"  # 동일 결함 가능성 점검
    - "scripts/gemini_review_gate.py"  # SHA 인자 처리 보강 시
    - "tests/regression/test_workflow_sha_payload*.py"
    - "tests/regression/test_workflow_taskid_regex*.py"  # 회귀 보강 시
    - "scripts/verify_workflow_sha_payload*.py"  # 신설 dry-run
    - "memory/tasks/task-2486*"
    - "memory/reports/task-2486*"
    - "memory/plans/tasks/task-2486/**"
    - "memory/events/task-2486*"
  forbidden_paths:
    - "scripts/refresh_bot_token.py"  # task-2483 영역
    - "utils/state_repair.py"
    - "utils/g3_fail_classifier.py"
    - "utils/silent_corruption_guard.py"
    - "utils/task_id_parser.py"  # task-2485 본질
    - "scripts/taskctl.py"
    - "scripts/dispatch.py"
    - "scripts/finish-task.sh"
    - "teams/dev1/qc/verifiers/**"  # task-2485 본질
    - "teams/shared/verifiers/**"
    - ".secrets/**"
    - "memory/events/task-2472*"
    - "memory/events/task-2479*"
    - "memory/events/task-2481*"
    - "memory/events/task-2483*"
    - "memory/events/task-2484*"
    - "memory/events/task-2485*"
  forbidden_actions:
    - admin_override
    - branch_protection_bypass
    - force_merge
    - manual_done
    - required_ci_bypass
    - force_merge_pr_47  # task-2485 PR 강제 머지 금지
    - workflow_skip
    - if_false_pattern
```

## 0. 배경 — 차단 evidence

- task-2485 PR #47 5회 재시도 모두 동일 FAIL 패턴
- 실패 로그: `missing pull_request payload (SHA= PR=47)` (PR=47은 정상, SHA만 빈 값)
- 시도 내역:
  1. commit ccaaf0e1 직후 → run 25505249701 FAIL
  2. `gh run rerun --failed` → 동일 run id 재시도 FAIL
  3. PR close + reopen → 새 run 미발생
  4. empty commit 7a4ba6a9 push → run 25505664583 FAIL
  5. main 동기화 + merge commit ebf8878d push → run 25506284674 FAIL
- evidence: `memory/events/task-2485.code-pass-merge-pending`, `memory/events/task-2485.followup.txt`

## 1. 작업 범위 (회장 명시 8단계)

### Step 1. SHA/PR 추출 로직 점검
- `.github/workflows/ci.yml`의 `gemini-review-gate` + `phase3-merge-gate` job
- 현재 패턴:
  ```yaml
  SHA="${{ github.event.pull_request.head.sha }}"
  PR="${{ github.event.pull_request.number }}"
  if [[ -z "$SHA" || -z "$PR" ]]; then exit 1; fi
  ```
- `.github/workflows/guard.yml` 동일 결함 가능성 점검

### Step 2. 이벤트 상황별 안전 fallback 설계
- `pull_request` (정상 케이스에서도 SHA 빈 값 발생 확인)
- `pull_request_target` (검토)
- `workflow_dispatch`
- rerun (re-run failed jobs)

### Step 3. SHA fallback 후보 (순서대로 검토)
1. `github.event.pull_request.head.sha`
2. `github.event.after`
3. `github.sha`
4. `gh pr view <PR> --json headRefOid` (마지막 fallback)

### Step 4. PR 번호 fallback 점검
- `github.event.pull_request.number`
- `github.event.number`
- `gh pr list --head $BRANCH --json number`

### Step 5. fallback audit 로그
- empty SHA일 때 즉시 실패하지 말고, fallback 후보 시도
- 모든 후보 결과를 audit log에 남김 (`memory/orchestration-audit/workflow-sha-fallback.jsonl` 등)
- 모든 후보 실패 시에만 진짜 실패 처리

### Step 6. PR #47 수정 후 required CI PASS 확인
- 본 task 머지 후 PR #47에서 자동 재실행
- gemini-review-gate / phase3-merge-gate PASS 검증

### Step 7. PR #47 MERGE_READY 확인
- 11개 required check 전부 PASS 확인
- mergeable=MERGEABLE 확인

### Step 8. PR #42 / task-2472+1 차단 해소 여부 확인
- task-2485 머지 후 PR #42에도 자동 영향 (workflow가 main 기준이므로)
- PR #42 taskctl-state-guard 2건 PASS 검증
- 단, PR #42 머지는 본 task 범위 외 (별도 자동화 또는 anu-direct 처리)

## 2. 합격 조건 (회장 명시 6건)

1. ✅ task-2486 PR 생성
2. ✅ workflow 관련 테스트 또는 dry-run PASS
3. ✅ PR #47의 `gemini-review-gate` PASS
4. ✅ PR #47의 `phase3-merge-gate` PASS
5. ✅ PR #47 MERGE_READY 확인
6. ✅ task-2485가 MERGED_DONE 경로로 전환 가능한지 확인

## 3. 금지 (회장 명시 4건 + 보강)

- ❌ admin override
- ❌ 수동 .done 발행
- ❌ required CI bypass / `if: false` 패턴
- ❌ task-2485 PR #47 강제 머지
- ❌ task-2472+1 / task-2483 본질 코드 추가 수정
- ❌ task-2485 / task-2486 외 영역 변경

## 4. 회귀 테스트 (필수)

- `tests/regression/test_workflow_sha_payload*.py` 신설 (또는 기존 workflow 테스트 확장)
- pull_request 이벤트 SHA 빈 값 시뮬레이션 → fallback 동작 검증
- 모든 fallback 후보가 빈 값일 때만 fail
- legacy 케이스 (정상 SHA) 미파괴

## 5. 검증 자동화

- `scripts/verify_workflow_sha_payload.py` 신설 또는 기존 검증 스크립트 확장
- 다양한 이벤트 페이로드 fixture에 대해 SHA 추출 결과 검증
- exit 0 = PASS

## 6. 보고 형식

- SCQA 4섹션
- Step 1~8 각 결과 (PASS / FAIL / N/A)
- 합격 조건 6가지 evidence
- forbidden_actions 위반 0건 검증
- PR #47 / PR #42 영향 검증 결과

## 7. 시스템 3문서 참조 (필수)

- 시스템 청사진: `/home/jay/.claude/projects/-home-jay--cokacdir-workspace-autoset/memory/system_bot_orchestration_blueprint_260506.md`
- task-2485 차단 evidence: `memory/events/task-2485.followup.txt`, `memory/events/task-2485.code-pass-merge-pending`
- MERGE_PENDING_DEPENDENCY 분류 룰: `memory/feedback/feedback_merge_pending_dependency_classification_260507.md`
- Phase B 통합 항목: `memory/orchestration/phase_b_integration_items_260507.md`

## 8. 후속 (회장 명시 — 본 task 범위 외)

- 본 task 머지 후:
  1. PR #47 CI 자동 재실행 → gemini-review-gate / phase3-merge-gate PASS
  2. PR #47 MERGED → task-2485 MERGED_DONE
  3. PR #42 CI 자동 재실행 → taskctl-state-guard 2건 PASS (이미 PASS 확인됨)
  4. PR #42 MERGED → task-2472+1 .done
  5. task-2483 finish-task 재실행 → MERGED_DONE
  6. task-2484 자동 해소 또는 보류 해제

## goal_assertions (auto-generated)

- `python3 scripts/verify_workflow_sha_payload.py` exit 0
- PR #47 statusCheckRollup에서 gemini-review-gate / phase3-merge-gate `conclusion=SUCCESS`
- task-2485 lifecycle close 가능 evidence