<!-- task=m-node-multi-target-serving-foundation/06+02,04_commands_caps plan=0 tag=API -->

# Code Review Reference - API

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> Fill implementation-owned sections and verification output, then report ready for review.
> Do not ask the user directly; record user-only blockers in `사용자 리뷰 요청`.

## 개요

date=2026-06-10
task=m-node-multi-target-serving-foundation/06+02,04_commands_caps, plan=0, tag=API

## Roadmap Targets

- Milestone: `agent-roadmap/phase/inference-provider-extension/milestones/node-multi-target-serving-foundation.md`
- Task ids:
  - `commands-caps`: `CAPABILITIES`, `SESSION_LIST`, `USAGE_STATUS`, provider passthrough command가 여러 adapter/profile/model target에서 모호하지 않은 결과를 반환한다.
- Completion mode: check-on-pass

## 이 파일을 읽는 리뷰 에이전트에게

> **[REVIEW AGENT ONLY]** 종결 절차는 코드리뷰 에이전트 전용이다.

command/capability 결과가 adapter instance와 target namespace를 잃지 않는지 확인한다.

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [API-1] Command Identity Contract | [x] |

## 구현 체크리스트

- [x] capabilities 응답이 adapter instance/profile/model target identity를 모호하지 않게 포함한다.
- [x] session/usage/provider command가 target namespace를 정확히 보존한다.
- [x] Edge service command DTO와 Node command handling 테스트를 갱신한다.
- [x] 최종 검증 명령을 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 코드리뷰 전용 체크리스트

- [x] `코드리뷰 결과`에 판정을 append한다.
- [x] 판정과 차원별 평가, Required 분류가 서로 일치한다.
- [x] active `CODE_REVIEW-local-G07.md`를 `code_review_local_G07_N.log`로 아카이브한다.
- [x] active `PLAN-local-G07.md`를 `plan_local_G07_M.log`로 아카이브한다.
- [x] `.gitignore`가 생성된 task `.md`/`.log` artifacts를 ignore하지 않는지 확인한다.
- [ ] PASS이면 `complete.log` 작성 후 archive 이동한다.
- [x] WARN/FAIL이면 후속 상태를 작성한다.

## 계획 대비 변경 사항

- `proto/iop/runtime.proto`: 변경 없음. 기존 proto가 `adapter`, `target`, `session_id`를 이미 충분히 보유하여 신규 필드 불필요.
- `apps/node/internal/runtime/types.go`: 변경 없음. `Capabilities.InstanceKey`, `CommandRequest/Response.Adapter/Target/SessionID`가 이미 존재.
- `apps/node/internal/node/node.go`: 변경 없음. `handleCapabilitiesCommand`, `toDomainCommandRequest`, `toProtoCommandResponse`가 이미 정확히 identity를 보존.
- `apps/node/internal/adapters/cli/cli.go`: 변경 없음. `handleSessionList`가 per-session `mode/target/session_id` 구조체를 이미 반환, `handleUsageStatus`가 adapter/target/session을 응답에 이미 보존.
- `apps/edge/internal/service/node_command.go`: `UsageStatusView`에 `Adapter` 필드 추가 + `UsageStatus()` 반환 시 `commandReq.GetAdapter()` 채움. (`NodeCommandView`는 이미 Adapter 있었으나 `UsageStatusView`만 누락).

## 주요 설계 결정

- **코드 변경 최소화**: G07/G08 이전 작업에서 capabilities/session/usage identity 처리가 이미 구현됨을 확인. 핵심 gap은 `UsageStatusView.Adapter` 누락뿐.
- **`UsageStatusView.Adapter` 추가**: `NodeCommandView`와 일관성을 맞추기 위해 추가. multi-adapter 환경에서 caller가 어느 어댑터의 usage 상태인지 명확히 알 수 있음.
- **`TestListNodeSnapshotsWithConfig` 버그 수정**: `Ollama` (legacy single-instance) 필드 대신 `OllamaInstances` 사용. `BuildConfigPayload` 주석("callers that bypass LoadEdge must populate OllamaInstances manually")과 일치.
- **신규 테스트 추가**:
  - `TestOnCommandRequest_MultiAdapterCapabilities` (node_test.go): 두 instance key 어댑터 등록 후 각각의 CAPABILITIES가 올바른 `instance_key`를 반환하는지 검증.
  - `TestUsageStatusPreservesAdapterIdentity` (service_test.go): pipe 기반 mock node로 `UsageStatusView.Adapter/Target/SessionID` identity 보존 검증.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._

