# iop 프로젝트 규칙

## 프로젝트 개요

- IOP(Inference Operations Platform)는 Control Plane - Edge - Node 계층 구조를 기반으로 모델 서빙과 오케스트레이션을 다루는 실행 오케스트레이션 모노레포이다. 핵심 서비스는 Go이고 운영 client는 Flutter/Dart이다.
- 내부 실행 개념은 model 중심이 아니라 `adapter + target` 중심으로 정리한다. 외부 OpenAI-compatible 경계나 외부 CLI 인자에서는 호환성을 위해 `model` 표현이 남을 수 있다.
- 현재 구현 중심은 `apps/node`와 `apps/edge`의 Edge-Node 실행 경로, `apps/control-plane`의 Control Plane-Edge/Client wire baseline, `apps/client`의 Flutter 운영 UI, `iop-edge` command 중심의 local/field 운영 UX, OpenAI-compatible/A2A 입력 표면, CLI adapter logical session/runtime이다.
- `apps/control-plane`은 health/readiness HTTP, Client proto-socket WebSocket, Edge proto-socket TCP 연결 baseline을 가진 제어 레이어이다. Edge의 실질 설정과 상태 원본을 소유하지 않고, 연결된 Edge를 제어하기 쉽게 만든다.
- `apps/worker`는 CLI placeholder 수준이므로 본격 구현 전 별도 domain rule을 만들거나 갱신한다.

## 주요 구조

- `apps/node/` — Edge에 연결되는 실행자. provider adapter execution과 runtime 실행을 담당하며, 승인된 execution preset의 request-scoped workspace/tool 실행은 provider runtime과 분리된 전용 경계로 수용한다.
- `apps/edge/` — 여러 Node를 묶는 백엔드 실행 그룹 컨트롤러. token 기반 등록, node registry, node 설정 전달, routing, stream relay, ops console, OpenAI-compatible/A2A 입력 표면을 담당한다.
- `apps/control-plane/` — 여러 Edge를 연결하고 상태 조회, 설정 변경 요청, 명령 전달, 이벤트 수신, 운영 제어 API 제공을 담당할 Go 기반 제어 서버이다. Edge 데이터의 canonical store가 아니다.
- `apps/client/` — Control Plane을 통해 Edge/Node 운영 상태를 보여주는 Flutter client이다.
- `apps/worker/` — 비동기 작업 처리 예정 영역이다. 현재 placeholder이다.
- `packages/go/` — 설정, 인증, 이벤트 helper, host setup, 정책, 메타데이터, 작업, 관측성, 버전 등 Go 공통 패키지이다.
- `packages/flutter/` — Flutter 재사용 패키지 root이다. 현재 `packages/flutter/iop_console`이 IOP-owned console package이다.
- `proto/iop/` — IOP 메시지 계약 원본이다.
- `proto/gen/iop/` — protobuf 생성물이다.
- `configs/` — 앱별 YAML 설정 예시이다.
- `scripts/dev/` — repo 내부 개발 진단 helper 위치이다. field 사용자 기본 경로로 안내하지 않는다.
- `build/bin/` — 로컬 바이너리 산출 위치이다.
- `build/artifacts/` — Node bootstrap artifact 산출 위치이다.
- `build/packages/` — Edge host에 전달할 압축 배포 archive 산출 위치이다. archive는 `iop-edge`와 `artifacts/`를 포함하고, Edge host에서 config 확정 후 Node bootstrap을 제공하는 흐름을 기준으로 한다.
- `scripts/` — 보조 E2E smoke와 입력 표면 검증 스크립트이다.
- `Makefile` — 빌드와 테스트 진입점을 정의한다.
- `docs/` — 사람용 최신 가이드만 둔다. local 테스트 환경값은 `agent-test/local/rules.md`에 둔다.

## 기술 스택

- 언어/모듈: Go `1.24`, module `iop`
- CLI: `github.com/spf13/cobra`
- 설정: `github.com/spf13/viper`, YAML
- DI: `go.uber.org/fx`
- 로깅: `go.uber.org/zap`
- 메트릭/헬스: Prometheus HTTP handler
- 저장소: `modernc.org/sqlite`
- 메시지 계약: `google.golang.org/protobuf`, `proto/iop/*.proto`
- 내부 소켓: `git.toki-labs.com/toki/proto-socket/go`
- Client: Flutter/Dart, `proto_socket` Dart client, Dart protobuf 생성물

