---
task_id: task-2434
type: context
scope: task
created: 2026-05-03
updated: 2026-05-04
status: completed
---

# 맥락 노트: task-2434

**task**: task-2434

---

## 결정 근거

### 핵심 결정 1: 가드 3개를 단일 task로 묶었다 (Phase 2/3 분리)
- **이유**: 회장이 "최소 안전장치"를 강조했고, 후속 task-2433 재위임이 가드 보호 하에 진행되어야 하므로 빠른 머지가 필요함. post_merge_probe 개선이나 merge_queue 도입까지 묶으면 task가 비대해져 머지 지연.
- **대안 (기각)**: Phase A/B/C/D를 별도 task 4개로 분리 → 각 가드 머지마다 대기 비용 발생. 단일 task로 묶고 Phase 2/3는 명시적으로 자리표시(`NotImplementedError`)만 둔다.

### 핵심 결정 2: 워크스페이스 main 브랜치에서 직접 작업 (worktree 미사용)
- **이유**: project_id 없는 시스템 작업(`/home/jay/workspace/scripts/` 직접 수정). worktree_manager는 `projects/<project_id>/.git` 전제. 시스템 스크립트는 main에 직접 작업하되 micro-commit + pre-push 가드(메타 적용)로 보호.
- **대안 (기각)**: workspace 자체를 worktree로 분리 → 인프라 미정비, 본 task에서 추가 작업 발생.

### 핵심 결정 3: 워크스페이스에 미리 있던 task 무관 modified 파일은 stash 격리
- **이유**: `config/constants.json`, `logs/done-watcher.heartbeat`, `memory/bot_settings_sync.json` 3건은 task-2434와 무관한 운영 산출물. 본 task 커밋에 섞이면 Phase B-1(working tree clean) 시뮬레이션에서 메타 가드가 본 task를 차단해야 정상.
- **조치**: `git stash push -u -m "task-2434 prep: stash unrelated modified files"` 완료. 본 task 머지 후 stash pop.

### 핵심 결정 4: task scope 매핑은 task 파일 YAML/마크다운의 `allowed_resources` 섹션을 파싱
- **이유**: task별 forbidden_paths/allowed paths는 task 파일에 이미 명시. 별도 메타 DB 없이 단일 source-of-truth 사용.
- **대안 (기각)**: 별도 `scopes.yaml` 도입 → 동기화 비용. task 파일 직접 파싱이 회장 4대 규칙(silent fix 금지, single source) 부합.

### 3 Step Why 자문 (Lv.3 필수)

**1st Why: "왜 이 설계(가드 3개)가 필요한가?" → A**
- A: 봇이 실수해도 main이 오염되지 않는 최소 안전장치를 만들기 위해. 사고 trigger 3건(task-2423/2429/2431)이 모두 가드 부재로 발생. 가드 3개는 push 직전(B), push 직후 보고서(C), task 책임 범위 계산(A) 3 지점을 동시에 막는다.

**2nd Why: "왜 A(가드 3개 동시 빌드 + 실 시뮬레이션)가 최선의 접근인가?" → B**
- B: 단일 가드 한 개씩 별도 task로 분리하면 (1) 사고 차단까지 시간 누적이 커지고 (2) 가드 간 협업(예: pre_push_guard.py가 qc_report_guard.py를 내부 호출)이 늦게 검증됨. 회장 4대 규칙 중 "실 작동 시뮬레이션"은 통합 환경에서만 의미가 있으므로 3개를 묶고, 대신 Phase 2/3는 자리표시로 분리해 task 비대화는 차단.

**3rd Why: "왜 B(통합 빌드+자리표시 분리)가 다른 대안보다 나은가?" → C**
- C: (1) "전부 묶기"(Phase 2/3 포함) 대비 단일 책임 유지 — 본 task는 가드 3개만, 자리표시는 NotImplementedError로 명시하여 미구현임을 컴파일타임에 강제. (2) "전부 분리"(가드 1개씩 4 task) 대비 머지 사이클 단축 + 가드 간 의존(pre_push_guard ↔ qc_report_guard ↔ task_scope) 통합 검증 가능. (3) 회장 명시 후속 시퀀스(task-2433 재위임)가 본 task 머지 직후 시작되므로 단일 머지 단위로 보호 전선이 즉시 켜진다.

**A → B → C 일관성**: A(가드 3개 필요) → B(통합 빌드가 사고 차단 속도 + 협업 검증에 최적) → C(자리표시 분리로 단일 책임 유지). 일관됨.

## 참조 자료

- 본 task: `/home/jay/workspace/memory/tasks/task-2434.md`
- 회장 거버넌스 8원칙: `/home/jay/workspace/memory/system_governance_4layer.md`
- 사고 사례 보고서: `memory/reports/task-2429.md`, `memory/reports/task-2431.md`
- 사고 trigger: `scripts/post_merge_probe.py:151` (task-2431 P0 적용 영역, 본 task 무수정)
- task-2431 qc-result 참조: `memory/events/task-2431.qc-result` (WARN 케이스 fixture로 활용 가능)

## Codex G1 게이트 결과 (2026-05-04 00:01 UTC)

- 결과: **FAIL** (6 risks: high 1, medium 2, low 1)
- task 파일은 회장 직접 명시(변경 금지)이므로 task 파일 자체 수정 불가
- → **보강 설계**를 본 노트에 기록하고 그 설계로 구현 + 사고 시뮬레이션 + 보고서에 risk 해소 근거 명시

