<!-- task=m-agent-readable-repository-refactor/05_http_provider_adapters plan=2 tag=REVIEW_REVIEW_REFACTOR_ADAPTER_HTTP -->

# vLLM reasoning 이벤트 순서 및 검증 증거 복구 계획

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

테스트 assertion을 보완한 뒤 고정 검증을 실행하고 `CODE_REVIEW-*-G??.md`의 구현 소유 섹션에 실제 출력과 변경 내용을 채운다. active 파일은 유지하고 리뷰 준비 상태만 보고한다. 선택된 Milestone의 `구현 잠금 > 결정 필요`가 구현을 막을 때만 review stub의 `사용자 리뷰 요청`을 채우고 중단한다. 직접 사용자 질문, 선택지 제시, `request_user_input`, `USER_REVIEW.md` 작성, 로그 archive, `complete.log` 작성은 금지한다. 환경·서비스·증거 공백은 사용자 리뷰 요청이 아니다.

## 배경

두 provider reasoning alias 변환과 기능 코드는 복구됐지만 새 회귀 테스트가 `start`와 `complete`를 필터링해 필수 이벤트 순서를 검증하지 못한다. 또한 이전 검증 출력은 리뷰 시작 시점의 unused import와 `gofmt` 드리프트가 있는 소스와 일치하지 않았다. 리뷰어가 비동작성 import/format 드리프트는 정리했으므로 남은 assertion과 검증 신뢰만 복구한다.

## 사용자 리뷰 요청 흐름

구현 중 결정 차단은 active review stub의 `사용자 리뷰 요청` 섹션에만 기록한다. 직접 사용자 질문은 금지하며, `USER_REVIEW.md` 생성 여부는 code-review가 판단한다.

## Archive Evidence Snapshot

- 이전 plan: `agent-task/m-agent-readable-repository-refactor/05_http_provider_adapters/plan_cloud_G07_1.log`
- 이전 review: `agent-task/m-agent-readable-repository-refactor/05_http_provider_adapters/code_review_cloud_G07_1.log`
- 선행 원본 루프: `agent-task/m-agent-readable-repository-refactor/05_http_provider_adapters/plan_local_G07_0.log`, `agent-task/m-agent-readable-repository-refactor/05_http_provider_adapters/code_review_local_G07_0.log`
- 판정: FAIL; Required 2건, Suggested/Nit 없음. reasoning 테스트의 전체 이벤트 순서 누락과 검증 출력 불일치가 차단 항목이다.
- 영향 파일: `apps/node/internal/adapters/vllm/vllm_test.go`. 리뷰어가 stale import 제거와 `vllm_test.go`/`vllm_tunnel_test.go` `gofmt`는 직접 정리했다.
- 검증 근거: 리뷰 시작 시 대상 package test는 unused import로 실패했고 `gofmt -d`는 diff를 출력했다. 리뷰어 정리 후 `GOCACHE=/tmp/iop-go-cache go test -count=1 ./apps/node/internal/adapters/openai_compat ./apps/node/internal/adapters/vllm`는 통과했다. 전체 Node test/readability 재실행은 병렬 `06_cli_adapter`의 in-progress 파일 때문에 차단됐으며 이 task의 finding으로 분류하지 않았다.
- fake vLLM full-cycle의 HTTP 400은 최신 review log에 request가 raw provider tunnel로 전달되지만 fixture가 non-streaming 요청에도 `stream=true`를 요구한다는 blocker evidence로 보존돼 있다. 이번 test-only 후속에서 Edge/script/runtime 코드는 변경하지 않는다.
- 추가 확인이 필요할 때만 위 네 `.log`를 좁게 읽는다. `agent-task/archive/**`를 탐색하지 않는다.

## 분석 결과

### 읽은 파일

