<!-- task=m-provider-catalog-device-status/03_catalog_status_http plan=1 tag=REVIEW_API -->

# PLAN REVIEW_API - Preserve Zero Load Ratio In Status JSON

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

이 follow-up plan은 직전 코드리뷰의 Required 1건만 해결한다. 구현은 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션 작성까지 끝나야 완료다. 코드 변경 후 검증 명령을 실행하고 실제 stdout/stderr를 review stub에 붙인 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다.

구현 중 선택된 SDD 결정 또는 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 막으면 review stub의 `사용자 리뷰 요청` 섹션에 연결 대상, 차단 근거, 실행한 명령, 재개 조건을 기록하고 멈춘다. 직접 사용자에게 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 환경, secret, service 준비, 일반 범위 변경, 증거 공백은 사용자 리뷰 요청이 아니라 검증 결과 또는 후속 plan 대상으로 기록한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/operational-observability-provider-management/milestones/provider-catalog-device-status.md`
- Task ids:
  - `device-status`: provider health, capacity, in-flight, derived load ratio, served models, queued 상태가 catalog/status 표면에 정리된다.
- Completion mode: check-on-pass

## Spec Targets

- SDD: `agent-roadmap/sdd/operational-observability-provider-management/provider-catalog-device-status/SDD.md`
- Acceptance scenarios:
  - `S07`: task=`device-status`; evidence=`Control Plane HTTP status JSON exposes provider health, capacity, in_flight, derived load_ratio, served_models, queued without runtime/resource telemetry.`
- Completion mode: spec-check-on-pass

## Archive Evidence Snapshot

- Archived plan: `agent-task/m-provider-catalog-device-status/03_catalog_status_http/plan_local_G04_0.log`
- Archived review: `agent-task/m-provider-catalog-device-status/03_catalog_status_http/code_review_local_G04_0.log`
- Verdict: FAIL
- Required summary:
  - `apps/control-plane/cmd/control-plane/http_views.go:158` uses `json:"load_ratio,omitempty"`, so a valid idle provider with `load_ratio=0` omits the required status field from `/edges/{id}/status` JSON.
  - `apps/control-plane/cmd/control-plane/main_test.go:638` already has a second provider fixture with implicit zero load ratio, but raw JSON assertions do not verify that `load_ratio` is present and equals `0`.
- Affected files:
  - `apps/control-plane/cmd/control-plane/http_views.go`
  - `apps/control-plane/cmd/control-plane/main_test.go`
- Prior verification evidence:
  - Implementer recorded `go test ./apps/control-plane/cmd/control-plane -run TestEdgeRegistryHTTPHandlersGetLiveStatus -count=1`, `go test ./apps/control-plane/... -count=1`, and `git diff --check` as passing.
  - Review rerun confirmed `go test ./apps/control-plane/cmd/control-plane -run TestEdgeRegistryHTTPHandlersGetLiveStatus -count=1`, `go test ./apps/control-plane/... -count=1`, and `git diff --check` pass before this follow-up.
- Carryover:
  - Roadmap Targets and Spec Targets remain unchanged.
  - This follow-up still works toward SDD `S07` and Milestone task `device-status`.
- Narrow archive reread allowed if needed:
  - `agent-task/m-provider-catalog-device-status/03_catalog_status_http/plan_local_G04_0.log`
  - `agent-task/m-provider-catalog-device-status/03_catalog_status_http/code_review_local_G04_0.log`

## 분석 결과

### 빌드 등급

- lane/grade: `local-G03`.
- 근거: 단일 JSON tag 조정과 기존 HTTP handler test assertion 보강이다. 로컬 Go test와 `git diff --check`로 결정적으로 검증 가능하다.

### 범위 결정 근거

- 포함: `LoadRatio` zero value가 Control Plane HTTP JSON에서 보존되도록 DTO tag를 수정한다.
- 포함: 기존 status handler success fixture의 second provider를 사용해 raw JSON에 `load_ratio: 0`이 존재하는지 확인한다.
- 제외: provider queue/status 계산, proto 원본/생성물, Client DTO/UI, Edge CLI 표시. 이번 Required와 직접 관련이 없다.

## 구현 체크리스트

- [ ] `apps/control-plane/cmd/control-plane/http_views.go`에서 `providerSnapshotView.LoadRatio` JSON tag를 `json:"load_ratio"`로 바꿔 zero value도 직렬화한다.
- [ ] `apps/control-plane/cmd/control-plane/main_test.go`에서 second provider raw JSON assertion에 `load_ratio` key 존재 여부와 `float64(0)` 값을 추가한다.
- [ ] `go test ./apps/control-plane/cmd/control-plane -run TestEdgeRegistryHTTPHandlersGetLiveStatus -count=1`를 실행한다.
- [ ] `go test ./apps/control-plane/... -count=1`와 `git diff --check`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_API-1] Zero Load Ratio JSON 보존

#### 문제

`ProviderSnapshot.LoadRatio`의 `0`은 idle provider의 정상 상태값이다. 현재 Control Plane HTTP DTO는 `json:"load_ratio,omitempty"`를 사용해 `0`을 JSON에서 생략한다. 이러면 SDD `S07`이 요구한 derived `load_ratio` 노출이 idle provider에서 깨지고, Client는 `0`과 필드 없음/unknown을 구분할 수 없다.

#### 해결 방법

`LoadRatio` JSON tag에서 `omitempty`를 제거한다. 기존 테스트 fixture의 second provider는 `LoadRatio`를 명시하지 않아 zero value 케이스로 쓸 수 있으므로, raw JSON assertion에서 `rawP1["load_ratio"]`가 존재하고 `float64(0)`인지 검증한다.

#### 수정 파일 및 체크리스트

- [ ] `apps/control-plane/cmd/control-plane/http_views.go`: `LoadRatio float32  `json:"load_ratio"``
- [ ] `apps/control-plane/cmd/control-plane/main_test.go`: `rawP1` assertion에 `load_ratio` 존재/값 검증 추가.

#### 중간 검증

```bash
go test ./apps/control-plane/cmd/control-plane -run TestEdgeRegistryHTTPHandlersGetLiveStatus -count=1
```

기대 결과: status handler success/missing/upstream error subtest가 모두 통과하고, zero `load_ratio` raw JSON assertion도 통과한다.

## 최종 검증

```bash
go test ./apps/control-plane/... -count=1
git diff --check
```

기대 결과: Control Plane Go tests가 통과하고 공백 오류가 없다. Go test cache output은 허용하지 않는다.
