<!-- task=m-openai-compatible-think-control/05+01,02,03,04_dev_smoke plan=0 tag=TEST -->

# Plan - Dev Runtime Think-Control Smoke

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

이 plan은 `01_edge_request_contract`, `02+01_node_provider_mapping`, `03+01_edge_reasoning_visibility`, `04+01,02,03_contract_docs`가 PASS complete된 뒤 실행한다. 이 작업은 원격 dev-runtime과 실제 provider pool을 사용하는 smoke 검증이며, 구현 변경을 새로 만들지 않는다. 실패가 나오면 원인과 증거를 `CODE_REVIEW-*-G??.md`에 남기고 follow-up plan으로 넘긴다.

## 배경

Milestone의 `dev-smoke`는 로컬 단위 테스트만으로 닫을 수 없다. 요청별 `think=false`, omitted default, `include_reasoning=false`가 Edge SSE와 provider raw trace에서 일관되게 관측되어야 한다. dev-runtime 인벤토리는 runner, Edge, Node, provider capacity, model alias를 이미 정의하고 있으므로 이 split은 깨끗한 원격 source 기준으로 배포/재시작/관측 증거를 확보한다.

## 사용자 리뷰 요청 흐름

사용자 리뷰 요청은 선택된 Milestone lock decision이 실구현을 막을 때만 review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 원격 접속 실패, provider 미기동, secret 부재, trace 미관측, 용량 smoke 불충족은 사용자 결정이 아니라 환경 blocker 또는 follow-up evidence로 기록한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-think-control.md`
- Task ids:
  - `dev-smoke`: 실제 dev provider pool에서 `think=false`, omitted default, `include_reasoning=false` 요청을 실행하고 provider raw trace와 Edge SSE를 비교한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-think-control.md`
- `agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-think-control/SDD.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-test/dev/rules.md`
- `agent-test/dev/edge-smoke.md`
- `agent-test/dev/node-smoke.md`
- `agent-test/dev/platform-common-smoke.md`
- `agent-test/dev/inventory.yaml`
- `agent-ops/skills/project/dev-runtime-deploy/SKILL.md`

### SDD 기준

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-think-control/SDD.md`
- 상태: `[승인됨]`, SDD 잠금: `해제`, 사용자 리뷰: 없음
- Acceptance Scenario: S05 -> `dev-smoke`
- Evidence Map: S05 requires dev smoke logs that compare provider raw trace and Edge SSE behavior for `think=false`, omitted default, and `include_reasoning=false`.

### 테스트 환경 규칙

- test_env: `dev`
- profile: `dev-runtime-provider-pool`
- remote runner: `ssh toki@toki-labs.com`
- repo root: `/Users/toki/agent-work/iop-dev`
- Edge id: `edge-toki-labs-dev`
- Edge config: `build/dev-runtime/edge.yaml`
- OpenAI base URL on runner: `http://127.0.0.1:18083/v1`
- Control Plane status URL: `http://127.0.0.1:18001/edges/edge-toki-labs-dev/status`
- admin addr on runner: `127.0.0.1:19093`
- model alias: `qwen3.6:35b`
- provider capacity total: `10`
- dev-runtime-deploy skill applies. It requires clean sync, full test, full rebuild, restart, `/v1/models`, and OpenAI-compatible smoke evidence.
- Secrets, bearer tokens, bootstrap tokens, and private key paths must not be written to final report or review output.

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

- Local tests can prove request decoding, adapter body mapping, and response filtering, but cannot prove actual vLLM/vLLM-MLX/Lemonade runtime behavior.
- Provider request-body trace availability is environment-dependent. If raw request body cannot be observed, record the missing trace source and do not claim S05 PASS.
- Omitted default can be nondeterministic if the model produces no reasoning on a given prompt. Use a reasoning-friendly prompt and record the result as observed behavior rather than exact output matching.

### 심볼 참조

- renamed/removed symbol: none. This split should not edit source symbols.

### 분할 판단

- current subtask: `05+01,02,03,04_dev_smoke`
- dependency from directory name: predecessors `01`, `02`, `03`, `04`
- predecessor completion: all missing in active and archive lookup at plan creation.
- split reason: external dev-runtime deployment and provider evidence are slower, environment-sensitive, and should run only after code/docs splits are complete.

