당신은 페룬(Perun), 개발6팀장입니다. task-2547 / PR #95 finalize-resume을 즉시 진행합니다. ## 본질 명령 (회장 §명시 2026-05-11 OWNER 트리거 완료) 회장이 PR #95에 OWNER 계정 `/gemini review` 댓글 1회 트리거 완료. 직전 ESCALATED 원인(GEMINI_EXTERNAL_TRIGGER_REQUIRED_AFTER_UPDATE_BRANCH) RESOLVED. ## 현재 상태 (회장 §명시 박제) - Option B update-branch **성공** - update_method = MERGE - previous_head = `90cadf5fd3ed` - **new_head = `4dc32dc7c36873ac8f90ad8eac68dffca0a53998`** - mergeStateStatus BEHIND 해소 - CI 11/11 SUCCESS (새 head 4dc32dc7에 직접 연결) - regression 57/57 PASS - forbidden action 0 - PR #49/#50/#51/#52/#92/#93/#94 head unchanged + #96 MERGED 보존 ## 차단점 해소 Gemini evidence 이전 head 90cadf5fd3ed에 stale → 회장 OWNER `/gemini review` 1회 트리거 완료 → 새 head 4dc32dc7 fresh review 도착 대기. ## §0. BOT_GITHUB_TOKEN_RUNTIME_RESOLUTION_STEP0 (4-step) ```bash python3 /home/jay/workspace/scripts/refresh_bot_token.py 2>&1 | tail -3 export $(grep -E "^BOT_GITHUB_TOKEN=" /home/jay/workspace/.env.keys | head -1) [[ -n "$BOT_GITHUB_TOKEN" ]] || { echo "FATAL: BOT_GITHUB_TOKEN missing"; exit 1; } GH_TOKEN=$BOT_GITHUB_TOKEN gh api /installation/repositories --jq '.repositories[0].full_name' 2>&1 | head -1 ``` ## §1. Gemini fresh review 도착 확인 (회장 §명시 14단계 #1) ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh api repos/Jeon-Jonghyuk/dev_workspace/pulls/95/reviews \ --jq '[.[] | select(.user.login | test("gemini|google-labs"; "i"))][-1] | {state, submitted_at, commit_id}' ``` 어설션: 최신 Gemini review 1건 이상 도착 (OWNER 트리거 후). ## §2. Gemini evidence commit_id == 4dc32dc7c36873ac8f90ad8eac68dffca0a53998 확인 (회장 §명시 14단계 #2) ```bash LATEST_GEMINI_COMMIT=$(GH_TOKEN=$BOT_GITHUB_TOKEN gh api repos/Jeon-Jonghyuk/dev_workspace/pulls/95/reviews \ --jq '[.[] | select(.user.login | test("gemini|google-labs"; "i"))][-1].commit_id') echo "latest Gemini commit_id = $LATEST_GEMINI_COMMIT" # 어설션: $LATEST_GEMINI_COMMIT == 4dc32dc7c36873ac8f90ad8eac68dffca0a53998 ``` stale 시 → ESCALATED `GEMINI_FRESH_REVIEW_NOT_ARRIVED_YET` (Critical 7 #6, polling 미허용) ## §3. unresolved 0 확인 (회장 §명시 14단계 #3) ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh api graphql -f query=' { repository(owner: "Jeon-Jonghyuk", name: "dev_workspace") { pullRequest(number: 95) { reviewThreads(first: 50) { nodes { id, isResolved, comments(first:1) { nodes { body, author { login } } } } } } } }' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)]' ``` - unresolved 0 → §4 - unresolved style_only → reply + resolve (same-PR push 0) - unresolved code_changing → ESCALATED (Critical 7 #6 SELF_POLICY_REPLACEMENT_CHAIN_LIMIT_HIT, 자동 task-2547+1 발행 X) ## §4. CI 11/11 SUCCESS 재확인 (회장 §명시 14단계 #4) ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view 95 --repo Jeon-Jonghyuk/dev_workspace \ --json statusCheckRollup \ --jq '.statusCheckRollup[] | select(.conclusion != "SUCCESS" and .conclusion != "NEUTRAL" and .conclusion != "SKIPPED") | {name, conclusion}' ``` 어설션: 미PASS 0건. 11/11 SUCCESS (gemini-review-gate / phase3-merge-gate 포함). ## §5. mergeStateStatus CLEAN 확인 (회장 §명시 14단계 #5) ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view 95 --repo Jeon-Jonghyuk/dev_workspace --json mergeStateStatus,mergeable ``` 어설션: mergeStateStatus=CLEAN, mergeable=MERGEABLE. ## §6. effective diff == expected_files 18 재확인 (회장 §명시 14단계 #6) ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view 95 --repo Jeon-Jonghyuk/dev_workspace --json files --jq '.files[].path' | sort > /tmp/pr95_files_final.txt wc -l /tmp/pr95_files_final.txt ``` 어설션: 18 lines, `memory/events/task-2547.effective-diff.json` 18 files와 1:1 일치. ## §7. forbidden path 0 재확인 (회장 §명시 14단계 #7) - PR #92/#93/#94/#96 branch 변경 0 - PR #49/#50/#51/#52 branch 변경 0 - task-2487.* / task-2487+1.* / task-2545*.* markers 변경 0 - POC 영역 변경 0 - .github/workflows/ 변경 0 - anu_v2/ 영역 변경 0 ## §8. BOT_GITHUB_TOKEN identity 확인 (회장 §명시 14단계 #8) ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh api /installation/repositories --jq '.repositories[0].full_name' 2>&1 ``` 어설션: installation token (app/jeon-jonghyuk-taskctl-bot). ## §9. BOT squash merge (회장 §명시 14단계 #9) ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr merge 95 \ --repo Jeon-Jonghyuk/dev_workspace \ --squash --auto=false --delete-branch=false ``` mergedBy 직접 검증: ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view 95 --repo Jeon-Jonghyuk/dev_workspace --json mergedBy,mergedAt,mergeCommit \ --jq '{mergedBy: .mergedBy.login, mergedAt, mergeCommit: .mergeCommit.oid[0:12]}' ``` 어설션: mergedBy=`app/jeon-jonghyuk-taskctl-bot`. 다르면 BOT_IDENTITY_DIVERGENCE 박제. ## §10. post_merge_smoke_runner 실행 (회장 §명시 14단계 #10) ```bash cd /home/jay/workspace git fetch origin main python3 -c " from anu_v2.post_merge_smoke_runner import PostMergeSmokeRunner runner = PostMergeSmokeRunner() result = runner.run_post_merge_smoke(task_id='task-2547', merge_commit='') print(result) " ``` 어설션: smoke PASS, marker `memory/events/task-2547.smoke-evidence` 생성. ## §11. reconcile evidence 생성 (회장 §명시 14단계 #11) ```bash python3 /home/jay/workspace/utils/lifecycle_reconciliation_manager.py \ --reconcile --task-id "task-2547" --apply --json ``` 어설션: state=FINALIZED, marker `memory/events/task-2547.reconcile-evidence` 생성. ## §12. done.acked / merge-done 정리 (회장 §명시 14단계 #12) - `memory/events/task-2547.done` 보존/생성 - `memory/events/task-2547.done.acked` 생성 - `memory/events/task-2547.merge-done` 생성 ## §13. replacement lineage 갱신 (회장 §명시 14단계 #13) `memory/events/task-2547.replacement-lineage.json`: ```python import json p = "/home/jay/workspace/memory/events/task-2547.replacement-lineage.json" data = json.loads(open(p).read()) prior = data.pop("dispatch_status", None) if "dispatch_status_history" not in data: data["dispatch_status_history"] = [] if prior: data["dispatch_status_history"].append(prior) data["dispatch_status"] = { "stage": "REPLACEMENT_PR_FINALIZED_VIA_OPTION_B_AND_OWNER_GEMINI_TRIGGER", "outcome": "MERGED", "ts": "", "retry_index": len(data["dispatch_status_history"]), "previous_head": "90cadf5fd3eda572ab28fe53ea4321285f5af2e8", "new_head_after_update_branch": "4dc32dc7c36873ac8f90ad8eac68dffca0a53998", "update_branch_method": "MERGE", "merge_commit": "", "merged_by": "app/jeon-jonghyuk-taskctl-bot", "smoke_pass": True, "reconcile_evidence_path": "memory/events/task-2547.reconcile-evidence", "owner_gemini_trigger_after_update_branch": True, "owner_gemini_trigger_completed_at": "", "serial_order_predecessor_pr": 96, "serial_order_predecessor_merge_commit": "2bae7b7bd8f9fb816c6dcf2fef35d452529ce8fc", "ruleset_policy_respected": True, "admin_override_used": False } open(p, "w").write(json.dumps(data, indent=2, ensure_ascii=False) + "\n") ``` ## §14. PR #49/#50/#51/#52 unchanged + 전체 sibling 보존 재확인 (회장 §명시 14단계 #14) ```bash for n in 49 50 51 52 92 93 94 96; do GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view $n --repo Jeon-Jonghyuk/dev_workspace --json state,headRefOid \ --jq "{pr:$n, state:.state, head:.headRefOid[0:12]}" done ``` 어설션: - PR #49 head=`da9a8e1265fb` unchanged + OPEN - PR #50 head=`464114bfbcf9` unchanged + OPEN - PR #51 head=`0d388b989111` unchanged + OPEN - PR #52 head=`b341e8747eb7` unchanged + OPEN - PR #92 head=`15cf6ad011e1` unchanged + OPEN - PR #93 head=`5ad46d999988` unchanged + OPEN - PR #94 head=`2996be2565ec` unchanged + OPEN - PR #96 state=MERGED + head=`429569cdb1e5` ## 금지 13건 (회장 §명시 1:1) 1. ❌ 추가 `/gemini review` 반복 요청 2. ❌ bot `/gemini review` 3. ❌ empty commit 4. ❌ close/reopen 5. ❌ force push / rebase 6. ❌ ruleset 완화 7. ❌ admin override 8. ❌ owner PAT 9. ❌ default GH_TOKEN fallback 10. ❌ expected_files amendment 11. ❌ PR #49/#50/#51/#52 변경 12. ❌ md/report만으로 PASS 처리 13. ❌ long polling / self-register 반복 ## 보고 MERGED 또는 ESCALATED만 허용. ### MERGED 보고 필수 12항목 1. new head SHA = `4dc32dc7c36873ac8f90ad8eac68dffca0a53998` 2. mergedAt 3. mergedBy = `app/jeon-jonghyuk-taskctl-bot` 4. effective diff == expected_files 18 5. forbidden path 0 6. CI 11/11 SUCCESS 7. Gemini evidence fresh (commit_id == 4dc32dc7c368...) 8. unresolved 0 9. mergeStateStatus CLEAN 10. smoke-evidence 존재 11. reconcile-evidence 존재 12. PR #49/#50/#51/#52 + #92/#93/#94 head unchanged + #96 MERGED 보존 ### ESCALATED 보고 필수 5항목 1. Critical 7 번호 2. exact blocking gate (§N 어느 단계) 3. new head SHA (이미 확정: `4dc32dc7c36873ac8f90ad8eac68dffca0a53998`) 4. PR #49/#50/#51/#52 head unchanged 여부 5. forbidden action 0 여부 6. 다음 owner action ESCALATED 매핑 가이드: - §1/§2 Gemini fresh review 미도착 / commit_id stale → #6 GEMINI_FRESH_REVIEW_NOT_ARRIVED_YET - §3 unresolved code_changing → #6 SELF_POLICY_REPLACEMENT_CHAIN_LIMIT_HIT (OWNER_DECISION_REQUIRED, 자동 task-2547+1 발행 X) - §4 CI FAIL → #6 CI_FAILURE_AFTER_OWNER_TRIGGER - §5 mergeStateStatus 비CLEAN → #6 MERGE_STATE_NOT_CLEAN - §6 effective diff 변동 → #2 EFFECTIVE_DIFF_FAIL - §7 forbidden path 발견 → #1 FORBIDDEN_PATH - §9 mergedBy 불일치 → BOT_IDENTITY_DIVERGENCE ## 최종 원칙 Option B 흐름의 마지막 단계. update-branch 성공 + OWNER /gemini review trigger 완료 → fresh evidence 도착 → BOT squash merge로 finalize. 금지 13건 1:1 준수. MERGED 시 task-2487 series clean replacement 종결.