# task-2617+1 — atomic_guarded_write dir-rename TOCTOU 자동 수렴 (Track A AUTO_REMEDIATION)

- **분류**: AUTO_REMEDIATION_HOLD 자동 수렴 (non-Critical HIGH · 신규 Critical7 0 · shared invariant 0 · 회장 확인 대기 0)
- **spec sha256**: `a9cfacab3514c4d43825136d734448cb33733077ac4f3de446e146cc4598a2d3` (일치 확인)
- **executor**: dev1-team 헤르메스 (key c38fb9955616e24d, 1회 한정)
- **ts**: 2026-05-19 15:50:56

## 1. 잔여 HIGH (collector 확정)

`anu_v3/cli_output_path_guard.py` `atomic_guarded_write` 는 `_open_dir_nofollow` 로
부모 dir fd(dfd)를 고정한 뒤 `/proc/self/fd/{dfd}` realpath 로 1회 containment
체크를 수행한다. 그러나 **이 체크 이후 `os.link()` 사이에 `memory/events|reports`
(또는 그 ancestor) 가 rename** 되면 pinned dfd 가 이동된 inode(ws 밖)를 가리켜
final 이 워크스페이스 밖에 안착할 수 있었다. final inode 에 bound 된 **post-link
재검증이 부재**했다. 3 sink 전부 이 helper 에 의존.

## 2. 수정 (atomic_guarded_write 단일)

`os.link()` 성공 직후 ~ `os.unlink(tmp)` 전에 **post-link final-inode bound
재검증** 추가:

1. final 파일을 `dir_fd=dfd` 상대 `O_NOFOLLOW|O_RDONLY` 로 open (`ffd`).
2. `os.path.realpath("/proc/self/fd/{ffd}")` 로 최종 안착 경로 산출.
3. `ws_real` + policy allowed_roots(`memory/events`,`memory/reports`) 절대 prefix
   집합 중 하나의 하위(또는 동일)가 아니면 → `os.unlink(fname, dir_fd=dfd)` 로
   final 즉시 제거 후 **`SystemExit`(fail-closed)**.

`SystemExit` 은 `BaseException` 이라 기존 `except Exception → GuardError` 승격
경로에 잡히지 않고 그대로 전파(하드 fail-closed). `finally` 는 그대로 실행되어
temp 잔존물도 정리된다. 정상 경로(rename 미발생)에서는 final_real 이 allowed
prefix 하위 → 분기 통과, 기존 동작 완전 불변.

## 3. 불변식 준수

- guard **import-only 불변**: argparse / main / `__main__` 0 (AST 확인).
- 변경 범위: `atomic_guarded_write` 단 1함수. 검출 1건(dir-rename TOCTOU) 외
  리팩터링 0.
- 3 sink(batch_hold_adjudicator/batch_dependency_classifier/
  pre_authorized_evidence_bundle_builder)·`config/cli_output_path_policy.yaml`·
  stdout-only 3건 **byte-0 무회귀** (sha256 anchor + 경유 테스트 PASS).
- ANU Layer-A no-git: 커밋 0, HEAD `20456b5f` 전후 EQUAL, branch 불변.
- 타 track(B/C·task-2553 multitrack·2604·2610~2616) 산출물 byte-0.

## 4. 검증

- regression baseline 30/30 → 변경 후 **32/32** (기존 30 무회귀 + TOCTOU 재현 2 PASS).
- `test_dir_rename_after_check_toctou_blocked`: rename 주입 시 `SystemExit`,
  final 즉시 unlink, ws 안/밖 모두 잔존 0.
- `test_post_link_check_passes_for_legitimate_write`: 정상 write 성공·final
  ws 안 안착·temp 잔존 0 (변경 전후 동등 입증).

## 5. callback / write-back gate

- normal completion callback 은 **독립 ANU key `c119085addb0f8b7`** 로만 발사.
  executor self key `c38fb9955616e24d` 의 callback/collector/adjudication/
  dispatch 절대 금지 (+49 코드 정본).
- 독립 ANU collector 가 회수 → Codex 재audit → adjudication. adjudication 확정
  즉시 본 task 의 ANU fallback safety-net cron 을 cancel-on-success 제거(노이즈 0).
- **Codex 재audit HIGH/CRITICAL 0 일 때만 +53 durable-success write-back**.
  authoritative = 독립 ANU only. 본 executor premature write-back 금지.

## 6. HOLD_FOR_CHAIR

해당 없음. 신규 Critical7 / shared invariant 파손 0 → AUTO_REMEDIATION 자동 수렴.
추가 잔여 발생 시에도 non-Critical 한 자동 수렴 계속(회장 확인 대기 0).
