iop/agent-ops/rules/project/domain/edge/rules.md
toki ff161b9b12 feat: runtime reconnect config refresh milestone completion
- Add runtime-reconnect-config-refresh milestone and SDD
- Archive m-runtime-reconnect-config-refresh task with full logs
- Update edge/node domain rules, bootstrap, transport sessions
- Update config package and node.yaml configuration
- Update documentation and ROADMAP/PHASE files
2026-06-21 16:14:16 +09:00

13 KiB

domain last_rule_review_commit last_rule_updated_at
edge f59ecea97e 2026-06-21

edge

목적 / 책임

여러 Node를 하나의 로컬 실행 그룹으로 묶는 백엔드 실행 그룹 컨트롤러 영역이다. node 연결을 수락하고 token 기반 등록을 검증한 뒤 adapter/runtime 설정을 내려주며, iop-edge command 중심의 local/field 운영 UX, ops console, OpenAI-compatible HTTP, A2A JSON-RPC, Control Plane outbound connector를 내부 Edge-owned operation으로 수렴시킨다. Edge는 자신의 설정, Node registry, runtime/automation 상태의 원본 소유자다.

포함 경로

  • apps/edge/cmd/edge/ — edge CLI 진입점과 serve/console/config/env/setup/node/nodes/smoke 커맨드
  • apps/edge/internal/bootstrap/ — fx 의존성 주입과 서버 시작/종료 lifecycle
  • apps/edge/internal/controlplane/ — Edge에서 Control Plane으로 outbound 연결하는 proto-socket connector
  • apps/edge/internal/events/ — run/node event in-process fanout bus
  • apps/edge/internal/input/ — OpenAI-compatible/A2A 입력 서버 lifecycle 관리
  • apps/edge/internal/node/ — 연결된 node registry와 node 선택
  • apps/edge/internal/openai/ — OpenAI-compatible HTTP 입력 표면
  • apps/edge/internal/opsconsole/ — edge-local 운영 콘솔
  • apps/edge/internal/service/ — console/HTTP 입력 표면이 공유하는 실행·명령 application service
  • apps/edge/internal/transport/ — node 연결 수락, RegisterRequest/Response 처리, run event 수신
  • apps/edge/README.md — edge 실행 흐름과 운영 표면 설명

제외 경로

  • apps/node/ — 실제 모델 실행과 adapter 관리
  • apps/control-plane/ — 여러 Edge 연결 관리와 운영 제어 API 제공 영역
  • apps/client/ — Control Plane을 소비하는 Flutter client UI/UX 영역
  • apps/worker/ — 비동기 작업 처리 예정 영역
  • packages/go/ — 공통 설정/관측성/인증 Go 패키지
  • proto/ — 메시지 계약 원본과 생성물

주요 구성 요소

  • transport.Server — proto-socket TCP 서버 wrapper; NodeStore와 Registry를 모두 주입받아 등록 흐름을 처리
  • node.Registry — 연결된 node의 NodeEntry 저장/조회 (ID·alias 이중 인덱스, 동시성 안전)
  • node.NodeEntry — node ID, alias, TCP client 정보
  • node.NodeStore — 사전 등록된 NodeRecord를 token/ID로 조회; 설정 파일에서 seed
  • node.NodeRecord — 사전 등록된 node 정의 (ID, alias, token, adapter/runtime config)
  • node.BuildConfigPayload()NodeRecord의 adapter 설정을 proto NodeConfigPayload로 변환하는 mapper
  • rootCmd() / resolveConfigPath() — bundle-local edge.yaml, binary-adjacent config, repo-dev fallback을 처리하는 CLI entrypoint
  • config init / config check / config print — bundle-local Edge 설정 생성·검증·출력 command
  • env — config discovery, advertise host, log path, node bootstrap URL, OpenAI/A2A URL을 서버 기동 없이 출력하는 진단 command
  • node registeredge.yamlnodes[]를 보존형 YAML patch로 추가/갱신하고 one-line bootstrap command를 출력하는 command
  • nodes list — 설정된 node record를 offline/configured 상태로 조회하는 command
  • smoke openai/healthz, /v1/models, /v1/chat/completions를 확인하는 OpenAI-compatible 진단 command
  • bootstrap.Module — fx lifecycle에 bootstrap.Runtime start/stop을 연결
  • bootstrap.Runtime — logger, registry, node store, event bus, service, transport server, input manager, artifact server, Control Plane connector를 묶는 실행 조립체
  • bootstrap.ArtifactServer — Node bootstrap artifact를 제공하는 Edge-local HTTP server
  • controlplane.Connector — Control Plane TCP wire에 outbound로 연결하고 hello/status/event relay를 처리하는 connector
  • controlplane.StatusProvider — Control Plane status request에 답할 Edge-owned node snapshot provider boundary
  • events.BusRunEventEdgeNodeEvent subscriber fanout 및 bounded replay
  • service.Service — node 선택, run dispatch, cancel/terminate-session, node command 요청을 표면 중립 DTO로 제공
  • service.NodeSnapshot — Control Plane status response에 쓰는 Edge-owned node snapshot DTO
  • service.RunHandle — foreground run event stream과 dispatch metadata를 함께 들고 있는 handle
  • service.NodeCommandView / UsageStatusView — console/HTTP/RPC surface가 공유할 수 있는 node command 결과 DTO
  • input.Manager — OpenAI-compatible 서버와 A2A 서버 lifecycle 소유자
  • openai.Server/v1/models, /v1/chat/completions, SSE stream, strict output policy, Ollama API passthrough를 service로 연결하는 HTTP 표면
  • a2a.Server / a2a.TaskStore — A2A message/send, tasks/get, tasks/cancel과 task 상태 보관
  • opsconsole.Run — edge-local console loop와 slash command 처리
  • opsconsole.EventRouter — run/node event를 edge console 출력으로 라우팅

