# Auto Finalize Chain Default — 자동 finalize 12단계 default 정책

> **task-2529 (2026-05-10)**
> 회장 §명시 박제 — 코드 수정 task의 default 동작은 자동 finalize chain 진입.

## 0. 본질 (회장 §명시 그대로)

> 봇이 본질 작업과 자체 검증을 완료하면, 회장이 별도로 말하지 않아도 **자동으로** commit → push → PR → CI/Gemini → bot identity merge → smoke → reconcile까지 진입하게 만든다.
>
> **명시적 opt-out이 없는 모든 code task는 자동 finalize chain을 기본값으로 가진다.**
>
> 자동화 시스템의 기본값:
> 본질 작업 완료 → 자체 검증 PASS → **자동 finalize chain 진입**

## 1. 분류

- **AUTO_FINALIZE_CHAIN_MISSING** — 봇이 본질+검증 완료했지만 commit~merge 단계로 자동 진입하지 않은 시스템 결함
- 본 사건 fixture: task-2524+1 (dev5 사라스와티, 2026-05-10) — 자체 검증 PASS 후 PR 미생성

## 2. 자동 finalize chain 12단계

순서대로 수행. 단계 사이에 사람 confirm 필요 없음. `read_only` / `analysis_only` / `report_only` /
`finalize_policy:no_pr` 명시가 없는 한 default다.

| # | 단계 | 도구 | 실패 시 |
|---|------|------|---------|
| 1 | commit | `git add <files>` + `git commit -m "<task-id> ..."` | 단계 1 retry / Critical은 escalate |
| 2 | push | `git push origin task/<id>` | 단계 2 retry, main push는 영원히 금지 |
| 3 | PR 생성 | `gh pr create` (본문에 expected_files / 회귀 / 영향 범위) | 단계 3 retry |
| 4 | CI 통과 확인 | `gh pr checks` | FAILURE 시 fix → 단계 1로 |
| 5 | Gemini 리뷰 통과 | gemini review thread | high/critical 시 fix → 단계 1로 |
| 6 | auto_gemini_triage | `utils/auto_gemini_triage` | high/critical 코드로 수용 |
| 7 | bot identity merge | `GH_TOKEN=$BOT_GITHUB_TOKEN gh pr merge --squash` | owner_pat fallback 금지 |
| 8 | post_merge_smoke | `utils/post_merge_smoke_runner` | FAIL 시 Critical 7종 ESCALATE |
| 9 | reconcile | `utils/lifecycle_reconciliation_manager --reconcile --apply` | manual forgery 금지 |
| 10 | `.done.acked` + `.merge-done` 마커 검증 | `memory/events/<task>.done.acked` 등 | evidence 부재 시 RuntimeError |
| 11 | timer end + audit JSONL | `task-timers.json` + audit | — |
| 12 | 한 줄 결과 보고 | `<task> AUTO_FINALIZE_PASS — mergeCommit <sha>, mergedBy=app/jeon-jonghyuk-taskctl-bot` | — |

## 3. opt-out 4 필드 (회장 §명시)

다음 중 하나라도 task md 또는 cron prompt에 명시되어 있으면 자동 finalize chain은 진입하지 않는다.

| 필드 | 의미 | 사용 예 |
|------|------|---------|
| `finalize_policy: no_pr` | PR 생성하지 않음 (수동/외부 finalize) | task-2524+2 finalize phase 회복 task |
| `read_only: true` | 파일 읽기/조회만, 변경 0 | audit / status scan task |
| `analysis_only: true` | 분석/리포트만 (코드 변경 0) | task-2527 같은 root cause audit |
| `report_only: true` | 보고서 작성만 (코드 변경 0) | retrospective / 회고 task |

## 4. 자동 footer 삽입 (`scripts/safe_cron_dispatch.py`)

cron 발사 직전 wrapper가 prompt를 검사:

1. `task_kind ∈ {independent_task, merge_task, bot_task}` (followup_readonly / human_response 제외)
2. opt-out 토큰 미포함
3. footer marker `[AUTO_FINALIZE_CHAIN_FOOTER_v1]` 미포함 (멱등)

세 조건 모두 만족 시 prompt 끝에 12단계 footer 자동 추가. 봇 prompt에 박제되어 봇이 항상
finalize chain을 인지한다.

## 5. lifecycle 단계 stuck 분류 (`utils/lifecycle_reconciliation_manager.py`)

자동화 chain이 중간에 끊기는 4 stuck 분류:

| StuckReason | 신호 |
|-------------|------|
| `CODE_DONE_BUT_NO_COMMIT` | report_artifact 존재, push된 commit 없음, age ≥ 5분 |
| `COMMIT_DONE_BUT_NO_PR` | branch push됨, PR 없음, age ≥ 5분 |
| `PR_OPEN_BUT_NO_MERGE_ATTEMPT` | pr_state=OPEN + ci=SUCCESS, pr_open_age ≥ 5분, merge_commit 없음 |
| `SELF_VERIFIED_BUT_NOT_FINALIZED` | report_artifact 존재 + (PR 없음 또는 OPEN/CLOSED), age ≥ 5분 |

`scan_stuck` CLI가 주기적 호출 시 이 4 stuck을 다른 stuck들과 함께 자동 보고.
`pr_state=MERGED`인 task는 절대 본 분류 대상 아님 (이미 finalize chain 성공한 것).

## 6. 회장 §금지

- ❌ 정책 문서만 작성하고 종료 금지 (실행 가능한 코드 필수)
- ❌ `dispatch.py` 대규모 rewrite 금지 (외과적 변경만)
- ❌ owner_pat fallback 금지
- ❌ manual `.done` 금지
- ❌ admin override / force push / rebase 금지
- ❌ Critical 7종 외 회장 보고 금지

## 7. 참조

- 구현체: `scripts/safe_cron_dispatch.py` (`auto_inject_finalize_footer`, `is_finalize_opt_out`)
- 구현체: `utils/lifecycle_reconciliation_manager.py` (`StuckReason.CODE_DONE_BUT_NO_COMMIT` 외 3종)
- 회귀: `tests/regression/test_auto_finalize_chain_default_2529.py` (5건)
- 의존: task-2526.merged (cron --session safety wrapper), task-2528.merged (worktree timer reconcile)
- 본 사건: task-2524+1 (dev5 사라스와티) — 자체 검증 PASS 후 PR 미생성
