refactor: move edge-direct-oto-agent phase to archive and add independent-control-plane phase

This commit is contained in:
toki 2026-06-05 05:02:43 +09:00
parent 2932427759
commit 64f11149c0
5 changed files with 156 additions and 22 deletions

View file

@ -2,8 +2,8 @@
## 전체 목표 ## 전체 목표
OTO는 YAML 기반 빌드/배포 파이프라인을 실행하는 Dart CLI에서 출발해, Jenkins 내부 실행 도구에 머물지 않고 Edge에 직접 연결되는 가벼운 build/deploy agent로 확장한다. OTO는 YAML 기반 빌드/배포 파이프라인을 실행하는 Dart CLI에서 출발해, 서버 없이도 동작하는 경량 typed-command CI/CD runner와 선택적 OTO Control Plane으로 확장한다.
기존 CLI, YAML 파이프라인, 커맨드 확장 모델은 유지하면서 외부 자동화와 원격 제어가 다루기 쉬운 실행 표면을 만든다. 기존 CLI, YAML 파이프라인, 커맨드 확장 모델은 유지하면서 Jenkins보다 가볍고 shell보다 구조화된 실행 표면을 만들고, iop는 OTO가 AI agent/model 기능이 필요할 때 선택적으로 소비하는 외부 provider로 둔다.
## Phase 흐름 ## Phase 흐름
@ -14,9 +14,12 @@ OTO는 YAML 기반 빌드/배포 파이프라인을 실행하는 Dart CLI에서
- [완료] CLI 자동화 표면 정리 - [완료] CLI 자동화 표면 정리
- 경로: `agent-roadmap/archive/phase/cli-automation-surface/PHASE.md` - 경로: `agent-roadmap/archive/phase/cli-automation-surface/PHASE.md`
- 요약: Jenkins, 파일 실행, 스케줄러로 동작하는 현재 CLI 표면을 장기 호환 경계와 외부 자동화 계약으로 정리했다. - 요약: Jenkins, 파일 실행, 스케줄러로 동작하는 현재 CLI 표면을 장기 호환 경계와 외부 자동화 계약으로 정리했다.
- [진행중] Edge 직접 연결 기반 `oto-agent` - [폐기] Edge 직접 연결 기반 `oto-agent`
- 경로: `agent-roadmap/phase/edge-direct-oto-agent/PHASE.md` - 경로: `agent-roadmap/archive/phase/edge-direct-oto-agent/PHASE.md`
- 요약: OTO가 iop Edge와 proto-socket 기반 outbound 통신을 할 수 있는 최소 연결 계약과 bootstrap 설치/등록 경험을 정리한다. - 요약: OTO가 iop Edge와 proto-socket 기반 outbound 통신을 하는 경로는 검증 근거만 보존하고, 독립 OTO Control Plane 방향으로 전환하며 기본 제품 경로에서는 폐기한다.
- [계획] 독립 Control Plane 기반 OTO
- 경로: `agent-roadmap/phase/independent-control-plane/PHASE.md`
- 요약: OTO를 iop 직접 연결 구조에서 분리해 `apps/runner`, `apps/client`, `services/core`를 가진 독립 CI/CD runner/control plane 제품 구조로 전환한다.
- [계획] 메시지 기반 빌드 에이전트 - [계획] 메시지 기반 빌드 에이전트
- 경로: `agent-roadmap/phase/message-based-build-agent/PHASE.md` - 경로: `agent-roadmap/phase/message-based-build-agent/PHASE.md`
- 요약: `oto agent` 또는 `oto daemon` 모드에서 Edge와 양방향 메시지 통신을 사용하며, OTO를 build/deploy 전용 domain agent로 노출한다. - 요약: `oto agent` 또는 `oto daemon` 모드에서 Edge와 양방향 메시지 통신을 사용하며, OTO를 build/deploy 전용 domain agent로 노출한다.

View file

