# OTO-iop proto-socket 통신 기반

## 목표

OTO가 iop Edge에 직접 outbound 연결하는 build/deploy domain agent가 될 수 있도록 proto-socket 기반 최소 통신 기반을 정리한다.
iop의 기존 Edge-Node 연결 흐름과 상위 `proto-socket` Dart 구현을 확인해 OTO에서 먼저 심어야 할 transport, parser, handshake, heartbeat, 검증 경계를 정의한다.

## 단계

Edge 직접 연결 기반 `oto-agent`

## 상태

완료

## 구현 잠금

- 상태: 해제
- 이유: 사용자가 OTO-iop proto-socket 통신 기반 작업과 문서 잠금 해제를 명시해 구현 시작 승인 상태다. 잠금 해제는 완료 판정이 아니며, 완료 여부는 아래 `필수 기능`과 `완료 기준`의 evidence로 별도 판단한다.
- 해제 근거: 2026-05-24 사용자 요청 `그럼 해당 방향으로 작업해`, `iop와 oto의 간단한 접속 테스트를 하고 문서 잠금을 해제해`.
- 해제 후 주의:
  - 실제 구현은 기존 iop node transport/API 계약을 우선 재사용한다.
  - Edge bootstrap command, registry 저장 모델, credential schema는 후속 Milestone에서 확정한다.
  - build/deploy run request, artifact, log stream 전체 메시지 프로토콜은 후속 agent 메시지 프로토콜에서 확정한다.

## 범위

- iop의 Edge-Node proto-socket 연결 흐름을 OTO agent 관점에서 정리한다.
- 상위 `proto-socket` Dart 구현을 OTO에서 사용할 때 필요한 SDK, dependency, parser map, heartbeat, request-response 지원 범위를 확인한다.
- OTO agent의 최소 outbound 연결이 bootstrap보다 먼저 갖춰야 할 transport/handshake 산출물을 정의한다.
- generic `iop-node`와 OTO specialized domain agent가 공유할 수 있는 메시지와 분리해야 할 메시지를 후보 수준으로 정리한다.

## 필수 기능

- [x] [iop-flow-map] iop Edge-Node 연결 흐름의 register, config, run/event, command, heartbeat 책임이 OTO 관점에서 매핑되어 있다.
- [x] [proto-socket-dart] 상위 `proto-socket` Dart 구현의 사용 가능 범위와 OTO SDK/dependency 호환성 이슈가 정리되어 있다.
- [x] [handshake-scope] OTO agent 최소 handshake가 기존 `RegisterRequest/RegisterResponse`를 재사용할지 specialized agent 메시지로 분리할지 판단 기준이 정의되어 있다.
- [x] [session-lifecycle] 연결, heartbeat, disconnect, reconnect, parser map 구성의 최소 세션 생명주기가 문서화되어 있다.
- [x] [smoke-criteria] OTO에서 실제 구현 전 확인할 최소 통신 smoke 기준이 정의되어 있다.

## 완료 기준

- [x] Edge bootstrap 계약이 통신 기반 없이 bootstrap UX를 선확정하지 않도록 필요한 통신 기준이 명확하다.
- [x] OTO와 iop 구현자가 같은 transport/handshake 경계를 보고 병렬로 후속 작업을 시작할 수 있다.
- [x] OTO의 Dart SDK와 `proto_socket` Dart 패키지 호환성 처리 방향이 정리되어 있다.
- [x] 최소 통신 smoke가 코드 구현 전 검증 기준으로 설명되어 있다.

## 범위 제외

- 실제 OTO 통신 모듈을 구현하지 않는다.
- iop Edge 서버 API, agent registry, credential schema를 확정하지 않는다.
- build/deploy run request, artifact, log stream 전체 메시지 프로토콜을 확정하지 않는다.
- Edge bootstrap command 발급 UX를 구현하지 않는다.

## 작업 컨텍스트

- 관련 iop 경로: `../iop/proto/iop/runtime.proto`, `../iop/apps/edge/internal/transport/server.go`, `../iop/apps/node/internal/transport/client.go`, `../iop/apps/node/internal/transport/session.go`
- 관련 proto-socket 경로: `../proto-socket/dart/`, `../proto-socket/README.md`
- 관련 OTO 경로: `pubspec.yaml`, 향후 agent/transport 모듈 후보
- 선행 작업: CLI 자동화 표면 정리 완료
- 후속 작업: Edge bootstrap 계약, `oto-agent` 등록 흐름, agent 메시지 프로토콜
- handshake-scope 정리:
  - OTO agent의 최소 register handshake는 기존 iop `RegisterRequest(token)` / `RegisterResponse(accepted, node_id, alias, config)`를 재사용한다.
  - OTO 전용 specialized register 메시지는 현 단계에서 만들지 않는다. token 발급, credential schema, registry 저장 모델은 Edge bootstrap/registration Milestone에서 결정한다.
  - `RegisterResponse.config` 전달 패턴은 재사용하되, build/deploy 전용 설정 payload가 필요한지는 OTO config 설계 시 별도 판단한다.
- session-lifecycle 정리:
  - OTO agent는 iop node와 같이 Edge로 outbound TCP 연결을 열고, proto-socket heartbeat를 통해 생존성을 확인한다.
  - 기본 heartbeat 후보는 iop node와 같은 30초 interval, 45초 wait window다.
  - parser map의 기본 수신 대상은 `RegisterResponse`, `RunRequest`, `CancelRequest`, `NodeCommandRequest`, `EdgeNodeEvent`다.
  - disconnect listener는 local shutdown, transport close, heartbeat timeout을 구분할 수 있어야 한다.
  - reconnect/backoff 정책은 최소 smoke 범위 밖이며 `oto-agent` 등록 흐름 또는 원격 실행 생명주기에서 구현 기준을 정한다.
