# task-2716 — PR_DIFF_HYGIENE_GUARD 완료 보고 (final evidence packet)

- **팀/담당**: dev4-team · 비슈누(Vishnu)
- **확정**: 회장 2026-05-30 1순위 (4규칙 중 Rule 3 단일)
- **범위**: 로컬 구현 only — PR/push/merge/GitHub write 없음. 로컬 commit + 검증 + ANU callback.
- **단일소스**: memory/specs/system_anu_executor_4rule_codification_spec_260530.md (Rule 3)
- **task md sha256**: 5949db5046bef32c43763ad5d9ea08d9d913ed785d2bfc93e4f3f87972e4c058 (검증 일치)

## 1. 산출물 (코드 + 테스트)

| 구분 | 경로 | 비고 |
|---|---|---|
| 신규 모듈 | scripts/harness/v36/pr_diff_hygiene_guard.py | classify_pr_diff 핵심 |
| 테스트 | tests/harness/test_v36_pr_diff_hygiene_guard.py | 회장10 + 모듈7 = 17 |
| 주 결선 | scripts/finish-task.sh (pre-push 단계, 최소 수정 +21 라인) | contamination 차단 |
| 보조 결선 | scripts/harness/v36/closeout_marker_watcher.py (+33 라인) | read-only detection |

- **new_commit_sha (로컬)**: 75fdf540df44825ec2b53f0f98c3a7c7d0745d4d
- **branch (로컬, 미푸시)**: task/task-2716-pr-diff-hygiene-guard-dev4
- 커밋 포함 파일 정확히 4개. 무관한 dirty tree 파일은 제외(스코프 격리).

## 2. 설계 (allowlist-aware)

핵심 함수:
`classify_pr_diff(changed_files: list[str], expected_files: list[str]) -> {"status", "blocked", "reasons"}`

- status: `PASS` | `PR_DIFF_CONTAMINATED`
- allowlist 는 **함수 인자(expected_files)** 로만 받음 — 하드코딩 금지. task md 파싱 헬퍼 `extract_expected_files()` 별도 제공(동적 수집).
- 차단(미선언 시): `memory/events/**` · `memory/artifacts/**` · `*callback-envelope*.json` · `*auth*marker*.json` · `*-evidence.md`(+`*fix-evidence*.md`) · temp report · cleanup evidence.
- 통과: code + expected_files 에 선언된 파일(예: 선언된 `memory/reports/task-*.md`). 선언분은 artifact 패턴이어도 예외 통과 → 정상 expected_files false-positive 0.
- **★ .github/workflows/\*\* 는 artifact 패턴에 미포함 — 본 가드가 절대 차단/수정하지 않음**.

## 3. 결선 지점 (wired_points)

1. **주 결선 = finish-task.sh pre-push 단계**: `git diff --name-only main..HEAD` → `pr_diff_hygiene_guard.py --changed - --task-md $TASK_FILE` 호출. `PR_DIFF_CONTAMINATED` 시 non-zero → merge 차단. 모듈/diff 부재 시 graceful skip.
2. **보조 결선 = closeout_marker_watcher.detect_pr_diff_contamination()**: `detect_contamination()` 재사용, read-only(보고만, 차단 아님, never raise).

## 4. 테스트 결과 — 17/17 PASS

회장 지정 10:
1. clean code-only → PASS
2. 선언 memory/reports/task-2712.md → PASS
3. 미선언 fix-evidence.md → BLOCK
4. memory/events/*.json → BLOCK
5. memory/artifacts/** → BLOCK
6. *callback-envelope.json → BLOCK
7. *auth*marker*.json → BLOCK
8. allowlist 포함 시 위 패턴 예외 → PASS
9. **PR #161 ea2eb02a (4 code + evidence md) → BLOCK** (evidence md 단독 지목, code 4건 무차단)
10. **PR #161 4aa779ec 결과 code-only → PASS**

모듈 단위 7: reasons 매핑 / glob 선언 / 빈 allowlist 차단(하드코딩無 입증) / detection-only alias / task-md 파싱 / .github/workflows 무차단 / CLI exit code(1·0·0).

fixture 는 실제 PR #161 파일목록(ea2eb02a · 4aa779ec) 기반으로 회귀 고정.

실행: `python3 -m pytest tests/harness/test_v36_pr_diff_hygiene_guard.py -q` → `17 passed`.

## 5. 금지사항 준수

- task-2713/2714/2715 dispatch 없음.
- CI workflow(.github/workflows/**) 수정 0건 (commit diff 검증: 리터럴 매치 0).
- PR/push/merge/GitHub write 없음 — 로컬 commit 1건만.
- task-2712 evidence 변경 없음 / merged history 수정 없음 / 기존 PR 되돌리기 없음.
- self-check marker 남발 없음 · spec 복제 없음 · final evidence packet 본 보고 1개만.

## 6. push 정책

dev bot App token 부재 + 회장 push 금지 → **push 안 함**. 로컬 commit(75fdf540) + 본 검증 + ANU callback 까지.