- 상태: 없음
- 사유 유형: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음

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

- capabilities/session/usage가 동일 target 이름 충돌에서 모호하지 않다.
- Edge command DTO와 proto/runtime DTO가 같은 identity를 전달한다.
- long command 처리와 concurrency scheduling 범위가 이 plan을 넘어 확장되지 않았다.

## 검증 결과

### API-1 중간 검증

```
ok  	iop/apps/node/cmd/node	0.015s
ok  	iop/apps/node/internal/adapters	0.013s
ok  	iop/apps/node/internal/adapters/cli	42.120s
ok  	iop/apps/node/internal/adapters/cli/status	39.766s
ok  	iop/apps/node/internal/adapters/ollama	0.010s
ok  	iop/apps/node/internal/adapters/vllm	0.013s
ok  	iop/apps/node/internal/bootstrap	0.267s
ok  	iop/apps/node/internal/node	0.027s
ok  	iop/apps/node/internal/router	0.012s
ok  	iop/apps/node/internal/store	0.052s
ok  	iop/apps/node/internal/terminal	0.441s
ok  	iop/apps/node/internal/transport	5.149s
ok  	iop/apps/edge/internal/service	0.005s
```

### 최종 검증

```
ok  	iop/apps/node/cmd/node	0.015s
ok  	iop/apps/node/internal/adapters	0.013s
ok  	iop/apps/node/internal/adapters/cli	42.120s
ok  	iop/apps/node/internal/adapters/cli/status	39.766s
ok  	iop/apps/node/internal/adapters/ollama	0.010s
ok  	iop/apps/node/internal/adapters/vllm	0.013s
ok  	iop/apps/node/internal/bootstrap	0.267s
ok  	iop/apps/node/internal/node	0.027s
ok  	iop/apps/node/internal/router	0.012s
ok  	iop/apps/node/internal/store	0.052s
ok  	iop/apps/node/internal/terminal	0.441s
ok  	iop/apps/node/internal/transport	5.149s
ok  	iop/apps/edge/internal/service	0.005s
```

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - Correctness: Fail
  - Completeness: Fail
  - Test coverage: Fail
  - API contract: Fail
  - Code quality: Pass
  - Plan deviation: Fail
  - Verification trust: Pass
- 발견된 문제:
  - Required: `apps/edge/internal/openai/ollama_passthrough.go:21`에서 `/api/*` Ollama passthrough가 `OllamaAPIRequest.Target`을 채우지 않는다. 결과적으로 `apps/edge/internal/service/node_command.go:153`의 `NodeCommandRequest.Target`도 빈 문자열이 되어, configured `openai.target` 또는 route target이 있는 multi-target 환경에서 provider passthrough command가 어느 model target에 대한 명령인지 보존하지 못한다. `handleOllamaAPI`가 `resolveRouteDispatch` 또는 적어도 `resolveTarget` 기준으로 target을 채우고, `TestOllamaAPIPassthrough`에 target 보존 assertion을 추가한다.
  - Required: `apps/edge/internal/opsconsole/status.go:44`가 새로 추가된 `UsageStatusView.Adapter`를 버리고 `FormatUsageStatus`는 `target/session`만 출력한다. `/status`는 `SendStatus`의 sent line 이후 실제 status result header에서 adapter identity를 잃으므로 같은 target/session을 여러 adapter instance가 공유하는 경우 결과가 모호하다. `FormatUsageStatus`와 호출부를 adapter 포함 형태로 바꾸고, opsconsole formatter 테스트에 `adapter=...` 출력 assertion을 추가한다.
- 다음 단계:
  - FAIL 후속: `PLAN-local-G08.md` / `CODE_REVIEW-local-G08.md`에서 passthrough target 보존과 usage status 출력 identity를 보완한다.
