137 lines
6.6 KiB
Text
137 lines
6.6 KiB
Text
<!-- task=edge_multi_point_routing plan=0 tag=API -->
|
|
|
|
# Code Review Reference - API
|
|
|
|
## 개요
|
|
|
|
date=2026-05-04
|
|
task=edge_multi_point_routing, plan=0, tag=API
|
|
|
|
## 이 파일을 읽는 리뷰 에이전트에게
|
|
|
|
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
|
|
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.
|
|
|
|
1. `CODE_REVIEW.md` → `code_review_N.log` (N = 기존 code_review_*.log 수)
|
|
2. `PLAN.md` → `plan_M.log` (M = 기존 plan_*.log 수)
|
|
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.
|
|
|
|
---
|
|
|
|
## 구현 항목별 완료 여부
|
|
|
|
| 항목 | 완료 여부 |
|
|
|------|---------|
|
|
| [API-1] Registry를 임의 Pick에서 명시적 조회 API 중심으로 전환 | [x] |
|
|
| [API-2] Console 실행/세션 종료를 target node 명시 모델로 변경 | [x] |
|
|
| [API-3] RunEvent에 node 출처를 추가해 foreground/background 출력 모두 node-aware 하게 만들기 | [x] |
|
|
|
|
## 계획 대비 변경 사항
|
|
|
|
- `apps/node/internal/node/node.go`의 `sessionSink`를 테스트하기 위해 `protoSender` 인터페이스를 도입했습니다. 이를 통해 `toki` 의존성 없이 `iop.RunEvent` 필드(특히 `node_id`)가 올바르게 채워지는지 단위 테스트할 수 있게 되었습니다.
|
|
|
|
## 주요 설계 결정
|
|
|
|
- **Implicit Resolve Logic**: `Resolve("")` 호출 시 연결된 node가 정확히 1개인 경우에만 성공하도록 하여, 하위 호환성을 유지하면서도 멀티 노드 환경에서의 모호성을 원천 차단했습니다.
|
|
- **Unified Node Labeling**: `consoleEventRouter.nodeLabel` helper를 통해 `node_id`를 `alias`로 변환하는 로직을 일원화하고, registry에 없는 노드라도 `node_id`를 그대로 출력하여 추적성을 보장했습니다.
|
|
- **State Consolidation**: Console의 상태를 `consoleTarget` 구조체로 묶어 관리함으로써, `/node`, `/session`, `/background` 등 여러 명령이 상태를 안전하게 변경하고 전파할 수 있게 했습니다.
|
|
|
|
## 리뷰어를 위한 체크포인트
|
|
|
|
- `apps/edge/internal/node/registry.go: Resolve`가 빈 ref에서 단일 node만 자동 선택하고, multi-node에서는 반드시 명시적 선택 에러를 반환하는지 확인
|
|
- `apps/edge/cmd/edge/console.go` 내의 `sendConsoleRun`, `sendTerminateSession`, `sendConsoleStatus`가 모두 `resolveConsoleNode`를 거쳐 `Registry.Pick()` 직접 호출을 제거했는지 확인
|
|
- `RunEvent.node_id`가 `apps/node/internal/node/node.go`에서 실제로 채워지고, `apps/edge/cmd/edge/console_events.go`에서 `[node-{alias|id}-...]` 형식으로 출력되는지 확인
|
|
|
|
## 검증 결과
|
|
|
|
### API-1 중간 검증
|
|
```bash
|
|
$ go test ./apps/edge/internal/node/... ./apps/edge/internal/transport/...
|
|
ok iop/apps/edge/internal/node 0.003s
|
|
ok iop/apps/edge/internal/transport 0.006s
|
|
```
|
|
|
|
### API-2 중간 검증
|
|
```bash
|
|
$ go test ./apps/edge/cmd/edge/... ./apps/edge/internal/node/...
|
|
ok iop/apps/edge/cmd/edge 0.004s
|
|
ok iop/apps/edge/internal/node (cached)
|
|
```
|
|
|
|
### API-3 중간 검증
|
|
```bash
|
|
$ make proto
|
|
protoc \
|
|
--go_out=. \
|
|
--go_opt=module=iop \
|
|
--proto_path=. \
|
|
proto/iop/runtime.proto \
|
|
proto/iop/node.proto \
|
|
proto/iop/control.proto \
|
|
proto/iop/job.proto
|
|
$ go test ./apps/node/internal/node/... ./apps/edge/cmd/edge/...
|
|
ok iop/apps/node/internal/node 0.007s
|
|
ok iop/apps/edge/cmd/edge (cached)
|
|
```
|
|
|
|
### 최종 검증
|
|
```bash
|
|
$ make proto
|
|
(already up to date)
|
|
$ go test ./apps/edge/... ./apps/node/internal/node/...
|
|
ok iop/apps/edge/cmd/edge (cached)
|
|
ok iop/apps/edge/internal/node (cached)
|
|
ok iop/apps/edge/internal/transport (cached)
|
|
ok iop/apps/node/internal/node (cached)
|
|
$ go test ./...
|
|
? iop/apps/control-plane/cmd/control-plane [no test files]
|
|
ok iop/apps/edge/cmd/edge (cached)
|
|
? iop/apps/edge/internal/bootstrap [no test files]
|
|
ok iop/apps/edge/internal/node (cached)
|
|
ok iop/apps/edge/internal/transport (cached)
|
|
? iop/apps/node/cmd/node [no test files]
|
|
ok iop/apps/node/internal/adapters (cached)
|
|
ok iop/apps/node/internal/adapters/cli (cached)
|
|
? iop/apps/node/internal/adapters/cli/internal/testutil [no test files]
|
|
ok iop/apps/node/internal/adapters/cli/lifecycle (cached)
|
|
ok iop/apps/node/internal/adapters/cli/oneshot (cached)
|
|
ok iop/apps/node/internal/adapters/cli/persistent (cached)
|
|
ok iop/apps/node/internal/adapters/cli/status (cached)
|
|
? iop/apps/node/internal/adapters/mock [no test files]
|
|
? iop/apps/node/internal/adapters/ollama [no test files]
|
|
? iop/apps/node/internal/adapters/vllm [no test files]
|
|
ok iop/apps/node/internal/bootstrap (cached)
|
|
ok iop/apps/node/internal/node (cached)
|
|
ok iop/apps/node/internal/router (cached)
|
|
? iop/apps/node/internal/runtime [no test files]
|
|
ok iop/apps/node/internal/store (cached)
|
|
ok iop/apps/node/internal/transport 0.006s
|
|
? iop/apps/worker/cmd/worker [no test files]
|
|
? iop/packages/auth [no test files]
|
|
ok iop/packages/config (cached)
|
|
? iop/packages/jobs [no test files]
|
|
? iop/packages/metadata [no test files]
|
|
? iop/packages/observability [no test files]
|
|
? iop/packages/policy [no test files]
|
|
? iop/packages/version [no test files]
|
|
? iop/proto/gen/iop [no test files]
|
|
```
|
|
|
|
## 코드리뷰 결과
|
|
|
|
- 종합 판정: FAIL
|
|
|
|
- 차원별 평가
|
|
- correctness: Pass
|
|
- completeness: Fail
|
|
- test coverage: Fail
|
|
- API contract: Pass
|
|
- code quality: Pass
|
|
- plan deviation: Fail
|
|
- verification trust: Pass
|
|
|
|
- 발견된 문제
|
|
- Required — [apps/edge/cmd/edge/console.go](/config/workspace/go-iop/apps/edge/cmd/edge/console.go:126): `/terminate-session` 성공 메시지가 여전히 `terminated session <id>`만 출력해, 계획서의 "startup banner와 `/terminate-session` 결과도 `node=<alias>`를 포함" 요구를 충족하지 못합니다. 멀티 노드 환경에서 어떤 node의 세션을 종료했는지 즉시 확인할 수 없고, 이에 대한 회귀 테스트도 없습니다. 성공 경로에서 `resolveConsoleNode(...)`로 얻은 node label을 포함해 `terminated session <id> node=<alias|id>` 형태로 출력하고, console 테스트에 해당 문자열을 검증하는 케이스를 추가하세요.
|
|
|
|
- 다음 단계
|
|
- FAIL: Required 이슈를 반영하는 새 `PLAN.md`와 `CODE_REVIEW.md` 스텁을 작성하고 리뷰 루프를 계속한다.
|