# task-2720+4 보고서 — PR #166 P0-a 4차 micro-fix: done_path atomic write

## Situation
PR #166 P0-a callback 파이프라인. `dispatch/anu_result_pickup_runner.py` 의 done marker 기록부가 `open(done_path,"w")` 직접 기록 방식이라, 크래시/중단 시 빈·절단 마커가 잔존 → 이후 `pickup_once` 가 `os.path.exists(done_path)` 만 보고 silent skip → P0-a callback 미발사 위험.

## Complication
Gemini High: done_path 비원자 write = 유효 결함. 회장 Option A — 단일 micro-fix(atomic write) **4차 예외** 승인. lock 재도입/스키마 변경 금지. 4차 이후 새 High 발생 시 추가 fix 금지 → LOOP_BOUNDARY 재보고.

## Question
done_content/스키마/`done_path_out` 의미를 전혀 바꾸지 않고 done marker 기록을 원자적으로 만들 수 있는가?

## Answer (수정 내역)
대상: `dispatch/anu_result_pickup_runner.py` (단일 파일, L323~336)
- done_path 직접 기록 제거 → 같은 디렉터리에 `tmp_path = f"{done_path}.tmp-{os.getpid()}"` 생성 → done_content 기록 → `flush()` + `os.fsync(fileno())` → `os.replace(tmp_path, done_path)` 원자 교체.
- OSError 시 tmp 파일 best-effort `os.unlink` 후 `pass` (done_path_out=None 유지, 기존 except 동작 보존).
- done_content/스키마/필드/반환 의미 변경 0. lock 심볼 0 유지.
- commit `85329563` (1 file changed, +9 -2), 로컬 commit only.

## 검증
- grep: `os.replace` 1건 / `open(done_path,"w")` 0건 / lock 심볼(pickup.lock|_lock_acquired|_STALE_LOCK|O_EXCL) 0 / `py_compile` OK
- regression: `test_anu_result_pickup_runner_2720.py` + `test_anu_owned_callback_enforcement_2717.py` = **32 passed**
- `git diff --name-only origin/main` (코드 변경): `dispatch/anu_result_pickup_runner.py` 1개

## L1 스모크테스트 결과
- 서버 재시작: 해당없음 (런타임 데몬 없음 — 순수 함수/파일 IO 단위 변경)
- API 응답 확인: 해당없음
- subprocess/함수 실행 검증: regression 테스트(test_anu_result_pickup_runner_2720.py)가 실제 done marker 기록 경로를 실행하여 32 PASS — 수정된 atomic write 경로가 실동작에서 정상 통과. (정상 시 done_path 생성·내용 일치, `.tmp` 잔존 0)
- 스크린샷: 해당없음

## 게이트
- G1 설계: affected_files = `dispatch/anu_result_pickup_runner.py` 단일, 타 팀 겹침 없음
- G2 구현: regression 32 PASS + 셀프 QC
- G3 머지: 로컬 commit only. PR/머지 = ANU governance (봇 수행 금지)

## 모델 사용 기록
- 불칸(백엔드): sonnet — 코드 수정/테스트/커밋
- 헤르메스(팀장): opus — 설계/검토/통합/완료 절차

## 머지 판단
- 머지 필요: No (ANU 수행)
- 브랜치: `task/task-2720-dev1`
- 워크트리: `/home/jay/workspace/.worktrees/task-2720-dev1`
- 머지 의견: 코드 1파일·32 PASS·회귀 0. ANU 독립 재검증 후 PR 진입 권고. 새 High 시 LOOP_BOUNDARY.
