<!-- task=m-provider-catalog-device-status/04+03_client_catalog_view plan=2 tag=REVIEW_REVIEW_API -->

# PLAN REVIEW_REVIEW_API - Provider Availability State Follow-up

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

이 plan은 G04 리뷰의 FAIL 후속이다. 범위는 Client Provider Catalog 상태색이 실제 Control Plane JSON의 `available/unavailable/unknown` 값을 해석하도록 보완하고, 같은 값을 검증하는 test를 추가하는 것으로 제한한다. 구현이 끝나면 active `CODE_REVIEW-local-G03.md`의 구현 에이전트 소유 섹션까지 실제 출력으로 채운 뒤 멈춘다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review 전용이다.

구현 중 선택된 SDD 결정 또는 선택된 Milestone lock decision이 막으면 review stub의 `사용자 리뷰 요청` 섹션에만 기록한다. 직접 사용자에게 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/operational-observability-provider-management/milestones/provider-catalog-device-status.md`
- Task ids:
  - `ops-review`: Edge config와 Edge-owned read-only catalog/status를 기준으로 `iop-edge` CLI, Control Plane, Client가 어떤 정보를 소비하는지 확인할 수 있다.
- Completion mode: check-on-pass

## Spec Targets

- SDD: `agent-roadmap/sdd/operational-observability-provider-management/provider-catalog-device-status/SDD.md`
- Acceptance scenarios:
  - `S10`: task=`ops-review`; evidence=`Edge CLI configured-provider summary, Control Plane provider status JSON, Client Nodes panel provider catalog/status rendering, and resolved user_review_0.log are present.`
- Completion mode: spec-check-on-pass

## Archive Evidence Snapshot

- Archived plan: `agent-task/m-provider-catalog-device-status/04+03_client_catalog_view/plan_local_G04_1.log`
- Archived review: `agent-task/m-provider-catalog-device-status/04+03_client_catalog_view/code_review_local_G04_1.log`
- Earlier loop:
  - `agent-task/m-provider-catalog-device-status/04+03_client_catalog_view/plan_local_G05_0.log`
  - `agent-task/m-provider-catalog-device-status/04+03_client_catalog_view/code_review_local_G05_0.log`
- Verdict: FAIL
- Required summary:
  - `apps/client/lib/widgets/nodes_panel.dart:125` does not map actual Control Plane provider snapshot values `available` and `unavailable`; available/unavailable providers render neutral grey.
  - `apps/client/test/widget_test.dart:980` DTO/UI regression fixture covers `degraded/healthy` but not predecessor Control Plane JSON combinations such as `health=available`, `status=available`, `health=unavailable`, `status=backlog`.
- Affected files:
  - `apps/client/lib/widgets/nodes_panel.dart`
  - `apps/client/test/widget_test.dart`
  - `agent-task/m-provider-catalog-device-status/04+03_client_catalog_view/CODE_REVIEW-local-G03.md`
- Verification evidence from failed loop:
  - `cd apps/client && flutter test test/widget_test.dart` passed with `+14: All tests passed!`
  - `cd apps/client && flutter test` passed with `+30: All tests passed!`
  - `cd apps/client && flutter analyze --no-fatal-infos` exited 0 with existing info-level issues.
  - `git diff --check` passed with no output.
- Narrow archive reread allowed:
  - `agent-task/m-provider-catalog-device-status/04+03_client_catalog_view/code_review_local_G04_1.log`
- Roadmap/spec carryover:
  - Keep `Roadmap Targets` and `Spec Targets` above. This follow-up still works toward `ops-review` and S10 completion.

## 범위 결정 근거

- 포함: provider state color mapping, available/unavailable/unknown DTO/UI regression tests, active review evidence.
- 제외: Control Plane/Edge code changes. The predecessor JSON exposure already passed in `03_catalog_status_http`.
- 제외: runtime control or provider scheduling behavior.

## 구현 체크리스트

- [ ] `_stateColor` health branch에 `available` green, `unavailable` red, `unknown` neutral mapping을 추가한다.
- [ ] `_stateColor` status fallback에 `available` green, `unavailable` red, `unknown` neutral mapping을 추가하고 기존 `active/ready`, `error/failed`, `draining` 동작을 유지한다.
- [ ] widget/DTO test에 실제 Control Plane predecessor 값과 같은 `health=available/status=available` 및 `health=unavailable/status=backlog` provider fixture를 추가해 상태 텍스트와 색상 매핑을 검증한다.
- [ ] `cd apps/client && flutter test test/widget_test.dart`를 실행한다.
- [ ] `cd apps/client && flutter test`를 실행한다.
- [ ] `cd apps/client && flutter analyze --no-fatal-infos`를 실행하거나 생략 사유를 기록한다.
- [ ] `git diff --check`를 실행한다.
- [ ] CODE_REVIEW-local-G03.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

## 최종 검증

```bash
cd apps/client && flutter test test/widget_test.dart
cd apps/client && flutter test
cd apps/client && flutter analyze --no-fatal-infos
git diff --check
```

Client test 규칙상 원격 runner evidence가 필요한 환경이면 동기화된 runner에서 같은 명령을 실행한다. 현재 checkout에서만 실행했다면 active review의 검증 결과에 실행 host와 원격 미실행 사유를 명시한다.
