# Milestone: Node 단일 통로 멀티 타겟 서빙 기반

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/inference-provider-extension/PHASE.md`

## 목표

하나의 Node proto-socket 연결 위에서 여러 CLI profile, terminal gateway, 추론 엔진 연결, model target을 함께 사용할 수 있는 기준선을 만든다.
Edge는 Node별 adapter/profile/engine/model 라우팅과 Edge-owned runtime option을 소유하고, Node는 그 단일 통로에서 여러 실행 target을 안정적으로 처리한다.

## 상태

[완료]

## 승격 조건

- 없음

## 구현 잠금

- 상태: 해제
- 결정 필요: 없음

## 범위

- Node 하나가 단일 TCP/proto-socket 연결로 여러 adapter와 target을 동시에 제공하는 구조를 공식 기준선으로 정리한다.
- CLI profile map, terminal gateway, Ollama/vLLM/SGLang 같은 추론 엔진 연결을 같은 `adapter + target` 실행 모델에서 표현한다.
- Edge config와 proto payload가 adapter type별 단일 endpoint에 갇히지 않고 여러 engine/profile instance와 model route를 표현할 수 있게 한다.
- OpenAI-compatible `/v1/models`, `/v1/chat/completions`, `/v1/responses`가 Edge-owned model catalog와 route table을 통해 내부 `adapter + target`으로 변환되게 한다.
- 모델별 context window, runner sizing, keep-alive 같은 load/unload 영향 옵션은 agent request가 아니라 Edge 설정이 소유한다.
- Node runtime concurrency와 adapter capability가 멀티 타겟 동시 실행에서 실제로 적용되는지 검증한다.

## 기능

### Epic: [multi-target-node] Single Node Multi Target Serving

- [x] [config-topology] Edge `nodes[]` 설정과 `NodeConfigPayload`가 하나의 Node 안에 여러 CLI profile, terminal gateway, 추론 engine/profile instance, model target route를 표현한다.
- [x] [adapter-registry] Node adapter registry가 동일 adapter type의 여러 engine/profile instance를 덮어쓰지 않고 라우팅 가능한 target namespace로 관리한다.
- [x] [route-catalog] Edge OpenAI-compatible model catalog가 외부 `model`을 Edge-owned route table로 해석하고, 고정 `openai.target` 단일 override 없이 내부 `adapter + target`으로 변환한다. 검증: `/v1/models`가 여러 route를 노출하고 각 model 요청이 기대 adapter/target으로 dispatch되는 단위 테스트를 통과한다.
- [x] [engine-profiles] Ollama는 여러 `base_url`/model target과 target별 `context_size`를 지원하고, vLLM/SGLang 같은 OpenAI-compatible inference engine 연결을 같은 Node 통로에서 확장할 수 있는 provider/profile 기준이 정리되어 있다.
- [x] [edge-owned-options] context window와 runner sizing 옵션은 Edge config가 최종 소유하며, 외부 agent request의 `options.num_ctx` 같은 값이 Edge-owned 값을 변경하지 못한다. 검증: 요청 option override가 route/profile 설정으로 덮이는 테스트를 통과한다.
- [x] [commands-caps] `CAPABILITIES`, `SESSION_LIST`, `USAGE_STATUS`, provider passthrough command가 여러 adapter/profile/model target에서 모호하지 않은 결과를 반환한다.
- [x] [runtime-concurrency] `runtime.concurrency`와 adapter capability가 Node 멀티 호출에서 실제 제한 또는 스케줄링 정책으로 적용된다. 검증: 동시 run 테스트에서 제한 초과 요청이 queue/reject/timeout 중 정의된 정책대로 동작한다.
- [x] [field-smoke] split-host smoke에서 하나의 연결된 Node가 최소 두 개의 inference model target과 하나의 CLI target을 같은 Edge-Node 연결로 호출할 수 있음을 확인한다.

## 작업 분할

- 상태: 모든 split subtask가 `agent-task/archive/2026/06/m-node-multi-target-serving-foundation/` 아래 complete.log와 함께 PASS/RESOLVED로 정리되었고, Milestone 종료 전 코드 레벨 최종 리뷰와 검증도 통과했다.
- Archived task group: `agent-task/archive/2026/06/m-node-multi-target-serving-foundation/`
- 분할:
  - `01_config_topology`: `[config-topology]`
  - `02+01_adapter_registry`: `[adapter-registry]`
  - `03+01_route_catalog`: `[route-catalog]`
  - `04+01,02_engine_profiles`: `[engine-profiles]`
  - `05+03,04_edge_owned_options`: `[edge-owned-options]`
  - `06+02,04_commands_caps`: `[commands-caps]`
  - `07+02_runtime_concurrency`: `[runtime-concurrency]`
  - `08+03,04,05,06,07_field_smoke`: `[field-smoke]`
- 적용 원칙: 작은 보정이 각 subtask 구현 중 발견되면 해당 plan 범위 안에서 바로 처리하고, 구조 변경 또는 검증 실패는 plan/code-review loop로 이어간다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-06-12
- 완료 근거: `config-topology`, `adapter-registry`, `route-catalog`, `engine-profiles`, `edge-owned-options`, `commands-caps`, `runtime-concurrency`, `field-smoke`가 모두 archived `complete.log`의 `Roadmap Completion` 증거와 함께 PASS/RESOLVED 처리되었다.
- 완료 근거: 최종 field smoke는 사용자 제공 원격 Edge/Node 환경에서 `gemma4_ext:26b`, `gemma4:26b` 개별 호출과 `runtime.concurrency=2` 병렬 호출 성공으로 USER_REVIEW stop state가 해소되었다.
- 완료 근거: 2026-06-12 종료 전 코드 레벨 최종 리뷰에서 현재 코드 diff에 milestone 관련 미해결 코드 변경이 없음을 확인했고, `go test -count=1 ./...`, `go test -race -count=1 ./apps/node/internal/node/...`, `./scripts/e2e-smoke.sh`가 통과했다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: `field-smoke`의 원래 CLI target 별도 호출 문구는 사용자 리뷰에서 두 Ollama 추론엔진 smoke 범위로 축소 승인되었고, 실제 수집 증거는 archived `USER_REVIEW.md`와 `complete.log`에 기록되어 있다. 최종 코드 리뷰에서 추가 Required/Suggested issue는 발견되지 않았다.

## 범위 제외

- Control Plane이 Node에 직접 연결하거나 Node를 직접 스케줄링하는 구조
- OpenAI-compatible/A2A payload에 terminal 제어 기능을 섞는 구조
- cloud fallback, 품질 평가 feedback, 자동 비용/품질 최적화
- RAG, context 압축, web search, MCP/tool policy 같은 후속 최적화 계층
- 모든 provider의 완전한 production hardening을 한 번에 끝내는 작업

## 작업 컨텍스트

- 관련 경로: `packages/go/config`, `proto/iop`, `apps/edge/internal/node`, `apps/edge/internal/service`, `apps/edge/internal/openai`, `apps/node/internal/adapters`, `apps/node/internal/router`, `apps/node/internal/node`, `configs`, `docs`
- 표준선(선택): Node transport는 node id당 하나의 TCP/proto-socket 연결을 유지하고, 그 연결 위에서 `adapter + target + session_id` 기준으로 여러 실행을 multiplex한다.
- 표준선(선택): Edge는 Node registry, adapter/profile configuration, model catalog, routing, runtime option의 원본 소유자다.
- 표준선(선택): CLI adapter의 profile map과 `(target, session_id)` session key는 멀티 타겟 구조의 기존 기준선으로 유지한다.
- 선행 작업: Ollama 서빙 안정화 기반, proto-socket 멀티 호출 안정화
- 후속 작업: SGLang provider 서빙 경로 추가, 지식과 도구 최적화 확장
- 확인 필요: 구현 중 발견되는 provider별 세부 옵션은 Edge-owned route/profile 설정에 남기고, agent request가 runner sizing을 직접 바꾸는 경로는 허용하지 않는다.
