<!-- task=07_node_command_ops_surface plan=1 tag=REVIEW_NCO -->

# Review Follow-up Plan - REVIEW_NCO

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

이 plan은 `code_review_cloud_G09_0.log`의 FAIL 후속 작업이다. 범위는 이미 추가된 NodeCommand ops surface가 실제 node/adapter 경로에서 동작하도록 연결하는 데 한정한다.

구현 완료 후 `agent-task/07_node_command_ops_surface/CODE_REVIEW-cloud-G09.md`의 모든 섹션을 실제 구현 내용과 명령 출력으로 채운다. 리뷰 아카이브는 구현 에이전트가 수행하지 않는다.

## 배경

이전 루프는 `NodeCommandType` enum, `NodeCommandResponse.result`, edge service typed method, opsconsole slash command, parser/unit test를 추가했다. 그러나 node runtime dispatch가 모든 새 command를 adapter `CommandHandler`에만 위임하면서 실제 기본 adapter에서는 command가 동작하지 않는다.

- `apps/node/internal/node/node.go`: `CAPABILITIES`, `SESSION_LIST`, `TRANSPORT_STATUS`까지 모두 `runtime.CommandHandler` 필요.
- `apps/node/internal/adapters/cli/cli.go`: `HandleCommand`가 `usage_status` 외 command를 모두 unsupported 처리.
- `mock`/`ollama`/`vllm`: `Adapter.Capabilities()`는 있지만 `CommandHandler`는 없다.

## 구현 항목

### [REVIEW_NCO-1] NodeCommand 실제 처리 경로 연결

#### 문제

`/capabilities`, `/sessions`, `/transport`가 edge/console 표면에는 존재하지만 실제 요청은 node에서 대부분 unsupported로 끝난다. 특히 capabilities는 이미 모든 adapter가 `Capabilities(ctx)`를 구현하는데도 `CommandHandler`가 없다는 이유로 실패한다.

#### 해결 방법

- `apps/node/internal/node/node.go`에서 command type별 처리 책임을 분리한다.
  - `CAPABILITIES`: `runtime.Adapter.Capabilities(ctx)`를 호출해 `NodeCommandResponse.result`로 변환한다. 최소 키는 `adapter`, `targets`, `max_concurrency`를 포함한다. `targets`는 deterministic하게 정렬/결합한다.
  - `TRANSPORT_STATUS`: adapter command가 아니라 node/transport 상태 조회로 처리한다. 요청이 도달한 `transport.Session` 기준으로 `node_id`, `connected`, `adapter`, `target`, `session_id` 같은 안정적인 key/value 결과를 반환한다.
  - `USAGE_STATUS`: 기존처럼 adapter `CommandHandler`로 위임한다.
  - `SESSION_LIST`: 실제 세션을 소유한 adapter가 처리한다. 우선 `cli` adapter에서 지원하고, 지원하지 않는 adapter는 명시적 unsupported error를 반환한다.
- `apps/node/internal/adapters/cli/cli.go`에서 `SESSION_LIST` command를 지원한다.
  - `sessions`, `codexSessions`, `opencodeSessions`를 lock 아래 snapshot으로 읽는다.
  - 출력은 `result` map으로 반환한다. 최소 키는 `count`, `sessions`를 포함하고, `sessions` 값은 deterministic한 정렬 문자열로 만든다.
  - 기존 `USAGE_STATUS` 동작은 유지한다.
- `apps/node/internal/node/node_test.go`와 `apps/node/internal/adapters/cli` 테스트를 보강한다.
  - `CAPABILITIES`가 `CommandHandler` 없는 adapter에서도 성공하는지 검증한다.
  - `TRANSPORT_STATUS`가 adapter handler 없이 node/transport 상태를 반환하는지 검증한다.
  - `cli` `SESSION_LIST`가 실제 session snapshot을 반환하는지 검증한다.
  - unsupported command 정책은 command별로 명확히 유지한다.
- 필요 시 `apps/edge/internal/opsconsole` 테스트를 보강해 empty/error 출력 정책이 실제 서비스 결과와 어긋나지 않는지 확인한다.

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

- [ ] `apps/node/internal/node/node.go` - command type별 dispatch 및 result mapper 추가
- [ ] `apps/node/internal/node/node_test.go` - capabilities/transport status real-path 테스트 추가
- [ ] `apps/node/internal/adapters/cli/cli.go` - session list command 구현
- [ ] `apps/node/internal/adapters/cli/*_test.go` - CLI session list 테스트 추가
- [ ] 필요한 경우 `apps/edge/internal/opsconsole/*_test.go` - rendering/error 정책 보강

#### 구현 체크리스트

- [ ] [REVIEW_NCO-1] `CAPABILITIES`가 `Adapter.Capabilities()` 기반 result를 반환한다.
- [ ] [REVIEW_NCO-1] `TRANSPORT_STATUS`가 node/transport 상태 result를 반환한다.
- [ ] [REVIEW_NCO-1] `cli` adapter가 `SESSION_LIST` result를 반환한다.
- [ ] [REVIEW_NCO-1] unsupported command/adapter 정책이 명시적 error로 유지된다.
- [ ] [REVIEW_NCO-1] 관련 node/cli/edge tests가 추가 또는 갱신된다.
- [ ] [REVIEW_NCO-1] `CODE_REVIEW-cloud-G09.md`의 모든 섹션과 검증 출력이 실제 결과로 채워진다.

#### 중간 검증

```bash
go test -count=1 ./apps/node/internal/node ./apps/node/internal/adapters/cli ./apps/edge/internal/service ./apps/edge/internal/opsconsole
```

기대 결과: 새 command real-path 테스트 포함 PASS.

## 리뷰어를 위한 체크포인트

- `/capabilities`가 `CommandHandler` 없는 adapter에서도 성공하는가.
- `/transport`가 adapter-specific unsupported로 떨어지지 않고 node/transport 상태를 반환하는가.
- `/sessions`가 `cli` adapter의 실제 session maps를 deterministic하게 보여주는가.
- unsupported 정책이 command type 미지정/미지원 adapter/미지원 command 각각에서 조용한 success가 아닌 명시적 error인가.
- README/opsconsole 출력 설명이 실제 command 동작과 일치하는가.

## 최종 검증

```bash
go test -count=1 ./apps/node/internal/runtime ./apps/node/internal/node ./apps/node/internal/adapters/cli ./apps/node/internal/transport ./apps/edge/internal/transport ./apps/edge/internal/service ./apps/edge/internal/opsconsole
go test -count=1 ./...
```

사용자 실행 파이프라인에 닿는 변경이므로 가능한 경우 mock 기반 edge/node smoke에서 `/capabilities`, `/transport`, `/sessions`를 한 번 통과시킨다. 실행하지 못하면 `CODE_REVIEW-cloud-G09.md`에 이유와 남은 위험을 명시한다.

## 완료 조건

- 새 node command가 문서화된 opsconsole surface에서 실제로 동작하거나, 미지원 adapter에서는 command별 명시적 unsupported를 반환한다.
- 새 테스트가 실패 케이스를 재현하고 수정 후 PASS한다.
- 대상 패키지 테스트와 전체 테스트가 PASS한다.
- `CODE_REVIEW-cloud-G09.md`에 실제 구현 내용과 검증 출력이 기록되어 있다.
