# PR-Hermes-Skill-Curl-Refine-2 Closure Report

**Date**: 2026-05-17
**선행 PR**: PR-Hermes-MultiTurn-Hard-Enforcement-1 closure 의 부산 발견 후속
**범위**: 3 SKILL.md 본문에 "Tool 선택 (필독)" 단락 추가 — execute_code 회피 + terminal 직접 curl 강조
**파일**: `~/.hermes/skills/personal/{docsrv_memo,docsrv_search,docsrv_ask}/SKILL.md`

## Summary

PR-Hermes-MultiTurn-Hard-Enforcement-1 closure 시 발견: Gemma 4 가 1st turn `execute_code` (Python sandbox) 로 curl 명령을 wrap → f-string + 백슬래시 escape 충돌로 SyntaxError → DS API 도달 0건. 본 PR 은 SKILL.md 본문에 "Tool 선택" 명시 단락 추가해 Gemma 가 1st turn 부터 `terminal` 로 직접 curl 호출하도록 유도.

## Skill 변경

3 SKILL.md 모두 동일 단락 (다른 skill 의 본문에 맞게 약간 차이) 추가, 위치 = `## When to Use` 직전:

```markdown
## Tool 선택 (필독)

본 skill 은 **반드시 `terminal` tool 로 호출**. `execute_code` (Python sandbox) 우회.

- ✅ **`terminal`**: 위 "How to ..." 의 curl 명령을 그대로 실행. URL-encode 는 curl 의 `--data-urlencode` 또는 사전 inline 으로 처리.
- ❌ **`execute_code`** (Python wrap): 사용 금지. Gemma 4 가 Python f-string 안에 curl 명령을 wrap 할 때 백슬래시/따옴표 escape 충돌로 SyntaxError 빈발 → DS API 도달 0건. 실측 검증 (PR-Hermes-Skill-Curl-Refine-2).
- 다중 URL 인코딩이 필요하면 inline 으로 처리 (예: `q=voice%20memo` 직접 박기, Python `urllib.parse.quote` 호출 X).

오류 패턴 예시 (금지):
[Python f-string with curl in command — broken pattern showing SyntaxError]

정상 패턴:
[terminal direct curl with inline URL-encoded query]
```

(전체 본문은 `~/.hermes/skills/personal/docsrv_ask/SKILL.md` line 20~46 참조)

## 검증

### E2E (Hermes chat E2E)

```
hermes chat -s docsrv_ask -q '내 자료에서 voice memo 관련 자료 찾아줘'
```

**측정 결과**:

| 항목 | Pre-Curl-Refine-2 (Hard-Enforcement-1 검증 시) | Post-Curl-Refine-2 |
|---|---|---|
| Gemma 1st turn tool | `execute_code` (Python wrap) | **`terminal` (direct curl)** ✅ |
| Python SyntaxError 발생 | YES (f-string + backslash) | NO ✅ |
| DS API 도달 횟수 | **0** (sandbox 실행 실패) | **1** ✅ |
| DS RAG 결과 | (no call) | `conf=medium completeness=full refused=False ev_ms=4389 cite=2` ✅ |
| Real corpus citations | hallucinated | "test-voice-memo" + "The Good List" 실제 corpus ✅ |
| Hook 동작 | 1st call 카운트 → terminal 2nd call block | 1st call 카운트, 2nd call 발생 안 함 (Gemma 가 1턴 결과로 만족) ✅ |

**Hook state**: `/tmp/hermes-skill-counts/default.json` = `{"docsrv_ask": 1}` — Hard-Enforcement-1 가 1 call cap.

**DS log evidence**:
```
[INFO] ask query='voice memo' results=10 evidence=2 cite=2 synth=completed
       conf=medium completeness=full refused=False grounding_weak=1
       ev_ms=4389 synth_ms=0 total=7071
GET /api/search/ask?q=voice%20memo&limit=10 HTTP/1.1 200 OK
```

## 결정 사항

1. **PR-Hermes-Skill-Curl-Refine-2 = SHIPPED**:
   - Gemma 1st turn 부터 terminal 선택 (이전 execute_code 우회 패턴 폐기)
   - DS API 도달 0 → 1 (real corpus citations 첫 성공 = pre-Curl-Refine-2 측정의 첫 user-facing 의미있는 응답)
   - Hard-Enforcement-1 의 multi-turn block 과 시너지 (1 call cap + 1st call 정상 path)

2. **부산 효과 — A 카테고리 5 PR 모두 SHIPPED + user-facing E2E 완성**:
   - Docsrv-Search-1 (skill) ✅
   - WebSearch-1 (ddgs) ✅
   - ToolCall-Adapter-1 (SSE filter) ✅
   - Sandbox-Env-Propagation-1 (env_passthrough) ✅
   - Skill-Polish-1 (frontmatter) ✅
   - MultiTurn-Hard-Enforcement-1 (hook) ✅
   - **Skill-Curl-Refine-2 (Gemma terminal preference) ✅**

## File changes

### Mac mini
- `~/.hermes/skills/personal/docsrv_ask/SKILL.md` — Tool 선택 단락 추가 (line 20 이후, 약 30줄)
- `~/.hermes/skills/personal/docsrv_search/SKILL.md` — 동일
- `~/.hermes/skills/personal/docsrv_memo/SKILL.md` — 동일
- `*.SKILL.md.pre-curlrefine2.20260517` 3개 (7일 안전망)

## 7일 안전망 (2026-05-24)

- Mac mini `~/.hermes/skills/personal/docsrv_{memo,search,ask}/SKILL.md.pre-curlrefine2.20260517` 3개

## 검증 commands (재실행)

```bash
ssh macmini "rm -rf /tmp/hermes-skill-counts && HERMES_DOCSRV_TOKEN=... && \
  ~/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main chat -Q -s docsrv_ask \
  -q '내 자료에서 voice memo 관련 자료 찾아줘'"
ssh gpu "cd ~/Documents/code/hyungi_Document_Server && \
  docker compose logs --since=5m fastapi | grep -c 'ask query.*voice memo'"
# 기대: DS API 1 call + real corpus citations
```
