# spec-rollback-procedure.md
# 롤백 절차 — 상세 구현 스펙

**작성자:** 아테나 (UX/UI 디자이너, MoAI-ADK)
**작성일:** 2026-03-31
**상태:** DRAFT
**관련 Task:** MoAI-ADK Phase 1

---

## 1. 목적

Phase 1 기능 배포 후 문제 발생 시 신속하고 안전하게 이전 상태로 복원한다. 3계층 롤백 구조(Feature Flag → 설정 파일 → git revert)를 통해 장애 심각도에 맞는 최소 범위의 롤백을 수행한다.

**핵심 목표:**
- 기능 오동작 시 즉각 대응 (~30초, L1)
- 설정 파일 충돌 시 신속 복원 (~5분, L2)
- 코드 버그 시 안전한 코드 롤백 (~15분, L3)
- 불필요한 과도한 롤백 방지 (의사결정 트리 활용)

---

## 2. 상세 스펙

### 2.1 3계층 롤백 구조 개요

```
문제 발생
    │
    ├─ 기능 오동작 (플래그 on/off로 해결 가능)
    │   └─ Layer 1: Feature Flag (즉시, ~30초)
    │
    ├─ 설정 파일 충돌 (settings.json 등 설정 불일치)
    │   └─ Layer 2: 설정 파일 복원 (~5분)
    │
    └─ 코드 버그 (로직 오류, 타입 오류 등)
        └─ Layer 3: git revert (~15분)
```

---

### 2.2 Layer 1: Feature Flag 롤백

**소요 시간:** 즉시, ~30초
**대상:** 특정 기능의 오동작 (성능 저하, 예상치 못한 동작 등)
**방법:** 해당 플래그를 `false`로 변경

#### 절차

```bash
# 1. 현재 플래그 상태 확인
cat .claude/feature_flags.json

# 2. 문제 플래그를 false로 변경 (Python 로더 사용)
python3 -c "
from utils.feature_flags import FeatureFlagLoader
f = FeatureFlagLoader()
f.set('progressive_disclosure_enabled', False)  # 해당 플래그명으로 변경
print('롤백 완료:', f.all())
"

# 3. 변경 확인
cat .claude/feature_flags.json

# 4. 동작 확인 (에이전트 재실행)
python dispatch.py --task "테스트 태스크"
```

#### 플래그별 롤백 명령 빠른 참조

| 기능 | 플래그명 | 롤백 명령 |
|---|---|---|
| P1-1 Progressive Disclosure | `progressive_disclosure_enabled` | `f.set('progressive_disclosure_enabled', False)` |
| P1-2 RW Isolation | `rw_isolation_enabled` | `f.set('rw_isolation_enabled', False)` |
| P1-7 Hooks Enforcement | `hooks_enforcement_enabled` | `f.set('hooks_enforcement_enabled', False)` |
| Trust5 Tagging | `trust5_tagging_enabled` | `f.set('trust5_tagging_enabled', False)` |
| Model Map | `model_map_enabled` | `f.set('model_map_enabled', False)` |
| Haiku A/B | `haiku_ab_enabled` | `f.set('haiku_ab_enabled', False)` |

#### L1 완료 기준

- [ ] 해당 플래그가 `false`로 변경됨
- [ ] 에이전트 재실행 시 이전 동작과 동일함을 확인
- [ ] 장애 보고서에 플래그 롤백 기록

---

### 2.3 Layer 2: 설정 파일 복원

**소요 시간:** ~5분
**대상:** 설정 파일 충돌, 잘못된 설정으로 인한 오동작 (L1으로 해결 불가)
**방법:** git show로 이전 버전 복원

#### 절차

