# task-868.1 완료 보고서 — Hermes Agent 학습 도입 최종 Phase

**작성자:** 다그다(Dagda), dev3-team 팀장
**작성일:** 2026-03-24
**태스크:** task-868.1

---

## SCQA 프레임워크

**S**: task-856.1(Phase 1) + task-860.1(Phase 2)를 거쳐 utils/ 37개 모듈, 582개 테스트가 구축된 상태였다. 미구현 15개 중 가치 높은 7개를 선별하여 최종 Phase를 수행했다.

**C**: Phase A에서 7개 신규 모듈 구현 + Phase B에서 전체 통합 검증 및 실전 시뮬레이션이 필요했다. 각 모듈당 최소 15개 pytest, 200줄 이하, pyright 0 에러 기준을 충족해야 했다.

**Q**: 7개 신규 모듈을 품질 기준에 맞게 구현하고 기존 582개 테스트를 모두 유지할 수 있는가?

**A**: Phase A 7개 모듈 완전 구현 (합계 961줄), 156개 신규 테스트 추가, 전체 738 PASS(기존 582 + 신규 156). Phase B 통합: dispatch.py에 model_router, orchestrator.py에 checkpoint+persistent_shell, code-review.py에 patch_parser 연결. 실전 시뮬레이션 8개 항목 전체 확인. pyright 0 errors.

---

## Phase A 구현 결과

### 생성 파일 목록

| 파일 | 모듈 | 줄 수 | 테스트 수 |
|------|------|-------|----------|
| `utils/model_router.py` | M-03 스마트 모델 라우팅 | 124줄 | 31개 |
| `utils/checkpoint.py` | M-08 체크포인트 관리 | 175줄 | 25개 |
| `utils/patch_parser.py` | M-18 패치 파서 (unified diff) | 168줄 | 30개 |
| `utils/persistent_shell.py` | M-21 Persistent Shell | 165줄 | 22개 |
| `utils/context_refs.py` | M-05 @ 참조 시스템 | 166줄 | 25개 |
| `tests/fakes/fake_llm_client.py` | M-24 Fake LLM Client | 84줄 | — |
| `tests/fakes/fake_dispatch.py` | M-24 Fake Dispatch | 79줄 | — |
| `tests/fakes/__init__.py` | M-24 패키지 초기화 | 13줄 | — |
| `tests/fakes/test_fakes.py` | M-24 테스트 | — | 23개 |
| `utils/tests/test_model_router.py` | — | 205줄 | 31개 |
| `utils/tests/test_checkpoint.py` | — | 346줄 | 25개 |
| `utils/tests/test_patch_parser.py` | — | 308줄 | 30개 |
| `utils/tests/test_persistent_shell.py` | — | 244줄 | 22개 |
| `utils/tests/test_context_refs.py` | — | 217줄 | 25개 |

**M-25 pyproject.toml**: `[project]` + `[project.optional-dependencies]` 섹션 추가 (voice, ml, dev, search, async, all 6개 그룹)

### Phase A 핵심 설계

- **M-03 model_router**: `max_simple_chars=160`, `max_simple_words=28` 임계값. 복잡 키워드 frozenset 조회. haiku → sonnet → opus 3단계 라우팅
- **M-08 checkpoint**: 파일별 서브디렉토리 구조. `atomic_text_write` 사용. 파일명 형식: `YYYYMMDD_HHMMSS_ffffff__label__original.ext`
- **M-18 patch_parser**: difflib.unified_diff 기반. context 라인 원본 유지, add/delete 원자 적용. atomic_text_write 보장
- **M-21 persistent_shell**: subprocess.Popen 단일 bash 유지. sentinel 패턴(`echo SENTINEL_TAG$?`)으로 exit code 추출
- **M-05 context_refs**: @file:, @folder:, @diff, @staged 4종. 50KB/파일 + 100KB 총합 제한
- **M-24 fakes**: FakeLLMClient (응답 순환, async 지원), FakeDispatch (위임 기록, 실패 모드)

---

## Phase B 통합 검증

### B-1. 전체 테스트

```
738 passed, 0 failed (3.49s)
pyright: 0 errors, 0 warnings, 0 informations (Phase A 7개 모듈 + dispatch.py + orchestrator.py)
```

### B-2. 기존 코드 통합

| 통합 대상 | 통합 내용 | 방식 |
|----------|---------|------|
| `dispatch.py` | M-03 model_router — task_desc 분석 후 권장 모델 로깅 | try/except ImportError |
| `orchestrator.py` | M-08 checkpoint — save_state_snapshot 전 이전 파일 체크포인트 | try/except ImportError |
| `orchestrator.py` | M-21 persistent_shell — import 연결 (`_PERSISTENT_SHELL_AVAILABLE`) | try/except ImportError |
| `scripts/code-review.py` | M-18 patch_parser — apply_patch/generate_patch 선택적 import | try/except ImportError |

모든 통합은 backward compatible (ImportError 시 graceful fallback).

### B-3. 실전 시뮬레이션 결과

