# POST#186 Callback/Finalize Dogfood + G4 Cap Audit — 설계 (task-2729+11)

> 작성: 2026-06-07 | 팀: dev4 (비슈누) | 레벨: Lv.3 (audit-first, production activation 아님)
> doctrine: canonical 무손상 · isolated temp root · 증거기반 과장 0 · G4 counter reset/수동 .done 금지 · ANU 독립 collector

## 0. 목표 (회장 verbatim)
1. #186(7e18ab4d) 이후 start_task_guard/finish-task 가 canonical task-2716 parked 에서도 **worktree-root 기준** 정상 작동 검증.
2. G4_FIX_LOOP_CAP_PATTERN **stale residue vs live blocker** 분리.
3. `.done`/`.qc-done`/callback prereg/result.json 경로 정상화 audit-first 확인.
4. 정상 callback 자동수렴 성공 과장 금지 — 실제 증거 있을 때만 기록.
5. production activation / real ANU spawn 없이.

## 1. 배경 단일 소스
- 상태: `CALLBACK_FINALIZE_PATH_EXPECTED_IMPROVED_NOT_YET_DOGFOODED`. #186 코드는 origin/main 반영, dogfood 미수행.
- 반복 증상: task-2729+5/+7/+8/+10 callback 미발사 (EXTERNAL_DIRTY_BLOCKER / START_TASK_GUARD #7 canonical=main 가정 / G4 fix_loop_cap).
- #186 후보 해소: #7 worktree-root 전환 + finish-task G2 nullglob-safe.

## 2. 핵심 사실 (audit 으로 확정)
- **origin/main HEAD = 7e18ab4d = #186** 포함. canonical working tree 는 `task/task-2716-...`(75fdf540) 에 parked → **canonical 체크아웃의 start_task_guard.py 는 #186 미포함 구버전**(`main_current_branch != "main"` 강제).
- 따라서 dogfood 는 **#186 버전(origin/main, 또는 origin/main 기반 worktree)** 스크립트로 수행해야 정합. 본 task 의 worktree(`.worktrees/task-2729+11-dev4`, base=7e18ab4d)가 곧 #186 검증 매체이자 라이브 dogfood 환경.

## 3. 검증 매체: isolated temp root + live worktree (이중)
직접 코딩 금지(ANU)·canonical 무손상 원칙상, 동작 검증은 (A) `tempfile.mkdtemp()` 격리 git repo, (B) 실제 canonical-parked + origin/main worktree 라이브 실행, 두 경로로 교차 입증.

## 4. audit 항목 설계

### A. start_task_guard #7 worktree-root (CHECK A1)
- 격리 temp repo: bare origin(main) → work repo 를 non-main `task/parked-canonical` 로 checkout + untracked dirty (canonical parked+dirty 모사) → `git worktree add -b task/<t>-<bot> .worktrees/<t>-<bot> origin/main`.
- WORKSPACE_ROOT=temp work repo (env override), cwd=worktree, **GUARD_186** (`.worktrees/task-2729+11-dev4/scripts/start_task_guard.py`) 실행.
- 기대: 검증 #7 통과("worktree base가 origin/main과 일치 (fresh)") + exit 0. canonical 브랜치 무관.
- static fallback: GUARD_186 소스에 `cwd=cwd` 기반 origin/main·HEAD 비교 존재 + `main_current_branch != "main"` 부재 검증.

### A2. finish-task.sh G2 nullglob-safe dirty 면제
- G2 핵심(origin/main:finish-task.sh ~L877): `for _wt in "$WORKSPACE/.worktrees/${TASK_ID}-"*; do [ -e "$_wt" ] && _WT_ISOLATED=1; done` → nullglob ON/OFF 모두 부재 시 0 (fail-closed).
- dirty 분류: `utils/dirty_registry.classify_blocker(expected, dirty)` → 무관 dirty=EXTERNAL_DIRTY_BLOCKER, expected 포함=OWN_DIRTY_FAIL.
- 매트릭스: EXTERNAL+격리→EXEMPT, EXTERNAL+비격리→BLOCKED, OWN+격리→BLOCKED(면제 불가).

### B. G4 fix_loop_cap stale-vs-live (CHECK B) — counter reset 0
- 읽기: task-2729+10 `.g4-fix-loop-count`(=2, mtime 11:40), `.g4-fix-loop-cap.json`(ts 02:49Z=11:49 KST), `.finalize-only`, `.callback-cause.json`.
- 판정 로직: cap(11:49) < PR#186 merge(13:24) → cap 이 머지 **이전** finalize 경로에서 pre-existing count=2 를 읽어 발생. PR#186 은 HIGH/CRITICAL 0 으로 정상 머지 → 3차 live fix 아님 → **STALE_RESIDUE**.
- 선례: task-2729+1 `P0A_G4_SUPERSEDE_ADJUDICATION` = `STALE_RESIDUE_CONFIRMED` (동일 패턴).

### C. callback prereg seed vs robust (CHECK C)
- seed: `task-2729+9.callback-envelope.json` schema=`utils.anu_callback_registrar.v2` + REGISTERED + delivery=PENDING + receipt=UNCONFIRMED → SEED_PLACEHOLDER (intent marker).
- robust: `task-2729+10.callback-launch.json` schema=`dispatch.normal_fallback_callback_helper.launcher.v1` + verdict=PASS + owner=ANU key + argv + enforcement.verdict=PASS → ROBUST_FRAMEWORK_REGISTRATION_REQUEST.
- ANU key raw 출력 0 (마스킹).

## 5. 산출물 (EXPECTED FILES 정확히 5)
1. `scripts/harness/v36/post186_callback_finalize_dogfood_audit.py` — read-only 격리 dogfood 하니스
2. `tests/regression/test_post186_callback_finalize_dogfood_2729p11.py` — 회귀 10건
3. `memory/reports/task-2729+11.md` — audit 결과
4. `memory/plans/p0b-pickup/post186_dogfood_g4_audit_design_260607.md` — 본 설계
5. `memory/events/task-2729+11.live-dogfood-evidence.json` — 라이브 증거(gitignored on-disk)

## 6. 완료 판정 기준
- A1·A2 PASS + B=STALE_RESIDUE + C 분리 → `CALLBACK_FINALIZE_DOGFOOD_PASS_ACTIVE_FALSE`.
- B=LIVE_BLOCKER / canonical write 필요 / real spawn 필요 / ACTIVE=true 필요 / 수동 .done 필요 → `HOLD_FOR_CHAIR`.

## 7. status
completed (2026-06-07)