@ -2,12 +2,12 @@
## 상태 ## 상태
[진행중] [폐기]
## 목표 ## 목표
OTO가 `iop-node`를 거치지 않고 iop Edge에 직접 outbound 연결하는 최소 agent 계약을 정리한다. OTO가 `iop-node`를 거치지 않고 iop Edge에 직접 outbound 연결하는 최소 agent 계약을 정리한다.
bootstrap 설치 경험, proto-socket 연결 기반, 등록 상태 전이를 묶어 Linux MVP에서 구현 가능한 경계로 만다. bootstrap 설치 경험, proto-socket 연결 기반, 등록 상태 전이를 묶어 Linux MVP에서 구현 가능한 경계로 만들려 했으나, 제품 방향을 독립 OTO Control Plane으로 전환하면서 iop Edge 직접 연결 기본 경로는 폐기한다.
## Milestone 흐름 ## Milestone 흐름
@ -20,9 +20,9 @@ bootstrap 설치 경험, proto-socket 연결 기반, 등록 상태 전이를 묶
- [완료] Edge bootstrap 계약 - [완료] Edge bootstrap 계약
- 경로: `agent-roadmap/archive/phase/edge-direct-oto-agent/milestones/edge-bootstrap-contract.md` - 경로: `agent-roadmap/archive/phase/edge-direct-oto-agent/milestones/edge-bootstrap-contract.md`
- 요약: Jenkins node 연결식 UX를 Linux 대상 OTO bootstrap script 설치/등록 계약으로 정리했다. - 요약: Jenkins node 연결식 UX를 Linux 대상 OTO bootstrap script 설치/등록 계약으로 정리했다.
- [진행중] `oto-agent` 등록 흐름 - [폐기] `oto-agent` 등록 흐름
- 경로: `agent-roadmap/phase/edge-direct-oto-agent/milestones/oto-agent-registration.md` - 경로: `agent-roadmap/archive/phase/edge-direct-oto-agent/milestones/oto-agent-registration.md`
- 요약: `oto-agent` 설치 후 Edge 직접 outbound 등록 흐름을 구현 가능한 단위로 정리한다. - 요약: iop Edge 직접 outbound 등록 흐름은 독립 OTO Server/Runner 마이그레이션 입력으로만 보존하고 기본 제품 경로에서는 폐기한다.
## Phase 경계 ## Phase 경계
@ -30,3 +30,4 @@ bootstrap 설치 경험, proto-socket 연결 기반, 등록 상태 전이를 묶
- `iop-node`를 경유하는 generic node agent 기능은 포함하지 않는다. - `iop-node`를 경유하는 generic node agent 기능은 포함하지 않는다.
- 메시지 기반 원격 실행, 로그, artifact, cancel, self-update 전체 생명주기는 다음 Phase에서 다룬다. - 메시지 기반 원격 실행, 로그, artifact, cancel, self-update 전체 생명주기는 다음 Phase에서 다룬다.
- Edge identity 검증, checksum/signature, 장기 credential 운영 정책은 MVP 이후 보안 강화 항목으로 분리한다. - Edge identity 검증, checksum/signature, 장기 credential 운영 정책은 MVP 이후 보안 강화 항목으로 분리한다.
- 폐기 사유: OTO는 iop native module이나 iop Edge domain agent가 아니라 독립 CI/CD runner/control plane 제품으로 전환한다. iop는 AI provider로 선택 소비하는 경계로 둔다.

View file

