# task-2469 — Phase D: Penetration Tests (재dispatch, 회장 ANU MERGE ORDER 옵션 A)

- 작업 유형: **penetration-test** (회장 명시 "기능 추가 아님 / 우회 불가능성 증명")
- 작업 레벨: **Lv.4 critical**
- 위임팀: **dev2-team (오딘, opus)** — Phase D fresh perspective 유지
- Track: **dev_workspace**
- 우선순위: **★★★ critical**
- 일시: 2026-05-06
- 선행: task-2467+3 MERGED (8d667080) ✅ + task-2468+3 MERGED (f248eb26) ✅ — **5a77b554 in main 확인됨**
- 후행: task-2470 (pre_push_guard.py 결함 4건 + regression test)

## ⚠️ 본 task의 본질 — 회장 명시

> "이번 task-2469의 목적은 **'기능 추가'가 아니라 '우회 불가능성 증명'**이다.
> 보고서가 아니라 **자동화된 방어 검증 체계**를 남겨라."

> "task-2469는 기존 task ID 그대로 진행한다. 새 task ID 생성 금지."
> "이전 ESCALATED/timer stale 정리를 위해 --force 사용 허용."

→ **task-2469 재dispatch (--force)**, 최신 main 위에서 단독 diff 정리 후 PR/merge/DONE 완결.

## 0. 배경 — 직전 ESCALATED 사유 + 현 상태

| task | 결과 |
|------|------|
| task-2469 (1차) | scope_guard_violation (task-2468 inherited diff) ESCALATED |
| task-2468+3 | MERGED (f248eb26, 5a77b554 in main) ✅ |
| **task-2469 (재dispatch)** | **목표: rebase + 단독 diff + MERGED + DONE** |

origin/main HEAD: `f248eb26` (task-2468+3 머지 후)
worktree: `/home/jay/workspace/.worktrees/task-2469-dev2` (현 HEAD `1df358ec`, 5a77b554 위에 쌓임)

## ★★★ Step 0 — rebase/base 정리 (회장 명시 7단계, 최우선 수행)

```bash
# 1. 최신 main fetch
cd /home/jay/workspace
git fetch origin

# 2. origin/main이 f248eb26 또는 그 이후인지 확인
git rev-parse origin/main  # 기대: f248eb26... 또는 그 이후

# 3. 5a77b554가 main ancestor인지 확인
git merge-base --is-ancestor 5a77b554 origin/main && echo "OK" || exit 1

# 4. 기존 worktree 사용
cd /home/jay/workspace/.worktrees/task-2469-dev2

# 5. branch를 최신 origin/main 위로 rebase
git status  # clean 확인
git fetch origin
git rebase origin/main
# rebase 충돌 시: scripts/lifecycle_guards.py / gemini_severity_parser.py 등 task-2468 산출물은 main 우선 ('theirs' 또는 main 버전)
# task-2469 단독 산출물 (tests/taskctl/test_lifecycle_penetration.py 등)만 유지

# 6. task-2468 inherited diff 제거 확인
git diff origin/main --stat  # task-2469 단독 산출물만 보여야 함
git diff origin/main scripts/lifecycle_guards.py  # 0 lines (main 그대로)
git diff origin/main scripts/gemini_severity_parser.py  # 0 lines
git diff origin/main scripts/taskctl.py  # 0 lines

# 7. task-2469 단독 산출물만 diff에 남는지 확인
git diff origin/main --stat | grep -E '(test_lifecycle_penetration|fixtures/task-2469|penetration_test_spec_260506|penetration-test-2469)' || exit 1
```

→ Step 0이 PASS해야 다음 단계 진행. 미완료 시 ESCALATED.

## 1. 작업 산출물 (재확인 — 1차 dispatch와 동일)

### 신설 (이미 1차 dispatch에서 작성됨, rebase 후 유지)
- `tests/taskctl/test_lifecycle_penetration.py` — pentest 39건 (A~F + G~M)
- `tests/fixtures/task-2469/**` — 30+ fixture
- `memory/specs/penetration_test_spec_260506.md` — 시나리오 spec
- `memory/orchestration-audit/penetration-test-2469.jsonl` — **38 entries 이상, blocked=true 38/38**

### 절대 금지 (회장 명시)
- 새 task ID 생성 금지
- task-2470 항목 섞기 금지
- `scripts/pre_push_guard.py` 수정 금지
- `scripts/lifecycle_guards.py` 수정 금지 (main에 이미 반영됨)
- `scripts/gemini_severity_parser.py` 수정 금지 (main에 이미 반영됨)
- task-2468 산출물 수정 금지
- admin override 금지
- **state 수동 복원 금지** (FAILED → HUMAN_APPROVED 강제 변경 X)
- **Gemini thread 임의 resolve 금지**
- **`.gitignore` / `.secrets` 우회 금지** (페룬 task-2468+3 우회 사례 차단)
- 보고서만 수정해서 통과 처리 금지
- `gh pr merge` 직접 호출 금지

