# task-2553+12 — PR #128 BOT_MERGE + POST-MERGE SMOKE/RECONCILE/CLOSEOUT 자동화 (회장 merge GO, 코드/파일 자동화)

> **Lv**: Lv.4 — 실 BOT merge + post-merge 자동화. **Executor**: 적합 dev 1회 한정 (ANU 배치안·Codex lint·refine·re-lint 선행 후 dispatch). **TTL**: 2h.
> **상태**: 회장 merge GO — **runner/marker/evidence 실행 파일**로 처리(md 보고서만 완료처리 금지). task-2553+11 = RESOLVED_THREAD__MERGE_READY 수용.
> **선행 의존**: task-2553+11(thread resolve, MERGE_READY). task-2553+10(코드 스트리밍 fix push). task-2553+9(PR #128 OPEN). task-2553+1(F1-solo, closeout 대상).

---

## 1. 확정 전제 (회장 수용 — ANU read-only 재확인 2026-05-17 14:47 KST)

- PR #128 head **`0ea36fc9a724b1763be34710e283e088fae39a59`** == sanctioned. state OPEN, isDraft false.
- mergeStateStatus **CLEAN** / mergeable **MERGEABLE** / reviewDecision "" (∉ CHANGES_REQUESTED).
- reviewThreads total 1, **unresolved 0** (Gemini thread PRRT_kwDORcJVSM6CnKyZ resolved by +11).
- CI **11/11 SUCCESS** (cancel-kill-switch·ci/guard·gemini-review-gate·guard·hidden-path-audit·lock-in-check·merge-safety-check·phase3-merge-gate·qc-check·taskctl-state-guard×2).
- PR #102 보존 (`task/task-2553-dev5` @ `bd5ad74f5d443b354319fc8b3cb006816b8a9025`, OPEN, 무변).
- task-2553+11 Codex GO / ANU-Codex CONVERGED 상속.

## 2. 목표 (회장 verbatim)

PR #128 merge GO 를 **코드/파일 자동화 흐름**으로 수행: merge 전 gate · BOT merge · post-merge smoke · reconcile evidence · task-2553+1 closeout · closeout packet 을 **실행 가능한 runner/marker/evidence 파일**로 처리. md 보고서만으로 완료 처리 금지.

## 3. 필수 산출 (회장 verbatim 6 — 전부 실행 파일/JSON, md-only 금지)

1. **pre-merge gate decision JSON** — `memory/events/task-2553+12.pre-merge-gate.json` (11 gate 조건 평가 결과)
2. **merge execution result JSON** — `memory/events/task-2553+12.merge-exec.json` (mergedAt/mergedBy/mergeCommit/method)
3. **post-merge smoke evidence JSON/log** — `memory/events/task-2553+12.smoke.json` + `.smoke.log`
4. **reconcile evidence JSON** — `memory/events/task-2553+12.reconcile.json` (origin/main 6-file 반영·PR state 정합)
5. **task-2553+1 closeout marker/result** — `memory/events/task-2553+1.closeout.json` + result/report 정리(evidence-based, manual .done echo 금지)
6. **final closeout packet report** — `memory/reports/task-2553+12.closeout-packet.md` + `memory/events/task-2553+12.result.json`(packet 12 단일 권위)

> runner: `scripts/run_pr128_merge_closeout.py`(또는 기존 ANU merge 정책 모듈과 정합되는 위치) — pre-merge gate → BOT merge → post-merge smoke → reconcile → closeout marker → final packet 을 단일 실행 흐름으로 orchestrate. 각 단계 산출 JSON 을 atomic write. **gate FAIL/HOLD 시 merge 호출 0**(fail-closed).

## 4. merge 전 필수 gate (회장 verbatim 11 — 전건 충족 시에만 merge, 하나라도 불충족 → §7 HOLD, merge 0)

1. PR #128 head SHA == `0ea36fc9a724b1763be34710e283e088fae39a59` (실시간 `gh pr view` 재측, 불일치 → HOLD)
2. CI 11/11 SUCCESS 유지 (rollup + 11 check 개별 재측)
3. Gemini unresolved threads == 0 유지 (GraphQL reviewThreads 재측)
4. mergeStateStatus == CLEAN 유지
5. mergeable == MERGEABLE 유지
6. effective diff == task-2553+1 허용 6파일 정확 일치 (anu_v2/owner_trigger_pat.py / tests/regression/test_owner_trigger_2553_plus1_high_fix.py / memory/reports/task-2553+1.md / memory/events/task-2553+1.result.json / .red-evidence.log / .green-evidence.log)
7. forbidden path 0 (6파일 밖 diff 0)
8. PR #102 원본 보존 (`task/task-2553-dev5` head == `bd5ad74f5d443b354319fc8b3cb006816b8a9025`)
9. F2 token transport block byte-identical (PR head 파일에서 재도출, task-2553+10 post `b02140738e372578a8f39af3d8ca3e13ce8ec099f86393a49e1e224a3f6a7560` 와 일치)
10. phase3/mqe 무변 (diff 미포함)
11. no admin override 필요 AND no force push/rebase 필요 (정상 BOT merge 경로로 충분)

> gate 결과 = `task-2553+12.pre-merge-gate.json` (각 조건 boolean + 측정값 + ALL_PASS). ALL_PASS=false → merge 호출 정적·런타임 부재 + §7 HOLD.

## 5. 허용 (회장 verbatim)

BOT squash merge **또는 기존 ANU merge policy 에 맞는 BOT merge**(green-path taskctl BOT merge 메커니즘 — 기존 정책 발견·정합 사용, 신규 merge 경로 발명 금지) / post-merge smoke / reconcile evidence 생성 / result·report·evidence marker 생성 / final closeout packet 작성 / callback normal+fallback collector.

- **merge 형태**: `gh pr merge 128 --squash`(또는 기존 ANU merge policy 가 지정하는 method) — BOT 식별자, **admin override·--admin·force·rebase 0**. merge method 는 기존 정책 단일 권위(임의 선택 금지, 정책 부재 시 squash 기본 + 근거 기록).
- post-merge smoke: 병합된 origin/main 에서 **isolated worktree** 로 ① `anu_v2/owner_trigger_pat.py` import OK ② 신규 스트리밍 regression(test_owner_trigger_2553_plus1_high_fix.py 의 +10 추가 4 case) PASS ③ is_duplicate_trigger 기본 동작 sanity. live workspace 미사용.
- reconcile: origin/main 이 6-file diff 반영·PR #128 state==MERGED·mergeCommit 존재·PR #102 무변 확인(read-only fetch).

## 6. task-2553+1 closeout (evidence-based — manual .done echo 절대 금지)

task-2553+1(F1-solo) 은 PR #128 merge 로 본질 충족. closeout 은 **runner 가 evidence 기반**으로: `memory/events/task-2553+1.closeout.json`(merge_commit + merged_at + effective_diff_6_verified + ci_11_pass + gemini_resolved + 본질 완료기준 충족 매핑) 생성 + task-2553+1.result.json/report 에 closeout 섹션 append. `.done` 마커는 **runner 가 evidence 정합 확인 후에만** 생성(echo/수동 금지, evidence 없는 자동 closeout 금지). `.done` → 처리 후 `.done.acked` lifecycle 은 기존 프로토콜 준수.

## 7. HOLD_FOR_CHAIR 조건 (회장 verbatim — 적중 시 merge/이후단계 0·즉시 회장 보고)

head SHA mismatch / CI·check failure / Gemini unresolved thread 재발 / mergeStateStatus BLOCKED·DIRTY·BEHIND / mergeable != MERGEABLE / effective diff 6파일 밖 변경 / forbidden path 발생 / PR #102 원본 변경 / F2·phase3·mqe 변경 / BOT merge 불가 / merge 실패 / post-merge smoke 실패 / reconcile evidence 생성 실패 / closeout marker 생성 실패 / credential·permission expansion 필요 / Critical 7.

## 8. 금지 (회장 verbatim)

force push / rebase / admin override / PR #102 원본 변경 / F2 수정 / token transport 변경 / phase3·mqe 수정 / expected_files 6개 밖 변경 / credential·OWNER PAT 조작 / merge 조건 불충족 상태 merge / evidence 없는 자동 closeout / manual .done echo / **task-2553+2 자동 dispatch** / **task-2553+3 자동 dispatch** / live workspace cleanup·reset·stash·rm·unlink·rmtree.

> merge 자체 외 GitHub write 최소화: `gh pr merge 128`(정책 method) 1회 + closeout 에 필요한 evidence-marker(로컬 파일). PR comment·review·label·다른 PR 조작·credential op 0. live `/home/jay/workspace` @ `task/task-2553p1-f1-clean-replacement` `20456b5f` HEAD/branch/ref 전후 불변(assertEqual). post-merge 작업은 isolated worktree(origin/main fetch 기준) 전용.

## 9. ANU 배치안 / expected_files (task-2553+12 자체)

- `scripts/run_pr128_merge_closeout.py` — orchestrator runner (pre-merge gate → BOT merge → smoke → reconcile → closeout → packet, fail-closed)
- `memory/events/task-2553+12.pre-merge-gate.json` / `.merge-exec.json` / `.smoke.json` / `.smoke.log` / `.reconcile.json` / `.result.json` / `.activation-decision.json` / `.hold-for-chair.json`(조건부)
- `memory/events/task-2553+1.closeout.json` + task-2553+1 result/report closeout append + `.done`(evidence 확인 후 runner 생성)
- `memory/reports/task-2553+12.md` / `memory/reports/task-2553+12.closeout-packet.md` / `memory/reports/task-2553+12.collector-final-packet.md`
- (선택) `tests/regression/test_pr128_merge_closeout_2553plus12.py` — runner gate fail-closed·smoke·reconcile 단위 regression

> 본 marker 는 PR #128 effective diff·commit·push **0**(PR 은 이미 merge 대상, 추가 commit 금지). live `memory/` 보고 채널 기록 — git tracked HEAD/branch/ref 불변이면 충족(보고 marker 와 git 불변 별개 축, task-2553+10 9-R.1/9-R.5 패턴).

## 10. 완료 후 최종 packet (회장 verbatim 12 — md-only 금지, JSON 단일 권위 + report)

1. pre-merge gate decision JSON 경로 + 결과(ALL_PASS) 2. mergedAt / mergedBy / mergeCommit 3. final merged head SHA(origin/main) 4. CI/Gemini/CLEAN 최종 pre-merge 상태 5. effective diff 6파일 일치 증거 6. post-merge smoke evidence 결과 7. reconcile evidence 결과 8. PR #102 원본 보존 최종 확인 9. task-2553+1 closeout marker/result 경로+상태 10. callback collector 결과 11. HOLD_FOR_CHAIR 여부 12. 후속 task-2553+2 / +3 / callback hardening 후보 **분리 상태**(자동 dispatch 0 — 후보 목록만, 회장 결정 대기 명시).

## 11. ANU-Codex loop (자동 수렴)

batch plan(본 §9) → Codex lint → ANU refine(필요 시 9-R) → Codex re-lint → dispatch(적합 dev 1회, TTL 2h, callback (a) normal+fallback) → runner 구현 → pre-merge gate → BOT merge → smoke → reconcile → closeout → regression → post-result audit → ANU·Codex adjudication → 최종 packet 12 → 회장 보고. 회장 중간 라우팅 0, §7 HOLD 적중 시만 회장 보고.

## 13. 9-R — Codex lint 반영 정밀 보강 (NEEDS_REFINEMENT → 자동 수렴, agent acdfa196565f6b1f2: CRITICAL 0 / HIGH 5 / MED)

### 9-R.1 (HIGH#1 해소) merge atomicity — head-SHA-pinned merge (TOCTOU 제거)
gate 평가와 merge 사이 상태 drift 차단: ① merge 호출 **직전** 동일 runner step 에서 §4 11-gate **전건 재측·재검증**(특히 head SHA·CI rollup·unresolved threads·mergeStateStatus·mergeable) ② merge 호출 = **`gh api -X PUT /repos/Jeon-Jonghyuk/dev_workspace/pulls/128/merge -f sha=0ea36fc9a724b1763be34710e283e088fae39a59 -f merge_method=<policy>`** — `sha` 파라미터로 **head 불일치 시 GitHub 이 409 로 거부**(원자적 pin, race 시 merge 0). 409/422 → merge 미발생으로 기록 + §7 pre-merge HOLD. `gh pr merge` 비핀 형태 단독 사용 금지.

### 9-R.2 (HIGH#2 해소) HOLD 의미 pre/post-merge 2분기 (merge 비가역 명문화)
§7 정정: **(pre-merge HOLD)** gate 불충족·head mismatch·merge 거부(409) 등 → **merge 호출 0**, 상태 복구 불요. **(post-merge HOLD)** smoke 실패·reconcile 실패·closeout marker 실패 등은 merge 가 **이미 비가역 완료된 후** → **rollback·revert·force 0**(merge 유지), 후속 step 중단, `task-2553+12.hold-for-chair.json`(stage=POST_MERGE, merge_commit 기록) + 회장 보고. merge 는 point-of-no-return — post 실패는 보고/escalate 이지 되돌리기 아님.

### 9-R.3 (HIGH#3 해소) merge-method 발견 규칙 구체화
discovery 순서(증거 기록 필수): ① `gh api repos/Jeon-Jonghyuk/dev_workspace` 의 `allow_squash_merge`/`allow_merge_commit`/`allow_rebase_merge` + branch protection `required_*` 확인 ② dev_workspace 내 기존 ANU/taskctl merge policy 모듈·설정(green-path 자동머지 정책 — `scripts/`·`.github/`·taskctl config) 탐색 ③ 단일 authoritative method 정의 발견 시 그대로 사용(근거 경로 기록) ④ **policy 부재 증거(탐색 경로 + 미발견 명시) 기록 후에만** squash fallback(`merge_method=squash`). rebase 는 §8 금지라 discovery 가 rebase-only 를 강제하면 §7 HOLD. 결과 = `pre-merge-gate.json.merge_method_provenance`.

### 9-R.4 (HIGH#4 해소) BOT auth context 명시 (credential escalation 0)
허용 auth = **기존 사전구성 taskctl-bot GitHub App installation token 단일**(refresh_bot_token.py 가 갱신하는 기설치 토큰, 비-OWNER, 권한 확대 0). OWNER PAT·개인 PAT·신규 토큰 발급·scope 확대 **정적·런타임 부재**. 토큰 부재·만료·획득에 credential op 필요 시 → §7 HOLD(credential·permission expansion). merge 는 이 기존 BOT 컨텍스트로만 실행, 실패 시 회장 보고(우회 0).

### 9-R.5 (HIGH#5 해소) callback collector 수용 기준 정의
§10 item 10 = `callback collector 결과` 수용 계약: normal callback cron 등록됨 + `task-2553+12.result.json`(packet 12) + closeout-packet + reconcile/smoke JSON 회수 + 독립 교차검증 PASS + 독립 Codex audit verdict + ANU-Codex adjudication=CONVERGED. 필드: `collector_cron_id`/`retrieved_artifacts[]`/`crosscheck=PASS|FAIL`/`codex_verdict`/`adjudication`. FAIL/미수렴 → 회장 보고(자동 closeout 0). collector 권한 = 회수·검증·보고 전용(write/merge/dispatch/closeout/재가동/cron-remove 0).

### 9-R.6 (MED 해소) idempotency + 산출 boundary
idempotency: merge step 진입 시 PR state==MERGED 이미면 → **no-op success**(merge_exec.json.idempotent_noop=true, 기존 mergeCommit 회수 후 smoke/reconcile/closeout 계속). 호출 중 mergeability 변동(409/blocked) → merge 미발생 + §7 pre-merge HOLD(merge-failure 기록). 산출 boundary: **회장 필수 6산출(§3)** = mandatory, 그 외 §9 항목(`task-2553+12.md`·collector-final-packet·activation-decision·regression)= auxiliary(ANU 보고 채널, mandatory 누락 시 HOLD / auxiliary 누락은 WARN 기록).

→ 9-R.1~9-R.6 으로 Codex HIGH 5 + MED 전건 해소. CRITICAL 0 유지. Codex re-lint GO_READY 시 dispatch.

## 12. task-2553 계열 (혼선 방지)

+1=F1(closeout 대상) / +4=gate / +5=deriver+binding / +6=runner / +7=controller / +8=iso-wt evidence / +9a=callback cancel SIM / +9=PR#128 OPEN / +10=코드 스트리밍 fix push(A) / +11=단일 Gemini thread resolve(MERGE_READY) / **+12(본건)=PR#128 BOT merge + post-merge smoke/reconcile/closeout 자동화**. 후속 +2/+3/callback-hardening 은 **본 task 에서 자동 dispatch 0** — 후보 분리만, 회장 결정 대기.