@ -3,7 +3,7 @@
## 위치 ## 위치
- Roadmap: `agent-roadmap/ROADMAP.md` - Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/edge-direct-oto-agent/PHASE.md` - Phase: `agent-roadmap/archive/phase/edge-direct-oto-agent/PHASE.md`
## 목표 ## 목표
@ -11,13 +11,12 @@
## 상태 ## 상태
[진행중] [폐기]
## 구현 잠금 ## 구현 잠금
- 상태: 잠금 - 상태: 해제
- 결정 필요: - 결정 필요: 없음
- [ ] iop2oto에서 `OTO Agent Registry 구현``OTO Bootstrap Command 발급``OTO Registration Online Smoke``OTO Registration Unlock Handoff` 선행 체인이 충족되었는지 확인한다.
## 범위 ## 범위
@ -40,13 +39,13 @@ bootstrap으로 설치된 Linux `oto-agent`가 설정 파일을 읽고 Edge에
## 완료 리뷰 ## 완료 리뷰
- 상태: 없음 - 상태: 폐기
- 요청일: 없음 - 요청일: 없음
- 완료 근거: `registration-state`와 iop2oto online smoke 근거가 남아 있어 완료 후보가 아니다. - 완료 근거: iop2oto online smoke와 workspace lock 해제 근거는 확인되었지만, 제품 기본 경로가 독립 OTO Server/Runner로 전환되어 iop Edge 직접 등록 Milestone은 완료 대상이 아니라 폐기한다.
- 리뷰 필요: - 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다 - [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다 - [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음 - 리뷰 코멘트: iop Edge 직접 연결 내용은 독립 Control Plane 분리 마이그레이션의 source map/evidence로만 보존한다.
## 범위 제외 ## 범위 제외
@ -69,13 +68,14 @@ bootstrap으로 설치된 Linux `oto-agent`가 설정 파일을 읽고 Edge에
- 구현 근거: `EdgeRegistrationClient``proto_socket`으로 Edge endpoint에 연결해 enrollment token을 `RegisterRequest`로 전송하고 `RegisterResponse`를 accepted/rejected 결과로 변환한다. - 구현 근거: `EdgeRegistrationClient``proto_socket`으로 Edge endpoint에 연결해 enrollment token을 `RegisterRequest`로 전송하고 `RegisterResponse`를 accepted/rejected 결과로 변환한다.
- 구현 근거: registration/config/CLI 검증은 `test/oto_agent_config_test.dart`, `test/oto_agent_registration_test.dart`, `test/oto_agent_cli_test.dart`, `test/oto_iop_connection_smoke_test.dart`에 있다. - 구현 근거: registration/config/CLI 검증은 `test/oto_agent_config_test.dart`, `test/oto_agent_registration_test.dart`, `test/oto_agent_cli_test.dart`, `test/oto_iop_connection_smoke_test.dart`에 있다.
- MVP 재시작 기준: bootstrap으로 시작한 background 프로세스의 pid/log를 기준으로 사용자가 상태를 확인하고 `oto agent run --config <path>`를 재실행한다. 자동 재시작과 systemd user service는 후속 강화로 둔다. - MVP 재시작 기준: bootstrap으로 시작한 background 프로세스의 pid/log를 기준으로 사용자가 상태를 확인하고 `oto agent run --config <path>`를 재실행한다. 자동 재시작과 systemd user service는 후속 강화로 둔다.
- 남은 작업: Edge 등록 완료 이후 최초 heartbeat 도착까지의 online 판정과 재시도 정책은 iop2oto의 `OTO Registration Unlock Handoff` 완료 근거와 맞춰 정리한다. - 남은 작업: Edge 등록 완료 이후 최초 heartbeat 도착까지의 online 판정과 재시도 정책은 iop2oto의 online smoke PASS evidence와 맞춰 OTO `registration-state` 정리한다.
- 선행 OTO Milestone: OTO-iop proto-socket 통신 기반 - 선행 OTO Milestone: OTO-iop proto-socket 통신 기반
- 선행 iop2oto Milestone: OTO Agent Registry 구현 → OTO Bootstrap Command 발급 → OTO Registration Online Smoke → OTO Registration Unlock Handoff - 선행 iop2oto Milestone: OTO Agent Registry 구현 → OTO Bootstrap Command 발급 → OTO Registration Online Smoke → OTO Registration Unlock Handoff
- iop2oto 진행 현황(2026-06-03): `OTO Agent Registry 구현`은 [진행중]이며, `OTO Bootstrap Command 발급`, `OTO Registration Online Smoke`, `OTO Registration Unlock Handoff`는 [계획]이다. - iop2oto 잠금 해제 근거(2026-06-04): `OTO Agent Registry 구현``OTO Bootstrap Command 발급`은 workspace lock에서 `enable`로 확인되었다. `OTO Registration Online Smoke``agent-task/archive/2026/06/m-oto-registration-online-smoke/03+01,02_smoke_evidence/complete.log` 기준 `make test-oto-registration-online-smoke` PASS, `registration accepted`, `node.online`, `reason=first_heartbeat` evidence가 확인되었다.
- 외부 의존 잠금: iop2oto에서 OTO agent registry, bootstrap command 발급, registration accepted 및 최초 heartbeat 기반 online smoke, OTO unlock handoff evidence가 충족되면 이 Milestone은 잠금 해제 후보가 된다. 런타임 판별은 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`에서 관리한다. - 외부 의존 잠금: `/config/workspace/.agent-roadmap-sync/locks.yaml``oto:oto-agent-registration` entry에서 모든 `rely-on.status``enable`로 동기화되어 이 Milestone의 구현 잠금은 해제되었다.
- 책임 경계: iop2oto는 Edge outbound enrollment를 받아들이는 registry/protocol/credential 기준을 정리한다. - 책임 경계: iop2oto는 Edge outbound enrollment를 받아들이는 registry/protocol/credential 기준을 정리한다.
- 책임 경계: OTO는 설치된 `oto-agent`가 해당 기준을 소비해 설정을 만들고 Edge에 직접 outbound 연결하는 상태 전이를 정리한다. - 책임 경계: OTO는 설치된 `oto-agent`가 해당 기준을 소비해 설정을 만들고 Edge에 직접 outbound 연결하는 상태 전이를 정리한다.
- 네트워크, 설치, packaging 관련 코드나 문서가 추가될 경우 관련 도메인 rule을 먼저 확인한다. - 네트워크, 설치, packaging 관련 코드나 문서가 추가될 경우 관련 도메인 rule을 먼저 확인한다.
- 구현 계획: `agent-task/m-oto-agent-registration/` 하위 plan-code-review 루프로 진행한다. - 구현 계획: `agent-task/m-oto-agent-registration/` 하위 plan-code-review 루프로 진행한다.
- 확인 필요: iop2oto `OTO Registration Unlock Handoff` 완료 evidence를 받아 Edge 등록 완료 이후 최초 heartbeat 도착까지의 online 판정과 재시도 정책을 OTO `registration-state`에 반영한다. - 확인 필요: Edge 등록 완료 이후 최초 heartbeat 도착까지의 online 판정과 재시도 정책을 OTO `registration-state`에 반영한다.
- 폐기 사유: OTO는 iop Edge에 직접 연결되는 domain agent가 아니라 `services/core` OTO Server와 `apps/runner` OTO runner 간 계약으로 재구성한다. 이 문서의 registration/heartbeat/bootstrap 근거는 `agent-roadmap/phase/independent-control-plane/milestones/control-plane-separation-migration.md`의 migration source로만 사용한다.