```bash
# 1. 현재 설정 파일 상태 확인
git log --oneline -5 -- .claude/settings.json
git log --oneline -5 -- .claude/feature_flags.json

# 2. 이전 버전의 설정 파일 내용 확인
git show HEAD~1:.claude/settings.json
git show HEAD~1:.claude/feature_flags.json

# 3. 이전 버전으로 복원 (특정 파일만)
git show HEAD~1:.claude/settings.json > .claude/settings.json
git show HEAD~1:.claude/feature_flags.json > .claude/feature_flags.json

# 4. 복원 내용 확인
cat .claude/settings.json
cat .claude/feature_flags.json

# 5. 변경 사항 커밋 (롤백 이력 보존)
git add .claude/settings.json .claude/feature_flags.json
git commit -m "rollback: L2 설정 파일 복원 (HEAD~1 기준)"

# 6. 동작 확인
python dispatch.py --task "테스트 태스크"
```

#### 특정 커밋 기준 복원 (HEAD~1이 아닌 경우)

```bash
# 특정 커밋 해시로 복원
git log --oneline -- .claude/settings.json   # 커밋 히스토리 확인
git show <commit-hash>:.claude/settings.json > .claude/settings.json
```

#### L2 완료 기준

- [ ] 설정 파일이 정상 버전으로 복원됨
- [ ] `git diff HEAD~1 -- .claude/` 으로 복원 내용 검증
- [ ] 에이전트 정상 동작 확인
- [ ] 롤백 커밋 생성 및 이력 보존

---

### 2.4 Layer 3: git revert

**소요 시간:** ~15분
**대상:** 코드 버그, 로직 오류 (L1, L2로 해결 불가)
**방법:** 해당 Task 커밋 revert

#### 절차

```bash
# 1. 문제 커밋 식별
git log --oneline -10
# 예: abc1234 feat: P1-1 Progressive Disclosure 구현

# 2. 해당 커밋의 변경 내용 확인
git show abc1234

# 3. git revert (새 커밋 생성, 이력 보존)
git revert abc1234 --no-edit

# 4. revert 커밋 내용 확인
git show HEAD

# 5. pyright + ruff 검증
pyright .
ruff check .

# 6. 테스트 실행
pytest tests/ -v

# 7. 원격 브랜치에 push
git push origin <current-branch>

# 8. 동작 확인
python dispatch.py --task "테스트 태스크"
```

#### 여러 커밋을 연속으로 revert해야 하는 경우

```bash
# 최신 커밋부터 순서대로 revert
git revert HEAD --no-edit
git revert HEAD~1 --no-edit

# 또는 범위 지정 (주의: 역순으로 적용됨)
git revert HEAD~2..HEAD --no-edit
```

#### L3 완료 기준

- [ ] `git revert` 커밋 생성 완료
- [ ] pyright 오류 0건
- [ ] ruff 위반 0건
- [ ] 테스트 전체 통과
- [ ] 에이전트 정상 동작 확인
- [ ] 원격 브랜치 push 완료

---

### 2.5 롤백 의사결정 트리

```
문제 발생
    │
    ▼
[Q1] 특정 기능의 동작이 이상한가? (성능, 출력, 예외 없이 동작하지만 다름)
    ├─ YES → Layer 1 (Feature Flag 비활성화)
    │           └─ 해결됨? YES → 완료
    │           └─ 해결됨? NO  → Q2로
    └─ NO  → Q2로
    │
    ▼
[Q2] 설정 파일(settings.json, feature_flags.json)이 변경되었는가?
    ├─ YES → Layer 2 (설정 파일 복원)
    │           └─ 해결됨? YES → 완료
    │           └─ 해결됨? NO  → Q3로
    └─ NO  → Q3로
    │
    ▼
[Q3] 특정 커밋 이후 코드 오류/예외/테스트 실패가 발생했는가?
    ├─ YES → Layer 3 (git revert)
    │           └─ 해결됨? YES → 완료
    │           └─ 해결됨? NO  → 에스컬레이션
    └─ NO  → 에스컬레이션 (수동 조사 필요)

에스컬레이션: 리드 엔지니어 호출 + 인시던트 기록
```

#### 의사결정 요약표

