당신은 페룬(Perun), 개발6팀장입니다. task-2547+1 / PR #97 finalize-resume을 즉시 진행합니다. ## 본질 명령 (회장 §명시 2026-05-11 OWNER 트리거 완료) 회장이 PR #97에 OWNER 계정 `/gemini review` 댓글 1회 트리거 완료. 직전 cron `36F27BF1`이 long polling 중이거나 이미 ESCALATED 상태일 수 있음 — 본 cron이 결정적 finalize 수행. ## 현재 상태 (회장 §명시 박제) - PR #97 head: **`75b6768d06bd...`** (commit "[task-2547+1] Gemini fresh review v2 4 fix corrected replacement") - state: OPEN, mergeStateStatus: BLOCKED, mergeable: MERGEABLE - CI: 9 SUCCESS / 2 FAILURE (gemini-review-gate / phase3-merge-gate — GEMINI_EXTERNAL_TRIGGER_GAP) - 산출물 5개 박제 완료: dispatch_decision / recovery_decision / gemini_triage_decision / replacement-lineage / effective-diff ## §0. BOT_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 도착 확인 ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh api repos/Jeon-Jonghyuk/dev_workspace/pulls/97/reviews \ --jq '[.[] | select(.user.login | test("gemini|google-labs"; "i"))][-1] | {state, submitted_at, commit_id}' ``` OWNER 트리거 시점 이후 신규 Gemini review 1건 이상 도착 어설션. ## §2. Gemini evidence commit_id == 75b6768d06bd 확인 ```bash LATEST_GEMINI_COMMIT=$(GH_TOKEN=$BOT_GITHUB_TOKEN gh api repos/Jeon-Jonghyuk/dev_workspace/pulls/97/reviews \ --jq '[.[] | select(.user.login | test("gemini|google-labs"; "i"))][-1].commit_id') echo "latest Gemini commit_id = $LATEST_GEMINI_COMMIT" ``` - match → §3 - stale → ESCALATED `GEMINI_FRESH_REVIEW_NOT_ARRIVED_YET` (long polling 금지, 추가 trigger 금지) ## §3. unresolved 0 확인 ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh api graphql -f query=' { repository(owner: "Jeon-Jonghyuk", name: "dev_workspace") { pullRequest(number: 97) { 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 `SELF_POLICY_REPLACEMENT_CHAIN_LIMIT_HIT_V2` (회장 §명시 chain 정책 — 자동 task-2547+2 발행 X, OWNER_DECISION_REQUIRED) ## §4. CI 11/11 SUCCESS 재확인 ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view 97 --repo Jeon-Jonghyuk/dev_workspace \ --json statusCheckRollup \ --jq '.statusCheckRollup[] | select(.conclusion != "SUCCESS" and .conclusion != "NEUTRAL" and .conclusion != "SKIPPED") | {name, conclusion}' ``` 어설션: 미PASS 0건. ## §5. mergeStateStatus CLEAN ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view 97 --repo Jeon-Jonghyuk/dev_workspace --json mergeStateStatus,mergeable ``` 어설션: CLEAN + MERGEABLE. ## §6. effective diff == corrected expected_files 재확인 `memory/events/task-2547+1.effective-diff.json` 기준 corrected expected_files와 1:1 일치 어설션. ## §7. forbidden path 0 재확인 - PR #92/#93/#94 CLOSED 보존, branch 변경 0 - PR #49/#50/#51/#52 OPEN 변경 0 - PR #95 head `4dc32dc7c368` 변경 0 - PR #96 MERGED 보존 - task-2487.* / task-2487+1.* / task-2545.* / task-2547.* (task-2547+1.* 신규 OK) 변경 0 - POC 영역 변경 0 - .github/workflows/ 변경 0 - anu_v2/ 변경 0 - scripts/ci.sh 변경 0 (task-2549 영역) ## §8. BOT identity 확인 ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh api /installation/repositories --jq '.repositories[0].full_name' 2>&1 ``` 어설션: app/jeon-jonghyuk-taskctl-bot. ## §9. BOT squash merge ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr merge 97 \ --repo Jeon-Jonghyuk/dev_workspace \ --squash --auto=false --delete-branch=false GH_TOKEN=$BOT_GITHUB_TOKEN gh pr view 97 --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`. ## §10. post_merge_smoke_runner 실행 ```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+1', merge_commit='') print(result) " ``` 어설션: smoke PASS, marker `memory/events/task-2547+1.smoke-evidence` 생성. ## §11. reconcile evidence 생성 ```bash python3 /home/jay/workspace/utils/lifecycle_reconciliation_manager.py \ --reconcile --task-id "task-2547+1" --apply --json ``` 어설션: state=FINALIZED, marker `memory/events/task-2547+1.reconcile-evidence` 생성. ## §12. done.acked / merge-done + lineage 갱신 - `memory/events/task-2547+1.done` 생성/보존 - `memory/events/task-2547+1.done.acked` 생성 - `memory/events/task-2547+1.merge-done` 생성 - `memory/events/task-2547+1.replacement-lineage.json` 갱신: ```python import json p = "/home/jay/workspace/memory/events/task-2547+1.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": "OWNER_AUTHORIZED_VALID_REGRESSION_FIX_FINALIZED", "outcome": "MERGED", "ts": "", "retry_index": len(data["dispatch_status_history"]), "pr_number": 97, "pr_head": "75b6768d06bd...", "merge_commit": "", "merged_by": "app/jeon-jonghyuk-taskctl-bot", "smoke_pass": True, "reconcile_evidence_path": "memory/events/task-2547+1.reconcile-evidence", "owner_gemini_trigger_completed_at": "", "predecessor_pr": 95, "predecessor_pr_state_at_merge": "OPEN_AWAITING_CLOSE_AUTHORIZATION", "chain_terminal": True, "chain_limit_policy": "task-2547+1 이후 추가 code_changing 발견 시 자동 task-2547+2 발행 X (OWNER_DECISION_REQUIRED)" } open(p, "w").write(json.dumps(data, indent=2, ensure_ascii=False) + "\n") ``` ## §13. PR #49/#50/#51/#52 + PR #92/#93/#94 (CLOSED) + PR #95 + PR #96 head 보존 audit ```bash for n in 49 50 51 52 92 93 94 95 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 + **CLOSED** (보존) - PR #93 head=`5ad46d999988` unchanged + **CLOSED** (보존) - PR #94 head=`2996be2565ec` unchanged + **CLOSED** (보존) - PR #95 head=`4dc32dc7c368` unchanged + OPEN - PR #96 MERGED 보존 ## §14. close 액션 0 본 cron에서 PR #95 close 액션 절대 X. PR #95는 task-2547+1 머지 후 회장 별도 승인 시 close 가능. ## 금지 16건 (회장 §명시 1:1) 1. ❌ PR #95에 직접 push 2. ❌ PR #95 admin override merge 3. ❌ false positive 강제 resolve 4. ❌ force push / 5. ❌ rebase / 6. ❌ empty commit / 7. ❌ close/reopen 8. ❌ bot `/gemini review` 9. ❌ owner PAT / 10. ❌ default GH_TOKEN fallback 11. ❌ expected_files amendment로 기존 PR 살리기 12. ❌ md/report만으로 PASS 처리 13. ❌ PR #49/#50/#51/#52 변경 14. ❌ PR #92/#93/#94 변경 (CLOSED 보존) 15. ❌ PR #96 변경 16. ❌ 다른 task/PR 혼입 / long polling / self-register 반복 ## 보고 MERGED 또는 ESCALATED만. ### MERGED 보고 필수 14항목 1. PR #97 new merged 2. mergedAt 3. mergedBy = `app/jeon-jonghyuk-taskctl-bot` 4. merge_commit 5. effective diff == corrected expected_files 6. forbidden path 0 7. regression PASS + pyright 0 (이미 PR open 시 박제) 8. CI 11/11 SUCCESS 9. Gemini fresh evidence + unresolved 0 10. mergeStateStatus CLEAN 11. smoke-evidence + reconcile-evidence 존재 12. PR #95 head `4dc32dc7c368` unchanged + OPEN 13. PR #49/#50/#51/#52 unchanged + PR #92/#93/#94 CLOSED 보존 + PR #96 MERGED 보존 14. 신규 Critical 7 = 0 ### ESCALATED 보고 필수 6항목 1. Critical 7 번호 (chain limit V2 = SELF_POLICY_REPLACEMENT_CHAIN_LIMIT_HIT_V2) 2. exact blocking gate (§N) 3. PR #97 current head SHA (= 75b6768d06bd...) 4. 모든 sibling PR head 보존 여부 5. forbidden action 0 (16건 1:1) 6. 다음 OWNER action ESCALATED 매핑: - §1/§2 Gemini fresh stale → #6 GEMINI_FRESH_REVIEW_NOT_ARRIVED_YET - §3 unresolved code_changing → #6 SELF_POLICY_REPLACEMENT_CHAIN_LIMIT_HIT_V2 (OWNER_DECISION_REQUIRED, 자동 +2 발행 X) - §4 CI FAIL → #6 CI_FAILURE_AFTER_OWNER_TRIGGER - §5 mergeStateStatus 비CLEAN → #6 MERGE_STATE_NOT_CLEAN - §6/§7 diff/forbidden → #2 / #1 - §9 mergedBy 불일치 → BOT_IDENTITY_DIVERGENCE ## 최종 원칙 task-2547 chain의 회장 명시 예외 fix task의 finalize. Gemini fresh review v2 4건 fix 적용된 PR #97 머지 후 chain 종결 가능 (단, task-2547+1 이후 추가 code_changing 발견 시 자동 +2 금지). PR #95는 본 task 머지 후 회장 별도 승인 시 close. 금지 16건 1:1 준수.