<!-- task=m-control-plane-client/01_control_plane_status_api plan=0 tag=CPSTATUS -->

# Control Plane Status API Plan

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

구현 후 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 반드시 실제 구현 내용, 검증 명령, 출력 요약으로 채운다. 검증을 실행하고 active 파일은 그대로 둔 채 리뷰 준비를 보고한다. 최종 판정, log rename, `complete.log` 작성은 code-review 스킬 책임이다. 사용자만 결정할 수 있는 blocker가 있으면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 결정, 증거, 재개 조건을 채우고 멈춘다.

## 배경

현재 Control Plane은 `/edges`, `/edges/{id}`, `/edges/{id}/events`로 연결과 이벤트를 보여주지만, Edge에 `EdgeStatusRequest`를 보내 받은 Node snapshot을 HTTP 운영 표면으로 전달하지 않는다. Client가 lifecycle 화면을 만들려면 Control Plane HTTP가 Edge-owned Node registry와 설정 요약을 직접 조회 가능한 JSON으로 제공해야 한다.

## 사용자 리뷰 요청 흐름

구현 중 사용자 결정이 필요한 blocker는 `CODE_REVIEW-cloud-G06.md`의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 정당성을 검증해 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/control-plane-portal-ops/milestones/control-plane-client.md`
- Task ids:
  - `node-registry`: Control Plane은 Edge가 보고하는 Node registry와 Node 연결 상태를 운영 표면에 전달할 수 있다.
  - `edge-node-config-view`: Control Plane/Client는 Edge/Node의 현재 운영 설정 요약을 조회 중심으로 보여준다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/control-plane-portal-ops/PHASE.md`
- `agent-roadmap/phase/control-plane-portal-ops/milestones/control-plane-client.md`
- `agent-ops/rules/project/domain/control-plane/rules.md`
- `agent-ops/rules/project/domain/client/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/control-plane-smoke.md`
- `apps/control-plane/cmd/control-plane/main.go`
- `apps/control-plane/cmd/control-plane/main_test.go`
- `apps/client/lib/main.dart`
- `apps/client/test/widget_test.dart`
- `apps/client/pubspec.yaml`
- `apps/client/lib/client_config.dart`
- `packages/flutter/iop_console/lib/src/iop_console_overview.dart`
- `packages/flutter/iop_console/lib/src/iop_console_shell.dart`
- `packages/flutter/iop_console/lib/src/iop_console_contract.dart`
- `packages/flutter/iop_console/test/iop_console_shell_test.dart`

### 테스트 환경 규칙

- `test_env`: local.
- `agent-test/local/rules.md`와 `agent-test/local/control-plane-smoke.md`를 읽었다.
- 적용 명령: `go test ./apps/control-plane/...`.
- Control Plane-Edge TCP wire 자체를 바꾸면 `make test-control-plane-edge-wire`도 실행한다. 이번 plan은 HTTP adapter surface 추가가 중심이므로 unit test를 기본 검증으로 둔다.

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

- Node registry HTTP 전달: 현재 `EdgeServer.RequestStatus` unit test는 있으나 HTTP handler가 이를 호출하지 않아 커버리지 없음.
- 설정 요약: `EdgeNodeSnapshot`이 가진 `config`를 JSON view로 요약하는 handler/test가 없음.
- 기존 커버리지: `/edges`, `/edges/{id}`, `/edges/{id}/events`, Edge status wire request helper, Node event relay tests는 존재한다.

### 심볼 참조

- renamed/removed symbols: none.
- 새 handler가 `wire.EdgeServer.RequestStatus`를 소비하면 기존 호출부는 테스트뿐이다.

### 분할 판단

- split decision policy를 먼저 평가했다.
- 공유 task group: `m-control-plane-client`.
- `01_control_plane_status_api`: Control Plane HTTP 상태 API foundation. 선행 의존성 없음.
- `02+01_client_lifecycle_ui`: Client UI/API consumer. `01_control_plane_status_api`의 JSON contract와 `complete.log`에 의존한다.
- API와 UI가 다른 도메인, 다른 테스트 전략, 다른 risk profile이므로 split한다.

### 범위 결정 근거

