<!-- task=m-agent-readable-repository-refactor/02+01_openai_responses_workspace plan=2 tag=REVIEW_REVIEW_TEST -->

# Chat validation 테스트 책임 분류 복구

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

> 잘못 분류된 Chat request-field/think-control 테스트 4개만 본문 변경 없이 `server_test.go`로 복원한다. 구현 후 고정 검증을 실행하고 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션에 실제 메모와 stdout/stderr를 채운 뒤 active 파일을 유지한 채 리뷰 준비 완료를 보고한다. 종결 판정, log rename, `complete.log`, archive 이동은 code-review 전용이다. 선택된 Milestone의 미해결 `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 review stub의 `사용자 리뷰 요청`에 정확한 연결 근거를 기록한다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하거나 `USER_REVIEW.md`/`complete.log`를 만들거나 archive를 수행하지 않는다. 환경·secret·service 차단, 일반 범위 조정, 후속 에이전트가 보완할 수 있는 증거 공백은 사용자 리뷰 사유가 아니다.

## 배경

이전 후속 구현은 원래 대상 47개 테스트의 이름·본문과 top-level Test 226개를 보존했지만, Chat request-field/think-control validation 4개를 metadata/workspace 또는 cancellation/routes 책임 파일에 배치했다. active plan이 명시한 책임 경계를 맞추기 위해 네 선언만 `server_test.go`로 복원한다.

## 사용자 리뷰 요청 흐름

사용자 리뷰 요청은 선택된 Milestone의 구현 잠금 결정만 active review stub의 `사용자 리뷰 요청` 섹션에 기록하며, `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식을 따른다. 구현 중 직접 사용자 prompt는 금지하고, 요청 타당성 검증과 실제 `USER_REVIEW.md` 작성은 code-review가 소유한다.

## Archive Evidence Snapshot

- Prior task: `agent-task/m-agent-readable-repository-refactor/02+01_openai_responses_workspace`
- Archived plan: `agent-task/m-agent-readable-repository-refactor/02+01_openai_responses_workspace/plan_local_G07_1.log`
- Archived review: `agent-task/m-agent-readable-repository-refactor/02+01_openai_responses_workspace/code_review_local_G07_1.log`
- Verdict: `FAIL`
- Findings: Required 1, Suggested 0, Nit 0. `workspace_metadata_test.go`의 unsupported/think-control 3개와 `cancellation_routes_test.go`의 `num_ctx` validation 1개가 plan의 책임 경계를 위반했다.
- Affected files: `apps/edge/internal/openai/server_test.go`, `apps/edge/internal/openai/workspace_metadata_test.go`, `apps/edge/internal/openai/cancellation_routes_test.go`
- Verification evidence: 이동된 Test 47개의 이름 집합과 함수 본문은 HEAD 원본과 일치했고, `GOCACHE=/tmp/iop-go-build-cache go test -count=1 ./apps/edge/internal/openai`는 `ok`(6.728s), top-level Test는 226개였으며 고정 anchor 명령과 `git diff --check`도 통과했다.
- Roadmap carryover: 없음. 이 split은 Milestone `[openai-tests]` 전체 완료를 단독으로 주장하지 않는다.
- Narrow reread allowed when exact prior wording is needed: 위 archived plan/review 두 파일만 읽는다. `agent-task/archive/**`를 광범위하게 탐색하지 않는다.

## 분석 결과

### SDD 기준

선택 Milestone은 `SDD: 불필요`다. 외부 API/proto/config schema와 runtime 동작을 바꾸지 않고 테스트 선언 위치만 복구한다.

### 테스트 환경 규칙

`test_env=local`이다. 변경 package의 fresh `go test`, top-level Test 226개, 포맷과 책임 anchor를 고정 검증으로 사용한다. 생산 경로를 바꾸지 않으므로 추가 smoke/full-cycle은 적용하지 않는다.

### 범위 결정 근거

다음 네 선언만 본문 변경 없이 `server_test.go`로 복원한다.

- `TestChatCompletionsRejectsUnsupportedFields`
- `TestChatCompletionsAcceptsThinkControlFields`
- `TestChatCompletionsRejectsInvalidThinkControlFields`
- `TestChatCompletionsRejectsNumCtxOptionsWrapper`

Responses handler, metadata/workspace, cancel/timeout/route catalog 테스트와 provider-pool/tool/log 후반부는 수정하지 않는다.

### 빌드 등급

`local-G03`: 동작 판단이 필요 없는 네 함수 위치 복구와 고정 package 검증으로 종결되는 bounded mechanical follow-up이다.

## 구현 체크리스트

- [x] [REVIEW_REVIEW_TEST-1] 잘못 분류된 Chat request-field/think-control `Test*` 4개를 본문 변경 없이 `server_test.go`로 복원하고 책임 파일과 top-level Test 226개를 보존한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REVIEW_TEST-1] Chat validation 테스트 책임 복구