유지할 패턴

  • edge는 사전 등록된 node 정의를 검증하고 연결 상태를 registry에 반영하는 역할을 먼저 안정화한다.
  • edge는 단순 gateway가 아니라 Node registry, adapter/profile configuration, routing, stream relay의 소유자다.
  • edge는 edge.yaml, node 정의, adapter/runtime 설정, 로컬 runtime/automation 상태의 canonical owner다. Control Plane 연결 대상이 바뀌어도 Edge 실질 데이터 migration을 요구하지 않는 구조를 유지한다.
  • 공식 local/field 운영 UX는 iop-edge command 표면에 모은다. repo helper script나 README 절차를 공식 사용자 경로로 승격하지 않는다.
  • iop-edge command 표면은 bootstrap, bundle-local config, env/config 진단, node 등록 command 발급, smoke, Control Plane 없는 단일 Edge 유지보수 범위로 유지한다. 후속 specialized agent enrollment command도 같은 local/field fallback 원칙을 따른다. 상시 multi-edge 운영 UI/API 역할을 CLI에 확대하지 않는다.
  • config init은 bundle-local edge.yaml template을 만들고, env는 서버를 기동하지 않고 effective environment를 설명해야 한다.
  • node register는 사용자에게 대상 OS에 맞는 완성된 bootstrap URL과 실제 token 값을 포함한 한 줄 명령을 출력하는 경로를 유지한다. Linux/macOS는 curl -fsSL ... | bash -s ..., Windows native는 PowerShell .ps1 bootstrap과 Start-IopNode를 기준으로 한다. 사용자가 기본 경로에서 node.yaml을 직접 만들거나 iop-node serve --config ...를 직접 실행하게 하지 않는다.
  • bootstrap 사용자 기본 명령은 완성된 bootstrap URL과 positional token 하나만 포함한다. Edge address, artifact URL, target/platform, install/config path, metrics port, workspace path 같은 값은 Edge 설정이나 bootstrap script 기본값에 굽고, 사용자가 직접 추가 설정해야 하는 경우에는 기본 명령과 분리된 optional override로만 안내한다.
  • 사용자에게 실행 방법을 안내할 때는 placeholder 형식을 쓰지 않는다. token 같은 secret을 현재 채널에 표시할 수 없으면 runnable command처럼 꾸미지 말고, 먼저 안전한 secret 전달 절차를 끝낸 뒤 실제 값이 들어간 완성 명령만 제공한다.
  • 사용자 기본 명령 안에 ssh, awk, 원격 파일 조회, command substitution을 섞어 token을 즉석에서 추출하게 하지 않는다.
  • 외부 OpenAI-compatible HTTP API는 입력 표면일 뿐이며, 내부 실행 모델 전체를 대표하지 않는다.
  • node가 연결 직후 RegisterRequest를 보내고 edge가 RegisterResponse로 중앙 설정을 응답하는 흐름을 유지한다.
  • Registry는 동시성 안전성을 유지하고 외부로 내부 map을 노출하지 않는다.
  • NodeStore는 설정 파일에서 한 번 seed되며 런타임 중 변경하지 않는다; token 중복·빈 token은 LoadFromConfig에서 즉시 거부한다.
  • adapter config 변환(mapper)은 node.BuildConfigPayload()에서만 수행하고 transport 레이어에 변환 로직을 두지 않는다.
  • 내부 실행 요청은 adapter + target으로 표현한다. 외부 API 호환 경계의 model 표현을 edge 내부 책임 전체로 확장하지 않는다.
  • ops console과 HTTP 입력 표면은 apps/edge/internal/service를 호출하는 얇은 어댑터로 유지한다. node 선택, run dispatch, command request 생성은 service 계층에서 공유한다.
  • OpenAI-compatible 경계의 model과 A2A 경계의 Task/JSON-RPC 표현은 입력 표면 안에서만 유지하고, edge 내부 실행은 service.SubmitRun()adapter + target 요청으로 변환한다.
  • OpenAI-compatible /v1/modelsopenai.models를 우선하고, 없으면 openai.target을 advertised model로 사용한다. 내부 target override와 외부 model echo 정책을 혼동하지 않는다.
  • OpenAI/Ollama passthrough성 옵션은 입력 표면에서 명시적으로 변환하고, node adapter의 Ollama 실행 계약을 우회하지 않는다.
  • run/node event fanout은 events.Bus를 통해 수행하고, transport handler에서 console/HTTP 표면으로 직접 출력하거나 응답하지 않는다.
  • 입력 서버 lifecycle은 input.Manager가 소유하며, bootstrap runtime이 transport server와 함께 시작/종료한다.
  • Control Plane connector는 disabled 설정 또는 빈 wire_addr에서 no-op이어야 한다. 연결 재시도와 stop은 Edge serve lifecycle에 묶으며, Control Plane attachment 변경이 Edge-owned 설정/상태의 소유권을 바꾸지 않는다.
  • Control Plane status 응답은 service.ServiceListNodeSnapshots() 같은 Edge-owned 표면에서 만든다. connector가 registry나 transport internals를 직접 읽어 제품 계약을 만들지 않는다.
  • Control Plane node lifecycle event relay는 events.Bus 구독으로 수행하고, event metadata에는 필요한 Edge identity만 보강한다.
  • CLI, ops console, HTTP/A2A 입력 표면, Control Plane wire connector가 같은 Edge operation을 노출할 때는 service.Service 같은 표면 중립 application service로 수렴시킨다. registry 변경, run dispatch, command request 로직을 표면별로 복제하지 않는다.
  • apps/edge/cmd/edge/**, apps/edge/internal/bootstrap/**, apps/edge/internal/controlplane/**, apps/edge/internal/transport/**, apps/edge/internal/service/**, apps/edge/internal/events/**, apps/edge/internal/input/**, apps/edge/internal/openai/**, apps/edge/internal/opsconsole/**, apps/edge/internal/node/**, console/HTTP/Control Plane 입출력, run/node event relay를 바꾼 뒤에는 testing domain rule의 작업 후 검증 기준을 따른다.

다른 도메인과의 경계

  • node: edge는 node 내부 adapter를 직접 실행하지 않는다. edge는 사전 등록 정보와 연결 registry를 기반으로 요청을 보낼 대상과 실행 설정을 관리하고, TCP/protobuf로 RunRequest/CancelRequest/NodeCommandRequest를 보낸다.
  • platform-common: edge 설정, metrics, protobuf 타입은 platform-common 계약을 따른다.
  • external input surfaces: OpenAI-compatible HTTP와 A2A JSON-RPC는 edge inbound adapter이며, 내부 transport/protobuf 경계를 대체하지 않는다.
  • control-plane: control-plane은 Edge를 통해 시스템을 제어한다. Edge domain은 outbound connector와 Edge-owned status/event/command 응답을 소유하고, control-plane domain은 server endpoint와 Edge connection/control view를 소유한다. Control Plane 없는 bootstrap/local/field/진단 fallback은 iop-edge command 표면에 남긴다.

금지 사항

  • edge를 구현하면서 node adapter 실행 로직을 복제하지 않는다.
  • OpenAI-compatible HTTP API를 추가할 때 내부 TCP/protobuf 경계를 우회하지 않는다.
  • A2A/OpenAI/console 입력 표면에서 registry client에 직접 RunRequest를 조립·전송하지 않는다. 공유 로직은 service.Service에 둔다.
  • Control Plane 구현 전이라도 Node를 Control Plane에 직접 연결하는 경로를 edge 도메인에 추가하지 않는다.
  • Control Plane을 Edge 설정, Node registry, runtime/automation 상태의 원본 저장소로 전제하지 않는다.
  • Control Plane connector에서 Node token, Node address, transport client 내부 상태를 Control Plane status 계약으로 노출하지 않는다.
  • Control Plane 도입만을 이유로 iop-edge config, env, node register, nodes list, smoke, setup 같은 local/field fallback command 경로를 제거하거나 제품 기본 계약에서 제외하지 않는다. 축소는 별도 roadmap 결정과 대체 fallback 기준이 있을 때만 다룬다.
  • node register와 bootstrap UX에 named environment parameter 조합을 기본 사용자 경로로 노출하지 않는다.
  • bootstrap 안내를 IOP_*= 환경 변수 나열, shell wrapper, 원격 token 조회, 수동 node.yaml 작성, 수동 iop-node serve --config ... 흐름으로 길게 만들지 않는다. 이런 값은 디버그/고급 override 문서로만 분리한다.
  • gRPC 또는 WebSocket을 기본 내부 transport로 바꾸지 않는다.
  • proto/gen/iop/*.pb.go 생성 파일을 직접 수정하지 않는다.