View file

@ -0,0 +1,28 @@
# Phase: 독립 Control Plane 기반 OTO
## 상태
[계획]
## 목표
OTO를 iop Edge에 직접 붙는 domain agent가 아니라, 독립 실행 가능한 경량 typed-command CI/CD runner와 선택적 OTO Control Plane을 가진 제품 구조로 전환한다.
현재 OTO CLI/runtime은 `apps/runner`로 옮기고, Flutter client와 Go core service를 분리해 OTO Server가 runner registry, bootstrap, job, log, artifact 상태를 소유하게 한다.
## Milestone 흐름
완료된 Milestone은 archive 경로를 가리키고, 검토중, 진행중, 계획, 스케치 또는 보류 Milestone은 이 Phase 하위 `milestones/` 경로를 가리킨다.
완료, 검토중, 진행중, 계획, 스케치 순서로 두어 아래로 갈수록 미래 작업에 가까워지게 정렬한다.
스케치 Milestone은 아직 구현 가능한 계획이 아니므로 계획 Milestone보다 아래에 둔다.
- [계획] 독립 Control Plane 분리 마이그레이션
- 경로: `agent-roadmap/phase/independent-control-plane/milestones/control-plane-separation-migration.md`
- 요약: iop에 구현된 OTO 등록/heartbeat/bootstrap 구조를 OTO 전용 Server/Runner 계약으로 이관하고, repo를 `apps/runner`, `apps/client`, `services/core` monorepo로 전환한다.
## Phase 경계
- OTO는 iop의 native module이나 iop Edge domain agent로 동작하지 않는다.
- iop는 AI agent/model/provider 기능이 필요한 경우 OTO 또는 NomadCode가 선택적으로 호출하는 외부 provider로 둔다.
- OTO Server는 runner registry, bootstrap, job dispatch, execution history, log/artifact 상태를 OTO 제품 책임으로 소유한다.
- OTO runner는 서버 없이도 로컬 typed-command CI/CD runtime으로 실행 가능해야 하며, OTO Server 연결은 중앙 관리가 필요할 때의 선택 경로로 둔다.
- NomadCode 같은 외부 제품은 OTO Server API를 소비할 수 있지만, OTO client/server 구현을 직접 복제하지 않는다.

View file