- `apps/node/internal/adapters/vllm/vllm_test.go`
- `apps/node/internal/adapters/vllm/vllm_tunnel_test.go`
- `apps/node/internal/adapters/vllm/stream.go`
- `apps/node/internal/adapters/vllm/vllm.go`
- `apps/node/internal/adapters/vllm/request.go`
- `apps/node/internal/adapters/openai_compat/stream.go`
- `apps/node/internal/adapters/openai_compat/execute_test.go`
- `apps/node/internal/adapters/openai_compat/provider_tunnel.go`
- `scripts/e2e-openai-vllm.sh`
- `agent-ops/rules/project/domain/node/rules.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/node-smoke.md`
- `agent-test/local/testing-smoke.md`
- `agent-test/local/edge-smoke.md`
- `agent-ops/skills/project/e2e-smoke/SKILL.md`
- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md`
- Archive Evidence Snapshot의 plan/review log 네 개

### SDD 기준

선택 Milestone은 `SDD: 불필요`이다. 외부 API/proto/config schema나 runtime 책임 경계를 바꾸지 않는 동일 package 동작 보존형 분해라는 기록을 유지한다.

### 테스트 환경 규칙

`test_env=local`; `agent-test/local/rules.md`, node/testing/edge smoke profile을 읽었다. fresh package test와 `go test ./apps/node/...`, `gofmt`, readability ratchet을 적용한다. 현재 shared dirty checkout의 전체 Node test/readability는 병렬 `06_cli_adapter` 파일로 차단됐으므로 구현자는 그 파일을 수정하지 않고 고정 명령을 재실행해 실제 성공 또는 동일한 외부 차단 출력을 기록한다. 이전 fake vLLM full-cycle blocker는 최신 review log의 실제 출력과 script source로 교차 확인됐고, 이번 후속은 runtime 동작을 바꾸지 않으므로 재실행하지 않는다.

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

- `reasoning_content` 우선과 `reasoning` fallback의 delta 값은 검증된다.
- 두 case 모두 `start → reasoning_delta → delta → complete` 전체 이벤트 수와 순서는 검증되지 않는다.
- OpenAI-compatible model fallback과 vLLM typed tools request body는 기존 추가 테스트로 검증된다.

### 심볼 참조

새로 이름을 바꾸거나 제거하는 심볼은 없다. `TestVllmExecuteStreamsReasoningDeltas` 내부 assertion만 보완한다.

### 분할 판단

기존 split subtask `05_http_provider_adapters`의 두 번째 follow-up이다. 한 테스트 함수와 그 검증 증거가 같은 package 안의 단일 review unit이므로 새 sibling이나 추가 dependency를 만들면 조정 비용만 늘어난다.

### 범위 결정 근거

`apps/node/internal/adapters/vllm/vllm_test.go`와 active review evidence만 수정한다. production adapter, Edge, E2E script, 병렬 `06_cli_adapter` 파일, roadmap은 수정하지 않는다.

### 빌드 등급

`local-G05`: 기대 이벤트 배열과 검증 명령이 명시적이며 한 package test에서 결정적으로 확인할 수 있다. 이전 full-cycle 400은 이미 원인과 소유 범위가 분리된 carryover evidence다.

## 구현 체크리스트

- [ ] `TestVllmExecuteStreamsReasoningDeltas`가 두 alias case의 start/reasoning/content/complete 전체 이벤트 순서를 직접 검증하도록 보완한다.
- [ ] fresh 대상 package·전체 Node·readability·format/diff 검증을 실행하고 실제 stdout/stderr를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REVIEW_REFACTOR_ADAPTER_HTTP-1] reasoning 전체 이벤트 순서 검증

문제: `apps/node/internal/adapters/vllm/vllm_test.go:443`은 `start`와 `complete`를 제거한 뒤 delta 둘만 비교해 전체 순서 회귀를 잡지 못한다.

해결 방법:

```go
// before: vllm_test.go:443
var filtered []runtime.RuntimeEvent
for _, e := range sink.all() {
	if e.Type != runtime.EventTypeStart && e.Type != runtime.EventTypeComplete {
		filtered = append(filtered, e)
	}
}

// after
events := sink.all()
// start, expected reasoning delta, content delta, complete를 순서대로 검증한다.
```

수정 파일 및 체크리스트:

- [ ] `apps/node/internal/adapters/vllm/vllm_test.go`: 각 table case의 기대값에 start/complete를 포함하거나 네 이벤트를 명시적으로 assertion한다.
- [ ] 두 case 모두 event count가 정확히 4인지 확인하고 reasoning/content delta 값과 순서를 유지한다.

테스트 작성: 기존 `TestVllmExecuteStreamsReasoningDeltas`를 보강한다. 별도 fixture나 새 테스트 함수는 필요 없다.

중간 검증: `GOCACHE=/tmp/iop-go-cache go test -count=1 ./apps/node/internal/adapters/vllm -run '^TestVllmExecuteStreamsReasoningDeltas$'`가 통과해야 한다.

### [REVIEW_REVIEW_REFACTOR_ADAPTER_HTTP-2] 검증 신뢰 재수집

문제: `code_review_cloud_G07_1.log:167`의 `gofmt`/Node test 성공 출력은 리뷰 시작 소스와 일치하지 않았다.

해결 방법: 항목 1 완료 후 고정 명령을 fresh 실행하고 review stub에 실제 stdout/stderr를 붙인다. 병렬 sibling 파일이 전체 Node/readability를 계속 차단하면 명령, 정확한 파일/에러, 이 task에서 수정하지 않은 이유를 그대로 기록한다.

수정 파일 및 체크리스트:

- [ ] production Go 파일은 변경하지 않는다.
- [ ] `CODE_REVIEW-local-G05.md`: 실행한 모든 명령의 실제 출력과 sibling blocker 여부를 기록한다.

테스트 작성: skip. 이 항목은 기존 검증 명령의 신뢰 회복이다.

중간 검증: `GOCACHE=/tmp/iop-go-cache go test -count=1 ./apps/node/internal/adapters/openai_compat ./apps/node/internal/adapters/vllm`가 통과해야 한다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `apps/node/internal/adapters/vllm/vllm_test.go` | REVIEW_REVIEW_REFACTOR_ADAPTER_HTTP-1 |
| `agent-task/m-agent-readable-repository-refactor/05_http_provider_adapters/CODE_REVIEW-local-G05.md` | REVIEW_REVIEW_REFACTOR_ADAPTER_HTTP-2 |

## 최종 검증

```bash
gofmt -d apps/node/internal/adapters/vllm/vllm_test.go apps/node/internal/adapters/vllm/vllm_tunnel_test.go
GOCACHE=/tmp/iop-go-cache go test -count=1 ./apps/node/internal/adapters/openai_compat ./apps/node/internal/adapters/vllm
GOCACHE=/tmp/iop-go-cache go test -count=1 ./apps/node/...
make readability-audit
git diff --check -- apps/node/internal/adapters/openai_compat apps/node/internal/adapters/vllm agent-task/m-agent-readable-repository-refactor/05_http_provider_adapters
```

모두 종료 코드 0이어야 한다. 병렬 sibling의 in-progress 파일이 전체 Node/readability를 차단하면 실제 출력과 소유 범위를 review stub에 남기고 해당 파일은 수정하지 않는다.

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