# task-1643.1 완료 보고서: Absorption 중복 해소 — circuit_breaker 모듈 구현

## SCQA

**S**: fireauto의 circuit_breaker(에러 3회→중단)와 gstack의 CRITICAL GAP detector(에러 감지+수정)가 post-tool-use.sh, qc_verify.py, chain_manager.py에 분산 구현되어 있다. Agent Meeting에서 A(병합) 결정 완료.

**C**: 에러 감지/수정 로직이 3곳에 중복 존재하여 임계치 불일치(2회 vs 3회), 카운터 영속성 불안정(/tmp/ vs 파일), 롤백 메커니즘 부재 등 운영 리스크가 있다.

**Q**: 범용 circuit_breaker 모듈로 통합하고, 에러 감지 후 자동수정 실패 시 롤백 메커니즘을 구현할 수 있는가?

**A**: `utils/circuit_breaker.py` 범용 모듈을 구현하여 RecoveryStrategy 전략 패턴(AutoFix/Escalation) + FileSnapshot 기반 RollbackManager + 영속 상태 저장 + CLI 인터페이스를 완성했다. pyright_check를 첫 마이그레이션 대상으로 qc_verify.py에 통합 완료. 29개 단위 테스트 전체 통과, pyright 에러 0건.

---

## 구현 내용

### 1. 범용 circuit_breaker 모듈 (신규)
- **RecoveryAction Enum**: RETRY, ROLLBACK, ESCALATE, SKIP
- **CircuitState Enum**: CLOSED → OPEN → HALF_OPEN 상태 머신
- **RecoveryStrategy ABC**: on_error(), on_circuit_open() 추상 인터페이스
- **AutoFixStrategy**: threshold 미만 RETRY, 초과 ESCALATE (fireauto 패턴)
- **EscalationStrategy**: 즉시 ESCALATE (gstack CRITICAL GAP 패턴)
- **FileSnapshot**: 파일 스냅샷 캡처/복원, None 파일 삭제 처리
- **RollbackManager**: 스냅샷 생성 + 영속 저장 + 롤백 실행 + 실패 시 escalation
- **CircuitBreaker**: 에러 카운팅, 상태 전환, 영속 저장, cooldown 기반 자동 복구
- **CLI**: record-error, check, record-success, reset 4개 서브커맨드

### 2. 롤백 메커니즘 설계
- **방식**: FileSnapshot 기반 파일 내용 스냅샷 + 복원 (diff 기반 아님, 전체 내용 저장)
- **롤백 범위**: `last_operation` (기본값) 또는 `task_start` — RollbackManager scope 파라미터
- **실패 안전장치**: `rollback_with_escalation()` — 롤백 실패 시 escalation 파일 자동 생성 (human-in-the-loop)
- **영속 저장**: `memory/logs/rollback-snapshots/{task_id}_{scope}_{timestamp}.json`

### 3. pyright_check 마이그레이션
- qc_verify.py의 pyright_check 실행 블록에 circuit_breaker 연동 추가
- FAIL → `cb.record_error()` → ESCALATE 시 `_append_unresolved_issue()` 호출
- PASS → `cb.record_success()` 호출
- graceful degradation: circuit_breaker 임포트 실패 시 기존 동작 유지

---

## 산출물 파일

- `/home/jay/workspace/utils/circuit_breaker.py` (신규, 567줄)
- `/home/jay/workspace/utils/tests/test_circuit_breaker.py` (신규, 400줄)
- `/home/jay/workspace/teams/shared/qc_verify.py` (수정, 2개소)

## 영속 저장 경로

- circuit_breaker 상태: `/home/jay/workspace/memory/logs/circuit-breaker/{context}.json`
- escalation 파일: `/home/jay/workspace/memory/escalations/{context}_{timestamp}_escalation.json`
- 롤백 스냅샷: `/home/jay/workspace/memory/logs/rollback-snapshots/{task_id}_{scope}_{ts}.json`

## 테스트 결과

- **29개 테스트 전체 통과** (3.56초)
  - TestInitialState: 3개 (초기 상태, 에러/성공 기록)
  - TestStateTransitions: 7개 (CLOSED→OPEN, OPEN→ESCALATE, cooldown, HALF_OPEN 전환, force_reset)
  - TestStrategies: 5개 (AutoFix RETRY/ESCALATE, Escalation 상수 반환, on_circuit_open 파일 생성)
  - TestFileSnapshot: 6개 (캡처/복원/삭제)
  - TestRollbackManager: 2개 (정상 롤백, 실패 시 escalation)
  - TestPersistence: 2개 (영속 저장/로드, 미영속)
  - TestFactory: 2개 (autofix/escalation 전략)
  - TestCLI: 2개 (record-error, check)
- **pyright**: 에러 0건, 경고 0건 (circuit_breaker.py)

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **테스트-모듈 간 변수명 불일치** — 테스트가 `PERSISTENT_DIR`/`ESCALATION_DIR`를 monkeypatch했으나 모듈 실제 변수명은 `CB_STATE_DIR`/`ESCALATIONS_DIR`. 테스트의 monkeypatch 대상을 모듈 변수명과 일치시킴.
2. **CLI 테스트 PYTHONPATH 미설정** — subprocess로 모듈 직접 실행 시 `utils` 패키지를 찾지 못함. 테스트에서 `PYTHONPATH` 환경변수를 workspace root로 설정하여 해결.
3. **CLI 테스트 인자 불일치** — 테스트가 `--error` 플래그 사용했으나 CLI는 `--message` 요구. 테스트 인자를 `--message`로 수정.

### 범위 외 미해결 (2건)
1. **post-tool-use.sh 마이그레이션** — 범위 외 사유: bash hook에서 Python circuit_breaker CLI 호출로 전환하면 hook 실행 시간이 증가할 수 있어, 성능 측정 후 별도 태스크로 진행 필요.
2. **chain_manager.py의 `_trigger_circuit_breaker` 통합** — 범위 외 사유: chain_manager는 체인 전용 로직이 밀접하게 결합되어 있어, 범용 모듈로의 전환은 영향 범위 분석 후 별도 태스크 필요.

---

## 점진적 롤아웃 가이드 (후속 hook별 opt-in)

현재 circuit_breaker는 pyright_check에만 연결되어 있습니다. 다른 hook/검증기에 적용할 때:

```python
from utils.circuit_breaker import create_circuit_breaker

cb = create_circuit_breaker("{context_key}", strategy_type="autofix", threshold=3)
action = cb.record_error({"message": "...", "source": "...", "details": ...})
# action에 따라 RETRY / ESCALATE / ROLLBACK 처리
```

---

## 모델 사용 기록
- 토르(백엔드) / circuit_breaker.py 구현 + pyright_check 마이그레이션 / sonnet
- 헤임달(테스터) / test_circuit_breaker.py 작성 / sonnet
- 오딘(팀장) / 설계, 통합, 리뷰, 테스트 수정 / opus

## 세션 통계
- 총 도구 호출: 23회

### 수정 파일 목록
- /home/jay/workspace/utils/tests/test_circuit_breaker.py: 10회 (Edit, Write)
- bash_cmd: 6회 (Bash)
- /home/jay/workspace/teams/shared/qc_verify.py: 4회 (Edit)
- /home/jay/workspace/memory/reports/task-1643.1.md: 1회 (Write)
- /home/jay/workspace/memory/tasks/task-1643.1.md: 1회 (dispatch)
- /home/jay/workspace/utils/circuit_breaker.py: 1회 (Write)

### 도구 사용 현황
- Edit: 13회
- Bash: 6회
- Write: 3회
- dispatch: 1회

