완료 일시: 2026-05-17

요약: Edge operation contract DTO 정리와 opsconsole DTO 사용 전환을 3개 리뷰 루프로 완료했다.

루프 이력:

| Plan | Code Review | Verdict |
|---|---|---|
| `plan_cloud_G08_0.log` | `code_review_cloud_G08_0.log` | FAIL |
| `plan_cloud_G08_1.log` | `code_review_cloud_G08_1.log` | FAIL |
| `plan_cloud_G08_2.log` | `code_review_cloud_G08_2.log` | PASS |

최종 리뷰 요약:

- `apps/edge/internal/service`에 `NodeSnapshot`, `RunDispatch`, `RunStream`, `UsageStatusView`, `CommandResult` DTO가 추가되고 기존 `RunHandle`, `TerminateSessionResult`, `UsageStatusResult` 호환성이 유지되었다.
- opsconsole은 node list/status 경로에서 service DTO를 우선 사용하고, proto event rendering은 event router 내부에 유지했다.
- 후속 루프에서 `apps/edge/internal/service/service_test.go`의 `gofmt` 이슈를 정리했다.
- 실제 `./bin/edge.sh` + `./bin/node.sh` 기반 mock smoke/full-cycle을 임시 config/포트로 검증했고, node store DB가 `/tmp/iop-smoke/workspace/iop.db`로 격리되어 repo root `iop.db`가 남지 않음을 확인했다.
- 리뷰어 재현 검증: `gofmt -l`, `git diff --check`, `git status --short -- iop.db`, 대상 패키지 테스트, `go test -count=1 ./...` 모두 PASS.

잔여 Nit:

- 최종 review 기록의 `test -f Makefile && rg -n "test-e2e" Makefile || true` 설명은 "Makefile 없음"이 아니라 "Makefile은 있으나 test-e2e target 없음"이 더 정확하다. 검증 결과에는 영향 없다.
- smoke 후 node process가 하나 남아 리뷰 중 종료했다. 이후 수동 smoke 기록에는 종료/cleanup 명령도 함께 남기면 좋다.
