# task-2617 — ANU v3 CLI OUTPUT PATH GUARD (회장 직접 승인 BOUNDED REMEDIATION) 결과 보고

- **승인**: 회장 직접 2026-05-19 — task-2616 scan ACCEPT 후 Critical7 3건 한정 공통 guard remediation.
- **spec sha256**: `66eb32af868268c8dc3387f1ed2fae289d167d0cb555a94668627db85f989e3e` (일치 검증 ✓)
- **executor**: dev1-team 헤르메스 (key c38fb9955616e24d) 1회 한정
- **상태**: 구현·테스트·Codex 재audit 완료 → independent ANU 재검증 대기
- **완료 판정 기준**: Codex HIGH/CRITICAL 0 **AND** independent ANU PASS — *authoritative = 독립 ANU only*

## 1. 검출 3건 한정 remediation (변경 전후 sha256)

`if <out>:` 파일출력 분기만 `cli_output_path_guard.atomic_guarded_write` 경유로 교체. `else:` stdout 분기는 byte 불변. 파일당 net +4 line.

- `anu_v3/batch_hold_adjudicator.py` (`--output`) — `b255bb42…` → `2683b473…` · 핵심로직 불변(`--selfcheck` PASS 11/11)
- `anu_v3/batch_dependency_classifier.py` (`--out`) — `93ffc27e…` → `7e1bad7f…` · 핵심로직 불변(`--mode regression` all_pass=True). task-2613+1 이 명시적 CHAIR_HOLD 로 남긴 `--out` Critical7 의 회장 승인 후속 해제.
- `anu_v3/pre_authorized_evidence_bundle_builder.py` (`--out`, 신규 Critical7) — `9344f9aa…` → `5fd92c49…` · 핵심로직 불변(stdout default bundle 정상). §2 회장 직접 sha256 명시 = HOLD 해제.

## 2. stdout-only 3건 byte-0 (guard 미적용·불변 입증)

`auto_remediation_planner.py` / `codex_high_classifier.py` / `critical7_classifier.py` 의 sha256 이 baseline 과 **완전 동일**. byte-0·동작 불변 확인.

## 3. guard 모듈 (`anu_v3/cli_output_path_guard.py`) — import-only

- argparse / `main()` / `__main__` 부재(AST 검증). 순수 import-only.
- 기본 stdout 유지. 파일출력 = `CANONICAL_WS_ROOT(/home/jay/workspace)/memory/events|reports` **직하위**·**task-id prefix** 강제.
- fail-closed: absolute · `../` · ws-escape · 비허용 root · 중첩 · symlink-component · hardlink · overwrite.
- TOCTOU 방어: `Path.resolve` strict-prefix 단독 가정 금지 → ws_root 부터 부모까지 component 별 `lstat`+`O_NOFOLLOW` open → `O_CREAT|O_EXCL|O_NOFOLLOW` temp+fsync → `os.link` no-overwrite(EEXIST=fail-closed)+dir-fd 상대연산 → post-resolve `/proc/self/fd` 재검증. 실패 시 write 전 차단·부분파일/temp 미잔존.
- policy: `config/cli_output_path_policy.yaml` (`anu_v3.cli_output_path_policy.v1`).

## 4. 검증

- **regression**: `tests/regression/test_cli_output_path_guard_2617.py` — **30 passed**. (허용/거부/atomic/overwrite/symlink/3 CLI sink/stdout 불변/비허용 --output fail-closed/stdout-only byte-0/policy 유효성)
- **충돌 없음**: task-2610.result(`d5356277…`) · task-2613+1.result(`525be4a8…`) · task-2613.result(`3447355c…`) byte-0 불변 → 기존 remediation 무충돌 입증.
- **Codex 재audit** (codex-cli 0.106.0, read-only): **VERDICT: HIGH/CRITICAL count = 0**. 원 Critical7 `arbitrary fs write` mitigated 확인(absolute/traversal/escape 차단·parent symlink TOCTOU 차단·overwrite/hardlink 차단).
  - non-Critical **MEDIUM**: `task_id=None` 시 동일 namespace 내 임의 `task-*` prefix 신규파일 생성 가능(cross-task spoofing residue). blast radius 가 *파일시스템 전역 → ws/memory/{events,reports} 신규·task-id prefix* 로 축소됨. `task_id=None` 은 3 CLI 범용성 보존 위한 의도적 설계(hardcoded task-id = 검출 3건 외 임의 리팩터링 회피). **AUTO_REMEDIATION_HOLD 자동 수렴** 대상 — 비-Critical·shared-invariant 미파손·CHAIR_HOLD 아님.

## 5. 금지·동결 준수

task-2611+1 precedence 미수정 · +53/+54/+55/Track E 미트리거 · durable-success write-back 0 · GitHub merge/PR/branch/main write 0 · 검출 3건 외 임의 리팩터링 0 · stdout-only 3건 byte-0 · task-2611+1 scope 혼합 0 · executor self key `c38fb9955616e24d` callback/collector/adjudication/dispatch 0(+49 코드 정본) · credential 0 · 문서-only 아님(실 구현+테스트+감사).

## 6. callback / 다음 게이트

완료+30s 에 **독립 ANU key `c119085addb0f8b7`** (chat 6937032012) 로 normal completion callback 등록 → 독립 ANU collector 회수·Codex 재audit·adjudication. executor self key 절대 금지. **+53/+54/+55/Track E·durable-success write-back 은 회장 별도 승인 (본 task 자동 진행 0).** 본 보고는 self-finalization 아님(HOLD_CANDIDATE 성격) — 최종 판정 권위는 독립 ANU only.
