# Milestone: Control Plane-Edge Wire Baseline

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/control-plane-portal-ops/PHASE.md`
- Archive: `agent-roadmap/archive/phase/control-plane-portal-ops/milestones/control-plane-edge-wire-baseline.md`

## 목표

Control Plane과 Edge가 proto-socket 기반 IOP Wire Protocol로 연결되는 최소 통신 레일을 구축한다.
이 Milestone이 끝나면 Control Plane은 연결된 Edge를 식별하고, 상태 snapshot과 lifecycle event를 Edge-owned operation 경계를 통해 관찰할 수 있어야 한다.

## 상태

[완료]

## 구현 잠금

- 상태: 해제
- 결정 필요: 없음

## 범위

- Control Plane-Edge proto-socket TCP wire endpoint와 Edge outbound connector
- Edge hello/enrollment, heartbeat, reconnect, disconnect lifecycle
- Control Plane의 connected Edge in-memory registry
- Edge 상태 snapshot 요청/응답의 최소 계약
- Edge node lifecycle event relay의 최소 골격
- Control Plane-Edge 설정값과 local smoke 검증 기준

## 기능

### Epic: [wire-contract] Wire Contract

Control Plane-Edge 연결에서 공유할 protobuf 메시지와 transport 경계를 정의한다.

- [x] [edge-hello] Edge hello/enrollment protobuf 계약은 `edge_id`, `edge_name`, version, capabilities를 포함한다. 실제 Edge outbound 송신은 `[edge-outbound]`에서 다룬다. 검증: proto roundtrip 또는 wire handshake 테스트가 통과한다.
- [x] [wire-protocol] Control Plane-Edge 통신은 proto-socket TCP 기반 IOP native protocol로 정의되고, HTTP는 health/readiness/bootstrap 보조 표면에 남는다.
- [x] [no-node-direct] Control Plane-Edge 계약은 Node 직접 연결이나 직접 스케줄링 계약을 만들지 않는다.

### Epic: [edge-connector] Edge Connector

Edge가 Control Plane에 outbound로 붙고 연결 상태를 안정적으로 유지한다.

- [x] [edge-outbound] Edge는 설정된 Control Plane wire endpoint로 outbound 연결을 시작할 수 있다. 검증: 로컬 Control Plane과 Edge를 함께 띄웠을 때 hello가 성공한다.
- [x] [heartbeat] Control Plane과 Edge는 heartbeat 또는 동등한 keepalive로 연결 생존 상태를 판단할 수 있다.
- [x] [disconnect] Edge 종료, transport close, reconnect 시 Control Plane registry의 Edge 상태가 갱신된다.

### Epic: [cp-edge-registry] Control Plane Edge Registry

Control Plane은 연결된 Edge를 제품 운영 표면에서 소비할 수 있는 상태로 보관한다.

- [x] [edge-registry] Control Plane은 연결된 Edge의 id, name, protocol, connected state, last seen time을 in-memory registry로 조회할 수 있다.
- [x] [edge-status] Control Plane은 Edge에 상태 snapshot을 요청하고 Edge-owned 상태를 응답받을 수 있다. 검증: 최소 status request/response 테스트가 통과한다.
- [x] [event-relay] Edge의 node lifecycle event가 Control Plane까지 relay되는 최소 경로가 있다.

### Epic: [operation-boundary] Operation Boundary

Control Plane wire handler가 Edge 내부 구현을 복제하지 않고 Edge-owned operation을 소비하도록 정리한다.

- [x] [service-boundary] Edge wire handler는 node registry, run dispatch, command request 로직을 복제하지 않고 `apps/edge/internal/service`와 `events.Bus` 같은 표면 중립 경계를 사용한다.
- [x] [local-smoke] Control Plane-Edge wire baseline을 확인하는 local smoke 기준이 `agent-test/local` 또는 관련 README에 정리된다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-05-30
- 완료 근거: 모든 기능 Task가 완료 근거를 갖춘 것으로 확인되었다. `04_status_snapshot` PASS 완료 로그는 `edge-status`와 status request/response 검증을 기록했고, `05+04_event_relay_boundary` PASS 완료 로그는 `event-relay`와 `service-boundary` 검증 및 boundary search 통과를 기록했다. `03+01,02_local_smoke` PASS 완료 로그는 Control Plane-Edge wire smoke 기준을 기록했다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 2026-05-30 사용자 요청으로 Milestone 종료와 archive 이동을 승인했다.

## 범위 제외

- Control Plane을 Kubernetes식 중앙 스케줄러로 만드는 작업
- Control Plane에서 Node를 직접 연결하거나 직접 스케줄링하는 작업
- Edge 내부 DB나 Node registry 원본을 Control Plane DB로 대체하는 작업
- Flutter client 운영 화면 구현
- 정책, 권한, 감사 로그의 durable model
- Multi-Edge fleet-level routing 또는 federation

## 작업 컨텍스트

- 관련 경로: `proto/iop`, `apps/control-plane/internal/wire`, `apps/control-plane/cmd/control-plane`, `apps/edge/internal/bootstrap`, `apps/edge/internal/service`, `apps/edge/internal/events`, `packages/config`, `configs/control-plane.yaml`, `configs/edge.yaml`, `agent-test/local/control-plane-smoke.md`, `agent-test/local/edge-smoke.md`
- 표준선(선택): Control Plane-Edge 통신은 proto-socket TCP 기반 IOP native protocol을 우선하고, 브라우저/앱 경계가 아니면 WebSocket을 기본 transport로 삼지 않는다.
- 표준선(선택): Edge가 소유한 node registry와 runtime state를 Control Plane이 복제하지 않고, Edge operation boundary를 통해 관찰/제어한다.
- 표준선(선택): Control Plane은 Node 직접 연결/직접 스케줄링 경로를 만들지 않는다.
- 진행 근거(2026-05-30): `proto/iop/control.proto`에 `EdgeHelloRequest`/`EdgeHelloResponse`를 추가하고 `make proto`, `make proto-dart`로 Go/Dart 생성물을 갱신했다. `apps/control-plane/internal/wire`에 Edge hello parser와 roundtrip/transport-boundary 테스트를 추가했으며 `go test ./apps/control-plane/... ./packages/... ./proto/gen/...`, `go test ./...`, `flutter test`가 통과했다.
- 진행 근거(2026-05-30): `agent-task/archive/2026/05/m-control-plane-edge-wire-baseline/02+01_edge_connector/complete.log` 기준 Edge `control_plane` 설정/default/template, outbound hello, heartbeat, disconnect, reconnect, runtime wiring이 PASS 완료되었다. `go test -count=1 ./apps/edge/internal/controlplane`, `go test -race -count=1 ./apps/edge/internal/controlplane` 계열 검증이 통과했다.
- 진행 근거(2026-05-30): `agent-task/archive/2026/05/m-control-plane-edge-wire-baseline/03+01,02_local_smoke/complete.log` 기준 `make test-control-plane-edge-wire`가 local Control Plane과 Edge를 함께 띄워 `edge hello accepted`, `connected to control plane`, `edge disconnected`를 확인했다.
- 진행 근거(2026-05-30): Control Plane HTTP `/edges`와 `/edges/{edge_id}`에서 Edge registry snapshot을 조회하도록 했고, `go test -count=1 ./apps/control-plane/...`, registry/HTTP focused tests, `make test-control-plane-edge-wire`가 통과했다.
- 진행 근거(2026-05-30): `agent-test/local/control-plane-smoke.md`에 Control Plane-Edge TCP wire baseline의 `make test-control-plane-edge-wire` 실행 기준과 hello/connect/disconnect marker 판정 기준을 정리했다.
- 선행 작업: Edge Command와 Control Plane 운영 경계
- 후속 작업: Control Plane과 Client, 정책, 이력, 감사, Multi-Edge 운영
- 확인 필요: 없음