| 모듈 | 테스트 항목 | 결과 |
|------|-----------|------|
| redact | API 키 `sk-ant-*` 마스킹 | ✓ PASS |
| injection_guard | "ignore previous instructions" 탐지 | ✓ PASS (threats=1) |
| approval | `rm -rf /important` → critical | ✓ PASS |
| audit_logger | audit-trail.jsonl 기록 | ✓ PASS |
| config_loader | system.yaml 로드, models.default 조회 | ✓ PASS |
| interrupt | 안전 종료 시그널 set/reset | ✓ PASS |
| memory_manager | MEMORY.md FrozenMemory 로드 (4,929 chars) | ✓ PASS |
| M-03 model_router | 단순='haiku', 복잡='opus' 라우팅 | ✓ PASS |
| M-08 checkpoint | 스냅샷 생성 및 목록 조회 | ✓ PASS |
| M-18 patch_parser | 패치 생성 + 적용 라운드트립 | ✓ PASS |
| M-21 persistent_shell | 명령 실행, cwd 유지 | ✓ PASS |
| M-05 context_refs | @file: 참조 파싱 | ✓ PASS |

---

## 전체 모듈 목록

### 구현 완료 (44개)

**Phase 0 (기반 인프라):** M-01 atomic_write, M-02 prompt_cache, M-04 usage_pricing, M-06 model_metadata, M-17 fuzzy_match, M-19 interrupt, M-20 robots_policy, S-01 redact

**Phase 1 (보안):** S-02 injection_guard, S-03 approval, M-16 clarify

**Phase 2 (설정/저장소):** S-14 config_loader, S-09 session_store, session_store_search, M-22 event_hooks, audit_logger

**Phase 3 (핵심 기능):** S-06 memory_manager, S-11 skill_loader, skill_parser, M-03 model_router *(신규)*, M-05 context_refs *(신규)*, M-08 checkpoint *(신규)*, M-18 patch_parser *(신규)*, M-21 persistent_shell *(신규)*

**Phase 4 (분석/라우팅):** S-07 aux_llm_router, S-08 insights_engine, S-13 context_compressor

**Phase 5 (고난이도):** S-04 skill_guard, skill_guard_patterns, S-05 pre_exec_scan, pre_exec_patterns

**테스트 인프라:** M-24 fakes (fake_llm_client, fake_dispatch) *(신규)*, M-25 pyproject optional deps *(신규)*

### 미선별 (8개 — 현재 불필요 또는 외부 의존)

| ID | 이름 | 미선별 사유 |
|----|------|-----------|
| M-09 | Honcho 사용자 모델링 | 외부 SaaS 의존, 로컬 SQLite 대안 검토 필요 |
| M-10 | MoA 앙상블 | dispatch 기반 멀티에이전트로 이미 커버 |
| M-11 | 스킬 허브 연동 | agentskills.io 외부 의존 |
| M-12 | 도구 레지스트리 | MCP로 커버 |
| M-13 | 터미널 다중 환경 | Docker/SSH 현재 불필요 |
| M-14 | 코드 실행 샌드박스 | 보안팀(로키) 영역 |
| M-15 | STT (Faster Whisper) | GPU 환경 필요 |
| M-23 | CI/CD (GitHub Actions) | 별도 프로젝트 예정 |

**향후 검토 권장:** M-09는 S-09 SQLite 기반으로 자체 구현 가치 있음. M-12는 현 utils/ 규모에서 오버엔지니어링 우려.

---

## Health Score

| 지표 | 수치 | 기준 |
|------|------|------|
| pytest 통과율 | 738/738 (100%) | 100% 필수 |
| pyright 에러 | 0건 | 0건 필수 |
| 구현 모듈 | 44개 / 40개 설계 대상 | — |
| 신규 테스트 | 156개 추가 | 모듈당 15개 이상 |
| 200줄 이하 | 전체 7개 모두 준수 | 필수 |
| backward compatible | 전체 통합 | try/except ImportError |

---

## 발견 이슈 및 해결

### 자체 해결 (4건)

1. **async 테스트 Python 3.12 호환성** — `asyncio.get_event_loop().run_until_complete()` → `asyncio.run()`으로 수정
   - 수정 파일: `tests/fakes/test_fakes.py:103`

2. **test_medium_paragraph 텍스트 경계값** — 단어 수 기준이 160자/28단어 중 큰 값 적용. 122자 텍스트가 haiku로 분류되어야 하나 words < 28 조건 적용됨. 테스트 조건을 29단어 기준으로 재설계
   - 수정 파일: `utils/tests/test_model_router.py`

3. **checkpoint.py 200줄 초과** — 최초 222줄. docstring 간소화 + 헬퍼 함수 추출로 175줄로 축소
   - 수정 파일: `utils/checkpoint.py`

4. **context_refs.py 200줄 초과** — 최초 226줄. `_read_safe()` 통합 + `_resolve_git()` 통합으로 166줄로 축소
   - 수정 파일: `utils/context_refs.py`

### 범위 외 미해결 (0건)

---

## 생성/수정 파일 전체 목록

### 신규 생성
- `utils/model_router.py`
- `utils/checkpoint.py`
- `utils/patch_parser.py`
- `utils/persistent_shell.py`
- `utils/context_refs.py`
- `tests/fakes/__init__.py`
- `tests/fakes/fake_llm_client.py`
- `tests/fakes/fake_dispatch.py`
- `tests/fakes/test_fakes.py`
- `utils/tests/test_model_router.py`
- `utils/tests/test_checkpoint.py`
- `utils/tests/test_patch_parser.py`
- `utils/tests/test_persistent_shell.py`
- `utils/tests/test_context_refs.py`

### 수정
- `dispatch.py` — model_router 선택적 import + route_model 호출
- `orchestrator.py` — checkpoint + persistent_shell 선택적 import + save_state_snapshot 통합
- `scripts/code-review.py` — patch_parser 선택적 import
- `pyproject.toml` — [project] + [project.optional-dependencies] 6개 그룹 추가
- `tests/fakes/test_fakes.py` — asyncio.run() 호환성 수정