## 2. 진행 단계 (회장 명시 12단계)

### Step 0: 최신 main 확인 + rebase + inherited diff 제거 (위 §★★★ Step 0)

### Step 1: audit jsonl 생성/검증
```bash
# 38 entries 이상, blocked=true 38/38
cat memory/orchestration-audit/penetration-test-2469.jsonl | wc -l
python3 -c "import json; [exit(1) for l in open('memory/orchestration-audit/penetration-test-2469.jsonl') if not json.loads(l).get('blocked')]"
```

### Step 2: pentest + regression 재실행
```bash
PYTHONPATH=scripts python3 -m pytest tests/taskctl/test_lifecycle_penetration.py -v
# 기대: 39 passed
PYTHONPATH=scripts python3 -m pytest tests/taskctl/test_lifecycle_guards.py -v
# 기대: 14 passed
PYTHONPATH=scripts python3 -m pytest tests/taskctl/ tests/state_machine/ -v
# 기대: 81 passed, 2 xfailed
```

### Step 3: scope-guard 재실행
```bash
# forbidden_paths 0 violation, allowed_resources 0 violation
# inherited task-2468 diff 0
git diff origin/main --stat | grep -v -E '(task-2469|test_lifecycle_penetration|fixtures/task-2469|penetration)' && exit 1 || echo "PASS"
```

### Step 4: PR open
```bash
cd /home/jay/workspace
python3 scripts/taskctl.py pr-open task-2469 --auto
```

### Step 5: Gemini review / G3 / required checks PASS 확인

### Step 6: 실제 GitHub merge
```bash
python3 scripts/taskctl.py approve task-2469
python3 scripts/taskctl.py merge task-2469
```

### Step 7: 머지 후 검증
```bash
gh pr view <PR_NUM> --json state,mergedAt,mergeCommit
git fetch origin
git rev-parse origin/main  # 새 HEAD
git merge-base --is-ancestor <task-2469-merge-sha> origin/main && echo "PASS"
```

### Step 8: .done 발행
```bash
python3 scripts/taskctl.py done task-2469
ls memory/events/task-2469.done
ls memory/events/task-2469.g3-fail 2>/dev/null && exit 1
ls memory/events/task-2469.done.escalated 2>/dev/null && exit 1
ls memory/events/task-2469.escalated 2>/dev/null && exit 1
```

## 3. 진행 조건 (회장 명시 — 모두 PASS해야 진행)

| 조건 | 미충족 시 |
|------|----------|
| inherited task-2468 diff 0 | PR open 금지 |
| scope-guard 0 violation | merge 금지 |
| audit jsonl 38 entries 이상, blocked=true 38/38 | merge 금지 |
| pentest 39/39 PASS | merge 금지 |
| task-2468 regression 14/14 PASS | merge 금지 |
| 전체 81 passed, 2 xfailed | merge 금지 |

## 4. 합격 조건 (회장 명시)

전부 충족해야 합격:
1. ✅ Step 0 rebase 완료, inherited task-2468 diff 0
2. ✅ pentest 39/39 PASS
3. ✅ task-2468 regression 14/14 PASS
4. ✅ 전체 81 passed, 2 xfailed pre-existing
5. ✅ audit jsonl 38/38 blocked=true
6. ✅ scope-guard 0 violation
7. ✅ PR author = bot
8. ✅ Gemini High = 0
9. ✅ required checks PASS
10. ✅ 시스템 승인자 approve
11. ✅ merge commit SHA가 origin/main HEAD에 ancestor로 존재
12. ✅ task-2469 `.done` 발행
13. ❌ pre_push_guard.py / lifecycle_guards.py / gemini_severity_parser.py / task-2468 산출물 변경 0
14. ❌ state 수동 복원 / Gemini thread 임의 resolve / .gitignore 조작 / .secrets 우회 모두 0

## 5. ESCALATED 조건

