# task-2729+22 — RAW_KEY_DENYLIST_LITERAL_IN_TEST_HYGIENE Option A REPLACEMENT (QC/evidence-root, activation 0)

## 레벨
Lv.3 (QC verifier evidence-root hardening + test denylist hygiene. production activation 아님)

## 발번 주석
PR #194(task-2729+21) HOLD_FOR_CHAIR 후속 Option A replacement(회장 2026-06-08 옵션 B 승인). #194는 기능(top-level 정규화) 정상이나 회귀 테스트 denylist 에 raw key full literal(`c119085addb0f8b7`, `c38fb9955616e24d`)이 PR diff 노출 = `RAW_KEY_DENYLIST_LITERAL_IN_TEST_HYGIENE_BLOCKER`. **#194 same-branch push/rebase/force/cherry-pick 금지** — fresh origin/main 새 branch. #194(245db3de)는 **참고만**.

## ★★★ FRESH BASE HARD GATE
1. worktree 반드시 **origin/main `571a4ce3`(또는 이후 최신 main)** 분기. canonical(task-2716 계열) 분기 절대 금지.
2. `git worktree add -b task/task-2729+22-<bot> <path> origin/main`.
3. commit 전: `merge-base --is-ancestor 571a4ce3 HEAD == YES` AND `task-2716 divergence 0`. 실패 시 즉시 HOLD.
4. diff `origin/main..HEAD` = expected_files 만(3~4). 오염 diff → HOLD.
- ★ origin/main(571a4ce3)에 +20/+21 CODE_ROOT 코드 없음 → 본 task 가 **CODE_ROOT recognition 전체를 새로 구현**(#194 기능 유지 + denylist 마스킹). #194 코드는 참고만, 복붙/cherry-pick 금지.

## 목표 (회장 verbatim)
1. fresh origin/main 새 branch. #194 코드 참고만, same-PR push/rebase/force/cherry-pick 강행 금지.
2. ★ **테스트 denylist 에서 실제 raw key full literal 전체 문자열 제거**.
3. raw key 탐지 테스트 필요 시 **split literal / synthetic sentinel / fixture placeholder / runtime-assembled non-logged pattern** 사용.
4. ★ **PR diff 에 `c119085addb0f8b7`, `c38fb9955616e24d` 같은 full key literal 0**.
5. 기능적으로 #194의 **top-level normalization fix 유지**(git rev-parse --show-toplevel).
6. **HEAD~5 / shallow / commit 부족 fail-safe 유지**.
7. MEDIUM base_root `/` edge 는 non-blocking 이면 **D안 가능 여부만 보고**(필요 시 해당 edge 처리 포함 가능).
8. dev8 symlink anomaly 는 이번 replacement 에서 **구조 리팩터 금지 — caveat 유지**.
9. **디듀프 리팩터 착수 금지**.

## 핵심 로직 (#194 기능 + 마스킹)
- env 인식: PROJECT_PATH → WORKTREE_PATH → QC_EVIDENCE_ROOT (유효 git dir 시), 없으면 workspace_root fallback.
- **top-level 정규화**: selected env root 가 repo 하위 디렉토리여도 `git rev-parse --show-toplevel` 로 git 최상위 정규화 → diff root 와 path normalization 일치.
- report root(canonical memory/reports) 와 diff/evidence root(정규화된 CODE_ROOT) **분리**.
- **HEAD~5 fail-safe**: 커밋<5/shallow/HEAD~5 부재 → fail-safe 또는 bounded fallback(미정의 crash 금지).
- ★ **denylist 마스킹**: 회귀 테스트가 raw key 0 을 검증하되 **full literal 을 소스에 박지 않음**. 예) split (`"c119085" + "addb0f8b7"`) / synthetic sentinel(`"<ANU_KEY_SENTINEL>"` placeholder + runtime env assemble) / fixture file 외부화. 단 **로그/PR diff 에 full literal 재구성 출력 0**.
- canonical task-2716 dirty/diff 가 selected CODE_ROOT clean finalize 를 false-block 안 함.

## symlink parity (구조 변경 금지)
- per-team 9 = `teams/<team>/qc/verifiers` 디렉토리 symlink → shared. **shared 1파일 수정으로 10카피 동일성**. per-team 파일 직접수정 금지. dev8 absolute double-hop = caveat 만(구조 리팩터 금지). 디듀프 금지.

