# task-2561 plan — Track B baseline noise cleanup (회장 §명시 2026-05-12 2순위, Lv.2)

## 목표

`anu_v2/tests/test_post_merge_smoke_runner_2539.py::test_clean_origin_main_base_assertion` (lines 584-627) 의 task-2539+1 hard-coded ALLOWED_PATHS mis-scope 문제 해결.

근거: `memory/events/baseline-noise-diagnosis.20260512T142519Z.json` (Track D 결과).

## 본질

- 문제: 해당 테스트가 `git diff --name-only origin/main..HEAD` 를 무조건 실행하고 결과를 task-2539+1 의 7개 paths whitelist 와 강제 비교 → task-2539+1 worktree 외 모든 branch 에서 deterministic FAIL.
- 의도: 원래는 task-2539+1 worktree 사고 재발 방지 가드였음 (one-shot pre-merge guard).
- 문제 원인: 커밋 시 scope-guard 누락 → main 에 박혀서 후속 모든 PR baseline noise 오염 (PR #110 task-2550+1, task-2557, task-2550 등에서 이미 인용).

## 선택한 방식 — Option A (scope-guard 추가) + 정적 fixture 동반 (Option A 우선, 일부 Option B 기능 합성)

회장 §명시 우선순위: **Option A > Option B > Option C (test 삭제는 최후 수단)**.

채택:
1. **Option A (primary)** — task-2539+1 worktree 컨텍스트가 아니면 `pytest.skip` 으로 deterministic skip
2. **Option B (보조)** — 정적 fixture (`baseline_noise_repro_2561.json`) 추가로 noise 재현/기록 + 추가 회귀 테스트 (live git 의존 0)

Option C (delete) 는 채택 안 함 — 회장 §명시 "test 삭제 우선 선택 0" 금지 항목.

## Phase 1 — scope-guard 헬퍼 추가

- `_is_task_2539plus1_scope()` 헬퍼 함수 신설:
  - `os.environ.get("TASK_ID") == "task-2539+1"` OR
  - 현재 git branch name 이 `task/task-2539+1` prefix 매칭 OR
  - worktree dir basename 이 `task-2539+1` 매칭
  - 셋 중 어느 하나라도 true 면 in-scope, 아니면 out-of-scope

## Phase 2 — 기존 test_clean_origin_main_base_assertion 에 scope-guard 적용

- 함수 시작부에 scope-guard 호출:
  - out-of-scope → `pytest.skip(reason)` (deterministic skip, no live git diff)
  - in-scope → 기존 ALLOWED_PATHS 검증 유지 (회귀 보호 의도 보존)

## Phase 3 — 정적 baseline noise fixture 신설

- `anu_v2/tests/fixtures/baseline_noise_repro_2561.json`
  - mis-scoped test 의 ALLOWED_PATHS 7개 paths
  - mis-scope mechanism 기록 (diagnosis 참조)
  - 검증용 sample diff entries (in-scope vs out-of-scope)

## Phase 4 — 회귀 테스트 4건 추가 (test_post_merge_smoke_runner_2539.py 내)

1. `test_baseline_noise_fixture_2561_present_and_well_formed` — fixture 파일 존재 + 필수 필드 검증
2. `test_clean_origin_main_skipped_outside_task_2539plus1_scope` — monkeypatch 로 env/branch 모두 out-of-scope → 테스트가 skip 됨을 검증 (deterministic, no live git)
3. `test_clean_origin_main_runs_under_task_2539plus1_scope_with_clean_diff` — monkeypatch TASK_ID=task-2539+1 + git diff stub 으로 clean diff → 통과
4. `test_clean_origin_main_in_scope_detects_forbidden_path` — monkeypatch TASK_ID + git diff stub 으로 forbidden path → AssertionError (보호 의도 유지 검증)

## expected_files (회장 §명시 strict)

1. `anu_v2/tests/test_post_merge_smoke_runner_2539.py` (수정 — scope-guard + 4 신규 회귀 테스트)
2. `anu_v2/tests/fixtures/baseline_noise_repro_2561.json` (신규)
3. `memory/reports/task-2561.md` (신규)
4. `memory/events/task-2561.dispatch-decision.json` (신규)
5. `memory/plans/tasks/task-2561/plan.md` (이 파일)
6. `memory/plans/tasks/task-2561/context-notes.md`
7. `memory/plans/tasks/task-2561/checklist.md`

## forbidden_paths (회장 §명시 strict 0)

- `anu_v2/post_merge_smoke_runner.py` 본체 변경 0
- PR #98~#111 branch 변경 0
- task-2558 expected_files 재수정 0
- task-2560 / task-2562 영역 변경 0
- 다른 anu_v2 modules 변경 0
- dashboard/ 변경 0
- 회장 수동 `/gemini review` 0

## 검증

- pytest `anu_v2/tests/test_post_merge_smoke_runner_2539.py` 전체 → PASS (기존 12 + 신규 4 = 16/16)
- pytest `anu_v2/tests/` 전체 회귀 → 영향 없음
- worktree task-2561-dev2 (out-of-scope) 에서 `test_clean_origin_main_base_assertion` 실행 → SKIPPED (deterministic, fail 0)
- PR #110 / task-2550+1 follow-up branch 등 out-of-scope 환경에서도 동일하게 SKIPPED → false failure 0

## 14단계 standard

cokacdir → worktree task-2561-dev2 → BOT identity PR → Gemini fresh → unresolved 0 → CI 11/11 → CLEAN → BOT squash merge admin override 0 → smoke + reconcile + 보고서.