@ -0,0 +1,102 @@
# Milestone: 독립 Control Plane 분리 마이그레이션
## 위치
- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/independent-control-plane/PHASE.md`
## 목표
OTO repo를 독립 CI/CD 제품 monorepo로 전환하고, iop에 구현된 OTO 등록/heartbeat/bootstrap 검증 내용을 OTO 전용 Server/Runner 구조로 이관한다.
완료 후 OTO runner는 `apps/runner`에서 단독 실행되고, OTO Server는 `services/core`에서 runner registry와 bootstrap/online 상태를 소유하며, Flutter client는 `apps/client`에서 독립 운영 가능한 콘솔로 동작한다.
## 상태
[계획]
## 승격 조건
- 없음
## 구현 잠금
- 상태: 해제
- 결정 필요: 없음
## 범위
- 현재 루트 OTO Dart CLI/runtime을 `apps/runner`로 이동하고, root entrypoint/test/build helper를 monorepo 기준으로 정리한다.
- Flutter 형식의 독립 client를 `apps/client`에 두고, OTO Server를 제어하는 standalone web/desktop client 기준을 만든다.
- Go 기반 OTO Control Plane backend를 `services/core`에 만들고, runner registry, enrollment token, bootstrap command, heartbeat online 상태를 OTO 책임으로 옮긴다.
- iop/iop2oto에 구현된 OTO agent registration, first heartbeat online, bootstrap command 발급, smoke evidence 구조를 OTO Server/Runner 계약으로 마이그레이션한다.
- runner-server wire 계약은 Go server와 Dart runner/client가 공유할 필요가 생기는 메시지만 `proto/oto`에 둔다.
## 기능
### Epic: [monorepo-boundary] Monorepo 경계 전환
현재 단일 Dart CLI repo를 OTO 제품 monorepo로 재배치하고, 초기 공유 패키지는 만들지 않는 최소 구조를 확정한다.
- [ ] [runner-app] 현재 OTO CLI/runtime 소스, 테스트, pubspec, 실행 entrypoint가 `apps/runner` 기준으로 이동되어 기존 로컬 CLI 실행이 유지된다. 검증: runner 경로에서 기존 Dart analyze/test가 통과한다.
- [ ] [client-app] Flutter client가 `apps/client` 기준으로 추가되고, OTO 독립 콘솔의 source of truth가 client app에 위치한다. 검증: client 경로에서 Flutter analyze/test 또는 초기 scaffold 검증이 통과한다.
- [ ] [core-service] OTO Server backend가 `services/core` 기준으로 생성되고, health/readiness와 local run entrypoint가 준비된다. 검증: core service 경로에서 Go test 또는 smoke가 통과한다.
- [ ] [root-entrypoints] root `bin/`, Makefile 또는 동등한 helper가 runner/client/core 작업을 위임하도록 정리되어 monorepo root에서 개발 진입점이 명확하다.
### Epic: [iop-extraction] iop OTO 연결 구조 추출
iop의 Edge 구조를 그대로 복제하지 않고, OTO에 필요한 등록/heartbeat/bootstrap 부분만 OTO Server 용어와 책임으로 이관한다.
- [ ] [source-map] iop/iop2oto의 OTO 관련 구현 위치가 migration source map으로 정리되어 있다. 포함: config `agent_kind=oto-agent`, bootstrap URL/release URL, `agent register`, transport register handler, first heartbeat online, domain agent summary, smoke target.
- [ ] [term-translation] iop 용어가 OTO 용어로 번역되어 있다. 예: Edge -> OTO Server, Node/DomainAgent -> Runner, domain agent summary -> runner status/capability, Edge bootstrap -> runner enrollment/bootstrap.
- [ ] [discard-iop-scope] OTO Server로 가져오지 않을 iop 범위가 명시되어 있다. 포함: model serving, OpenAI/A2A routing, generic node adapter, iop control-plane wire, iop client domain-agent panel.
- [ ] [migration-tests] 기존 OTO-iop online smoke가 OTO Server 대상 smoke로 전환될 수 있는 테스트 계획과 fixture 경계가 정리되어 있다.
### Epic: [server-runner-contract] Server-Runner 연결 계약
OTO Server와 OTO runner가 독립 제품 계약으로 등록, online, capability, job dispatch의 최소 기반을 공유한다.
- [ ] [runner-register] runner 등록 요청/응답은 enrollment token뿐 아니라 runner id, alias, protocol version, command catalog/capability summary를 전달할 수 있게 정의된다.
- [ ] [online-state] registration accepted와 first heartbeat online 상태가 OTO Server registry에 분리되어 기록되고, heartbeat timeout/disconnect 실패 상태가 정의된다.
- [ ] [bootstrap-command] OTO Server가 runner bootstrap command를 발급하고, bootstrap script가 `apps/runner` binary/config를 기준으로 runner를 실행하는 흐름이 정의된다.
- [ ] [wire-contract] runner-server 장기 연결에 필요한 protobuf/proto-socket 또는 대체 wire 계약의 원본 위치와 생성물 경로가 확정된다. 검증: Go server와 Dart runner/client가 같은 계약을 기준으로 빌드 가능하다.
### Epic: [product-boundary] 제품 책임 경계 정리
OTO, iop, NomadCode의 소비 관계를 분리해 OTO가 독립 CI/CD 제품으로 유지되도록 한다.
- [ ] [oto-owns-cicd] OTO Server는 CI/CD runner registry, job, execution history, log/artifact 상태를 소유하고, iop Edge나 iop Control Plane을 전제로 하지 않는다.
- [ ] [iop-ai-provider] iop는 AI agent/model/provider 기능이 필요할 때만 선택적으로 호출하는 외부 provider로 정의되고, OTO runner 연결의 기본 경로에서 제외된다.
- [ ] [nomadcode-consumer] NomadCode는 OTO Server API를 소비하는 host 제품으로 정리되고, OTO client/server 구현을 native module로 복제하지 않는다.
- [ ] [downstream-roadmap] 기존 `edge-direct-oto-agent``message-based-build-agent` Phase/Milestone이 새 독립 OTO Server 방향에 맞게 후속 갱신 대상인지 정리된다.
## 완료 리뷰
- 상태: 없음
- 요청일: 없음
- 완료 근거: 계획 상태이며 기능 Task와 검증이 아직 충족되지 않았다.
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외
- OTO Server의 전체 job scheduling policy, artifact storage 운영 정책, 장기 권한/감사 모델을 완성하지 않는다.
- Jenkins 전체 기능을 한 번에 대체하지 않는다.
- iop native module 또는 iop Edge domain agent로 OTO를 연결하는 경로를 새 기본 경로로 유지하지 않는다.
- 초기 전환 단계에서 `packages/` 공유 패키지를 만들지 않는다. 둘 이상의 runtime이 실제 import해야 하는 코드가 생길 때만 후속으로 분리한다.
- AI 기반 pipeline 생성, 실패 분석, command 추천은 iop provider 연동 후속 작업으로 둔다.
## 작업 컨텍스트
- 관련 경로: `lib/**`, `test/**`, `assets/script/shell/oto_agent_bootstrap.sh`, `pubspec.yaml`
- 신규 경로: `apps/runner/`, `apps/client/`, `services/core/`, `proto/oto/`
- migration source: `../iop/apps/edge/internal/transport/server.go`, `../iop/apps/edge/internal/node/**`, `../iop/apps/edge/internal/service/service.go`, `../iop/apps/edge/cmd/edge/main.go`, `../iop/packages/go/config/config.go`, `../iop/Makefile`, `../iop/proto/iop/runtime.proto`
- 표준선(선택): OTO runner는 서버 없이도 로컬 typed-command CI/CD runtime으로 유지한다.
- 표준선(선택): OTO Server 연결은 중앙 registry, web control plane, 원격 job/log/artifact 관리가 필요할 때 사용하는 선택 경로다.
- 표준선(선택): `apps/runner`, `apps/client`, `services/core`를 먼저 만들고, 공유 코드는 실제 중복 import 수요가 생기기 전까지 `packages/`로 빼지 않는다.
- 표준선(선택): runner-server wire가 proto-socket 장기 연결을 유지한다면 원본 계약은 `proto/oto`에 둔다. HTTP/JSON만으로 충분한 client-core 표면은 `services/core` API 문서 또는 후속 contracts 경계에서 정리한다.
- 폐기된 경로: `agent-roadmap/archive/phase/edge-direct-oto-agent/PHASE.md``agent-roadmap/archive/phase/edge-direct-oto-agent/milestones/oto-agent-registration.md`는 iop Edge 직접 연결 기본 경로로는 폐기되었고, migration source/evidence로만 참조한다.
- 선행 작업: OTO-iop proto-socket 통신 기반, Edge bootstrap 계약, `oto-agent` 등록 흐름의 검증 근거
- 후속 작업: OTO Server job dispatch, log streaming, artifact reporting, typed command catalog remote execution, iop AI provider integration
- 확인 필요: 기존 iop 직접 연결 Phase를 완료/보류/폐기 중 어떤 상태로 정리할지는 이 Milestone의 `downstream-roadmap` Task에서 판단한다.