당신은 마르둑(Marduk), 개발5팀장입니다. task-2545+1 / PR #93 finalize 재개를 즉시 진행합니다. ## 본질 명령 (회장 §명시 2026-05-11 OWNER 트리거 완료) 회장이 PR #93에 OWNER 계정 `/gemini review` 댓글 1회 트리거 완료. 직전 ESCALATED 원인(GEMINI_AUTO_REVIEW_NOT_TRIGGERED) RESOLVED. 잔여 §6-13~§6-16 finalize 즉시 재개. ## §0. BOT_GITHUB_TOKEN 재주입 (50분 만료 가능성) ```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~§14 회장 §명시 finalize 재개 14단계 1:1 ### §1. Gemini fresh review 도착 확인 ```bash gh api repos/Jeon-Jonghyuk/dev_workspace/pulls/93/reviews \ --jq '.[] | select(.user.login | test("gemini|google-labs"; "i")) | {id, state, submitted_at, commit_id}' ``` 어설션: 신규 review 1건 이상, OWNER 트리거 후 도착. ### §2. evidence commit_id == PR #93 current head `5ad46d99` 확인 ```bash HEAD=$(gh pr view 93 --repo Jeon-Jonghyuk/dev_workspace --json headRefOid --jq '.headRefOid') # 어설션: HEAD == 5ad46d99... (cron 발사 시점, 추가 push 0) # Gemini review commit_id가 HEAD와 일치하면 FRESH ``` ### §3. unresolved threads 확인 ```bash gh api graphql -f query=' { repository(owner: "Jeon-Jonghyuk", name: "dev_workspace") { pullRequest(number: 93) { 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 있으면 triage: - false_positive / style_only / no_code_change → reply + resolve (same-PR push 0) - code_changing_fix → ESCALATED (task-2545+2 권고, 본 PR #93 close-reopen 금지) ### §4. CI all SUCCESS 확인 ```bash gh pr view 93 --repo Jeon-Jonghyuk/dev_workspace \ --json statusCheckRollup \ --jq '.statusCheckRollup[] | select(.conclusion != "SUCCESS") | {name, conclusion}' ``` 어설션: 미PASS 0건. 11/11 SUCCESS 확인. ### §5. mergeStateStatus CLEAN 확인 ```bash gh pr view 93 --repo Jeon-Jonghyuk/dev_workspace \ --json mergeStateStatus,mergeable ``` 어설션: mergeStateStatus=CLEAN, mergeable=MERGEABLE. ### §6. effective diff == expected_files 1개 재확인 ```bash gh pr view 93 --repo Jeon-Jonghyuk/dev_workspace \ --json files --jq '.files[].path' ``` 어설션: 정확히 1줄 = `anu_v2/gemini_stale_prevention_runner.py`. ### §7. forbidden_paths 변경 0 재검증 (13개 path) - `anu_v2/fixtures/__init__.py` - `anu_v2/post_merge_smoke_runner.py` - `anu_v2/replacement_pr_runner.py` - `anu_v2/auto_gemini_triage.py` - `anu_v2/merge_queue_executor.py` - `anu_v2/critical_escalation_reporter.py` - `anu_v2/executor_self_resume.py` - `anu_v2/recovery_decision_contract.py` - `memory/tasks/task-2545.md` - `memory/events/task-2545.*` (단 task-2545+1.* 는 OK) - `anu_v2/tests/test_gemini_stale_prevention_runner_2545.py` - `anu_v2/fixtures/gemini_stale_*.json` - `memory/orchestration-audit/critical-escalations.jsonl` (append만 허용) ### §8. BOT_GITHUB_TOKEN identity 재확인 ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh auth status 2>&1 | grep -i "logged in" | head -2 GH_TOKEN=$BOT_GITHUB_TOKEN gh api /user --jq '.login' ``` 어설션: BOT identity = `app/jeon-jonghyuk-taskctl-bot` 또는 `jeon-jonghyuk-taskctl-bot[bot]`. ### §9. BOT squash merge ```bash GH_TOKEN=$BOT_GITHUB_TOKEN gh pr merge 93 \ --repo Jeon-Jonghyuk/dev_workspace \ --squash --auto=false --delete-branch=false ``` ### §10. post_merge_smoke_runner 실행 ```bash python3 -c " from anu_v2.post_merge_smoke_runner import PostMergeSmokeRunner runner = PostMergeSmokeRunner() result = runner.run_post_merge_smoke(task_id='task-2545+1', merge_commit='') print(result) " ``` 어설션: smoke PASS, 모든 회귀 통과. ### §11. reconcile evidence 생성 ```bash python3 /home/jay/workspace/utils/lifecycle_reconciliation_manager.py \ --reconcile --task-id "task-2545+1" --apply --json ``` 어설션: state=FINALIZED, actions_taken에 created_done_acked + wrote_merge_done 포함. ### §12. done.acked / merge-done 정리 (lifecycle_reconciliation_manager가 자동 처리) - `memory/events/task-2545+1.done` 보존 - `memory/events/task-2545+1.done.acked` 생성 또는 보존 - `memory/events/task-2545+1.merge-done` 생성 ### §13. replacement-lineage dispatch_status_history 갱신 파일: `memory/events/task-2545+1.replacement-lineage.json` ```python import json p = "/home/jay/workspace/memory/events/task-2545+1.replacement-lineage.json" data = json.loads(open(p).read()) # 직전 dispatch_status (PENDING 또는 ESCALATED)를 history에 push 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) # 최종 dispatch_status (MERGED) data["dispatch_status"] = { "stage": "REPLACEMENT_PR_FINALIZED", "outcome": "MERGED", "ts": "", "retry_index": len(data["dispatch_status_history"]), "merge_commit": "", "merged_by": "app/jeon-jonghyuk-taskctl-bot", "smoke_pass": True, "reconcile_evidence_path": "memory/events/task-2545+1.reconcile-evidence", "owner_gemini_trigger_required": True, "owner_gemini_trigger_completed_at": "" } open(p, "w").write(json.dumps(data, indent=2, ensure_ascii=False) + "\n") ``` ### §14. PR #92 original head unchanged 재확인 ```bash gh pr view 92 --repo Jeon-Jonghyuk/dev_workspace \ --json state,headRefOid \ --jq '. | "state=\(.state) head=\(.headRefOid)"' ``` 어설션: state=OPEN, headRefOid=`15cf6ad011e184ca298996d47253501152700287` (절대 변경 0). ## 금지 13건 (회장 §명시 1:1) 1. ❌ 추가 /gemini review 요청 (OWNER 트리거 1회로 충분) 2. ❌ bot /gemini review (신규 발사) 3. ❌ empty commit 4. ❌ close/reopen 5. ❌ force push / rebase 6. ❌ PR #92 변경 (head 보존 검증) 7. ❌ PR #93에 Gemini evidence 없이 추가 commit 8. ❌ owner PAT 사용 9. ❌ default GH_TOKEN fallback merge 10. ❌ expected_files amendment 11. ❌ 다른 task / PR 혼입 12. ❌ long polling / self-register 반복 13. ❌ md/report만으로 PASS 처리 ## 보고 MERGED (mergedBy=app/jeon-jonghyuk-taskctl-bot, 14/14 PASS, PR #92 head unchanged) 또는 ESCALATED (Critical 7 #N 매핑) 만 보고. 무변화 polling 금지. 회장 chat 노출 X. ESCALATED 시 Critical 7 매핑: - Gemini unresolved 중 code_changing_fix 발견 → #6 (subtype: GEMINI_REAL_BUG_REQUIRES_FURTHER_SCOPE_EXPANSION) → task-2545+2 권고 - §0 token 만료 → #6 (subtype: BOT_TOKEN_REFRESH_FAILED) - §6/7 어설션 실패 → #1 FORBIDDEN_PATH 또는 #2 EFFECTIVE_DIFF_FAIL - 기타 → 직접 분류 + audit jsonl 1줄 append ## 최종 원칙 ANU v2 runner가 PR state / Gemini evidence / check_run / diff / marker / token source / mergeStateStatus를 직접 조회하여 finalize 14단계를 자동 수행. 본 attempt는 자기참조 정책 + token resolution + OWNER trigger handoff 첫 통합 적용 사례.