- `proto/iop/*.proto`는 변경하지 않는다. `EdgeStatusResponse`와 `EdgeNodeSnapshot`에 이미 필요한 snapshot/config 필드가 있다.
- `apps/edge/**`는 변경하지 않는다. Edge status provider는 이미 `EdgeStatusRequest`에 응답한다.
- durable history, audit, policy, command execution UX는 후속 Milestone 범위다.

### 빌드 등급

- lane/GNN: `cloud-G06`.
- 이유: Control Plane HTTP contract와 Edge wire helper를 연결하는 protocol-facing 작업이며, 후속 Client plan의 기반이 된다.

## 구현 체크리스트

- [ ] `apps/control-plane/cmd/control-plane/main.go`에서 registry-only handler와 live status requester를 분리해 `/edges/{edge_id}/status` 또는 동등한 조회 전용 path를 추가한다. `node-registry` 검증: Node 목록과 연결 상태가 Control Plane을 통해 조회된다.
- [ ] `EdgeStatusResponse.Nodes[].Config`를 JSON에 노출할 때 adapter names/count, runtime limits 같은 요약만 담고 secret/settings 원문을 그대로 풀어 쓰지 않는다. `edge-node-config-view` 검증: 설정 원본이나 effective config 요약이 조작 없이 표시된다.
- [ ] `apps/control-plane/cmd/control-plane/main_test.go`에 live status success, missing edge, upstream error/timeout, config summary JSON test를 추가한다.
- [ ] `go test ./apps/control-plane/...`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [CPSTATUS-1] HTTP Status Handler

문제: [main.go](/config/workspace/iop/apps/control-plane/cmd/control-plane/main.go:241)의 `registerEdgeRegistryHandlers`는 registry snapshot과 events만 제공하고 [main.go](/config/workspace/iop/apps/control-plane/cmd/control-plane/main.go:181)에서는 `EdgeServer`가 아니라 registry만 전달한다.

해결 방법: handler 입력을 `registry *wire.EdgeRegistry, requestStatus func(string, time.Duration) (*iop.EdgeStatusResponse, error)` 형태로 확장하거나 작은 interface를 둔다. `/edges/{edge_id}/status`에서 connected edge에 live request를 보내고 JSON view를 반환한다.

수정 파일 및 체크리스트:

- [ ] `apps/control-plane/cmd/control-plane/main.go`: status response/view type 추가.
- [ ] `apps/control-plane/cmd/control-plane/main.go`: route 분기 추가.
- [ ] `apps/control-plane/cmd/control-plane/main_test.go`: success/error tests 추가.

테스트 작성: 작성한다. `TestEdgeRegistryHTTPHandlersGetLiveStatus` 계열로 fake requester를 주입해 node list와 status code를 검증한다.

중간 검증: `go test ./apps/control-plane/cmd/control-plane -run 'TestEdgeRegistryHTTPHandlers'`.

### [CPSTATUS-2] Node Config Summary

문제: `EdgeNodeSnapshot.Config`는 proto message이고, 운영 화면에는 raw settings보다 안전한 요약이 필요하다.

해결 방법: `nodeConfigSummaryView`를 만들어 adapter name/type count, runtime concurrency/timeout 같은 비밀이 아닌 구조만 JSON으로 변환한다. unknown/empty config는 빈 요약으로 둔다.

수정 파일 및 체크리스트:

- [ ] `apps/control-plane/cmd/control-plane/main.go`: config summary helper 추가.
- [ ] `apps/control-plane/cmd/control-plane/main_test.go`: adapter/runtime summary assertion 추가.

테스트 작성: 작성한다. raw `settings` 값이 response에 노출되지 않는 assertion을 포함한다.

중간 검증: `go test ./apps/control-plane/cmd/control-plane -run 'Status|Config'`.

## 수정 파일 요약

| 파일 | 항목 |
| --- | --- |
| `apps/control-plane/cmd/control-plane/main.go` | CPSTATUS-1, CPSTATUS-2 |
| `apps/control-plane/cmd/control-plane/main_test.go` | CPSTATUS-1, CPSTATUS-2 |

## 최종 검증

```bash
go test ./apps/control-plane/...
```

예상 결과: control-plane command와 wire package tests가 모두 통과한다.

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