## 프로젝트 특화 컨벤션

- Preserve the existing hexagonal structure. Keep host-neutral provider interfaces in `packages/go/execution`, protobuf translation at `apps/node/internal/node`, and adapter/store implementations outside that core.
- Execution preset의 request-scoped workspace/tool 실행은 IOP Edge가 조정하고 선택된 IOP Node가 수행한다. provider `RunRequest`, caller metadata, closed `NodeCommand` 또는 `packages/go/execution`에 이 책임을 섞지 않고 전용 typed Edge-Node request/result 경계로 둔다.
- request-scoped tool executor는 operator가 승인한 workspace root, path containment, bounded process/output/timeout/cancel을 강제한다. 범용 interactive shell, persistent host process, desktop session, scheduler 또는 caller가 고른 임의 Node/path 실행으로 확대하지 않는다.
- 새 node 어댑터는 `runtime.Adapter`를 구현하고 `apps/node/internal/bootstrap/module.go`에서 registry에 등록한다.
- 내부 실행 요청과 상태 저장에서는 `adapter`, `target`, `execution` 용어를 우선한다. `model`은 외부 API 호환이나 legacy placeholder일 때만 허용한다.
- Control Plane은 Node를 직접 연결/스케줄링하지 않고 Edge를 통해 시스템을 제어한다. Edge는 자신의 설정, 로컬 런타임 상태, Node registry의 원본을 소유한다. 여러 Control Plane이 있더라도 Edge는 실질 데이터 이전 없이 다른 Control Plane으로 연결 대상을 옮길 수 있어야 한다.
- 사용자 실행, 로컬/dev 배포, field 테스트, 임시 Control Plane 대체 흐름은 사용법을 `scripts/dev/`, 보조 smoke script, 별도 dev deploy 바이너리, 모델용 skill로 흩뜨리지 않고 `iop-edge`와 `iop-node` command 표면에 모은다. helper script가 필요해도 공식 사용자 경로가 되면 안 된다.
- Control Plane이 없는 테스트/개발 배포 단계에서는 `edge.yaml`을 테스트용 Edge-owned source of truth로 본다. Node별 id/alias/token/adapter/runtime 설정은 Edge config의 `nodes[]`에서 관리한다.
- Node 사용자 UX는 bootstrap 명령 하나로 끝나야 한다. 사용자가 `node.yaml`을 만들거나 편집하거나 `iop-node serve --config ...`를 직접 실행하는 흐름을 기본 경로로 두지 않는다. bootstrap 내부에서 임시 상태나 설정 파일을 만들 수 있더라도 이는 구현 세부이며 사용자 가이드와 기본 운영 UX에 노출하지 않는다.
- 바이너리 배포 UX는 repo checkout 위치에 묶이지 않아야 한다. `iop-edge`/`iop-node`는 아무 작업 디렉터리에서 실행 가능해야 하며, 로컬/dev bundle에서는 Edge 설정을 바이너리와 같은 디렉터리의 `edge.yaml` 같은 구조화된 config에 모으는 방향을 우선한다. Node 쪽은 별도 사용자 config 파일이 아니라 Edge가 제공하는 bootstrap으로 연결한다.
- Edge-Node 내부 통신은 TCP 기반 protobuf 메시지 흐름을 우선한다. 브라우저/앱 표면이 필요한 경계는 proto-socket WebSocket/WSS를 사용할 수 있다. gRPC 도입, Edge-Node 기본 transport의 WebSocket 전환, actor/FSM/plugin framework 도입은 금지한다.
- protobuf 계약 변경 시 `proto/iop/*.proto`를 먼저 수정하고 `make proto`로 `proto/gen/iop/*.pb.go`를 갱신한다. 생성 파일은 직접 수정하지 않는다.
- Edge/Node 앱 설정 구조 변경 시 `packages/go/config`의 struct/default와 `configs/*.yaml` 예시를 함께 확인한다. Control Plane 로컬 설정 구조 변경 시 `apps/control-plane`의 config loader와 `configs/control-plane.yaml` 예시를 함께 확인한다.
- 테스트는 변경 범위에 맞춰 `go test ./...` 또는 대상 패키지 테스트를 실행한다.
- 사용자 실행 파이프라인에 닿는 작업을 한 경우, 작업 완료 후 `agent-ops/rules/project/domain/testing/rules.md`의 검증 기준을 따른다.
- 활성 `agent-task`의 dry-run, worker/review 실행, blocked retry와 상태 관찰은 사용자의 명시적 실행 요청이 있을 때만 `agent-ops/skills/common/orchestrate-agent-task-loop/scripts/dispatch.py` dispatcher로 수행한다. 이 dispatcher는 Agent-Ops 작업 진행 전용이며 IOP 제품 runtime/API orchestration 경로가 아니다. execution preset, `/v1/messages` 단일 요청, provider stage와 workspace tool loop의 설계·구현·검증에서 dispatcher를 architecture component, caller continuation 또는 test harness로 사용하거나 참조하지 않는다.
- 이 프로젝트에서는 `agent-ops/rules/common/rules-roadmap.md`의 기존 task-group-only 및 `Roadmap Completion` 단건 반영 문구를 legacy 호환 규칙으로 한정한다. 새 `m-*` PLAN/CODE_REVIEW/complete.log는 첫 줄의 `milestone-task=<id>[,<id>...]`로 Milestone Task 기여 범위를 보존한다. 이 metadata나 단건 PASS는 완료 선언이 아니며, `sync-milestone-workstate`가 같은 Milestone task group의 완료 로그를 id별로 집계해 현재 Task 설명·검증·SDD evidence가 모두 충족된 경우에만 체크한다. 기존 `Roadmap Completion`은 first-line metadata가 없는 archive 로그의 호환 evidence로만 취급한다.
- field/bootstrap 작업은 `testing` domain rule을 따르고, 실제 local 환경값이 필요하면 `agent-test/local/rules.md`를 따른다.
- Node, specialized agent, domain agent, Control Plane enrollment 등 사용자가 대상 host에서 실행하는 bootstrap/install command 작업은 `agent-ops/rules/project/domain/testing/rules.md`의 one-line bootstrap UX 기준을 따른다.
- 상세 DB schema, event schema, permission/policy/audit model, federation, mTLS 구현 세부는 각 작업에서 별도로 결정한다.

