- Move contract files to inner/outer directory structure - Add create-contract and update-contract skills - Update agent-ops rules and domain rules - Update roadmap and SDD documentation - Update README files across apps
13 KiB
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 의존성 주입과 서버 시작/종료 lifecycleapps/edge/internal/controlplane/— Edge에서 Control Plane으로 outbound 연결하는 proto-socket connectorapps/edge/internal/events/— run/node event in-process fanout busapps/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 serviceapps/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로 조회; 설정 파일에서 seednode.NodeRecord— 사전 등록된 node 정의 (ID, alias, token, adapter/runtime config)node.BuildConfigPayload()—NodeRecord의 adapter 설정을 protoNodeConfigPayload로 변환하는 mapperrootCmd()/resolveConfigPath()— bundle-localedge.yaml, binary-adjacent config, repo-dev fallback을 처리하는 CLI entrypointconfig init/config check/config print— bundle-local Edge 설정 생성·검증·출력 commandenv— config discovery, advertise host, log path, node bootstrap URL, OpenAI/A2A URL을 서버 기동 없이 출력하는 진단 commandnode register—edge.yaml의nodes[]를 보존형 YAML patch로 추가/갱신하고 one-line bootstrap command를 출력하는 commandnodes list— 설정된 node record를 offline/configured 상태로 조회하는 commandsmoke openai—/healthz,/v1/models,/v1/chat/completions를 확인하는 OpenAI-compatible 진단 commandbootstrap.Module— fx lifecycle에bootstrap.Runtimestart/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 servercontrolplane.Connector— Control Plane TCP wire에 outbound로 연결하고 hello/status/event relay를 처리하는 connectorcontrolplane.StatusProvider— Control Plane status request에 답할 Edge-owned node snapshot provider boundaryevents.Bus—RunEvent와EdgeNodeEventsubscriber fanout 및 bounded replayservice.Service— node 선택, run dispatch, cancel/terminate-session, node command 요청을 표면 중립 DTO로 제공service.NodeSnapshot— Control Plane status response에 쓰는 Edge-owned node snapshot DTOservice.RunHandle— foreground run event stream과 dispatch metadata를 함께 들고 있는 handleservice.NodeCommandView/UsageStatusView— console/HTTP/RPC surface가 공유할 수 있는 node command 결과 DTOinput.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— A2Amessage/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-edgecommand 표면에 모은다. repo helper script나 README 절차를 공식 사용자 경로로 승격하지 않는다. iop-edgecommand 표면은 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-localedge.yamltemplate을 만들고,env는 서버를 기동하지 않고 effective environment를 설명해야 한다.node register는 사용자에게 대상 OS에 맞는 완성된 bootstrap URL과 실제 token 값을 포함한 한 줄 명령을 출력하는 경로를 유지한다. Linux/macOS는curl -fsSL ... | bash -s ..., Windows native는 PowerShell.ps1bootstrap과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/models는openai.models를 우선하고, 없으면openai.target을 advertised model로 사용한다. 내부 target override와 외부 model echo 정책을 혼동하지 않는다. - OpenAI/Ollama passthrough성 옵션은 입력 표면에서 명시적으로 변환하고, node adapter의 Ollama 실행 계약을 우회하지 않는다.
- OpenAI-compatible, A2A, Edge-Node, Control Plane connector, config/runtime refresh 계약 상세는
agent-contract/index.md에서 매칭 문서를 확인하고 README/rules에 schema 본문을 반복하지 않는다. - 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.Service의ListNodeSnapshots()같은 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를 바꾼 뒤에는testingdomain 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-edgecommand 표면에 남긴다.
금지 사항
- 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생성 파일을 직접 수정하지 않는다.