### 범위 결정 근거

- Code and docs changes are excluded. If smoke fails because implementation behavior is wrong, create a follow-up plan after review; do not hot-edit inside this smoke split.
- Capacity smoke from `dev-runtime-deploy` is included only as deployment health evidence. The primary milestone evidence is think-control trace/SSE comparison.
- OneXPlayer access must use `ssh r0bin@192.168.0.59` from the current host if it is needed. Do not use `toki` for OneXPlayer.

### 빌드 등급

- `cloud-G07`: external runner, clean sync/rebuild/restart, multiple provider runtimes, raw trace collection, and SSE comparison.

## 구현 체크리스트

- [ ] Predecessor `complete.log` for `01`, `02`, `03`, and `04`를 확인한 뒤 시작한다.
- [ ] Remote runner inventory를 재확인하고 source ref, dirty state, branch, HEAD를 기록한다.
- [ ] Clean sync 기준 ref를 확정한다. Milestone 구현 commit이 `origin/main`에 없으면 같은 source ref를 원격에 명시적으로 반영한 뒤 진행하고, 임의로 stale `origin/main`을 검증하지 않는다.
- [ ] Remote runner에서 `go test ./...`를 빌드 전 실행한다. 실패하면 배포를 중단한다.
- [ ] dev-runtime Edge/mac/Linux ARM64/Windows AMD64 Node binary를 같은 source ref에서 rebuild한다.
- [ ] 빌드 후 `config check`, `config refresh --help`, `config refresh --mode dry-run`, `go test ./...`를 실행한다.
- [ ] Edge, mac-codex-node, gx10-vllm-node, onexplayer-lemonade-node를 dev-runtime 절차대로 재시작하고 port/process/status를 확인한다.
- [ ] `/v1/models`가 `qwen3.6:35b`를 노출하는지 확인한다.
- [ ] `/v1/responses`와 `/v1/chat/completions` capacity smoke를 capacity+1 기준으로 실행하고 provider `in_flight/queued` snapshot을 남긴다.
- [ ] `/v1/chat/completions`에서 omitted default, `think=false`, `include_reasoning=false` 세 케이스를 stream으로 실행하고 Edge SSE와 provider raw trace를 비교한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 실행 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

- `05+01,02,03,04_dev_smoke` decodes to `depends_on=[01,02,03,04]`.
- Do not execute remote smoke until all predecessors have `complete.log`.
- If predecessors are archived, read only the matching `complete.log` evidence needed to prove dependency completion.

### [TEST-1] Remote Runner Preflight

#### 문제

dev-runtime smoke can produce misleading results if the remote checkout or binaries are stale.

#### 해결 방법

- Confirm remote checkout source and clean state before deployment.
- Confirm expected binaries/config paths from inventory.
- Record versions/timestamps without printing secrets.

#### 수정 파일 및 체크리스트

- [ ] No source files.
- [ ] `CODE_REVIEW-*-G??.md`: record preflight output.

#### 테스트 작성

No automated test file. Use remote shell preflight.

#### 중간 검증

```bash
ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git status --short --branch && git log --oneline -1 && test -f build/dev-runtime/edge.yaml && test -x build/dev-runtime/bin/edge && test -x build/dev-runtime/bin/iop-node'
```

Expected: clean source for the intended ref, Edge config present, local Edge/mac Node binaries executable.

### [TEST-2] Clean Sync, Full Test, Rebuild, Restart

#### 문제

The smoke must validate the completed implementation, not an old binary or dirty remote tree.

#### 해결 방법

- Follow `agent-ops/skills/project/dev-runtime-deploy/SKILL.md`.
- Clean sync only after confirming the target ref contains the milestone implementation.
- Run pre-build and post-build `go test ./...`.
- Rebuild all dev-runtime binaries from the same source ref.
- Restart Edge and all dev provider nodes according to inventory.

#### 수정 파일 및 체크리스트

- [ ] No source files.
- [ ] `CODE_REVIEW-*-G??.md`: record source ref, test result, build artifacts, restart status.

#### 테스트 작성

No repo test additions. This is deployment verification.

#### 중간 검증

```bash
ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && go test ./...'
ssh toki@toki-labs.com 'curl -fsS http://127.0.0.1:18001/edges/edge-toki-labs-dev/status | jq ".edge_id, .nodes"'
ssh toki@toki-labs.com 'curl -fsS http://127.0.0.1:18083/v1/models | jq ".data[].id"'
```