## 도메인 룰 로딩

- 아래 도메인 매핑에 해당하는 작업에서 해당 domain 최초 진입 시 domain rule을 1회 읽는다.
- 이미 읽은 domain rule은 같은 세션에서 반복해서 읽지 않는다.
- 사용자 실행 파이프라인에 닿는 작업의 검증 단계에서는 `testing` domain rule을 1회 읽는다.

## 도메인 매핑

| 경로 패턴 | 도메인 | rules.md |
|----------|--------|----------|
| `apps/node/**` | node | `agent-ops/rules/project/domain/node/rules.md` |
| `apps/edge/**` | edge | `agent-ops/rules/project/domain/edge/rules.md` |
| `apps/control-plane/**` | control-plane | `agent-ops/rules/project/domain/control-plane/rules.md` |
| `apps/client/**` | client | `agent-ops/rules/project/domain/client/rules.md` |
| `packages/flutter/**` | client | `agent-ops/rules/project/domain/client/rules.md` |
| `packages/go/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `proto/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `configs/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `scripts/dev/**` | testing | `agent-ops/rules/project/domain/testing/rules.md` |
| `scripts/e2e-*.sh` | testing | `agent-ops/rules/project/domain/testing/rules.md` |
| `scripts/fixtures/**` | testing | `agent-ops/rules/project/domain/testing/rules.md` |
| `Makefile` | testing | `agent-ops/rules/project/domain/testing/rules.md` |
| `docker-compose.yml` | testing | `agent-ops/rules/project/domain/testing/rules.md` |
| `cmd/iop-provider-smoke/**` | testing | `agent-ops/rules/project/domain/testing/rules.md` |
| `scripts/inventory-query/**` | testing | `agent-ops/rules/project/domain/testing/rules.md` |
| `scripts/readability_*` | testing | `agent-ops/rules/project/domain/testing/rules.md` |

## 도메인 후보

- `worker`: `apps/worker/**`가 placeholder를 넘어 작업 큐 소비/재시도/결과 저장을 구현하기 시작할 때 생성한다.
- `agent-client`: `agent-client/**`의 Claude/Pi host-local gateway·install 흐름을 반복 유지보수 대상으로 다루기 시작할 때 `create-domain-rule`로 별도 도메인 룰을 생성한다.

## 스킬 라우팅

- 설정 후보 기록, `설정으로 빼`, `설정으로 빼놔`, `설정값으로 분리해`, `설정으로 조절하게 해`: 현재 작업 맥락에서 사용자가 설정으로 조절할 필요가 있다고 지정한 내용을 뜻한다. 숨김·제외 의미로 해석하지 않는다.
- 설정 후보 기록은 `agent-ops/skills/common/update-agent-ui/SKILL.md`를 `view-id=settings`, `mode=definition`, `status=계획`, `post-validate=true`, `post-sync=false`로 사용해 `agent-ui/definition/views/settings/index.md`에 `SET-NNN` 항목으로 upsert한다. 정확한 config key나 component id가 아직 없어도 작업 맥락으로 등록하며, 새 항목과 변경 항목은 `대기`, 구현·검증 근거가 확인된 항목만 `완료`로 둔다.
- 설정 UI 설계·구현에서는 `대기` 항목만 대상으로 삼는다. `완료` 항목을 변경하면 같은 id를 유지하고 `대기`로 되돌린다.
- UI 없는 사용자 CRUD, OpenAI-compatible 사용자/principal 추가·조회·수정·비활성화·삭제, principal token 운영 CRUD: `agent-ops/skills/project/iop-user-crud-ops/SKILL.md`
- Confluence 문서 작성, 컨플 문서 생성·갱신·검토, Lab2 문서 작성, lgucorp 위키 업데이트: `agent-ops/skills/project/lgucorp-confluence-docs/SKILL.md`
- dev 또는 dev-corp OpenAI-compatible 사용자 token 발급·추가, `dev에 <사용자> 사용자 토큰 만들어줘`, `dev-corp에 <사용자> 사용자 토큰 만들어줘`, principal_ref token 등록, principal alias 매핑, raw IOP token 1회 전달: `agent-ops/skills/project/openai-usage-token-issue/SKILL.md`
- dev-corp 배포, dev-corp runtime 배포, 회사망 mac-mini Edge/Node dev-corp 환경 배포, dev-corp provider pool 배포, dev-corp OpenAI-compatible capacity smoke 검증: `agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md`
- dev 배포, dev-runtime 배포, Edge/Node dev 환경 배포, provider pool 배포, OpenAI-compatible capacity smoke 검증: `agent-ops/skills/project/dev-runtime-deploy/SKILL.md`
- 사용자 실행 파이프라인 검증, repo 내부 edge-node 진단, 메시지 2회 왕복, edge command 응답, 보조 E2E smoke, full-cycle 실제 구동, `scripts/dev/edge.sh`/`scripts/dev/node.sh` 진단 테스트: `agent-ops/skills/project/e2e-smoke/SKILL.md`
- agent-task의 작업들 실행해, agent-task 무인 실행, task-group dry-run/live pass, blocked retry, Go parity/disposal 확인: `agent-ops/skills/common/orchestrate-agent-task-loop/SKILL.md`
- field 테스트 포트, artifact/bootstrap HTTP, 외부 테스트 환경: `agent-test/local/rules.md`를 따른다.
- bootstrap/install UX, Agent Bootstrap, specialized agent 등록, Control Plane enrollment: `testing` domain rule과 `agent-test/local/rules.md`를 따른다.
- 반복 작업이 확인되면 `agent-ops/skills/project/<skill-name>/SKILL.md`를 생성하고 이 표에 등록한다.