| 증상 | 권장 Layer | 예시 |
|---|---|---|
| 기능 오동작 (플래그로 제어됨) | L1 | Progressive Disclosure 결과 이상 |
| 설정 충돌, 훅 미작동 | L2 | settings.json 손상 |
| 코드 예외, 타입 오류, 테스트 실패 | L3 | pyright CRITICAL 오류 코드 배포 |
| 원인 불명 | L1 → L2 → L3 순차 | 전체 롤백 |

---

### 2.6 Circuit Breaker 수동 리셋

Circuit Breaker halt 상태에서는 hooks가 항상 exit 1을 반환한다. 롤백 완료 후 Circuit Breaker를 리셋해야 정상 동작이 재개된다.

```bash
# Circuit Breaker 상태 확인
cat .metrics/circuit_breaker_state.json

# 수동 리셋
python3 hooks/circuit_breaker.py reset

# 리셋 후 상태 확인
cat .metrics/circuit_breaker_state.json
# 예상 결과:
# {
#   "warning_count": 0,
#   "critical_count": 0,
#   "last_triple": [],
#   "halted": false
# }
```

**주의:** Circuit Breaker를 리셋하기 전에 반드시 근본 원인을 해결해야 한다. 원인 해결 없이 리셋하면 즉시 재halt된다.

---

## 3. 인터페이스

### 3.1 관련 파일

| 파일 | 역할 |
|---|---|
| `.claude/feature_flags.json` | L1 롤백 대상 |
| `.claude/settings.json` | L2 롤백 대상 |
| `utils/feature_flags.py` | L1 롤백 도구 |
| `hooks/circuit_breaker.py` | 수동 리셋 도구 |
| `.metrics/circuit_breaker_state.json` | Circuit Breaker 상태 |

### 3.2 롤백 후 검증 체크리스트

```bash
# 1. Feature Flag 상태 확인
python3 -c "from utils.feature_flags import FeatureFlagLoader; print(FeatureFlagLoader().all())"

# 2. Circuit Breaker 상태 확인
cat .metrics/circuit_breaker_state.json

# 3. pyright 전체 검사
pyright .

# 4. ruff 전체 검사
ruff check .

# 5. 테스트 전체 실행
pytest tests/ -v

# 6. 에이전트 smoke test
python dispatch.py --task "smoke test: 기본 동작 확인"
```

---

## 4. 테스트 기준

### 4.1 롤백 시나리오 테스트

각 Layer에 대해 다음 시나리오를 정기적으로 드릴(drill)한다.

| Layer | 시나리오 | 예상 결과 |
|---|---|---|
| L1 | 플래그 `true` → `false` 변경 후 에이전트 실행 | 이전 동작과 동일 |
| L2 | settings.json 손상 후 `git show HEAD~1` 복원 | 정상 설정 복원 |
| L3 | 버그 커밋 `git revert` 후 테스트 실행 | 전체 테스트 통과 |
| CB | Circuit Breaker halt 후 reset + 에이전트 실행 | 정상 실행 재개 |

### 4.2 롤백 시간 기준

| Layer | 목표 시간 | 허용 최대 시간 |
|---|---|---|
| L1 Feature Flag | ~30초 | 2분 |
| L2 설정 파일 복원 | ~5분 | 15분 |
| L3 git revert | ~15분 | 30분 |

---

## 5. DoD (Definition of Done)

- [ ] 3계층 롤백 절차 문서화 완료 (본 문서)
- [ ] L1 롤백: `FeatureFlagLoader.set()` 동작 확인
- [ ] L2 롤백: `git show HEAD~1:<path>` 복원 절차 검증
- [ ] L3 롤백: `git revert` 절차 검증 (테스트 포함)
- [ ] 롤백 의사결정 트리 검토 완료 (팀 합의)
- [ ] Circuit Breaker 수동 리셋 동작 확인
- [ ] 롤백 시나리오 드릴 1회 완료
- [ ] 롤백 시간 목표 달성 확인 (L1: ~30초, L2: ~5분, L3: ~15분)
- [ ] PR 리뷰 승인 후 merge