- smoke-criteria 정리:
  - OTO Dart client가 `proto_socket` path dependency를 사용해 실제 iop Edge `serve` 프로세스에 TCP 연결한다.
  - OTO Dart client가 `RegisterRequest(token)`을 보내고 `RegisterResponse(accepted=true, node_id, alias, config.runtime)`를 받는다.
  - smoke는 제품 통신 모듈 구현 없이 테스트 전용 iop runtime proto 생성물과 임시 Edge config를 사용한다.
  - 검증 명령: `dart test test/oto_iop_connection_smoke_test.dart -r expanded`
  - 확인 결과: iop Edge serve 프로세스와 OTO Dart proto-socket client의 register handshake 통과.
- proto-socket-dart 정리:
  - OTO SDK 하한을 `>=3.2.3 <4.0.0`로 올리고 `proto_socket`을 `../proto-socket/dart` path dependency로 연결했다.
  - `../proto-socket/dart/pubspec.yaml`은 SDK `>=3.2.3 <4.0.0`, `protobuf: ^3.1.0`, `meta: ^1.9.0`을 요구한다.
  - Dart 구현은 `ProtobufClient`, `ProtobufServer`, `Communicator`, `BaseClient`, WebSocket transport, request-response, listener, heartbeat, disconnect listener를 export한다.
  - iop package-qualified protobuf typeName(`iop.RegisterResponse` 등)을 처리하기 위해 `../proto-socket/dart/lib/src/communicator.dart`의 listener/request/response 매칭을 일반화했다.
  - OTO 쪽 최초 세팅 검증은 `dart pub get`과 `dart analyze` 통과를 기준으로 확인했다.
  - 실제 OTO agent transport class와 generated proto import 구조는 후속 구현에서 확정한다.
- iop-flow-map 정리:
  - transport: 기존 iop node는 Edge에 outbound TCP 연결을 열고 proto-socket heartbeat를 사용하는 단일 persistent session으로 동작한다. OTO agent도 이 transport 방향을 기본 재사용하는 후보로 둔다.
  - register: node는 연결 직후 `RegisterRequest(token)`을 보내고 Edge는 token 기반 `NodeStore` 조회, 중복 연결 거부, config 생성 뒤 `RegisterResponse(accepted, node_id, alias, config)`를 돌려준다. OTO도 token 기반 등록 handshake는 재사용 후보로 두되, token 발급과 registry/credential schema는 Edge bootstrap/registration Milestone에서 확정한다.
  - config: iop의 `NodeConfigPayload`는 `AdapterConfig`와 `NodeRuntimeConfig`를 담고, 현재 adapter config는 `mock`, `ollama`, `vllm`, `cli` 중심이다. OTO는 response 안의 config 전달 패턴은 재사용 가능하지만, build/deploy agent 설정 payload는 OTO 전용 config 또는 `adapter=oto` 계열 확장이 필요할 수 있다.
  - run/event: Edge는 `RunRequest`를 node에 전송하고 node는 runtime 실행 결과를 `RunEvent(start, delta, complete, error, cancelled)`로 돌려준다. OTO는 이 실행 요청/이벤트 envelope를 재사용하는 후보로 두고, `adapter`는 `oto` 또는 `pipeline` 계열, `target`은 pipeline/profile 식별자, `input`/`metadata`는 YAML 경로, 파라미터, build metadata를 담는 후보로 둔다.
  - cancel: `CancelRequest`는 run 취소와 logical session 종료를 구분한다. OTO는 run 취소는 재사용 후보로 두되, 장수 logical session 종료 의미가 필요한지는 `session-lifecycle`에서 판단한다.
  - command: `NodeCommandRequest/Response`의 `CAPABILITIES`와 `TRANSPORT_STATUS`는 OTO agent에도 재사용 가치가 높다. `USAGE_STATUS`, `SESSION_LIST`는 기존 CLI adapter 의미가 강하므로 OTO에서 그대로 노출할지, build/deploy 전용 command를 추가할지는 후속 메시지 프로토콜에서 판단한다.
  - heartbeat: heartbeat는 domain message가 아니라 proto-socket transport 생존성 책임이다. iop는 30초 interval, 45초 wait window를 사용하므로 OTO도 같은 기본값을 후보로 두고 Dart SDK 지원 여부를 확인한다.
  - parser map: node side는 `RunRequest`, `EdgeNodeEvent`, `CancelRequest`, `NodeCommandRequest`, `RegisterResponse`를 파싱하고, edge side는 `RunEvent`, `EdgeNodeEvent`, `RegisterRequest`, `NodeCommandResponse`를 파싱한다. OTO agent는 node-side parser map을 기본형으로 삼고 OTO 전용 메시지가 생길 때만 추가한다.
  - 공유 후보: `RegisterRequest/RegisterResponse`, `RunRequest/RunEvent`, `CancelRequest`, `NodeCommandRequest/Response`의 capabilities/transport status, `EdgeNodeEvent`, heartbeat/transport session.
  - OTO 특화 후보: config payload 구조, build/deploy run input schema, artifact/log event 의미, OTO capability 결과 키, pipeline/profile target naming.
  - 보류: Edge bootstrap command, agent registry 저장 모델, credential schema, durable history/audit, 전체 build/deploy proto 메시지 세트.
- 확인 필요: 후속 구현에서 OTO build/deploy run input schema, artifact/log event 의미, reconnect/backoff 정책을 확정해야 한다.