## EXPECTED FILES (정확히 3~4 — 초과 시 즉시 HOLD_FOR_CHAIR)
1. `teams/shared/verifiers/file_touch_ratio_check.py` — env 인식 + top-level 정규화 + report/diff 분리 + HEAD~5 fail-safe
2. `tests/regression/test_file_touch_ratio_root_recognition_2729p22.py` — 회귀(isolated temp, **denylist 마스킹**)
3. `memory/reports/task-2729+22.md`
4. (필요 시) `memory/plans/p0b-pickup/raw_key_denylist_masking_replacement_design_260608.md`
- ★ per-team verifier / git_evidence.py / dispatch.py / callback prereg 무수정. symlink 구조변경 / 디듀프 필요 시 HOLD.

## 필수 regression (회장 verbatim 13, isolated temp)
1. **PR diff raw key literal 0** (full key 문자열 소스/로그/diff 부재). 2. env root=repo root PASS. 3. env root=repo 하위 디렉토리 top-level 정규화 후 PASS. 4. PROJECT_PATH/WORKTREE_PATH/QC_EVIDENCE_ROOT 우선순위. 5. env invalid → canonical fallback/fail-safe 명확. 6. canonical report + selected CODE_ROOT diff 조합 PASS. 7. worktree changed ↔ report changed 4/4 매칭 ratio 1.00 PASS. 8. HEAD~5 불가/shallow/커밋부족 fail-safe. 9. canonical task-2716 dirty/diff 가 selected CODE_ROOT clean finalize false-block 안 함. 10. per-team directory symlink parity 확인. 11. ACTIVE=false / systemd enable 0 / activation_epoch absent / real spawn 0. 12. git_evidence·dispatch·callback prereg 무수정. 13. canonical task-2716 branch·live memory artifacts 무손상.

## 금지 (회장 verbatim 14)
1. PR #194 same-branch push  2. rebase/force  3. merge  4. production ACTIVE 전환  5. systemctl enable  6. ACTIVE=true 선언  7. activation_epoch 생성  8. real ANU spawn  9. callback prereg Phase B 착수  10. git_evidence.py/dispatch.py 수정  11. canonical reset/clean/stash -u/checkout -f  12. task-2716 branch 수정  13. live memory artifacts 이동·삭제  14. 디듀프 리팩터 착수.
- per-team symlink 구조변경 금지. 모든 검증 isolated temp. canonical 무손상. #194 코드 복붙/cherry-pick 강행 금지(참고만).

## 이번 라운드 범위 (★PR 생성까지 진행)
- 구현 + isolated verify(회귀 13) + **PR 생성** + CI/Gemini fresh gate 확인까지.
- ★ self-dogfood: 본 task finalize 도 file_touch_ratio_check 통과 확인. ANU origin/main..HEAD diff 독립검증 회수.

## 완료 판정
- 회귀 13 PASS + **PR diff raw key literal 0** + top-level 정규화 유지 + HEAD~5 fail-safe + symlink parity + PR 생성 + CI GREEN + fresh Gemini(head 이후) HIGH/CRITICAL 0 + unresolved 0(또는 non-blocking) → **`MERGE_APPROVAL_CANDIDATE_FILE_TOUCH_RATIO_ROOT_RECOGNITION_ACTIVE_FALSE`**.
- fresh HIGH/CRITICAL 재발 / **raw key literal 재노출** / expected_files 초과 / symlink parity 깨짐 / git_evidence·dispatch·callback prereg 수정 필요 / activation·real spawn 필요 / task-2716 수정 → **`HOLD_FOR_CHAIR`**.
- ★ merge·production activation = 별도 회장 승인 전까지 0.

## 완료 후 callback
- 봇 완료 시 ANU(c119085addb0f8b7)로 normal callback cron 발사(envelope only, UTF-8 ≤3900 bytes, collector=ANU): task_id/result_path/report_path/PR번호/terminal_state/sha256/one-line summary. ★raw key literal 출력 0(.env.keys COKACDIR_KEY_ANU sealed, envelope 에 full key 박지 말 것).

## doctrine
직접 코딩 금지(ANU)/봇 위임 / fresh origin/main 571a4ce3 base / #194 기능(top-level 정규화·HEAD~5 fail-safe) 유지 + denylist 마스킹 / PR diff raw key literal 0 / report-root와 diff-root 분리 / symlink parity 보존(per-team 직접수정·디듀프 금지) / git_evidence·dispatch·callback prereg 무수정 / activation 0 / same-PR post-Gemini push 금지.
```yaml
callback_envelope_byte_limit: 3900
callback_collector_role: ANU
callback_owner_key_source: ".env.keys COKACDIR_KEY_ANU (sealed, literal 출력 0)"
```
