# task-2467+3 — taskctl PR Lifecycle 최종 재위임 (bot author 문제 해결)

- 작업 유형: **retry-final** (task-2467 계열 최종 재위임, +2 포맷)
- 작업 레벨: **Lv.4 critical**
- 위임팀: **dev6-team (페룬, opus)**
- Track: **dev_workspace** (시스템 거버넌스)
- 우선순위: **★★★ blocking** — task-2466 / 2468 / 2469 / PR #29 모두 의존
- 일시: 2026-05-06

## 0. 배경 — task-2467 계열 진화

| 단계 | 결과 | PR | 상태 |
|------|------|-----|------|
| task-2467 (1차) | 구현 성공, PR 미생성 | - | ESCALATED (state=COMMITTED) |
| task-2467+1 (2차) | PR #32 생성, REVIEW_READY 도달 | #32 (CLOSED 2026-05-06) | ESCALATED (운영 선행조건 부재) |
| **task-2467+3 (본 task)** | bot author 문제 해결한 최종 재위임 | TBD | 목표: MERGED+DONE |

## 1. task-2467+1 ESCALATED 사유 5건 (입력 자료)

본 task 시작 전 반드시 확인:

1. **BOT_GITHUB_TOKEN 미발급** — bot 계정 PAT가 환경에 없음
2. **`pr-open --auto`가 chairman gh auth로 fallback** — graceful degradation했지만 결과적으로 author=chairman
3. **PR author = JonghyukJeon (회장 계정)**
4. **self-approve guard 정상 작동** — author == approver 차단됨
5. **author != approver 룰 충족 불가** — 회장만 access 가능한 환경

→ **이 5가지 사유 자체가 본 task의 출발점**. 회장 명시: "실패 X / 운영 선행조건 부재 발견"

## 2. ★ task-2467+1 처리 (이미 완료)

- ✅ PR #32 close (2026-05-06, 아누가 처리, comment로 사유 박제)
- ✅ task-2467+1 ESCALATED 보존 (`.done.escalated`)
- ✅ `.done` 발행 안 됨 (회장 룰 준수)
- ✅ task-2467+1 보고서 / task 파일 read-only 보존

## 3. allowed_resources

