# task-2722+1 dispatch prompt — PR #168 uuid tmp suffix fix (#2/2)

## 회장 결정 근거
- 2026-06-02 회장 verbatim: "task-2722+1 uuid tmp suffix fix는 bounded fix #2/2로 기록하세요"
- bounded fix budget doctrine 적용 (feedback_bounded_fix_budget_doctrine_260602.md)
- HIGH thread [4] 회장 명시 승인된 1회 fix
- MEDIUM thread [5] ADJACENT_LAYER (테스트 동시 수정) → 같은 commit 묶음

## 대상 (PR #168, branch task/task-2722-dev1, head 59cb1b651f91e2537dc305f89cfc11eda15b129b)

### Production change
**파일**: `dispatch/anu_owned_callback_enforcement.py` (line ~688, `_atomic_write_json`)

**현재 (문제)**:
```python
tmp = f"{path}.{os.getpid()}.tmp"
```

**변경 (회장 승인 1회)**:
```python
import uuid
tmp = f"{path}.{os.getpid()}.{uuid.uuid4().hex}.tmp"
```

**근거 (Gemini HIGH thread [4])**:
> 동일한 프로세스 내에서 여러 스레드가 동시에 `_atomic_write_json`을 호출하는 경우, `os.getpid()` 값이 동일하므로 임시 파일 이름(`tmp`)이 중복되어 파일 쓰기 충돌 및 데이터 손상이 발생할 수 있습니다.

### Test change
**파일**: `tests/regression/test_anu_owned_callback_enforcement_2717.py`

- `test_19~test_23` 영역
- 변경: 고정 `tmp_path` 예측 → glob/디렉토리 스캔으로 `.tmp` 존재/부재 검증
- `test_21_atomicity_crash_during_write_no_partial`: uuid suffix 적용 후에도 `.tmp` 누수 0 검증
- 추가: 멀티스레드 시나리오 1건 (concurrent `_atomic_write_json` → 충돌 0 + 최종 파일 무결성)

**근거 (Gemini MEDIUM thread [5])**:
> `_atomic_write_json`에서 임시 파일 이름에 고유한 UUID를 사용하도록 변경함에 따라, 테스트 코드에서 고정된 임시 파일 경로(`tmp_path`)를 직접 예측하여 존재 여부를 검증하는 방식은 실패하게 됩니다.

## bounded fix budget 기록 (필수 artifact)

`memory/events/task-2722+1.bounded-loop-decision.json`:
```json
{
  "task_id": "task-2722+1",
  "pr_number": 168,
  "head_sha_before": "59cb1b651f91e2537dc305f89cfc11eda15b129b",
  "capability": "result_json_atomic_writer",
  "severity": "HIGH",
  "remediation_round": {"count_used": 2, "budget": 2},
  "finding_attribution": "SAME_ATTACK_SURFACE",
  "auto_continue_allowed": false,
  "chair_required_reason": "post-#2/2: 새 HIGH/CRITICAL 시 즉시 CHAIR_REQUIRED, medium 반복 시 defer/evidence resolve",
  "codex_cycle": 0,
  "gemini_cycle": 3,
  "push_count_before": 3,
  "task_plus_n": 1,
  "chair_authorization": "verbatim 2026-06-02: task-2722+1 uuid tmp suffix fix = bounded fix #2/2"
}
```

`memory/events/task-2722+1.finding-attribution.json`:
```json
{
  "task_id": "task-2722+1",
  "pr_number": 168,
  "findings": [
    {
      "thread_id": "HIGH thread [4]",
      "severity": "HIGH",
      "file": "dispatch/anu_owned_callback_enforcement.py",
      "function": "_atomic_write_json",
      "root_cause": "os.getpid() collision in multi-thread within same process",
      "vulnerability_class": "race_condition/data_corruption",
      "attribution": "SAME_ATTACK_SURFACE",
      "evidence": "이전 #1/2 (commit 59cb1b65) tmp cleanup fix와 동일 함수 + 동일 atomicity class"
    },
    {
      "thread_id": "MEDIUM thread [5]",
      "severity": "MEDIUM",
      "file": "tests/regression/test_anu_owned_callback_enforcement_2717.py",
      "function": "test_21_atomicity_crash_during_write_no_partial",
      "root_cause": "test predicts fixed tmp_path that no longer matches uuid suffix",
      "vulnerability_class": "test_brittleness",
      "attribution": "ADJACENT_LAYER",
      "evidence": "production code의 uuid 적용에 직접 결합된 test 수정. 같은 모듈 다른 layer (production ↔ test)"
    }
  ],
  "counter_decision": "기존 counter 누적 — 단일 commit으로 #2/2 한도 안에서 처리. 별도 reset 불가."
}
```

## 진행 절차 (회장 §5)

1. dev1 (불칸): production fix + test 수정 단일 commit
2. 회귀 테스트: 기존 5건 + 멀티스레드 1건 추가
3. non-force push (force push 금지, 새 commit만 push)
4. fresh head 확인 후 보고 → 회장 OWNER `/gemini review` trigger
5. CI_WATCH_HANDOFF로 watcher 위임 (ANU 직접 polling 금지)
6. MERGE_READY_CANDIDATE까지만 자동 수렴
7. merge는 회장 승인 전 금지

## HOLD 조건 (회장 §5)

- 새 HIGH/CRITICAL 발생 → 자동 fix 금지, 즉시 CHAIR_REQUIRED
- medium 반복 발생 → 코드수정 금지, defer/evidence resolve 또는 CHAIR_REQUIRED
- finding_attribution INDEPENDENT_FINDING 봇 자체 판정 금지 (Codex/회장 판정 필요)

## 금지 (회장 §"금지")

- doctrine/schema/task template 변경 → 별도 PR로 분리 (이 PR diff 혼입 금지)
- finish-task.sh 수정 금지
- QC/scope-guard hardening 혼입 금지
- activation/systemd/real wake 금지
- force push / rebase / admin override / merge 금지

## callback (필수)

- collector key: **ANU c119085addb0f8b7** (self-key 절대 금지)
- envelope schema: schedule_id / chair_facing_session_id / collector_role / lifecycle 2축 / merge_ready_classifier 포함
- 봇 종료 전 ANU callback 발사 강제 (성공/실패/HOLD/blocked 무관)

## 보고 형식 (회장 §"보고 형식" 7항목)

dev1 callback 시 다음 7항목 포함:
1. PR #168 current_state (post-push head, mergeStateStatus, CI rollup)
2. bounded_fix_budget status (remediation_round count_used=2/2)
3. finding_attribution 결과 (SAME_ATTACK_SURFACE + ADJACENT_LAYER)
4. next_action (OWNER /gemini review trigger 대기 → watcher 위임)
5. parallel_doctrine_update status (이 PR diff 혼입 0 확인)
6. auto_continue_allowed (post-#2/2: false hard-stop)
7. chair_required_reason (post-#2/2 정책)
