<!-- task=m-agent-readable-repository-refactor/10+07,08,09_adapter_control_plane_tests plan=0 tag=TEST -->

# Control Plane command 테스트 분해와 adapter-command 완료

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

> 구현 후 계획의 검증 명령을 그대로 실행하고 CODE_REVIEW의 구현 에이전트 소유 섹션에 실제 메모와 stdout/stderr를 채운 뒤 active 파일을 유지한 채 리뷰 준비 완료를 보고한다. 종결 판정, log rename, complete.log와 archive 이동은 code-review 전용이다. 선택된 Milestone의 미해결 구현 잠금 결정이 실제 구현을 차단할 때만 review stub의 사용자 리뷰 요청에 연결 근거를 기록하고 중단한다. 직접 사용자 질문, chat 선택지, request_user_input, USER_REVIEW.md/complete.log 작성은 금지한다. 환경·secret·service, 일반 범위 조정, 후속으로 보완 가능한 증거 공백은 사용자 리뷰 사유가 아니다.

## 배경

adapter-command-tests의 마지막 범위는 Control Plane main_test.go의 config, edge registry, fleet handler 테스트다. 세 선행 adapter/Edge command 분해가 끝난 뒤 이를 분리하고 전체 대상에서 사유 없는 1,000줄 초과가 남지 않았는지 확인한다.

## 사용자 리뷰 요청 흐름

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

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md)
- Task ids:
  - `adapter-command-tests`: adapter, CLI, Edge/Control Plane command와 config refresh 테스트를 실행 책임별 파일로 분해
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md
- agent-test/local/rules.md
- agent-test/local/profiles/control-plane-smoke.md
- agent-test/local/profiles/edge-smoke.md
- agent-test/local/profiles/node-smoke.md
- agent-spec/control/control-plane-operations.md
- apps/control-plane/cmd/control-plane/main_test.go

### SDD 기준

선택 Milestone은 SDD: 불필요다. 외부 API/proto/config schema와 runtime 책임 경계를 바꾸지 않는 동작 보존형 리팩터링이라는 기록 사유를 적용한다.

### 테스트 환경 규칙

test_env=local. local rules와 control-plane/edge/node smoke profile을 읽었다. 현재 checkout에서 adapter-command 대상 package가 모두 fresh PASS했고 Control Plane Test 목록은 24개다.

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

동작 변경은 없다. config credential redaction, registry HTTP, fleet concurrency/cache assertion을 그대로 이동한다. final command가 모든 선행 package도 재검증한다.

### 심볼 참조

운영 심볼의 rename/remove는 없다. 기존 테스트 이름과 package 경계를 유지한다.

### 분할 판단

이 디렉터리의 +07,08,09는 세 독립 predecessor의 complete.log를 모두 요구하며 현재 미충족이다. 이 plan만 adapter-command-tests Roadmap Target을 check-on-pass 한다.

### 범위 결정 근거

Control Plane main_test.go와 test-only support를 수정한다. server production code, DB/Redis integration, 외부 runtime은 제외한다.

### 빌드 등급

local-G07: 1,226줄 분해 자체는 명확하지만 세 선행 작업의 전체 package/LOC completion 검증을 소유한다.

## 구현 체크리스트

- [ ] [TEST-1] Control Plane config/registry/fleet 테스트를 분리하고 모든 adapter-command 대상 fresh test와 1,000줄 gate를 통과시킨다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [TEST-1] Control Plane config/registry/fleet 테스트 분리

- 문제: apps/control-plane/cmd/control-plane/main_test.go:23~1226에 config/env/log redaction, edge registry HTTP, fleet fanout/cache가 한 파일에 있다.
- 해결 방법:

~~~text
Before
main_test.go:23  func TestLoadConfigDatabaseDefaultsToLocal(...)
main_test.go:258 func TestEdgeRegistryHTTPHandlersListAndGetEdge(...)
main_test.go:864 func TestFleetStatusHTTPHandlerCombinesConnectionAndCapabilities(...)

After
main_test_support_test.go
config_test.go
edge_registry_handler_test.go
fleet_handler_test.go
~~~

- 수정 파일 및 체크리스트:
  - [ ] apps/control-plane/cmd/control-plane/main_test.go: 이동 후 삭제한다.
  - [ ] apps/control-plane/cmd/control-plane/main_test_support_test.go: registry/HTTP fixture를 둔다.
  - [ ] apps/control-plane/cmd/control-plane/config_test.go: config/env/log redaction을 둔다.
  - [ ] apps/control-plane/cmd/control-plane/edge_registry_handler_test.go: edge HTTP handler를 둔다.
  - [ ] apps/control-plane/cmd/control-plane/fleet_handler_test.go: fleet status/command/cache/concurrency를 둔다.
- 테스트 작성: 추가 테스트는 작성하지 않는다. 기존 Control Plane Test 24개와 모든 선행 Test 이름/assertion을 보존한다.
- 중간 검증:

~~~bash
gofmt -w apps/control-plane/cmd/control-plane/*_test.go
test ! -e apps/control-plane/cmd/control-plane/main_test.go
[ "$(GOCACHE=/tmp/iop-go-build-cache go test -list '^Test' ./apps/control-plane/cmd/control-plane | sed '/^ok[[:space:]]/d' | wc -l)" -eq 24 ]
~~~

기대 결과: 원본 삭제, gofmt 성공, Control Plane Test 24개.

## 의존 관계 및 구현 순서

1. agent-task/m-agent-readable-repository-refactor/07_adapter_openai_compat_tests/complete.log를 확인한다.
2. agent-task/m-agent-readable-repository-refactor/08_adapter_cli_tests/complete.log를 확인한다.
3. agent-task/m-agent-readable-repository-refactor/09_adapter_edge_command_tests/complete.log를 확인한다.
4. 디렉터리 이름에 없는 추가 predecessor는 요구하지 않는다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| apps/control-plane/cmd/control-plane/main_test.go | TEST-1 |
| apps/control-plane/cmd/control-plane/main_test_support_test.go | TEST-1 |
| apps/control-plane/cmd/control-plane/config_test.go | TEST-1 |
| apps/control-plane/cmd/control-plane/edge_registry_handler_test.go | TEST-1 |
| apps/control-plane/cmd/control-plane/fleet_handler_test.go | TEST-1 |

## 최종 검증

~~~bash
GOCACHE=/tmp/iop-go-build-cache go test -count=1 ./apps/node/internal/adapters/openai_compat ./apps/node/internal/adapters/cli ./apps/edge/cmd/edge ./apps/edge/internal/configrefresh ./apps/control-plane/cmd/control-plane
[ "$(GOCACHE=/tmp/iop-go-build-cache go test -list '^Test' ./apps/control-plane/cmd/control-plane | sed '/^ok[[:space:]]/d' | wc -l)" -eq 24 ]
python3 -c "from pathlib import Path; roots=[Path('apps/node/internal/adapters'),Path('apps/edge/cmd/edge'),Path('apps/edge/internal/configrefresh'),Path('apps/control-plane/cmd/control-plane')]; fs=sorted(f for r in roots for f in r.rglob('*_test.go')); bad=[(sum(1 for _ in f.open()),str(f)) for f in fs if sum(1 for _ in f.open())>1000]; print(bad); raise SystemExit(bool(bad))"
~~~

기대 결과: 다섯 package fresh test PASS, Control Plane Test 24개, 대상 전체에 1,000줄 초과 test 없음.

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

