# task-2553+16 — PR #129 TEST_ONLY_HARDENING_MERGE_LIFECYCLE (Track 1, profile-driven, 회장 GO, 코드/파일 자동화)

> **Lv**: Lv.4 — profile 생성 + 실 BOT merge + post-merge 자동화. **Executor**: dev2-team 오딘 (key fedf78d1d09509f5) 1회 한정. **TTL**: 2h.
> **상태**: 회장 Track 1 GO — PR #129(Track B landing, 회장 ACCEPT) 를 `test_only_hardening_pr_merge_v1` profile 기반 merge-readiness→BOT merge→post-merge smoke→reconcile→closeout 자동 진행. 중간 회장 보고 0(profile engine 자동 HOLD 산출). md 문서화만 금지 — schema/profile JSON/loader·runner binding/regression/decision JSON 필수.
> **선행**: task-2553+15 = PR #129 OPEN(회장 ACCEPT). Track 2+3(task-2553+17) 비대기·독립(SAFE_PARALLEL).

---

## 1. 확정 전제 (ANU read-only 16:38 확인)

PR **#129** OPEN, isDraft false, branch `task/task-2553+15-dev7-testloader-hardening`, head `2753e3cf7dad4d0d926d0197875fc3078a3cb19b`, base main, mergeable **MERGEABLE**, mergeStateStatus **BLOCKED**(신규 PR — Gemini review gate/CI 대기 추정), reviewDecision "". **files = 정확히 2 test 파일**: `tests/regression/test_load_otp_sysmodules_2553plus14.py`(신규) + `tests/regression/test_owner_trigger_2553_plus1_high_fix.py`(+1줄). production byte-0(task-2553+14/+15 검증 상속: owner_trigger_pat.py sha256 `7b7d996aae3c368561f63600f8e71017f7af85b86a63b5533153e956bdec7135`). policy_profile·coordinator 인프라 부재 → 신규.

## 2. 목표 (회장 verbatim)

PR #129 를 profile 기반 merge-readiness 진단 → 조건 충족 시 BOT merge → post-merge smoke → reconcile evidence → closeout packet 자동 진행. Track 1 중간 확인 없이 loop. HOLD_FOR_CHAIR 조건 = profile engine 자동 산출(회장 개별 열거 안 함).

## 3. policy_profile 생성 (부재 → 코드/파일 자동화)

`test_only_hardening_pr_merge_v1` 부재 → 생성:
- `schemas/policy_profiles/test_only_hardening_pr_merge_v1.schema.json` — profile 구조 정의(merge_ready_predicate / hold_conditions / merge_method / auth / post_merge_steps / irreversibility_policy / scope_invariants).
- `memory/policy_profiles/test_only_hardening_pr_merge_v1.json` — 실 profile 값. **merge_ready_predicate**(AND): mergeable==MERGEABLE / mergeStateStatus∈{CLEAN,HAS_HOOKS} / reviewDecision∉{CHANGES_REQUESTED} / CI 전건 SUCCESS / unresolved review thread==0 / effective diff ⊆ test-only(non-test·production 파일 0) / production byte-0(owner_trigger_pat.py sha==baseline) / head SHA==관측 sanctioned. **hold_conditions**(engine 자동 산출): 위 predicate 임의 미충족 / production diff / forbidden touch / BOT merge 불가 / post-merge fail / Codex HIGH·CRITICAL / credential expansion / Critical7. **merge_method**: repo allow_* 발견 사용(부재 시 squash+근거). **auth**: 기존 taskctl-bot GitHub App installation token 단일(비-OWNER·확대 0). **irreversibility_policy**: 9-R pre/post-merge split.
- `scripts/run_test_only_hardening_pr_merge.py` — profile loader+runner binding orchestrator(profile load→gate→merge→smoke→reconcile→closeout, fail-closed).
- `tests/regression/test_test_only_hardening_pr_merge_2553plus16.py` — profile predicate/hold/fail-closed/idempotency 단위 regression.

## 4. merge lifecycle (profile-driven, loop 자동)

