<!-- task=m-node-multi-target-serving-foundation/02+01_adapter_registry plan=1 tag=REVIEW_REFACTOR -->

# Plan - REVIEW_REFACTOR

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

이 계획은 이전 리뷰의 Required 항목만 해결한다. 구현 완료의 마지막 단계는 `CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션 작성이다. 사용자 전용 결정이나 외부 환경 prerequisite 없이는 사용자에게 직접 질문하지 말고, 필요한 경우 review stub의 `사용자 리뷰 요청` 섹션에 근거와 재개 조건을 기록한 뒤 멈춘다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/inference-provider-extension/milestones/node-multi-target-serving-foundation.md`
- Task ids:
  - `adapter-registry`: Node adapter registry가 동일 adapter type의 여러 engine/profile instance를 덮어쓰지 않고 라우팅 가능한 target namespace로 관리한다.
- Completion mode: check-on-pass

## 배경

1차 리뷰는 `FAIL`이다. registry/router의 핵심 namespace 구현은 들어갔지만, `Router.GetAdapter`가 `Registry.Lookup`의 ambiguous error를 bool로 접어 command/cancel 경로에서 명확한 instance key 안내를 잃는다. 또한 adapter registry 실행 경로 변경에 대해 Node smoke/full-cycle 검증 증거가 부족하다.

## 범위 결정 근거

- 새 adapter namespace 구조를 다시 설계하지 않는다.
- Edge route catalog, provider route table, engine profile 실행, concurrency scheduling은 sibling task 범위로 남긴다.
- 이 follow-up은 ambiguous error 보존과 검증 증거 회복만 수행한다.

## 구현 체크리스트

- [ ] Command/cancel adapter lookup 경로가 ambiguous legacy adapter 요청의 원인과 instance key 후보를 명확히 반환한다.
- [ ] node command/cancel 단위 테스트가 multi-instance ambiguous lookup과 exact instance key lookup을 검증한다.
- [ ] 최종 Go 검증과 Node smoke/full-cycle 검증을 실행하거나, 실행 불가 시 blocker 근거를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REFACTOR-1] Error-Preserving Adapter Lookup

- 문제: `apps/node/internal/router/router.go:67`의 `GetAdapter`가 `Lookup` error를 `(nil, false)`로 변환한다. `apps/node/internal/node/node.go:162`와 `apps/node/internal/node/node.go:209`는 이 bool만 보고 `"adapter ... not found"`를 반환하므로, multi-instance 상태에서 legacy `"ollama"` command/cancel 요청이 ambiguous임을 알 수 없다.
- 해결 방법: router/node 경계에 error-preserving lookup을 추가한다. 예: `LookupAdapter(adapterName string) (runtime.Adapter, error)`를 `runtime.Router`에 추가하거나, 기존 `GetAdapter` 계약을 error-returning 형태로 바꾸고 모든 call site/test stub을 갱신한다. node command/cancel 응답은 `Registry.Lookup`의 ambiguous 메시지 또는 동등하게 명확한 key 후보 안내를 보존해야 한다.
- 수정 파일 및 체크리스트:
  - [ ] `apps/node/internal/runtime/types.go`: router adapter lookup 계약 갱신.
  - [ ] `apps/node/internal/router/router.go`: ambiguous/not found error를 보존하는 lookup 구현.
  - [ ] `apps/node/internal/node/node.go`: cancel, capabilities, adapter command dispatch의 error response 갱신.
  - [ ] `apps/node/internal/node/node_test.go`: capabilities/adapter command/session termination에서 ambiguous legacy 요청과 exact instance key 요청을 검증.
  - [ ] `apps/node/internal/router/router_test.go`: 갱신된 router lookup 계약 테스트 보강.
- 중간 검증:
  - `go test -count=1 ./apps/node/internal/router/... ./apps/node/internal/node/...`

### [REVIEW_REFACTOR-2] Required Runtime Verification Evidence

- 문제: Node domain rule은 adapter/router 실행 경로 변경 후 testing domain rule의 검증 기준을 따르라고 한다. 현재 증거는 `go test -count=1 ./apps/node/...`뿐이라, adapter registry/input surface 변경에 필요한 edge-node smoke/full-cycle 증거가 없다.
- 해결 방법: 로컬 규칙의 `node-smoke` 기준에 맞춰 Go test, 보조 smoke, repo 내부 edge-node 진단/full-cycle 결과를 기록한다. full-cycle을 실행할 수 없으면 실행한 명령, 실제 stdout/stderr, 불가 사유, user-owned/external blocker 여부를 review stub의 `사용자 리뷰 요청` 또는 `검증 결과`에 명확히 남긴다.
- 수정 파일 및 체크리스트:
  - [ ] 코드 변경이 없어도 검증 증거를 `CODE_REVIEW-cloud-G07.md`에 기록.
  - [ ] 가능하면 `./scripts/e2e-smoke.sh`를 실행하고 결과를 기록.
  - [ ] `agent-test/local/node-smoke.md`의 repo 내부 edge-node 진단/full-cycle 기준을 수행하고, `/nodes`, 메시지 2회, 관련 command 결과 증거를 기록.
- 중간 검증:
  - `go test -count=1 ./apps/node/...`
  - `./scripts/e2e-smoke.sh`

## 최종 검증

```bash
go test -count=1 ./apps/node/...
./scripts/e2e-smoke.sh
```

또한 `agent-test/local/node-smoke.md`의 full-cycle 기준을 수행해 결과를 `CODE_REVIEW-cloud-G07.md`에 기록한다. 수행하지 못한 항목은 정확한 명령과 stdout/stderr, 차단 사유를 남긴다.