```yaml
allowed_resources:
  paths:
    # task-2467+1 worktree에서 1차 코드 합산
    - "scripts/taskctl.py"
    - "scripts/finish-task.sh"
    - "scripts/worktree_manager.py"
    - "scripts/anu_confirm_bot.py"
    - "scripts/guard.sh"
    - "scripts/qc_report_guard.py"
    - "scripts/start_task_guard.py"
    - "scripts/g3_independent_verifier.py"
    - "tests/taskctl/**"
    - "tests/state_machine/**"
    - "memory/tasks/task-2467+3*"
    - "memory/reports/task-2467+3*"
    - "memory/specs/taskctl-state-machine-spec*.md"
    - "memory/specs/pr-lifecycle-spec*.md"
    - "memory/specs/bot-pat-setup*.md"  # 신설 — bot PAT 운영 절차
    - ".env.keys"  # bot PAT 추가 (read-only 확인)
  bot_authentication_setup:
    - "★ BOT_GITHUB_TOKEN 환경변수 또는 .env.keys 로딩 경로 확인"
    - "bot 계정 GitHub PAT (repo + workflow + pull_request scope)"
    - "회장이 사전에 발급/주입한 PAT 활용 (본 task에서 발급 X)"
    - "PAT 부재 시 → 즉시 ESCALATED 종료, fail-fast"
  forbidden_paths:
    - "PR #29 / PR #30 / PR #31 / PR #32"  # 절대 변경 금지
    - "memory/events/task-2465*"
    - "memory/events/task-2466*"
    - "memory/events/task-2467.*"            # 1차 read-only
    - "memory/events/task-2467+1.*"          # 2차 read-only (ESCALATED 보존)
    - "memory/orchestration-audit/task-2465*"
    - "memory/reports/task-2465.md"
    - "memory/reports/task-2467.md"
    - "memory/reports/task-2467+1.md"        # 2차 보고서 read-only
    - "memory/tasks/task-2467+1.md"
    - ".github/**"
    - "dispatch.py"
    - "memory/organization-structure.json"
    - "bot_settings.json"
  forbidden_actions:
    - "PR #29 / #30 / #31 / #32 어떤 변경도 금지 (#32는 close 완료, 재open 금지)"
    - "task-2467 / task-2467+1 / task-2465 / task-2466 1차 결과 임의 수정 금지"
    - "GEMINI_API_KEY 도입 절대 금지"
    - "admin override 사용 금지 (회장 명시 — task-2465 1회 한정)"
    - "gh pr merge 직접 호출 금지 (taskctl 내부 제외)"
    - "gh pr create 직접 호출 금지 (taskctl 내부 제외)"
    - "git push origin main 직접 호출 금지"
    - "회장 직접 PR open 금지 (task-2467+1과 동일 fallback 재발 차단)"
    - "bot PAT 없이 새 lifecycle PR merge 금지"
    - "task-2466 / task-2468 / task-2469 / PR #29 선행 금지 (모두 본 task MERGED+DONE 후)"
    - "graceful fallback 금지 — bot PAT 부재 시 fail-fast 강제"
  commands:
    - "python3 scripts/taskctl.py <subcommand>"
    - "git / gh api / gh pr (taskctl 내부 + 테스트)"
    - "pytest / pyright"
    - "grep -rn"
  merge_policy: "★ 새 taskctl 흐름으로만 머지. admin override 절대 금지. bot author 강제."
  ttl_hours: 8
```

## 4. ★ START 절차

```bash
cd /home/jay/workspace
test "$(git branch --show-current)" = "main" || exit 1

# 0단계 — bot PAT 사전 확인 (★ fail-fast)
python3 -c "
import os
token = os.environ.get('BOT_GITHUB_TOKEN') or os.environ.get('GH_BOT_TOKEN')
if not token:
    # .env.keys 로드 시도
    from pathlib import Path
    env_path = Path('.env.keys')
    if env_path.exists():
        for line in env_path.read_text().splitlines():
            if line.startswith('BOT_GITHUB_TOKEN=') or line.startswith('GH_BOT_TOKEN='):
                token = line.split('=', 1)[1].strip().strip('\"').strip(\"'\")
                break
if not token:
    print('★ FAIL-FAST: BOT_GITHUB_TOKEN 미발급 → ESCALATED 즉시 종료')
    exit(1)
print('OK: bot token 확인됨 (앞 4자):', token[:4] + '...')
"

# 1단계 — task-2467+3 worktree (1차+2차 코드 합산)
python3 scripts/start_task_guard.py --task task-2467+3 --bot dev6 --pre-init
git worktree add .worktrees/task-2467+3-dev6 -b task/task-2467+3-dev6 origin/main
cd .worktrees/task-2467+3-dev6

# 2단계 — task-2467 / task-2467+1 코드 합산 (cherry-pick 또는 squash)
# (1차+2차 worktree에서 commit 가져오기)

python3 scripts/start_task_guard.py --task task-2467+3 --bot dev6

# 3단계 — 새 taskctl 흐름 (bot author 강제)
python3 scripts/taskctl.py init task-2467+3
python3 scripts/taskctl.py worktree-ready task-2467+3
python3 scripts/taskctl.py run task-2467+3
python3 scripts/taskctl.py commit task-2467+3
python3 scripts/taskctl.py handoff task-2467+3
python3 scripts/taskctl.py pr-open task-2467+3 --auto   # ★ bot token으로 PR 생성 (fail-fast)
python3 scripts/taskctl.py ci-check task-2467+3
python3 scripts/taskctl.py gemini-evidence task-2467+3
python3 scripts/taskctl.py review-ready task-2467+3
python3 scripts/taskctl.py verify task-2467+3

# verify PASS + bot author 확인 후 회장 approve
# (회장이 텔레그램으로 명시 승인 → taskctl approve --by chairman)

python3 scripts/taskctl.py merge task-2467+3
python3 scripts/taskctl.py done task-2467+3
```