- inherited task-2468 diff 발견 → ESCALATED (Step 0 PASS 못함)
- 우회 행위 1건이라도 → ESCALATED + reject
- 금지 산출물 1줄이라도 변경 → ESCALATED
- 합격 조건 1건이라도 미충족 → ESCALATED
- task-2470 항목 섞기 → ESCALATED

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "tests/taskctl/test_lifecycle_penetration.py"
    - "tests/fixtures/task-2469/**"
    - "memory/specs/penetration_test_spec_260506.md"
    - "memory/orchestration-audit/penetration-test-2469.jsonl"
    - "memory/tasks/task-2469*"
    - "memory/reports/task-2469*"
    - "memory/plans/tasks/task-2469/**"
    - "memory/events/task-2469*"
  forbidden_paths:
    - "scripts/pre_push_guard.py"
    - "scripts/lifecycle_guards.py"
    - "scripts/gemini_severity_parser.py"
    - "scripts/taskctl.py"
    - "scripts/finish-task.sh"
    - "scripts/worktree_manager.py"
    - "scripts/g3_independent_verifier.py"
    - "scripts/anu_confirm_bot/**"
    - "tests/taskctl/test_lifecycle_guards.py"
    - "memory/specs/allowed_bot_accounts.json"
    - "memory/specs/allowed_approvers.json"
    - "memory/orchestration-audit/admin-override.jsonl"
    - "memory/events/task-2467+3.*"
    - "memory/events/task-2468.*"
    - "memory/events/task-2468+1.*"
    - "memory/events/task-2468+2.*"
    - "memory/events/task-2468+3.*"
    - "memory/reports/task-2467+3.md"
    - "memory/reports/task-2468*.md"
    - "memory/tasks/task-2468*"
    - "task-2465* / task-2466* / task-2467*"
    - "PR #29 / #30 / #31 / #32 / #33 / #34"
    - "dispatch.py"
    - ".env.keys"
    - ".secrets/**"
    - ".gitignore"
  forbidden_actions:
    - "새 task ID 생성 금지"
    - "task-2470 항목 섞기 금지"
    - "scripts/pre_push_guard.py 수정 금지"
    - "scripts/lifecycle_guards.py 수정 금지"
    - "scripts/gemini_severity_parser.py 수정 금지"
    - "task-2468 산출물 수정 금지"
    - "admin override 금지"
    - "FAILED → HUMAN_APPROVED state 수동 복원 금지"
    - "Gemini unresolved thread 임의 resolve 금지"
    - ".gitignore 임시 조작 금지"
    - ".secrets/ 우회 처리 금지"
    - "보고서만 수정해서 통과 처리 금지"
    - "gh pr merge 직접 호출 금지"
    - "git push --force 금지"
    - "git push origin main 직접 호출 금지"
  bot_authentication:
    - "BOT_GITHUB_TOKEN .env.keys 자동 로드"
    - "PR author = jeon-jonghyuk-taskctl-bot[bot]"
    - "approver = 시스템 승인자 (taskctl-gate / anu-verifier)"
  merge_policy: "★ task-2468 Guard 통과 시에만 머지. drink your own champagne 3회차"
  ttl_hours: 12
```

## 7. 최종 보고 필수 항목 (회장 명시 14건)

`memory/reports/task-2469.md`에 반드시 포함:
1. PR 번호
2. PR state
3. mergedAt
4. merge commit SHA
5. origin/main HEAD
6. `git merge-base --is-ancestor <task-2469-merge-sha> origin/main` 결과
7. scope-guard 0 violation (증명 log)
8. pentest 39/39 PASS (raw output)
9. task-2468 regression 14/14 PASS (raw output)
10. 전체 81 passed, 2 xfailed (raw output)
11. audit jsonl 38/38 blocked=true (entries log)
12. `.done` 존재
13. `.g3-fail` / `.done.escalated` / `.escalated` 부재
14. production / scripts / config 무변조 (`git diff origin/main scripts/ memory/specs/` = 0 lines)
15. 회귀 0
16. 우회 행위 0건 (state 수동 복원 / Gemini thread / .gitignore / .secrets 모두 0)

## 8. 시스템 청사진

- task-2467+3 = Phase A+B (state machine + 명령 8개) ✅ MERGED
- task-2468+3 = Phase C (Guard 14개 + parser) ✅ MERGED
- **task-2469 (본 task) = Phase D (우회 불가능성 코드 증명)**
- task-2470 = pre_push_guard.py 정정 + regression test (별도)

→ Phase A~D 완결로 봇 오케스트레이션 OS 자동 PR lifecycle 신뢰성 100% 증명.

## 9. 위임 완결성 4대 규칙

1. 수신 확인: dispatch 출력
2. 빌드+배포: rebase + 단독 diff + PR + 머지 + main ancestor
3. 실 E2E: pentest 39 + regression 14 + 전체 81 + audit 38 + scope-guard 0 모두 PASS 후 머지
4. 구조 선행 파악: 직전 ESCALATED 사유 (scope_guard_violation) + task-2468+3 머지 후 main 변화 모두 read

## 10. 회장 명시 인용

> "task-2469는 기존 task ID 그대로 진행한다. 새 task ID 생성 금지."
> "Step 0으로 worktree/base 정리를 먼저 수행하라."
> "task-2469 단독 산출물만 diff에 남는지 확인."
> "scope-guard violation 1건 → merge 금지."
> "audit jsonl 38/38 blocked=true 미충족 → merge 금지."
> "state 수동 복원 / Gemini thread 임의 resolve / .gitignore 조작 / .secrets 우회 — 모두 금지."

## goal_assertions
- `git merge-base --is-ancestor <task-2469-merge-sha> origin/main`
- `pytest tests/taskctl/test_lifecycle_penetration.py -v` → 39 passed
- `pytest tests/taskctl/test_lifecycle_guards.py -v` → 14 passed
- `cat memory/orchestration-audit/penetration-test-2469.jsonl | wc -l` → 38+
- `git diff origin/main scripts/` → 0 lines