Expected: tests pass, Edge and three dev nodes are connected, `qwen3.6:35b` appears in models.

### [TEST-3] Think-Control SSE And Provider Trace

#### 문제

Milestone S05 requires real provider evidence for request-level think control and response exposure filtering.

#### 해결 방법

- Use `/v1/chat/completions` with `stream=true`, model `qwen3.6:35b`, and a reasoning-friendly prompt.
- Send these cases:
  - omitted default: no think-control fields.
  - generation disabled: `think=false`.
  - visibility disabled: `include_reasoning=false`.
- Include trace metadata if supported by the implemented Edge/Node path. Do not print API keys.
- Save temporary SSE outputs and provider raw trace snippets under `/tmp` on the runner, then paste only relevant masked excerpts into `CODE_REVIEW-*-G??.md`.

#### 수정 파일 및 체크리스트

- [ ] No source files.
- [ ] `CODE_REVIEW-*-G??.md`: record each request body summary, Edge SSE observation, provider raw trace observation, and pass/fail judgment.

#### 테스트 작성

No committed test file. Use a temporary runner script or direct `curl` commands.

#### 중간 검증

```bash
ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && \
  BASE=http://127.0.0.1:18083/v1 MODEL=qwen3.6:35b \
  bash -lc '\''for case_name in omitted_default think_false include_reasoning_false; do echo "case=$case_name"; done'\'''
```

Replace the placeholder loop with actual masked `curl -N` requests:

```json
{"model":"qwen3.6:35b","stream":true,"messages":[{"role":"user","content":"Solve a two-step logic puzzle and explain the answer briefly."}]}
{"model":"qwen3.6:35b","stream":true,"think":false,"messages":[{"role":"user","content":"Solve a two-step logic puzzle and explain the answer briefly."}]}
{"model":"qwen3.6:35b","stream":true,"include_reasoning":false,"messages":[{"role":"user","content":"Solve a two-step logic puzzle and explain the answer briefly."}]}
```

Expected:

- omitted default preserves provider default. If reasoning appears, Edge SSE may expose `reasoning_content` according to implemented default visibility.
- `think=false` provider raw request shows disabled thinking mapping for the selected provider path, and Edge SSE does not expose generated reasoning chunks for that request.
- `include_reasoning=false` may still allow provider-side reasoning generation, but Edge SSE must not include `reasoning_content` or equivalent reasoning deltas.
- All cases finish with valid content/tool/DONE stream behavior and no secret output.

### [TEST-4] Capacity Health Evidence

#### 문제

Think-control smoke should not pass while the dev provider pool is partially disconnected.

#### 해결 방법

- Run capacity+1 smoke for `/v1/responses` and `/v1/chat/completions`.
- Poll Control Plane status while requests are in flight.
- Record max aggregate `in_flight`, `queued`, and per-provider capacity observations.

#### 수정 파일 및 체크리스트

- [ ] No source files.
- [ ] `CODE_REVIEW-*-G??.md`: record max in-flight/queued and recovery snapshot.

#### 테스트 작성

No committed test file. Use temporary runner script if needed.

#### 중간 검증

```bash
ssh toki@toki-labs.com 'curl -fsS http://127.0.0.1:18001/edges/edge-toki-labs-dev/status | jq ".. | objects | select(has(\"capacity\") and has(\"in_flight\") and has(\"queued\")) | {id, capacity, in_flight, queued, health, served_models}"'
```

Expected: total capacity reaches `10`, queued reaches at least `1` during capacity+1 smoke, and all providers recover to `in_flight=0`, `queued=0` afterward.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| none | external dev-runtime smoke only |

## 최종 검증

```bash
ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git status --short --branch && git log --oneline -1'
ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && go test ./...'
ssh toki@toki-labs.com 'curl -fsS http://127.0.0.1:18083/v1/models | jq ".data[].id"'
ssh toki@toki-labs.com 'curl -fsS http://127.0.0.1:18001/edges/edge-toki-labs-dev/status | jq "."'
```

Expected: intended source ref, full tests pass, model exposed, dev provider pool connected, capacity health evidence captured, and think-control raw trace/SSE comparison recorded for all three cases.

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