## 5. ★★★ 회장 명시 12 필수 목표

1. **BOT_GITHUB_TOKEN 또는 bot PR author 경로 준비**
2. **PR author가 반드시 bot 계정인지 확인** (PR 생성 직후 즉시 검증)
3. **chairman gh auth fallback으로 PR 생성 금지**
4. **bot PAT 부재 시 `pr-open --auto`는 graceful fallback 하지 말고 fail-fast**
5. **GitHub API 기반 PR author 검증** (`/repos/{}/pulls/{}` → `user.login`)
6. **author != approver 강제** (taskctl approve에서 검사)
7. **self-approve guard 통과**
8. **PR_OPEN 도달**
9. **REVIEW_READY 도달**
10. **approve 통과**
11. **taskctl merge 경유로 MERGED 도달**
12. **MERGED 이후에만 DONE 처리**

## 6. ★ 실행 흐름 10단계

```
worktree-ready → commit → handoff → ci-check → gemini-evidence → review-ready → pr-open --auto → approve --by <chairman 또는 지정 reviewer> → merge → done
```

## 7. ★ 필수 검증 10건

1. pyright 0 errors
2. pytest state_machine/taskctl 관련 테스트 PASS
3. G3 PASS
4. QC PASS 또는 WARN 0건
5. Gemini evidence 박제
6. hidden path audit PASS
7. start-guard 최초 실패가 있으면 원인까지 evidence 박제
8. `.done`은 MERGED 전 발행 금지
9. BLOCKED/ESCALATED 시 `.done` 금지
10. PR #29 / #30 / #31 / #32 변경 없음 확인

## 8. ★★★ 절대 금지 (회장 명시 10건)

- PR #32 merge / approve / 재open 금지
- task-2467+1 수정 재개 금지
- 회장 직접 PR open 금지
- admin override 금지
- bot PAT 없이 새 lifecycle PR merge 금지
- task-2466 / 2468 / 2469 선행 금지
- PR #29 처리 금지
- gh pr merge 직접 호출 금지
- gh pr create 직접 호출 금지
- graceful fallback 금지 (fail-fast 강제)

## 9. ★ 최종 보고서 18 필수 항목

`memory/reports/task-2467+3.md`에 SCQA + 다음 18건 모두 명시:

1. task-2467+1 PR #32 close 여부
2. task-2467+1 ESCALATED 보존 여부
3. task-2467+3 생성 여부
4. bot PR author 확인 결과
5. PR 번호
6. PR author / approver
7. self-approve guard 통과 evidence
8. pyright 결과
9. pytest 결과
10. G3 결과
11. QC 결과
12. Gemini evidence 결과
13. hidden path audit 결과
14. merge commit SHA
15. 최종 state
16. `.done` 발행 시점
17. task-2468로 넘길 후속 항목
18. task-2466 / task-2468 / task-2469 진행 가능 여부

## 10. task-2468 부채 상환 항목 (회장 명시)

본 task-2467+3 MERGED+DONE 후 task-2468에서 진행:

1. `pr-open --auto` fail-fast 정식화
2. merge 시 Gemini evidence 강제
3. GitHub API 기반 author 검증 고도화
4. `taskctl --worktree` 인자 또는 worktree 자동 감지
5. `+M` task_id 형식 verifier 지원
6. `TASKCTL_BYPASS=1` 우회 경로 재검토
7. override 사용 시 audit log 필수화

## 11. 합격 / 판정 기준 (회장 명시)

