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

# Plan - Review Follow-up: Think=False Runtime Compatibility And Re-Smoke

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

이 plan은 이전 REVIEW_TEST loop의 FAIL Required를 닫기 위한 후속 작업이다. `mac-mlx-vllm`과 `onexplayer-lemonade`에서 `think=false`가 200 stream으로 성공하면서 reasoning을 생성/노출한 상태를 그대로 PASS 처리하지 않는다. 사용자에게 직접 질문하지 말고, Milestone lock 결정이 아니라면 `사용자 리뷰 요청`을 채우지 않는다. token, bearer value, private key path, node registration token 원문은 어떤 출력에도 남기지 않는다.

## 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

## Archive Evidence Snapshot

- Archived plan: `agent-task/m-openai-compatible-think-control/05+01,02,03,04_dev_smoke/plan_cloud_G07_1.log`
- Archived review: `agent-task/m-openai-compatible-think-control/05+01,02,03,04_dev_smoke/code_review_cloud_G07_1.log`
- Verdict: FAIL
- Required summary:
  - `code_review_cloud_G07_1.log` records that `mac-mlx-vllm` `think=false` returned a normal stream with Edge SSE `reasoning_content` nonempty 302 chunks and provider raw `reasoning_len>0` for 302/332 parsed chunks.
  - `code_review_cloud_G07_1.log` records that `onexplayer-lemonade` `think=false` returned a normal stream with Edge SSE `reasoning_content` nonempty 2067 chunks and provider raw `reasoning_len>0` for 2067/2283 trace lines.
  - Active plan expectation required `think=false` to produce no provider reasoning and no Edge `reasoning_content`; SDD S05 requires provider raw trace and Edge SSE generation/exposure state to match the defined expectation.
  - SDD and contract allow unsupported provider combinations only when they become a clear compatibility error or defined fallback, not a silent successful stream with reasoning.
- Affected files:
  - Likely source: `apps/node/internal/adapters/openai_compat/openai_compat.go`
  - Likely tests: `apps/node/internal/adapters/openai_compat/openai_compat_test.go`, `apps/edge/internal/openai/server_test.go`
  - Likely contract/docs if unsupported/fallback policy changes: `agent-contract/outer/openai-compatible-api.md`, `docs/openai-compatible-api-contract.md`
  - If a provider capability/config field is added: `packages/go/config/config.go`, `configs/edge.yaml`, `agent-contract/inner/edge-config-runtime-refresh.md`
  - Active evidence artifact to fill: `agent-task/m-openai-compatible-think-control/05+01,02,03,04_dev_smoke/CODE_REVIEW-cloud-G07.md`
- Verification evidence already trusted from prior loop:
  - Remote source ref `eea8dd0`; remote checkout clean and aligned with `origin/main`.
  - Remote `go test ./...` passed after restore in the previous loop.
  - Provider-isolated routing via `models["qwen3.6:35b"].providers` apply worked without restart-required paths.
  - `gx10-vllm` `think=false` produced no provider reasoning and no Edge `reasoning_content`.
  - `include_reasoning=false` suppressed Edge SSE reasoning exposure on all three providers while preserving content and `[DONE]`.
  - Final previous-loop restore returned all three nodes/providers to connected/healthy/recovered state.
- Allowed archive reread:
  - Read only the two archived files listed above if exact previous-loop context is needed. Do not scan `agent-task/archive/**`.
- Roadmap carryover:
  - `dev-smoke` remains incomplete until provider별 `think=false` behavior is either raw no-reasoning or an explicit unsupported/fallback outcome, and the provider matrix is re-recorded after any code/docs/config change.

## 분석 결과

### 문제

The previous follow-up gathered the missing provider별 matrix, but the matrix itself proves two required `think=false` rows do not satisfy the plan, SDD, or OpenAI-compatible contract. Treating those rows as "source 변경 범위 밖" would leave a public `think=false` request silently succeeding while reasoning is still generated and exposed.

### 해결 방법

- First prove whether mac vLLM-MLX and OneXPlayer Lemonade have an alternate request-level disable field that actually prevents reasoning generation.
- If an alternate supported field exists, update the Node provider mapping and tests to use that field.
- If no supported field exists for the current runtime, implement a compatibility error or explicitly documented fallback for that provider path so `think=false` is not silently accepted as a successful reasoning stream.
- Preserve the known-good `gx10-vllm` path and `include_reasoning=false` exposure filtering.
- Rebuild/redeploy the dev-runtime source ref if code/docs/config changed, then rerun the provider-isolated S05 matrix and record the final state.

