<!-- task=m-openai-compatible-tool-call-boundary-hardening/02+01_contract_dev_smoke plan=0 tag=API -->

# Contract And Dev Smoke Plan

## 이 파일을 읽는 구현 에이전트에게

`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 채우는 것이 구현의 마지막 단계다. 검증 명령의 실제 출력과 remote preflight/evidence path를 남긴 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 선택된 Milestone `구현 잠금 > 결정 필요` 항목만 `사용자 리뷰 요청`에 기록하며, secret, token, private endpoint 원문을 tracked 문서나 review output에 남기지 않는다.

## 배경

01번 core boundary가 완료되면 계약 문서와 dev 운영 문서는 provider raw text tool-call 후보의 정규화/차단 정책을 반영해야 한다. 또한 Pi/Cline형 긴 agent prompt와 `tools[]` 요청은 로컬 unit test로만 증명하기 어렵기 때문에 dev-runtime Edge에 직접 호출한 evidence가 필요하다. 이 작업은 문서 갱신과 credentialed dev smoke evidence를 한 task로 묶되, 선행 core 구현이 PASS된 뒤에만 실행한다.

## 사용자 리뷰 요청 흐름

사용자 리뷰 요청은 선택된 Milestone 잠금 결정이 구현을 차단할 때만 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 원격 credential 부재, source sync 필요, provider runtime 일시 장애는 사용자 리뷰가 아니라 blocker 또는 follow-up evidence로 기록한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-tool-call-boundary-hardening.md`
- Task ids:
  - `client-smoke`: Pi/Cline형 긴 agent prompt와 `tools[]` dev Edge 호출 evidence
  - `contract-docs`: OpenAI-compatible 계약 문서와 dev 운영 문서 정책 설명
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-roadmap/current.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-tool-call-boundary-hardening.md`
- `agent-ops/rules/project/domain/edge/rules.md`
- `agent-ops/rules/project/domain/platform-common/rules.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-test/dev/rules.md`
- `agent-test/dev/edge-smoke.md`
- `agent-test/dev/platform-common-smoke.md`
- `agent-contract/index.md`
- `agent-contract/outer/openai-compatible-api.md`
- `docs/openai-compatible-api-contract.md`
- `docs/edge-local-dev-guide.md`
- `apps/edge/internal/openai/server_test.go`

### SDD 기준

선택 Milestone은 `SDD: 불필요`다. 사유는 기존 OpenAI-compatible `tools[]`, `tool_calls`, text-tool fallback, validation retry 계약을 강화하는 호환성 보정이며 새 공개 request/response field를 만들지 않는다는 것이다.

### 테스트 환경 규칙

`test_env=dev` evidence가 필요하다. `agent-test/dev/rules.md`와 `agent-test/dev/edge-smoke.md`를 읽었다. 원격 preflight 결과는 2026-07-04 기준 `ssh toki@toki-labs.com`, workdir `/Users/toki/agent-work/iop-dev`, remote branch `main...origin/main`, HEAD `b55d1a2 fix: document and verify provider priority leveling`, `build/dev-runtime/bin/edge` 존재, `edge config refresh` help 존재, `build/dev-runtime/edge.yaml`에 `refresh:` 존재, ports `18001/18083/18084/19093` listen, Control Plane status HTTP `200`이다. 현재 local checkout은 `main...origin/main` HEAD `fcd6068 chore: update openai-compatible tool call boundary hardening milestone`이며 uncommitted code/roadmap/task 변경이 있으므로 remote source는 local changes와 동기화되어 있지 않다. 구현은 먼저 01 PASS commit/branch 또는 명시적 sync 절차로 remote dev-runtime artifact를 현재 source에 맞춰 rebuild해야 한다.

### 테스트 커버리지 공백

- 계약 문서: `agent-contract/outer/openai-compatible-api.md:227`이 provider raw text 합성 금지를 설명하므로 01 완료 후 정책이 stale해진다.
- dev 운영 문서: `docs/edge-local-dev-guide.md`는 provider-pool/think-control/capacity smoke는 설명하지만 raw text tool-call boundary smoke와 unknown tool hallucination 차단 판정은 없다.
- dev smoke: `agent-test/dev/edge-smoke.md:121-127`은 OpenAI-compatible와 provider-pool smoke 기준만 있고 Pi/Cline형 `tools[]` leak 차단 evidence 기준이 없다.

### 심볼 참조

symbol rename/remove 없음.

### 분할 판단

split 정책을 평가했다. 이 subtask는 `02+01_contract_dev_smoke`이며 predecessor `01_provider_text_boundary`의 `complete.log`가 필요하다. 현재 active sibling `agent-task/m-openai-compatible-tool-call-boundary-hardening/01_provider_text_boundary/complete.log`는 없고 archive predecessor도 확인하지 않았다. 따라서 실행은 01 PASS 이후로 제한한다.

### 범위 결정 근거

이 plan은 계약/운영 문서와 dev smoke evidence만 다룬다. `apps/edge/internal/openai` behavior 수정은 01 범위다. Pi provider/profile 소유권 이전, CLI `adapter=cli,target=pi` 구현, private token 기록, tracked 문서에 secret 원문 기록은 제외한다.

### 빌드 등급

`cloud-G07`. 원격 dev-runtime, credentialed OpenAI-compatible calls, source sync/rebuild, Edge trace/evidence 판단이 핵심이라 local 조건을 만족하지 않는다.

## 구현 체크리스트

- [ ] 01번 `agent-task/m-openai-compatible-tool-call-boundary-hardening/01_provider_text_boundary/complete.log`가 존재하고 Roadmap Completion에 `provider-raw-parse`, `unknown-tool-error`, `stream-flush-guard`, `native-preserve`가 포함됐는지 확인한다.
- [ ] `agent-contract/outer/openai-compatible-api.md`가 provider route/provider-pool raw text tool-call 후보의 구조화/차단, unknown/malformed 처리, sentinel sanitize 정책을 설명하도록 갱신한다.
- [ ] `docs/edge-local-dev-guide.md`와 `agent-test/dev/edge-smoke.md`에 dev-runtime Pi/Cline형 `tools[]` smoke 기준, evidence 보관 위치, secret 마스킹 원칙을 추가한다.
- [ ] 원격 dev-runtime source를 01 완료 source와 동기화하고 dev-runtime Edge/Node binaries를 rebuild한 뒤 `config check`와 필요한 refresh/restart를 수행한다.
- [ ] dev Edge OpenAI-compatible endpoint에 긴 agent prompt와 `tools[]` 요청을 호출해 valid raw text는 `tool_calls`, unknown hallucination은 `tool_validation_error` 또는 retry 후 차단으로 끝나며 raw block이 body/SSE에 남지 않는 evidence를 남긴다.
- [ ] `go test ./apps/edge/internal/openai -count=1`와 문서/evidence 검증 명령을 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [API-1] Contract Policy Update

문제: `agent-contract/outer/openai-compatible-api.md:227`은 provider route raw text tool-call을 합성하지 않는다고 명시한다. 01 완료 후 이 계약은 stale해진다.

해결 방법: 해당 문단을 provider route/provider-pool 정책으로 갱신한다. 요청 `tools[]`가 있고 raw text 후보가 감지되면 request tool schema에 맞는 known valid 후보는 OpenAI `tool_calls`로 정규화하고, unknown/malformed 후보는 성공 content가 아니라 validation retry/error로 처리한다고 쓴다. `tools[]`가 없는 자연어 추론은 여전히 제외임을 유지한다. `docs/openai-compatible-api-contract.md`는 계약 pointer라 원문 복제 없이 그대로 둔다.

Before:

```markdown
agent-contract/outer/openai-compatible-api.md:227
provider route에서 assistant content에 `<tool_call>`, `{{function(...)}}`, `[Calling tool: ...]` 같은 텍스트가 들어와도 Edge는 기본적으로 이를 파싱하거나 OpenAI `tool_calls`로 합성하지 않는다.
```

수정 파일 및 체크리스트:

- [ ] `agent-contract/outer/openai-compatible-api.md`: provider raw candidate 정책 갱신.
- [ ] `docs/openai-compatible-api-contract.md`: pointer 유지 확인.

테스트 작성: 문서 변경이므로 Go test 추가 없음.

중간 검증: `rg --sort path -n "provider route에서|raw text|tool_validation_error|mask_end" agent-contract/outer/openai-compatible-api.md docs/openai-compatible-api-contract.md` 실행.

### [API-2] Dev Smoke Guide And Test Rule

문제: `docs/edge-local-dev-guide.md`와 `agent-test/dev/edge-smoke.md`는 dev-runtime capacity와 think-control 기준은 있지만 Pi/Cline형 `tools[]` raw leak 차단 기준이 없다.

해결 방법: dev-runtime section에 raw text tool-call boundary smoke를 추가한다. 요청 payload는 tracked 문서에 secret 없이 남기고, token은 환경 변수에서 주입하도록 한다. 판정은 response body/SSE에 `<tool_call>`, `{{...}}`, `<|mask_end|>`가 없고, known valid tool은 `tool_calls` finish reason, unknown tool hallucination은 OpenAI-compatible error body 또는 SSE error `tool_validation_error`로 끝나는 것이다. evidence는 `agent-test/runs/` 같은 ignored run 위치 또는 review output path에 남기고 tracked docs에는 원문 secret을 남기지 않는다.

수정 파일 및 체크리스트:

- [ ] `docs/edge-local-dev-guide.md`: dev-runtime raw boundary smoke 절차 추가.
- [ ] `agent-test/dev/edge-smoke.md`: 필수/보조 검증과 판정 기준 보강.

테스트 작성: 문서/test-rule 변경이므로 Go test 추가 없음.

중간 검증: `rg --sort path -n "raw text tool|tool_validation_error|Pi/Cline|mask_end|agent-test/runs" docs/edge-local-dev-guide.md agent-test/dev/edge-smoke.md` 실행.

### [API-3] Credentialed Dev Runtime Evidence

문제: Milestone `client-smoke`는 Pi/Cline형 긴 prompt와 `tools[]` 요청이 raw text로 노출되지 않는 근거를 요구한다. local tests만으로 실제 provider-pool/Pi 스타일 prompt behavior를 대체할 수 없다.

해결 방법: 선행 01 완료 source를 원격 `/Users/toki/agent-work/iop-dev`에 반영하고 dev-runtime binaries를 rebuild한다. preflight로 `git status --branch --short`, `git log --oneline -1`, edge binary/config refresh help, ports `18001/18083/18084/19093`, Control Plane status HTTP를 다시 확인한다. 이후 token은 원격 환경 변수나 ignored secret file에서 읽고 stdout에는 마스킹한다. known tool payload와 unknown tool 유도 payload를 각각 non-stream/stream 중 최소 하나씩 호출하고, response finish reason/error type 및 Edge trace/log path를 review에 남긴다.

수정 파일 및 체크리스트:

- [ ] 원격 preflight 출력 기록.
- [ ] ignored evidence 파일 path 기록.
- [ ] tracked 파일에 token/secret 원문 미기록 확인.

테스트 작성: test code 추가 없음. dev smoke evidence가 검증이다.

중간 검증:

```bash
ssh -o BatchMode=yes -o ConnectTimeout=5 toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git status --branch --short && git log --oneline -1 && test -x build/dev-runtime/bin/edge && build/dev-runtime/bin/edge --config build/dev-runtime/edge.yaml config refresh --help >/dev/null && for p in 18001 18083 18084 19093; do lsof -nP -iTCP:$p -sTCP:LISTEN >/dev/null || exit 20; done && curl -fsS -m 3 -o /dev/null http://127.0.0.1:18001/edges/edge-toki-labs-dev/status'
```

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `agent-contract/outer/openai-compatible-api.md` | API-1 |
| `docs/edge-local-dev-guide.md` | API-2 |
| `agent-test/dev/edge-smoke.md` | API-2 |
| `agent-test/runs/**` 또는 review output path | API-3 evidence only |

## 의존 관계 및 구현 순서

이 directory 이름의 `+01`이 source of truth다. `agent-task/m-openai-compatible-tool-call-boundary-hardening/01_provider_text_boundary/complete.log`가 생기기 전에는 구현을 시작하지 않는다. predecessor가 missing이면 review stub에 blocker로 기록하고 active files를 유지한다.

## 최종 검증

```bash
go test ./apps/edge/internal/openai -count=1
rg --sort path -n "tool_validation_error|raw text tool|mask_end|Pi/Cline" agent-contract/outer/openai-compatible-api.md docs/edge-local-dev-guide.md agent-test/dev/edge-smoke.md
ssh -o BatchMode=yes -o ConnectTimeout=5 toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git status --branch --short && git log --oneline -1 && test -x build/dev-runtime/bin/edge && build/dev-runtime/bin/edge --config build/dev-runtime/edge.yaml config refresh --help >/dev/null && curl -fsS -m 3 -o /dev/null http://127.0.0.1:18001/edges/edge-toki-labs-dev/status'
```

기대 결과: local Go test PASS, 문서 검색 결과가 계약/운영/test-rule 세 위치를 가리킴, remote preflight PASS. Credentialed request/response evidence는 review `검증 결과`에 실제 command와 redacted output 또는 saved output path로 남긴다.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