1. **profile load/생성** → predicate·hold 로드.
2. **merge-readiness 진단**: PR #129 실시간 관측(head/CI/threads/mergeable/mss/reviewDecision/effective diff 2 test/production byte-0) ↔ profile predicate 평가 → `pre-merge-gate.json`(각 조건 boolean+측정값+ALL_PASS).
   - Gemini unresolved thread 존재 시: test-only hardening PR 은 task-2553+10/+11 와 동일 — 코드가 이미 검증·Codex GO·production byte-0 이므로, profile 이 정의한 sanctioned 경로(thread 해소 필요 시 resolveReviewThread 1회 — task-2553+11 패턴 재사용, **단 본 task scope 내 1회·근거 marker**)로 자동 해소 후 재진단. profile predicate 외 scope expansion 0.
3. **Codex audit + ANU-Codex adjudication**(loop 자동, LOW/MED·micro-fix·fixture·regression 보강 회장 보고 0).
4. predicate ALL_PASS → **BOT merge**: `gh api -X PUT /repos/Jeon-Jonghyuk/dev_workspace/pulls/129/merge -f sha=<관측 head> -f merge_method=<profile>` (head-pin, 불일치 409→pre-merge HOLD). `gh pr merge` 비핀 금지. 직전 predicate 재측(TOCTOU 제거).
5. **post-merge smoke**: isolated worktree(merged origin/main)에서 11 passed(F1 3 GREEN+streaming 4+신규 regression 4) + production import OK. smoke false-positive 해석은 task-2553+12 harness-artifact doctrine 자동 적용(회장 보고 0, 단 진짜 production 결함이면 HOLD).
6. **reconcile evidence**: origin/main 이 merge commit 포함·effective diff 2 test 파일·PR #129 MERGED·PR #128/#102 무변(read-only).
7. **closeout packet**: `task-2553+16.result.json`(final packet) + closeout-packet.md. evidence-based(manual .done echo·evidence 없는 closeout 0).

## 5. boundary (회장 verbatim)

production code 변경 / Track A closeout artifact(task-2553+13.*·task-2553+1.closeout/result기존키/.done/.md) 변경 / PR #128 재수정 / PR #102 원본 변경 / F2·phase3·mqe 변경 / credential·OWNER PAT·real write 일반진입 / merge 외 scope expansion / anu_v3 coordinator(Track2+3 도메인) 접촉 — **전부 금지**. live `/home/jay/workspace` @ `task/task-2553p1-f1-clean-replacement` `20456b5f` 전후 assertEqual. merge·post-merge 작업 = isolated worktree·gh api only, live ws 미접촉.

## 6. irreversibility doctrine (task-2553+12 상속 강제)

merge=point-of-no-return. **pre-merge HOLD**=gate 불충족·409 → merge 호출 0. **post-merge HOLD**=smoke/reconcile/closeout 실패 → merge 비가역 유지·rollback/revert/force 0·후속 중단·`task-2553+16.hold-for-chair.json`(stage=POST_MERGE,merge_commit)+회장 보고. idempotency: 이미 MERGED→no-op success 후 후속 계속 / 409·blocked→pre-merge HOLD.

## 7. HOLD_FOR_CHAIR (profile engine 자동 산출 — 회장 미열거)

§3 hold_conditions 자동 평가. 회장 보고 트리거(공통원칙): Critical7 / credential·OWNER PAT·permission expansion / forbidden touch / production diff / merge·profile gate auto-resolve 불가 / Codex unresolved HIGH·CRITICAL / ANU-Codex 반복충돌 / goal 달성불가. 그 외(CI 대기·LOW·MED·profile micro-fix·regression·smoke false-positive 해석·callback dup·fixture 보강) **회장 보고 0, loop 자동**.

## 8. 완료 후 (consolidated summary 로 통합 — 단독 보고 금지)