### 기대 기준

- `omitted_default`: record provider default as observed and require normal stream completion with content or valid finish evidence.
- `think=false`:
  - Supported provider path: provider raw trace has no generated reasoning and Edge SSE has no `reasoning_content`.
  - Unsupported provider path: request fails with a clear OpenAI-compatible/adapter compatibility error, or follows a documented fallback that does not present as silent generation-disable success. Do not PASS a 200 stream that contains reasoning.
- `include_reasoning=false`: Edge SSE must not expose `reasoning_content`; provider raw generation may be observed and recorded.
- Secrets stay masked.

## 구현 체크리스트

- [ ] mac vLLM-MLX와 OneXPlayer Lemonade의 request-level thinking disable 지원 여부를 direct provider probe 또는 equivalent trace로 확인하고, 지원 field 또는 미지원 결론을 기록한다.
- [ ] probe 결과에 따라 Node provider mapping을 수정하거나, 미지원 provider에서 `think=false`가 조용히 성공하지 않도록 compatibility error/명시 fallback 정책을 구현하고 계약/문서를 갱신한다.
- [ ] `gx10-vllm`의 기존 `think=false` 성공 경로와 `include_reasoning=false` 노출 억제를 단위/통합 테스트로 보존한다.
- [ ] 변경한 source ref로 dev-runtime binary를 rebuild/redeploy한 뒤 provider-isolated S05 matrix를 재실행하고, `mac-mlx-vllm`, `gx10-vllm`, `onexplayer-lemonade` 각각의 final judgment를 기록한다.
- [ ] 임시 config/trace 변경을 원복하고, 최종 `go test ./...`, `/v1/models`, 3-node connected/provider healthy/recovered 상태를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 실행 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

This follow-up stays in `05+01,02,03,04_dev_smoke` and reuses the already archived predecessor completions. Do not re-open `01`, `02`, `03`, or `04`. Because source or contract changes may be needed, do not claim PASS from evidence-only notes.

### [REVIEW_REVIEW_TEST-1] Provider Disable Capability Probe

#### 문제

The previous matrix proves IOP's current mapped fields do not disable reasoning on mac vLLM-MLX or OneXPlayer Lemonade, but it does not prove whether another supported provider field exists.

#### 해결 방법

- Use the dev-runtime inventory and avoid printing bearer/API keys.
- Probe mac vLLM-MLX and OneXPlayer Lemonade directly, or through provider-isolated IOP routing with raw trace, using a short deterministic script under `/tmp`.
- For each provider, compare current mapped field plus plausible provider-native alternatives only when supported by provider docs/help/runtime behavior.
- Record the conclusion as either `supported via <field>` or `unsupported in current runtime`.

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

- [ ] No committed source files unless probe discovers a mapping fix.
- [ ] `CODE_REVIEW-*-G??.md`: record probe command summary, masked request-body summary, raw reasoning count, Edge/provider response status, and conclusion.

#### 테스트 작성

