# WATCHER FRESHNESS TRUTH CONTRACT (★ 회장 verbatim 2026-05-27 · PR156 stale 사고 박제)

- 작성: 2026-05-27T13:55 KST · ANU 본 chair-facing session
- 완료 상태: `WATCHER_FRESHNESS_TRUTH_CONTRACT_READY`
- 트리거: task-2697 watcher report (head dd09f520) vs live (head 1d02bfd6 · taskctl-state-guard FAILURE x2) 불일치

## 0. 사고 핵심

watcher 가 dispatch 시점 head(dd09f520) 기준 분석 + report 작성 → 그 사이 PR head 가 1d02bfd6 으로 drift → report 가 stale 상태로 MERGE_READY/CHAIR_REQUIRED 주장. **callback 직전 live GitHub state 재조회 누락**이 근본 원인.

## 1. 핵심 원칙 (★ 회장 verbatim)

> watcher report 는 **callback 직전 live GitHub state 를 다시 조회**해야 한다. head SHA mismatch 가 있으면 기존 report 를 자동 stale 처리하고 CHAIR_REQUIRED 로 전환한다.

## 2. 필수 포함 12 필드 (★ 회장 verbatim · 모든 watcher callback envelope/report 의무)

| # | 필드 | 정의 |
|---|---|---|
| 1 | live_head_sha | callback 직전 `gh pr view --json headRefOid` 재조회 값 |
| 2 | watcher_target_head_sha | watcher 작업 시작 시 target head |
| 3 | fetched_at | live 재조회 timestamp (UTC ISO) |
| 4 | gh_api_source | `gh pr view <n> --json ...` / `gh api graphql` 명시 |
| 5 | ci_snapshot | live CI check 별 conclusion (★ 11개 전부 나열) |
| 6 | gemini_review_snapshot | latest Gemini review + review head SHA |
| 7 | unresolved_thread_snapshot | live unresolved count + path |
| 8 | mergeStateStatus_snapshot | live mergeStateStatus (CLEAN/BLOCKED/DIRTY/UNKNOWN) |
| 9 | reviewDecision_snapshot | live reviewDecision (APPROVED/빈값/...) |
| 10 | head_drift | watcher_target_head != live_head → true |
| 11 | stale_invalidation_rule | drift/CI mismatch 시 자동 stale 처리 규칙 |
| 12 | callback_pre_recheck_rule | callback 직전 live recheck 수행 evidence |

## 3. 필수 hard gate (★ 회장 verbatim · 2026-05-27 강화: HG5 unresolved mismatch 추가)

| gate | 조건 | 결과 |
|---|---|---|
| **HG1 head drift** | target_head != live_head | `STALE_WATCHER_REPORT_INVALIDATED` + `CHAIR_REQUIRED` |
| **HG2 CI mismatch** | CI snapshot 이 live 와 불일치 | `STALE_WATCHER_REPORT_INVALIDATED` + `CHAIR_REQUIRED` |
| **HG3 Gemini head mismatch** | Gemini review head != live head | `STALE_WATCHER_REPORT_INVALIDATED` + `CHAIR_REQUIRED` (또는 `GEMINI_EXTERNAL_TRIGGER_STALE`) |
| **HG4 pre-recheck 누락** | callback 직전 live recheck evidence 부재 | `HOLD_FOR_CHAIR` |
| **HG5 unresolved mismatch** (★ 2026-05-27 추가) | watcher unresolved count != live unresolved count | `STALE_WATCHER_REPORT_INVALIDATED` + `CHAIR_REQUIRED` |

★ 회장 verbatim 2026-05-27 정식 4 hard gate: **head drift / Gemini head mismatch / CI mismatch / unresolved mismatch** — 1개라도 발생 시 `STALE_WATCHER_REPORT_INVALIDATED` + `CHAIR_REQUIRED`.

★ 근본 예방: artifact contamination doctrine — runtime code PR 에 artifact 혼합 금지로 head drift 자체를 차단. 단일소스: [[feedback_runtime_code_artifact_separation_doctrine_260527]]

## 4. task-2697 사고 적용 (★ 본 contract 로 재판정)

| 필드 | task-2697 watcher report | live (ANU 확인) | gate |
|---|---|---|---|
| live_head | dd09f520 (★ target 만) | 1d02bfd6 | **HG1 FAIL → STALE** |
| ci_snapshot | "11/11 SUCCESS" | taskctl-state-guard FAILURE x2 + 9 SUCCESS | **HG2 FAIL → STALE** |
| unresolved | "처리 가능" | 4 unresolved | mismatch |
| head_drift | (미기록) | true | **HG1** |
| callback_pre_recheck | ✗ (★ dd09f520 기준 고정) | (필요) | **HG4 FAIL** |

→ **PR156_RELEASE_WATCHER_REPORT_STALE_INVALIDATED** (★ HG1+HG2+HG4 동시 FAIL)

## 5. watcher dispatch task md 적용 (★ 향후 모든 watcher)

향후 watcher task md 에 추가 의무:
- callback_on_terminal_state 직전 **live recheck 단계 명시**: `gh pr view <n> --json headRefOid,statusCheckRollup,mergeStateStatus,reviewDecision` 재조회 후 envelope 에 12 필드 기록
- target_head != live_head → terminal_state 강제 `CHAIR_REQUIRED` (★ MERGE_READY 선언 금지)
- CI snapshot 은 watcher 시작 시점 아닌 **callback 직전** 값

## 6. PR #156 재평가 조건 (★ 회장 verbatim 보고)

- live_head 1d02bfd6 기준 **재평가 필요** (★ dd09f520 watcher report 무효)
- live CI: **taskctl-state-guard FAILURE x2** 해소 필요 (★ in-progress/queued 또는 실패 원인 규명)
- live unresolved 4 thread 처리 필요
- mergeStateStatus BLOCKED → CLEAN 전환 필요
- ★ 재평가는 **fresh watcher (live recheck contract 적용)** 또는 **ANU 직접 live read-only** 로만

## 7. head drift 원인 분석 필요 (★ read-only 후속)

- dd09f520 (watcher dispatch 시) → 1d02bfd6 (현재): PR #156 head 가 watcher 작업 중/후 변경
- 원인 후보: dev7 task-2696 추가 commit / Gemini auto-fix / 기타 push
- ★ head drift 원인 규명 = PR #156 재평가 선행 (★ same-PR push doctrine 확인)

## 8. 금지 (★ 회장 verbatim)

- PR #156 merge / auto-merge
- watcher 결과를 merge-ready 로 사용
- stale report 기반 thread resolve
- code 수정 / commit/push / branch cleanup
- PR #152 old branch 처리 / PR #154 재검증 / PR #151 처리
- dispatch.py/hooks/settings/runtime 변경

## 9. forbidden_action_count

**0** (★ read-only contract 작성 + live 확인만 · 코드 0 · merge 0)

끝