### Risk 1 (HIGH) — B-1 working tree ignore 정책 누락 → 해소
- **수용**: 기존 `scripts/task-scope-guard.sh:69` `SYSTEM_IGNORE_PATTERN` 정규식을 `pre_push_guard.py`가 그대로 import/inline 채택
- ignore 대상: `memory/heartbeats/`, `memory/daily/`, `memory/logs/`, `memory/reports/`, `logs/`, `whisper/`, `memory/whisper/`, `bot-activity.json`, `token-ledger.json`, `memory/pipeline-status.json`, `memory/preview-state.json`, `memory/merge-log.json`, `memory/bot_settings_sync.json`, `memory/memory-check-log.json`, `memory/task-timers.json`, `memory/canary-status.json`, `.heartbeat`, `memory/.task-counter`, `config/constants.json`, `scripts/gemini_rate_tracker.json`, `tests/coverage-report.txt`, `memory/tasks/<task_id>.md`, `memory/reports/<task_id>.md`, `memory/events/<task_id>.<생성자동마커>`
- forbidden_paths는 ignore보다 **먼저** 매칭 (task-scope-guard.sh 동일 순서)

### Risk 2 (MEDIUM) — 보고서 상태 검색 오탐 → 해소
- **수용**: 자유 텍스트 검색 금지. 두 가지 source-of-truth 사용 (OR 매칭)
  - 우선 1: 보고서 YAML frontmatter `qc_verdict: PASS|WARN|FAIL|PASS_WITH_WARN`
  - 우선 2: 보고서 본문 첫 번째 `## QC Verdict` 섹션 직속 한 줄
- "이전 표현:", "정정된 표현:", `>` 인용 블록, 백틱 ``` 코드 블록 안의 매칭은 모두 무시
- frontmatter도 헤더도 없으면 → 명시적 verdict 없음 → FAIL (보고서 정직성 강제)

### Risk 3 (MEDIUM) — HEAD diff vs working tree 기준 혼동 → 해소
- **수용**: `task_scope.py`는 4 집합을 명시 분리해서 출력
  - `head_diff`: `git diff --name-only base..HEAD` (push될 commit)
  - `index_staged`: `git diff --name-only --cached` (staged)
  - `working_tree_modified`: `git diff --name-only` (modified)
  - `untracked`: `git ls-files --others --exclude-standard`
- `pre_push_guard.py` 검사별 사용 집합 명시:
  - B-1 working tree clean: `working_tree_modified ∪ untracked` 기준 (system-ignore 적용 후 task scope 외 1건이라도 있으면 FAIL)
  - B-3 task scope 일치: `head_diff` 기준 (push될 변경의 책임 범위)

### Risk 4 (MEDIUM) — capability snapshot resolver 분산 → 해소
- **수용**: `pre_push_guard.py`/`qc_report_guard.py`는 task 파일을 직접 파싱하지 않음
- 단일 resolver: `_resolve_allowed_resources(task_id)` → `memory/capabilities/<task_id>.json` 우선, 없으면 task 파일 `## allowed_resources` YAML 블록 fallback
- placeholder `task-XXXX/**` → 실제 task_id로 치환 (capability snapshot 원본은 그대로 두고 in-memory 치환만)

### Risk 5 (LOW) — guard.sh의 NotImplementedError → 해소
- **수용**: bash에서는 `echo "[guard] not implemented (Phase 2/3 자리표시)" >&2; exit 2` 형태
- 회귀 테스트도 exit code 2를 검증 (NotImplementedError 가짜 상속 회피)

### 추가 — Capability snapshot은 본 task에서 무수정
- `memory/capabilities/task-2434.json`은 dispatch가 자동 생성한 immutable snapshot
- 본 task는 `forbidden_paths: memory/capabilities/**` (본 task 자체 forbidden)에 따라 무수정

## 주의사항

- **변경 절대 금지**: `scripts/post_merge_probe.py`, `scripts/auto_revert.py`, `scripts/auto_merge.py`, `scripts/finish-task.sh`, `dispatch.py`, `dashboard/**`, `teams/shared/**`, `extension/**`, `skills/**`, `src/**`, `server/**`, `memory/specs/**`, `.github/**`, `CLAUDE.md`, `memory/capabilities/**`
- **메타 규칙**: 본 task 자체가 push될 때 가드 3개를 통과해야 함. 본 task의 changed_paths가 모두 `scripts/task_scope.py`, `scripts/pre_push_guard.py`, `scripts/qc_report_guard.py`, `scripts/guard.sh`, `tests/scripts/test_*.py`, `memory/plans/tasks/task-2434/**`, `memory/reports/task-2434*.md` 안에 있어야 함.
- **워크스페이스 잡음**: stash로 격리한 3개 파일은 본 task 머지 후 pop. 본 task 작업 중 새로운 무관 파일 생성 금지(특히 logs/, memory/whisper/ 등 자동 갱신 파일).
- **silent fix 금지**: pytest PASS만으로 완료 선언 금지. 실 작동 시뮬레이션 3종(사고 A/B/C 차단) 직접 실행 + 보고서에 출력 첨부 필수.
- **외부 AI sanitize**: Codex/Gemini 호출 전 PII 검사 필수. 본 task는 시스템 코드라 PII 위험 낮으나 task-2431 qc-result fixture에 PII 가능성 — 마스킹 후 사용.
