# task-2722+1 — PR #168 bounded fix #2/2: _atomic_write_json tmp 파일명 충돌 방지 (uuid suffix)

## 회장 인가 (2026-06-02, A안 — bounded fix #2/2 소진)
PR #168(head `59cb1b65`) fresh HIGH 1건 = 유효: `_atomic_write_json` tmp 파일명 `{path}.{os.getpid()}.tmp` → 동일 프로세스 내 동일 target path 동시 write 시 tmp **충돌 가능성**. writer atomicization 목적상 dismiss 금지·수정.
★ **이번이 bounded fix 예산 2/2 소진.** 이 후 새 HIGH/CRITICAL → 자동 fix 금지·CHAIR_REQUIRED. medium 반복 → defer/evidence-based resolve.

## worktree
- `/home/jay/workspace/.worktrees/task-2722-dev1` (branch `task/task-2722-dev1`, head `59cb1b65`)에서 **이어서**. base origin/main 7839dede.

## expected_files (PR #168 동일 2개 — 그 외 수정 금지)
1. `dispatch/anu_owned_callback_enforcement.py` ← 주 수정(tmp 파일명만)
2. `tests/regression/test_anu_owned_callback_enforcement_2717.py` ← 테스트 조정
(evidence: memory/events/task-2722+1.done · memory/reports/task-2722.md)

## 허용 수정 (회장 verbatim)
1. `dispatch/anu_owned_callback_enforcement.py`:
   - `_atomic_write_json` tmp 파일명에 **`uuid.uuid4().hex`(또는 동등 충돌방지 suffix)** 추가. 예: `f"{path}.{os.getpid()}.{uuid.uuid4().hex}.tmp"`.
   - ★ 기존 **schema / function signature / caller 동작 / callback authority 변경 금지**.
   - ★ 기존 **os.replace(atomic rename) 유지** · **fsync(file)+fsync(parent dir) 유지** · **tmp cleanup finally 로직 유지**.
   - `import uuid` 추가만 허용.
2. `tests/regression/test_anu_owned_callback_enforcement_2717.py`:
   - 고정 tmp 경로 전제 테스트가 깨지지 않도록 **디렉토리 내 `.tmp` 스캔 방식**으로 조정.
   - tmp 충돌 방지 또는 tmp cleanup 검증 추가/보강.

## 금지 (회장 verbatim)
- expected_files 2개 밖 수정 금지 · finish-task.sh / pickup driver / systemd unit 수정 금지.
- activation flag 생성 / systemctl / 실 pickup·wake·ANU key wake 금지.
- result schema/signature/callback authority 변경 금지 · credential/permission 확장 금지.
- QC text-token / finish-task PROJECT_PATH·scope-guard hardening 혼입 금지.
- force push/rebase/admin override/merge 금지. ANU key literal 노출 0. P0-a `anu_result_pickup_runner.py` 무수정.

## 검증 조건 (회장 verbatim)
1. regression PASS(증가).
2. tmp 파일명 **충돌 방지 확인**(uuid suffix → 동일 target 2회 write tmp 경로 상이).
3. os.replace 유지.
4. fsync(file)+fsync(parent dir) 유지.
5. tmp cleanup 유지.
6. schema/signature/caller 불변.
7. `git diff --name-only origin/main` = expected_files 2파일 내부.
8. forbidden 0.
9. ANU key full literal 0.
10. active=false / installed=false / wired=false 유지.
- smoke: `python3 -m py_compile dispatch/anu_owned_callback_enforcement.py`.

## finalize (로컬 commit 까지만)
1. fix → regression PASS → `git add` 2파일 → 로컬 commit. **push/PR/merge 금지(ANU governance)**.
2. `memory/reports/task-2722.md` 에 bounded fix #2(uuid tmp suffix) 추가.
3. `memory/events/task-2722+1.done` 생성. ANU key(c119085, sealed) callback. ★ ANU key literal 노출 0.

## ANU 후속 (봇 아님 — governance)
독립 재검증(2파일/uuid suffix/os.replace·fsync·cleanup 유지/schema·signature 불변/regression/key 0/active=false) → non-force push → **OWNER `/gemini review` 새 head 반드시 재발사** → CI/Gemini watcher 재가동 → CI GREEN + fresh unresolved 0 + diff 2파일 + forbidden 0 + ANU key 0 → **MERGE_READY_CANDIDATE** 보고. 새 HIGH/CRITICAL → CHAIR_REQUIRED. merge 회장 승인 전 금지.

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "dispatch/anu_owned_callback_enforcement.py"
    - "tests/regression/test_anu_owned_callback_enforcement_2717.py"
    - "memory/events/task-2722+1.done"
    - "memory/reports/task-2722.md"
  forbidden_paths:
    - "scripts/finish-task.sh"
    - "dispatch/anu_result_pickup_runner.py"
    - "dispatch/anu_pickup_driver.py"
    - "deploy/systemd/**"
    - ".github/**"
  commands:
    - "pytest"
    - "python3 -m pytest"
    - "python3 -m py_compile"
  merge_policy: "none"
  ttl_hours: 48
```

## ★ dispatch 템플릿 G3(PR/머지) 무시. finalize 로컬 commit only.

## goal_assertions (auto-generated)
- `python3 -m pytest tests/regression/test_anu_owned_callback_enforcement_2717.py -q`
- `python3 -c "import sys; s=open('dispatch/anu_owned_callback_enforcement.py').read(); sys.exit(0 if 'uuid' in s and 'os.replace' in s and 'os.fsync' in s else 1)"`
- `python3 -c "import sys; s=open('dispatch/anu_owned_callback_enforcement.py').read(); sys.exit(1 if 'c119085addb0f8b7' in s else 0)"`