No committed test file for probes. Temporary scripts are allowed under `/tmp` 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 'curl -fsS http://127.0.0.1:18001/edges/edge-toki-labs-dev/status | jq "{edge_id, nodes: [.nodes[] | {node_id, connected}], providers: [.nodes[].provider_snapshots[] | {id, health, in_flight, queued, served_models}]}"'
```

Expected: intended source/ref is known, three providers are connected/healthy before probe, and no secret value is printed.

### [REVIEW_REVIEW_TEST-2] Compatibility Policy Implementation

#### 문제

The public contract says `think=false` requests generation disable, while the SDD forbids silently ignoring unsupported think/budget combinations. Current behavior can return a normal reasoning stream on providers that do not honor the disable field.

#### 해결 방법

- If REVIEW_REVIEW_TEST-1 finds a working provider field, update `apps/node/internal/adapters/openai_compat/openai_compat.go` mapping and tests for that provider.
- If a provider is unsupported, return `unsupported think control` or another OpenAI-compatible compatibility error before presenting the request as a successful generation-disabled stream. If a fallback is chosen, document the fallback and test that it is explicit.
- Update `agent-contract/outer/openai-compatible-api.md` and `docs/openai-compatible-api-contract.md` if provider policy changes from the current text.
- If implementation requires a provider capability/config flag, update `packages/go/config/config.go`, `configs/edge.yaml`, and `agent-contract/inner/edge-config-runtime-refresh.md` consistently.
- Keep `include_reasoning=false` as response exposure filtering, not provider trace suppression.

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

- [ ] `apps/node/internal/adapters/openai_compat/openai_compat.go`: provider mapping or unsupported/fallback policy.
- [ ] `apps/node/internal/adapters/openai_compat/openai_compat_test.go`: request body or unsupported/fallback tests for vLLM/vLLM-MLX/Lemonade.
- [ ] `apps/edge/internal/openai/server_test.go`: OpenAI-compatible error/response behavior if the Node adapter error reaches the HTTP surface.
- [ ] Contract/docs/config files only if the implementation changes their documented policy or schema.

#### 테스트 작성

Add or update tests before claiming implementation complete. Tests must prove:

- supported disable path emits the expected provider request body;
- unsupported provider path does not silently accept `think=false`;
- `include_reasoning=false` still suppresses Edge response exposure;
- `gx10-vllm` behavior remains supported.

#### 중간 검증

```bash
go test -count=1 ./apps/node/internal/adapters/openai_compat ./apps/edge/internal/openai
```

Expected: targeted tests pass and include meaningful assertions for the changed provider policy.

### [REVIEW_REVIEW_TEST-3] Dev-Runtime Rebuild And S05 Re-Smoke

#### 문제

The Roadmap `dev-smoke` task cannot close from local tests alone; SDD S05 requires provider raw trace and Edge SSE evidence from the live dev-runtime provider pool.

#### 해결 방법

- Sync/rebuild/redeploy the dev-runtime binaries from the source ref containing REVIEW_REVIEW_TEST-2 if source changed.
- Reconfirm `config check`, `/v1/models`, connected nodes, and provider health.
- Rerun provider-isolated matrix for `omitted_default`, `think=false`, and `include_reasoning=false`.
- For `think=false`, record either raw no-reasoning success or explicit unsupported/fallback result. A normal 200 reasoning stream is a failure.
- Restore original provider config and trace settings, then confirm recovery.

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

- [ ] No tracked smoke artifact other than `CODE_REVIEW-*-G??.md`.
- [ ] `CODE_REVIEW-*-G??.md`: record source ref, rebuild/deploy evidence if applicable, final matrix, restore, and final verification.

#### 테스트 작성

No committed test file. Use remote shell verification and temporary `/tmp` scripts only.

#### 중간 검증

```bash
ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && build/dev-runtime/bin/edge --config build/dev-runtime/edge.yaml config check'
ssh toki@toki-labs.com 'curl -fsS -H "Authorization: Bearer <masked>" http://127.0.0.1:18083/v1/models'
ssh toki@toki-labs.com 'curl -fsS http://127.0.0.1:18001/edges/edge-toki-labs-dev/status | jq "{edge_id, nodes: [.nodes[] | {node_id, connected}], providers: [.nodes[].provider_snapshots[] | {id, capacity, in_flight, queued, health, served_models}]}"'
```

Expected: config OK, model exposed, original provider pool restored, all three providers healthy/recovered after matrix execution.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/node/internal/adapters/openai_compat/openai_compat.go` | provider disable mapping or unsupported/fallback policy |
| `apps/node/internal/adapters/openai_compat/openai_compat_test.go` | provider mapping/unsupported tests |
| `apps/edge/internal/openai/server_test.go` | HTTP error/response behavior if needed |
| `agent-contract/outer/openai-compatible-api.md` | provider unsupported/fallback policy if changed |
| `docs/openai-compatible-api-contract.md` | human docs mirror if contract policy changed |
| `packages/go/config/config.go`, `configs/edge.yaml`, `agent-contract/inner/edge-config-runtime-refresh.md` | only if provider capability config is introduced |

## 최종 검증

```bash
go test -count=1 ./apps/node/internal/adapters/openai_compat ./apps/edge/internal/openai
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 'export PATH=/opt/homebrew/bin:$PATH && 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: [.nodes[] | {node_id, connected}], providers: [.nodes[].provider_snapshots[] | {id, capacity, in_flight, queued, health, served_models}]}"'
```

Expected: targeted tests pass, remote full tests pass after rebuild/redeploy when source changed, final S05 matrix does not contain any normal 200 `think=false` stream with provider/Edge reasoning for an unsupported provider, and the dev-runtime pool is restored.