본 track 결과는 batch consolidated summary 항목 1(PR#129: MERGED/MERGE_READY/HOLD_FOR_CHAIR) + 항목 4(track별 최종상태)로 통합. 단독 중간/최종 보고 0. final packet(result.json): profile 경로·pre-merge-gate·mergedAt/mergeCommit·merged head·CI/Gemini/CLEAN·effective diff 2 test·post-merge smoke·reconcile·PR#128/#102 보존·closeout·callback collector·HOLD 여부.

## 9. ANU-Codex loop + callback (자동, 중간보고 0)

batch plan(§3) → Codex lint → ANU refine(9-R) → Codex re-lint → dispatch(dev2 1회 TTL2h, callback (a) normal+fallback, 4-tuple 분리·Track2+3 artifact 인용 0) → profile→gate→merge→smoke→reconcile→closeout → post-result audit → adjudication → result.json → batch coordinator 통합. §7 트리거만 회장 보고.

## 11. 9-R — Codex lint 반영 (NEEDS_REFINEMENT → 자동 수렴, agent abc5396fbcd03cae7: CRITICAL0/HIGH2/MED3/LOW1)

### 9-R.1 (HIGH#1) Gemini-thread-resolve 재사용 hard-bound
§4.2 정정: PR #129 한정, **사전 식별된 단일 blocking thread ID 1개**(evidence marker 에 threadId/path/line/author/severity 박제), `resolveReviewThread` **정확히 1회**, comment·다른 mutation 0(task-2553+11 9-R.1/9-R.2 discipline 재사용). **unresolved review thread 수가 정확히 1 이 아니거나** blocking thread 를 유일 식별 불가 → 즉시 **pre-merge HOLD**(resolve 0). resolve 가 profile predicate 충족의 유일 잔여 차단요소일 때만 수행, 그 외 차단요소 잔존 시 resolve 0·HOLD. 이 경로는 scope expansion 아님(단일 thread·단일 write·근거 marker).

### 9-R.2 (HIGH#2) merge_ready_predicate review-state fail-closed allowlist
§3 정정: `reviewDecision ∈ {APPROVED, ""}` **만 허용**(빈값은 required reviewer 부재 + mergeStateStatus==CLEAN + CI 전건 SUCCESS + unresolved thread==0 동반 시에만 affirmative-safe 로 간주). `CHANGES_REQUESTED`·`REVIEW_REQUIRED`·기타 비열거값 → **HOLD**(mergeable 취급 0). affirmative-safe 단일 신호 = mergeStateStatus==CLEAN(BLOCKED/UNSTABLE/DIRTY/BEHIND/UNKNOWN 절대 merge 0).

### 9-R.3 (MED#1) liveness — 무한 loop 금지
persistent BLOCKED/CI-pending 시 wait/retry budget(profile 정의: max_wait 예 90min·poll 간격·max_poll). budget 초과 시 loop 중단 + **pre-merge HOLD**(reason=PERSISTENT_BLOCKED_OR_CI_PENDING) emit, spin 금지.

### 9-R.4 (MED#2) decision JSON 산출물 §3 명시
§3 deliverable 에 명시 추가: `memory/events/task-2553+16.pre-merge-gate.json`(merge 전 decision, predicate 각 boolean+측정+ALL_PASS) + `task-2553+16.result.json`(reconcile 후 final). profile-as-code 계약 = schema+profile JSON+loader/runner+regression+**위 2 decision JSON** 필수(누락 → mandatory 미충족 HOLD).

### 9-R.5 (MED#3) runtime auth invariant fail-closed
merge 호출 직전 사용 credential 이 사전구성 taskctl-bot GitHub App installation token **이 아니면**(OWNER PAT·개인 PAT·신규 토큰·scope 확대 감지) → fail-closed, merge 0, HOLD(credential·permission expansion). 정상 token 부재·만료도 동일 HOLD(우회 0).

### 9-R.6 (LOW) merge_method 명시
endpoint 고정 = `gh api -X PUT /repos/Jeon-Jonghyuk/dev_workspace/pulls/129/merge -f sha=<관측 head> -f merge_method=<M>`. **M 결정적 우선순위**(repo allow_* 복수 활성 시 tie-break 명시): `allow_squash_merge` 활성 → **squash** / 아니면 `allow_merge_commit` 활성 → **merge** / 둘 다 비활성이고 `allow_rebase_merge` 만 → **§7 HOLD**(rebase 금지). 선택값+repo allow_* 관측 전부 `pre-merge-gate.json.merge_method_provenance` 기록. test-only hardening PR 기본 선호 = squash.

→ 9-R.1~9-R.6 으로 HIGH2+MED3+LOW1 해소. CRITICAL0. Codex re-lint GO_READY 시 dispatch.

## 10. task-2553 계열

+12=PR#128 merge / +13=Track A closeout / +14=Track B 하드닝 / +15=Track B landing PR#129 OPEN / **+16(Track1 본건)=PR#129 test-only hardening merge lifecycle(profile-driven)** / +17=Track2+3 coordinator+goal-loop generalization(병렬).