- 문제: Chat request-field/think-control validation 4개가 metadata/workspace 또는 cancellation/routes 파일에 있어 파일명이 실제 책임을 설명하지 못한다.
- 해결 방법:

~~~text
Before
workspace_metadata_test.go    unsupported fields + think-control 3개
cancellation_routes_test.go   num_ctx options wrapper validation 1개

After
server_test.go                위 Chat validation 4개
책임 파일                    plan이 정의한 metadata/workspace, cancel/timeout/route 테스트만 유지
~~~

- 수정 파일 및 체크리스트:
  - [x] `apps/edge/internal/openai/server_test.go`: 네 `Test*` 선언을 본문·assertion 변경 없이 복원한다.
  - [x] `apps/edge/internal/openai/workspace_metadata_test.go`: unsupported/think-control 선언 3개를 제거하고 metadata/workspace 테스트만 남긴다.
  - [x] `apps/edge/internal/openai/cancellation_routes_test.go`: `TestChatCompletionsRejectsNumCtxOptionsWrapper`를 제거하고 cancel/timeout/route 테스트만 남긴다.
- 테스트 작성: 추가하지 않는다. 기존 함수 본문과 226개 테스트 집합을 보존한다.
- 중간 검증:

~~~bash
rg --sort path -n '^func Test(ChatCompletionsRejectsUnsupportedFields|ChatCompletionsAcceptsThinkControlFields|ChatCompletionsRejectsInvalidThinkControlFields|ChatCompletionsRejectsNumCtxOptionsWrapper)' apps/edge/internal/openai/server_test.go
! rg -n '^func Test(ChatCompletionsRejectsUnsupportedFields|ChatCompletionsAcceptsThinkControlFields|ChatCompletionsRejectsInvalidThinkControlFields)' apps/edge/internal/openai/workspace_metadata_test.go
! rg -n '^func TestChatCompletionsRejectsNumCtxOptionsWrapper' apps/edge/internal/openai/cancellation_routes_test.go
~~~

기대 결과: 네 선언이 `server_test.go`에만 존재하고 책임 파일에는 남지 않음.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `apps/edge/internal/openai/server_test.go` | REVIEW_REVIEW_TEST-1 |
| `apps/edge/internal/openai/workspace_metadata_test.go` | REVIEW_REVIEW_TEST-1 |
| `apps/edge/internal/openai/cancellation_routes_test.go` | REVIEW_REVIEW_TEST-1 |

## 최종 검증

~~~bash
gofmt -w apps/edge/internal/openai/server_test.go apps/edge/internal/openai/workspace_metadata_test.go apps/edge/internal/openai/cancellation_routes_test.go
test -z "$(gofmt -l apps/edge/internal/openai/server_test.go apps/edge/internal/openai/responses_handler_test.go apps/edge/internal/openai/workspace_metadata_test.go apps/edge/internal/openai/cancellation_routes_test.go)"
GOCACHE=/tmp/iop-go-build-cache go test -count=1 ./apps/edge/internal/openai
test "$(GOCACHE=/tmp/iop-go-build-cache go test -list '^Test' ./apps/edge/internal/openai | sed '/^ok[[:space:]]/d' | wc -l)" -eq 226
rg --sort path -n '^func Test(ChatCompletionsRejectsUnsupportedFields|ChatCompletionsAcceptsThinkControlFields|ChatCompletionsRejectsInvalidThinkControlFields|ChatCompletionsRejectsNumCtxOptionsWrapper)' apps/edge/internal/openai/server_test.go
! rg -n '^func Test(ChatCompletionsRejectsUnsupportedFields|ChatCompletionsAcceptsThinkControlFields|ChatCompletionsRejectsInvalidThinkControlFields)' apps/edge/internal/openai/workspace_metadata_test.go
! rg -n '^func TestChatCompletionsRejectsNumCtxOptionsWrapper' apps/edge/internal/openai/cancellation_routes_test.go
rg --sort path -n '^func Test(ResponsesDispatchesNonStreamingRequest|ChatCompletionsMetadataContractAndWorkspace|CollectRunResultTimesOut|ModelsExposesCatalogRouteModels|ChatCompletionsProviderPoolOllamaSelectionUsesNormalizedRun|ChatCompletionsRetriesUnknownTextToolCallBeforeResponse|ResponsesMetadataIncludesTypedEstimateAndClassification|ChatCompletionsAssembledLogs)' apps/edge/internal/openai
git diff --check
~~~

기대 결과: 포맷 정상, fresh package test PASS, top-level Test 226개, Chat validation 4개는 `server_test.go`에만 존재, 기존 책임 anchor와 복원된 provider-pool/tool/log anchor는 계속 존재.

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