### 합격 (MERGED + DONE 도달)
1. PR author = bot ✅
2. approver != author ✅
3. G3 PASS / QC PASS or WARN 0건 / Gemini evidence PASS / hidden path audit PASS
4. `taskctl approve` 통과 → `taskctl merge` 통과
5. state == MERGED → state == DONE
6. `.done`은 MERGED 후에만 존재
7. **task-2467 계열 완료로 인정** → task-2466 / 2468 / 2469 / PR #29 진행 가능

### ESCALATED (PR_OPEN 또는 REVIEW_READY에서 bot author 문제로 막힘)
- ESCALATED 종료 + `.done` 금지
- task-2467 계열 미완료 유지
- task-2466 / 2468 / 2469 / PR #29 모두 차단 유지
- 다음 단계: bot PAT 운영 절차 별도 task로 분리 (task-2467+3 또는 신규 ID)

## 12. 위임 완결성 4대 규칙

1. **수신 확인**: dispatch 출력 "위임 완료" + cron status=ok. 백업 cron **금지**
2. **빌드+배포**: 새 taskctl 흐름으로 자기 자신 머지 (drink your own champagne)
3. **실 E2E**: PR 생성 + bot author 검증 + Gemini App review + 회장 approve + taskctl merge + main 반영. 모든 단계 evidence 9종 박제
4. **구조 선행 파악**: 위임 전 다음 read 필수
   - `.worktrees/task-2467-dev6/` (1차 코드)
   - `.worktrees/task-2467+1-dev6/` (2차 코드)
   - `memory/reports/task-2467.md` + `memory/reports/task-2467+1.md`
   - PR #32 evidence (close 사유)
   - 회장 박제 audit `memory/orchestration-audit/task-2465.jsonl`

## 13. 시스템 청사진 연관

본 task = `system_bot_orchestration_blueprint_260506.md` 5층 자동화의 **첫 self-merge 성공 케이스**.

- track: `dev_workspace` (시스템 거버넌스)
- 무거운 게이트: 3문서 + smoke + Gemini evidence + merge_queue
- excluded: production_deploy / security_change / credential_change / external_api_write / **gate_bypass** / **force_merge**

## 14. 의존 task

- **선행**: task-2465 (MERGED ✅) / task-2467 (ESCALATED) / task-2467+1 (ESCALATED, PR #32 closed)
- **후행**:
  - task-2466 (위스퍼 데이터 정합성) — 본 task MERGED+DONE 후
  - task-2468 (Phase C — Gate 통합 + 부채 상환 7건) — 본 task 후
  - task-2469 (Phase D — Penetration tests) — task-2468 후
  - PR #29 (task-2463) 머지 — 본 task 후

## 15. goal_assertions

- `python3 scripts/taskctl.py status task-2467+3` → state == DONE
- `gh pr view <task-2467+3 PR> --json author -q '.author.login'` → bot 계정 (NOT 'JonghyukJeon')
- `gh pr view <task-2467+3 PR> --json mergedAt -q '.mergedAt'` → 비어있지 않음
- `git log origin/main --oneline | head -3` → task-2467+3 merge commit 존재
- `cat memory/orchestration-audit/admin-override.jsonl` → 본 task 항목 0건
- `grep -rn "gh pr merge" --exclude-dir=.git --exclude-dir=tests` → `scripts/taskctl.py` 외 0건
- `pyright scripts/taskctl.py` → 0 errors
- `ls memory/events/task-2467+3.done` → 존재 (MERGED 후에만)
- `ls memory/events/task-2467+3.done.escalated` → 부재 (합격 시) 또는 존재 (ESCALATED 시)

## goal_assertions (auto-generated)
- `python3 scripts/taskctl.py status task-2467+3`
- `cat memory/orchestration-audit/admin-override.jsonl`
- `grep -rn "gh pr merge" --exclude-dir=.git --exclude-dir=tests`