refactor: organize contract files and update agent-ops structure

- 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
This commit is contained in:
toki 2026-06-27 07:02:48 +09:00
parent 46bd8563e2
commit de78479670
32 changed files with 607 additions and 137 deletions

View file

@ -12,7 +12,7 @@
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**`와 `agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다. - `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**`와 `agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다. - agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다. - tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 외부 API, 런타임 호출, 프로젝트 간 연동, 요청/응답 스키마 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다. - API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다. **세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
@ -32,7 +32,7 @@
- skill 생성 - skill 생성
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW - agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test - 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- agent-contract 생성/갱신, 계약 문서 작성/정리, 제공/소비 계약 포인터 관리 - 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- README 생성 - README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기 - 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신 - 로드맵/마일스톤 생성·갱신
@ -48,3 +48,4 @@
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.** **테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`) - local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

View file

@ -12,7 +12,7 @@
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**`와 `agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다. - `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**`와 `agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다. - agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다. - tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 외부 API, 런타임 호출, 프로젝트 간 연동, 요청/응답 스키마 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다. - API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다. **세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
@ -32,7 +32,7 @@
- skill 생성 - skill 생성
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW - agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test - 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- agent-contract 생성/갱신, 계약 문서 작성/정리, 제공/소비 계약 포인터 관리 - 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- README 생성 - README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기 - 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신 - 로드맵/마일스톤 생성·갱신
@ -48,3 +48,4 @@
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.** **테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`) - local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

View file

@ -12,7 +12,7 @@
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다. - `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다. - agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다. - tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 외부 API, 런타임 호출, 프로젝트 간 연동, 요청/응답 스키마 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다. - API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다. **세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
@ -32,7 +32,7 @@
- skill 생성 - skill 생성
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW - agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test - 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- agent-contract 생성/갱신, 계약 문서 작성/정리, 제공/소비 계약 포인터 관리 - 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- README 생성 - README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기 - 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신 - 로드맵/마일스톤 생성·갱신
@ -48,3 +48,4 @@
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.** **테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`) - local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

View file

@ -12,7 +12,7 @@
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다. - `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다. - agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다. - tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 외부 API, 런타임 호출, 프로젝트 간 연동, 요청/응답 스키마 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다. - API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다. **세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
@ -32,7 +32,7 @@
- skill 생성 - skill 생성
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW - agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test - 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- agent-contract 생성/갱신, 계약 문서 작성/정리, 제공/소비 계약 포인터 관리 - 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- README 생성 - README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기 - 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신 - 로드맵/마일스톤 생성·갱신
@ -48,3 +48,4 @@
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.** **테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`) - local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

View file

@ -12,7 +12,7 @@
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다. - `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다. - agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다. - tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 외부 API, 런타임 호출, 프로젝트 간 연동, 요청/응답 스키마 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다. - API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다. **세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
@ -32,7 +32,7 @@
- skill 생성 - skill 생성
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW - agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test - 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- agent-contract 생성/갱신, 계약 문서 작성/정리, 제공/소비 계약 포인터 관리 - 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- README 생성 - README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기 - 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신 - 로드맵/마일스톤 생성·갱신
@ -48,3 +48,4 @@
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.** **테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`) - local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

View file

@ -55,7 +55,7 @@ adapter = cli
target = codex-local target = codex-local
``` ```
외부 OpenAI API 호환 계층에서는 호환성을 위해 `model` 필드가 남을 수 있다. 그러나 내부 실행 개념에서는 모델 이름만으로 전체 실행을 설명하지 않고, `adapter`, `target`, `execution`, `node adapter`, `adapter execution` 같은 용어를 우선한다. IOP의 외부 실행 호출 계약은 OpenAI-compatible API 방식을 기본 표면으로 채택하되, IOP 고유의 workspace, session, agent, approval, artifact, notification 의미는 별도 `iop` wrapper field를 만들지 않고 `metadata` 또는 IOP native endpoint의 명시 필드로 전달한다. 외부 프로젝트가 참조할 OpenAI-compatible 요청 계약 원문은 [agent-contract/provided/openai-compatible-api.md](agent-contract/provided/openai-compatible-api.md)에 둔다. 외부 OpenAI API 호환 계층에서는 호환성을 위해 `model` 필드가 남을 수 있다. 그러나 내부 실행 개념에서는 모델 이름만으로 전체 실행을 설명하지 않고, `adapter`, `target`, `execution`, `node adapter`, `adapter execution` 같은 용어를 우선한다. IOP의 외부 실행 호출 계약은 OpenAI-compatible API 방식을 기본 표면으로 채택하되, IOP 고유의 workspace, session, agent, approval, artifact, notification 의미는 별도 `iop` wrapper field를 만들지 않고 `metadata` 또는 IOP native endpoint의 명시 필드로 전달한다. 외부 프로젝트가 참조할 OpenAI-compatible 요청 계약 원문은 [agent-contract/outer/openai-compatible-api.md](agent-contract/outer/openai-compatible-api.md)에 둔다.
## 아키텍처 ## 아키텍처
@ -175,7 +175,7 @@ IOP 내부 실행은 model 중심이 아니라 adapter 중심으로 정리한다
- `node adapter`: Node 안에 등록되어 실제 실행을 담당하는 adapter - `node adapter`: Node 안에 등록되어 실제 실행을 담당하는 adapter
- `adapter execution`: Node adapter가 수행하는 실행 단위 - `adapter execution`: Node adapter가 수행하는 실행 단위
현재 코드에는 `RunRequest`, `ExecutionSpec`, `RuntimeEvent`, `NodeCommandRequest`, `EdgeNodeEvent`처럼 이 방향을 담기 위한 타입들이 있다. `RunEvent`는 adapter execution stream에, `EdgeNodeEvent`는 node 연결/해제 같은 edge-node lifecycle과 이후 제어/상태성 이벤트에 사용한다. 세부 계약과 schema는 작업을 진행하면서 점진적으로 정리한다. 현재 코드에는 `RunRequest`, `ExecutionSpec`, `RuntimeEvent`, `NodeCommandRequest`, `EdgeNodeEvent`처럼 이 방향을 담기 위한 타입들이 있다. `RunEvent`는 adapter execution stream에, `EdgeNodeEvent`는 node 연결/해제 같은 edge-node lifecycle과 이후 제어/상태성 이벤트에 사용한다. 세부 계약과 schema는 [agent-contract/index.md](agent-contract/index.md)에서 inner/outer 계약으로 라우팅한다.
### 런타임 도메인(Runtime Domain) ### 런타임 도메인(Runtime Domain)
@ -260,12 +260,13 @@ Client의 장기 UI 기준은 Flutter 앱이며, 필요한 웹 표면은 Flutter
## 개발 메모 ## 개발 메모
- 기존 구조를 우선하며, 세부 구현은 각 작업의 domain rule과 현재 코드 경계를 먼저 확인한 뒤 진행한다. - 기존 구조를 우선하며, 세부 구현은 각 작업의 domain rule과 현재 코드 경계를 먼저 확인한 뒤 진행한다.
- API, wire protocol, runtime, event/config schema 계약은 [agent-contract/index.md](agent-contract/index.md)를 기준으로 확인하고, README에는 사람용 방향과 포인터만 둔다.
- Edge-Node 내부 통신은 TCP/protobuf 기반 소켓 흐름을 우선한다. - Edge-Node 내부 통신은 TCP/protobuf 기반 소켓 흐름을 우선한다.
- Client-Control Plane처럼 앱/브라우저 표면이 필요한 경계는 proto-socket WebSocket/WSS를 사용할 수 있다. Edge-Node 기본 transport를 WebSocket으로 전환하거나 gRPC, actor/FSM/plugin framework를 도입하는 것은 현재 단계의 기본 방향이 아니다. - Client-Control Plane처럼 앱/브라우저 표면이 필요한 경계는 proto-socket WebSocket/WSS를 사용할 수 있다. Edge-Node 기본 transport를 WebSocket으로 전환하거나 gRPC, actor/FSM/plugin framework를 도입하는 것은 현재 단계의 기본 방향이 아니다.
- OpenAI-compatible API 계층은 외부 모델 호출 호환을 위한 표면이며, 내부 실행 모델 전체를 대표하지 않는다. - OpenAI-compatible API 계층은 외부 모델 호출 호환을 위한 표면이며, 내부 실행 모델 전체를 대표하지 않는다.
- OpenAI-compatible API는 현재 chat completions baseline을 가지며, Responses API 호환 표면까지 지원하는 방향으로 확장한다. - OpenAI-compatible API는 현재 chat completions baseline을 가지며, Responses API 호환 표면까지 지원하는 방향으로 확장한다.
- IOP의 외부 통신 규약은 OpenAI-compatible API 방식을 기본 계약으로 채택하고, 나머지 IOP 전용 실행 문맥은 `metadata` 확장으로 전달한다. `iop` 같은 별도 wrapper field를 기본 표면에 추가하지 않는다. 구체 요청 계약은 [agent-contract/provided/openai-compatible-api.md](agent-contract/provided/openai-compatible-api.md)를 기준으로 한다. - IOP의 외부 통신 규약은 OpenAI-compatible API 방식을 기본 계약으로 채택하고, 나머지 IOP 전용 실행 문맥은 `metadata` 확장으로 전달한다. `iop` 같은 별도 wrapper field를 기본 표면에 추가하지 않는다. 구체 요청 계약은 [agent-contract/outer/openai-compatible-api.md](agent-contract/outer/openai-compatible-api.md)를 기준으로 한다.
- A2A API 계층은 agent 간 작업 위임과 상태 공유를 위한 표면이며, 단순 모델 호출 호환은 OpenAI-compatible API를 사용한다. NomadCode의 A2A 도입 시점은 아직 강제하지 않는다. - A2A API 계층은 agent 간 작업 위임과 상태 공유를 위한 표면이며, 단순 모델 호출 호환은 OpenAI-compatible API를 사용한다. A2A 요청 계약은 [agent-contract/outer/a2a-json-rpc-api.md](agent-contract/outer/a2a-json-rpc-api.md)를 기준으로 한다.
- IOP native protocol은 OpenAI-compatible API나 A2A API를 대체하는 것이 아니라, Edge/Node 운영 제어와 CLI/session/command/event 같은 IOP 고유 기능을 제공하는 병행 표면이다. - IOP native protocol은 OpenAI-compatible API나 A2A API를 대체하는 것이 아니라, Edge/Node 운영 제어와 CLI/session/command/event 같은 IOP 고유 기능을 제공하는 병행 표면이다.
- Remote terminal bridge는 Edge/Node 운영 제어 기능으로 분류하며, OpenAI-compatible API가 아니라 IOP native protocol과 정책/audit 계층에서 다룬다. - Remote terminal bridge는 Edge/Node 운영 제어 기능으로 분류하며, OpenAI-compatible API가 아니라 IOP native protocol과 정책/audit 계층에서 다룬다.
- 앱별 README에는 현재 수동 테스트나 구현 세부가 더 많이 남아 있을 수 있다. 루트 README는 전체 방향과 경계를 설명하는 문서로 유지한다. - 앱별 README에는 현재 수동 테스트나 구현 세부가 더 많이 남아 있을 수 있다. 루트 README는 전체 방향과 경계를 설명하는 문서로 유지한다.

View file

@ -2,19 +2,24 @@
## 읽기 규칙 ## 읽기 규칙
- 현재 작업이 외부 API, 런타임 호출, 프로젝트 간 연동, 요청/응답 스키마 계약에 닿을 때만 이 문서를 사용한다. - 현재 작업이 API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약에 닿을 때만 이 문서를 사용한다.
- 매칭되는 계약 문서만 읽는다. - 매칭되는 계약 문서만 읽는다.
- 계약 문서 경로가 없으면 계약을 추정하지 않고 사용자에게 확인한다. - 계약 문서 경로가 없으면 계약을 추정하지 않고 사용자에게 확인한다.
- 계약 원문은 `agent-contract/provided/**` 또는 외부 프로젝트의 `agent-contract/provided/**` 한 곳에 둔다. - 계약 원문은 `agent-contract/outer/**` 또는 `agent-contract/inner/**` 한 곳에 둔다.
- `docs/`, `README`, `rules.md`에는 계약 원문을 복제하지 않고 계약 원문 경로만 둔다. - `docs/`, `README`, `rules.md`에는 계약 원문을 복제하지 않고 계약 원문 경로만 둔다.
## 제공 계약 ## Outer Contracts
| id | 읽는 조건 | path | | id | 읽는 조건 | 원본 경로 | path |
|----|-----------|------| |----|-----------|-----------|------|
| `iop.openai-compatible-api` | OpenAI-compatible API, Responses API, Chat Completions, legacy Completions, `model` route, Codex/CLI workspace, generic authoring metadata, `metadata.workspace`, `metadata.task_id` | `agent-contract/provided/openai-compatible-api.md` | | `iop.openai-compatible-api` | OpenAI-compatible API, Responses API, Chat Completions, legacy Completions, `model` route, Codex/CLI workspace, generic authoring metadata, `metadata.workspace`, `metadata.task_id` | `apps/edge/internal/openai/*`, `packages/go/config/config.go`, `configs/edge.yaml` | `agent-contract/outer/openai-compatible-api.md` |
| `iop.a2a-json-rpc-api` | A2A JSON-RPC API, `message/send`, `tasks/get`, `tasks/cancel`, A2A task state, agent card, `a2a.bearer_token`, Edge A2A input surface | `apps/edge/internal/input/a2a/*`, `packages/go/config/config.go`, `configs/edge.yaml` | `agent-contract/outer/a2a-json-rpc-api.md` |
## 소비 계약 ## Inner Contracts
| id | 읽는 조건 | source | | id | 읽는 조건 | 원본 경로 | path |
|----|-----------|--------| |----|-----------|-----------|------|
| `iop.edge-node-runtime-wire` | Edge-Node TCP/protobuf, proto-socket transport, `RegisterRequest`, `RegisterResponse`, `RunRequest`, `RunEvent`, `CancelRequest`, `NodeCommandRequest`, `NodeConfigPayload`, `NodeConfigRefreshRequest` | `proto/iop/runtime.proto`, `apps/edge/internal/transport/*`, `apps/node/internal/transport/*`, `apps/edge/internal/node/mapper.go`, `apps/node/internal/adapters/config_set.go` | `agent-contract/inner/edge-node-runtime-wire.md` |
| `iop.control-plane-edge-wire` | Control Plane-Edge wire, `EdgeHelloRequest`, `EdgeStatusRequest`, `EdgeStatusResponse`, `EdgeCommandRequest`, `EdgeCommandEvent`, Edge connection registry | `proto/iop/control.proto`, `apps/control-plane/internal/wire/*`, `apps/edge/internal/controlplane/*` | `agent-contract/inner/control-plane-edge-wire.md` |
| `iop.client-control-plane-wire` | Client-Control Plane wire, `/client` WebSocket, proto-socket WS, `ClientHelloRequest`, `ClientHelloResponse`, Flutter client wire | `proto/iop/control.proto`, `apps/control-plane/internal/wire/client.go`, `apps/client/lib/iop_wire/*` | `agent-contract/inner/client-control-plane-wire.md` |
| `iop.edge-config-runtime-refresh` | Edge config schema, `configs/edge.yaml`, `packages/go/config`, provider pool, `models[]`, `nodes[].providers[]`, `openai.model_routes`, config refresh, restart/applied classification | `packages/go/config/config.go`, `configs/edge.yaml`, `apps/edge/internal/configrefresh/*`, `proto/iop/runtime.proto` | `agent-contract/inner/edge-config-runtime-refresh.md` |

View file

@ -0,0 +1,56 @@
# Client-Control Plane Wire Contract
## 계약 메타
- id: `iop.client-control-plane-wire`
- boundary: `inner`
- status: active-mvp
- 원본 경로:
- `proto/iop/control.proto`
- `apps/control-plane/internal/wire/wire.go`
- `apps/control-plane/internal/wire/client.go`
- `apps/client/lib/iop_wire/client_wire_client.dart`
- `apps/client/lib/iop_wire/parser_map.dart`
- human docs:
- `apps/control-plane/README.md`
- `apps/client/README.md`
## 읽는 조건
- Client `/client` WebSocket proto-socket endpoint를 바꿀 때
- `ClientHelloRequest` 또는 `ClientHelloResponse`를 바꿀 때
- Client가 Control Plane을 통해 Edge/Node 운영 상태를 관찰하는 wire baseline을 검토할 때
## 범위
이 계약은 Flutter/Web/Desktop Client와 Control Plane 사이의 proto-socket WebSocket 경계다.
현재 MVP는 hello baseline이며, Client는 Edge나 Node TCP/protobuf transport에 직접 연결하지 않는다.
## 주요 흐름
- Client는 `/client` WebSocket으로 Control Plane에 연결한다.
- Client가 `ClientHelloRequest`를 보내면 Control Plane은 `ClientHelloResponse`로 readiness, protocol, server time, message를 응답한다.
- Control Plane listen 주소는 server config와 `IOP_WIRE_LISTEN`/compose port 기준으로 주입한다.
## 필드 의미
- `ClientHelloRequest.client_id`: client instance 식별자다.
- `ClientHelloRequest.client_version`: client build/version 관찰값이다.
- `ClientHelloResponse.ready`: Control Plane이 client 요청을 받을 수 있는지 나타낸다.
- `ClientHelloResponse.protocol`: 현재 `protobuf-socket` 값을 사용한다.
- `server_time_unix_nano`: client가 Control Plane time 기준을 관찰하는 값이다.
## 금지 사항
- Client가 Edge나 Node 내부 TCP/protobuf transport에 직접 연결하는 계약을 만들지 않는다.
- Client를 특정 외부 제품 shell 또는 navigation 계약으로 고정하지 않는다.
- Client wire에 실제 환경 endpoint, credential, private host 값을 tracked 문서로 기록하지 않는다.
- Dart protobuf 생성물을 proto 원본과 불일치하게 두지 않는다.
## 변경 시 확인할 코드/테스트
- `proto/iop/control.proto`
- `apps/control-plane/internal/wire/client_test.go`
- `apps/client/test/iop_wire/client_wire_client_test.dart`
- `apps/client/test/iop_wire/parser_map_test.dart`
- proto 변경 시 `make proto``make proto-dart`

View file

@ -0,0 +1,58 @@
# Control Plane-Edge Wire Contract
## 계약 메타
- id: `iop.control-plane-edge-wire`
- boundary: `inner`
- status: active-mvp
- 원본 경로:
- `proto/iop/control.proto`
- `apps/control-plane/internal/wire/wire.go`
- `apps/control-plane/internal/wire/edge.go`
- `apps/control-plane/internal/wire/edge_server.go`
- `apps/edge/internal/controlplane/connector.go`
- human docs: `apps/control-plane/README.md`
## 읽는 조건
- Control Plane-Edge TCP proto-socket endpoint를 바꿀 때
- `EdgeHello*`, `EdgeStatus*`, `EdgeCommand*`, `EdgeNodeSnapshot`, `EdgeNodeEvent`를 바꿀 때
- Edge status/command/event relay가 Edge-owned node registry나 runtime state를 어떻게 노출하는지 검토할 때
## 범위
이 계약은 Edge가 Control Plane으로 outbound 연결하는 내부 운영 wire다.
Control Plane은 Edge 연결 view와 제어 요청/결과를 관리하고, Edge는 자신의 Node registry와 runtime 상태를 소유한 채 snapshot과 event를 보고한다.
## 주요 흐름
- hello: Edge가 `EdgeHelloRequest`를 보내고 Control Plane이 `EdgeHelloResponse`로 enrollment를 승인 또는 거부한다.
- status: Control Plane이 `EdgeStatusRequest`를 보내고 Edge가 `EdgeStatusResponse`로 Edge-owned snapshot을 반환한다.
- command: Control Plane이 `EdgeCommandRequest`를 보내고 Edge가 `EdgeCommandResponse``EdgeCommandEvent`로 처리 결과와 phase를 보고한다.
- lifecycle event: Edge는 `EdgeNodeEvent`로 node/edge lifecycle event를 relay한다.
## 필드 의미
- `EdgeHelloRequest.edge_id`: Control Plane connection registry의 Edge identity다. 비어 있으면 hello는 거부된다.
- `EdgeStatusResponse.nodes`: Edge가 소유한 node snapshot view다.
- `EdgeNodeSnapshot.config`: Node에 내려간 config payload의 관찰용 요약이다.
- `EdgeCommandRequest.operation`: Edge-owned operation 이름이다. Node 직접 scheduling 명령으로 사용하지 않는다.
- `EdgeCommandRequest.target_selector`: Edge 내부 operation이 해석할 대상 selector다. Node address나 token을 외부화하지 않는다.
- `metadata`: 필요한 Edge identity 또는 운영 보조 정보만 담는다. secret과 private endpoint 원문은 tracked 계약에 쓰지 않는다.
## 금지 사항
- Control Plane에서 Node를 직접 연결하거나 직접 스케줄링하는 계약을 만들지 않는다.
- `ScheduleRequest`/`ScheduleResponse` legacy tombstone을 활성 계약으로 되살리지 않는다.
- Edge가 보고하지 않은 Node address, token, transport internals를 status/command 응답에 넣지 않는다.
- Control Plane을 Edge 설정, Node registry, runtime/automation 상태의 원본 저장소로 만들지 않는다.
- gRPC를 기본 Control Plane-Edge wire로 도입하지 않는다.
## 변경 시 확인할 코드/테스트
- `proto/iop/control.proto`
- `apps/control-plane/internal/wire/edge_server_test.go`
- `apps/control-plane/internal/wire/edge_test.go`
- `apps/edge/internal/controlplane/connector_test.go`
- `apps/edge/internal/controlplane/heartbeat_test.go`
- proto 변경 시 `make proto`

View file

@ -0,0 +1,60 @@
# Edge Config And Runtime Refresh Contract
## 계약 메타
- id: `iop.edge-config-runtime-refresh`
- boundary: `inner`
- status: active
- 원본 경로:
- `packages/go/config/config.go`
- `configs/edge.yaml`
- `apps/edge/internal/configrefresh/request.go`
- `apps/edge/internal/configrefresh/result.go`
- `apps/edge/internal/configrefresh/classify.go`
- `proto/iop/runtime.proto`
- `apps/edge/internal/node/mapper.go`
- `apps/node/internal/adapters/config_set.go`
- human docs: `apps/edge/README.md`
## 읽는 조건
- `configs/edge.yaml`, `packages/go/config`, provider pool, `openai.model_routes`, `models[]`, `nodes[].providers[]`, adapter instance 설정을 바꿀 때
- `iop-edge config refresh`의 dry-run/apply 결과 schema나 restart/applied 분류를 바꿀 때
- Edge가 Node에 전달하는 `NodeConfigPayload` 또는 `NodeConfigRefresh*` payload를 바꿀 때
## 범위
이 계약은 Edge 설정 YAML, Go config struct, config refresh 결과, Edge-to-Node runtime config payload의 연결 규칙이다.
tracked config에는 public 예시와 기본 구조만 두고, 실제 endpoint/credential/private host 값은 환경별 private 설정으로 주입한다.
## 핵심 규칙
- `openai.model_routes[]`는 외부 OpenAI-compatible `model` id를 내부 `adapter + target` route로 매핑하는 compatibility catalog다.
- `models[]`는 provider pool 방향의 canonical routing key이며 `nodes[].providers[].id`를 참조한다.
- `nodes[].providers[].id`는 전체 Edge config 안에서 중복되면 안 된다.
- legacy single-instance adapter 설정은 load 시 named instance slice로 normalize된다.
- `NodeConfigPayload`는 Edge가 Node에 내려주는 실행 adapter/runtime payload다.
- refresh 결과는 `applied`, `restart_required`, `rejected`를 구분하고, changed node/provider/model/report slice는 안정적으로 non-nil이어야 한다.
## refresh 분류 기준
- live apply 가능: provider capacity, provider max queue, provider queue timeout, `models[]` display/provider mapping, node runtime concurrency.
- restart required: Edge identity/listen/bootstrap/logging/metrics/console/control-plane/openai/a2a listener config, node 추가/삭제, node token/alias/agent kind, adapter 설정, node workspace root, provider type/category/adapter/models/health/lifecycle capability.
- rejected: candidate config load/validate 실패, invalid refresh mode, apply failure.
## 금지 사항
- 설정 파일만 바꾸고 `packages/go/config` loading/default/validation과 불일치하게 두지 않는다.
- provider id, model id, route id의 의미를 섞지 않는다. 외부 `model`은 OpenAI-compatible 경계의 route key이고, 내부 실행은 `adapter + target`이다.
- credential, bearer token, private endpoint 원문을 tracked docs/roadmap/contract에 기록하지 않는다.
- Node bootstrap 기본 경로에서 사용자가 직접 node config를 작성하거나 adapter/provider 값을 명령줄로 넣어야 하는 계약을 만들지 않는다.
## 변경 시 확인할 코드/테스트
- `packages/go/config/config_test.go`
- `apps/edge/internal/configrefresh/classify_test.go`
- `apps/edge/internal/edgecmd/edgecmd_test.go`
- `apps/edge/internal/node/mapper_test.go`
- `apps/node/internal/adapters/config_set_test.go`
- `agent-test/local/platform-common-smoke.md`
- `agent-test/local/edge-smoke.md`

View file

@ -0,0 +1,68 @@
# Edge-Node Runtime Wire Contract
## 계약 메타
- id: `iop.edge-node-runtime-wire`
- boundary: `inner`
- status: active
- 원본 경로:
- `proto/iop/runtime.proto`
- `apps/edge/internal/transport/server.go`
- `apps/node/internal/transport/client.go`
- `apps/node/internal/transport/session.go`
- `apps/node/internal/transport/parser.go`
- `apps/edge/internal/node/mapper.go`
- `apps/node/internal/adapters/config_set.go`
- human docs:
- `apps/edge/README.md`
- `apps/node/README.md`
## 읽는 조건
- Edge-Node TCP/protobuf transport, register handshake, run stream, cancel, node command, node config refresh를 바꿀 때
- `RunRequest`, `RunEvent`, `CancelRequest`, `NodeCommandRequest`, `NodeCommandResponse`, `NodeConfigPayload`, `NodeConfigRefresh*` 필드를 바꿀 때
- node adapter 설정 payload나 runtime config가 Edge에서 Node로 전달되는 방식을 바꿀 때
## 범위
이 계약은 Edge와 Node 사이의 내부 TCP proto-socket 경계다.
Edge는 Node 연결을 수락하고, Node는 연결 직후 등록 요청을 보낸다.
실행 요청과 이벤트 스트림, 취소, 조회성 명령, 설정 refresh는 같은 내부 wire 계열에서 처리한다.
## 주요 흐름
- register: Node가 `RegisterRequest`를 보내고 Edge가 `RegisterResponse`로 수락 여부와 `NodeConfigPayload`를 돌려준다.
- execution: Edge가 `RunRequest`를 보내고 Node가 `RunEvent` stream으로 실행 상태를 보낸다.
- cancel: Edge가 `CancelRequest`를 보내며 `CANCEL_RUN``TERMINATE_SESSION`을 구분한다.
- command: Edge가 `NodeCommandRequest`를 보내고 Node가 `NodeCommandResponse`로 usage/capabilities/session/transport/provider 상태를 응답한다.
- refresh: Edge가 `NodeConfigRefreshRequest`로 새 config payload를 보내고 Node가 `NodeConfigRefreshResponse`로 적용/재시작 필요/실패를 응답한다.
## 필드 의미
- `RunRequest.adapter`, `RunRequest.target`: 내부 실행 식별자다. 외부 OpenAI-compatible `model`은 Edge 입력 표면에서 이 둘로 변환되어야 한다.
- `RunRequest.workspace`: CLI agent route 같은 workspace-bound 실행의 작업 디렉터리다.
- `RunRequest.input`: adapter가 해석할 실행 입력이다. CLI 실행에서는 prompt 계열 입력으로 변환된다.
- `RunRequest.metadata`: caller-defined 실행 metadata다. workspace 자체는 별도 `workspace` 필드로 전달한다.
- `RunEvent.type`: `start`, `delta`, `complete`, `error`, `cancelled` 같은 실행 이벤트 종류다.
- `NodeCommandRequest.type`: 실행이 아닌 조회/제어성 명령이다. adapter execution 요청과 섞지 않는다.
- `NodeConfigPayload.adapters`: Edge가 Node에 내려주는 adapter instance 설정이다.
- `AdapterConfig.name`: node 내부 stable adapter instance identity다. 비어 있으면 legacy single-instance type 이름과 동등하다.
- `NodeRuntimeConfig.workspace_root`: node runtime/store/workspace 기준 경로다. OS별 경로를 섞어 쓰지 않는다.
## 금지 사항
- Control Plane이나 Client가 Node에 직접 연결하거나 직접 스케줄링하는 계약을 만들지 않는다.
- 외부 API의 `model` 용어를 이 내부 경계의 대표 실행 식별자로 되살리지 않는다.
- `proto/gen/iop/*.pb.go` 생성물을 직접 수정하지 않는다.
- transport handler에서 console/HTTP/A2A 표면 응답을 직접 만들지 않는다. 표면별 변환은 Edge service/input 계층에 둔다.
- Node address, token, transport internals를 Control Plane status 계약으로 노출하지 않는다.
## 변경 시 확인할 코드/테스트
- `proto/iop/runtime.proto`
- `apps/edge/internal/transport/*_test.go`
- `apps/node/internal/transport/*_test.go`
- `apps/edge/internal/node/mapper_test.go`
- `apps/node/internal/adapters/config_set_test.go`
- `apps/node/internal/adapters/adapters_blackbox_test.go`
- proto 변경 시 `make proto`, Client가 소비하면 `make proto-dart`

View file

@ -0,0 +1,63 @@
# A2A JSON-RPC API Contract
## 계약 메타
- id: `iop.a2a-json-rpc-api`
- boundary: `outer`
- status: active-mvp
- 원본 경로:
- `apps/edge/internal/input/a2a/types.go`
- `apps/edge/internal/input/a2a/server.go`
- `packages/go/config/config.go`
- `configs/edge.yaml`
- human docs: `apps/edge/README.md`
## 읽는 조건
- Edge A2A HTTP 입력 표면, JSON-RPC, `message/send`, `tasks/get`, `tasks/cancel`을 다룰 때
- 외부 agent 또는 다른 프로젝트가 Edge 실행 그룹에 작업을 위임하는 요청/응답을 바꿀 때
- A2A task 상태, artifact, blocking/background 동작, bearer auth를 검토할 때
## 범위
이 계약은 Edge의 A2A JSON-RPC HTTP 입력 표면이다.
외부 caller는 JSON-RPC 2.0 envelope로 작업을 보내고, Edge는 내부 `adapter + target` 실행으로 변환한다.
OpenAI-compatible API와 달리 A2A는 task 상태 공유와 agent-to-agent 작업 위임에 맞춘 표면이다.
내부 Edge-Node protobuf transport를 대체하지 않는다.
## 최소 요청 형태
- endpoint: `POST <a2a.path>`; 기본 path는 `/a2a`
- agent card: `GET /.well-known/agent.json`
- auth: `a2a.bearer_token`이 비어 있지 않으면 `Authorization: Bearer <token>` 필요
- supported methods: `message/send`, `tasks/get`, `tasks/cancel`
`message/send`의 최소 params는 `message.role`과 text `parts[]`다.
`configuration.blocking`은 생략 시 `true`로 동작한다.
## 필드 의미
- `jsonrpc`: 반드시 `"2.0"`이어야 한다.
- `method`: 지원 method 중 하나다.
- `params.message.parts[].text`: 내부 실행 prompt로 추출되는 text다.
- `configuration.blocking`: `true` 또는 생략이면 완료까지 대기하고, `false`이면 working task를 즉시 반환한다.
- `Task.id`: Edge-local task id다.
- `Task.status.state`: 현재 MVP 값은 `working`, `completed`, `failed`, `canceled`다.
- `Artifact.parts`: 완료 결과 text를 담는 최소 artifact 표현이다.
## 금지 사항
- A2A 요청에 특정 외부 제품 전용 wrapper field를 추가하지 않는다.
- A2A를 OpenAI-compatible chat/completions 대체 표면으로 만들지 않는다.
- Edge 내부 실행을 `model` 중심으로 표현하지 않는다. 입력 표면에서만 A2A Task/JSON-RPC 표현을 유지하고 내부는 `adapter + target`으로 변환한다.
- Node address, token, transport client 내부 상태를 A2A 응답에 노출하지 않는다.
## 변경 시 확인할 코드/테스트
- `apps/edge/internal/input/a2a/types.go`
- `apps/edge/internal/input/a2a/server.go`
- `apps/edge/internal/input/a2a/server_test.go`
- `apps/edge/internal/input/a2a/task_store_test.go`
- `packages/go/config/config.go`
- `apps/edge/README.md`

View file

@ -3,8 +3,15 @@
## 계약 메타 ## 계약 메타
- id: `iop.openai-compatible-api` - id: `iop.openai-compatible-api`
- provider: `iop` - boundary: `outer`
- status: active - status: active
- 원본 경로:
- `apps/edge/internal/openai/routes.go`
- `apps/edge/internal/openai/chat_handler.go`
- `apps/edge/internal/openai/responses_handler.go`
- `apps/edge/internal/openai/types.go`
- `packages/go/config/config.go`
- `configs/edge.yaml`
- human docs: `docs/openai-compatible-api-contract.md` - human docs: `docs/openai-compatible-api-contract.md`
## 범위 ## 범위

View file

@ -12,7 +12,7 @@
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다. - `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다. - agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다. - tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 외부 API, 런타임 호출, 프로젝트 간 연동, 요청/응답 스키마 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다. - API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다. **세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
@ -32,7 +32,7 @@
- skill 생성 - skill 생성
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW - agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test - 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- agent-contract 생성/갱신, 계약 문서 작성/정리, 제공/소비 계약 포인터 관리 - 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- README 생성 - README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기 - 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신 - 로드맵/마일스톤 생성·갱신

View file

@ -57,6 +57,7 @@ IOP의 공식 Flutter client UI/UX 영역이다. Control Plane HTTP/WS endpoint
- Client는 Control Plane을 통해 Edge/Node 운영 상태를 조회한다. Client에서 Edge-Node TCP transport나 Node execution 경로에 직접 붙지 않는다. - Client는 Control Plane을 통해 Edge/Node 운영 상태를 조회한다. Client에서 Edge-Node TCP transport나 Node execution 경로에 직접 붙지 않는다.
- Client-Control Plane native 경계는 `/client` WebSocket proto-socket과 `ClientHelloRequest`/`ClientHelloResponse` baseline을 따른다. - Client-Control Plane native 경계는 `/client` WebSocket proto-socket과 `ClientHelloRequest`/`ClientHelloResponse` baseline을 따른다.
- Client-Control Plane wire 상세는 `agent-contract/inner/client-control-plane-wire.md`를 기준으로 확인한다.
- Control Plane URL은 `IOP_CONTROL_PLANE_HTTP_URL`, `IOP_CONTROL_PLANE_WIRE_URL` `--dart-define`으로 주입한다. 실제 환경값이나 private endpoint를 tracked source에 고정하지 않는다. - Control Plane URL은 `IOP_CONTROL_PLANE_HTTP_URL`, `IOP_CONTROL_PLANE_WIRE_URL` `--dart-define`으로 주입한다. 실제 환경값이나 private endpoint를 tracked source에 고정하지 않는다.
- Dart protobuf binding은 `proto/iop/*.proto`에서 생성한다. proto 계약 변경 시 `make proto-dart` 산출물과 Go 생성물 갱신 여부를 함께 확인한다. - Dart protobuf binding은 `proto/iop/*.proto`에서 생성한다. proto 계약 변경 시 `make proto-dart` 산출물과 Go 생성물 갱신 여부를 함께 확인한다.
- `apps/client/lib/gen/proto/iop/*.dart` 생성물은 사람이 직접 수정하지 않는다. - `apps/client/lib/gen/proto/iop/*.dart` 생성물은 사람이 직접 수정하지 않는다.

View file

@ -52,6 +52,7 @@ last_rule_updated_at: 2026-06-03
- `net/http`는 health/readiness와 단순 조회성 status endpoint에 우선 사용하고, IOP 고유 양방향 운영 통신은 proto-socket 기반 wire protocol로 확장한다. - `net/http`는 health/readiness와 단순 조회성 status endpoint에 우선 사용하고, IOP 고유 양방향 운영 통신은 proto-socket 기반 wire protocol로 확장한다.
- 브라우저/앱 경계는 WebSocket/WSS proto-socket을 사용할 수 있다. Edge-Node TCP transport 기준을 이 경계에 억지로 적용하지 않는다. - 브라우저/앱 경계는 WebSocket/WSS proto-socket을 사용할 수 있다. Edge-Node TCP transport 기준을 이 경계에 억지로 적용하지 않는다.
- Control Plane-Edge native wire는 Edge가 outbound로 연결하는 TCP proto-socket 경계로 둔다. Client WebSocket listener와 Edge TCP listener를 혼동하지 않는다. - Control Plane-Edge native wire는 Edge가 outbound로 연결하는 TCP proto-socket 경계로 둔다. Client WebSocket listener와 Edge TCP listener를 혼동하지 않는다.
- Control Plane-Edge wire 상세는 `agent-contract/inner/control-plane-edge-wire.md`, Client-Control Plane wire 상세는 `agent-contract/inner/client-control-plane-wire.md`를 기준으로 확인한다.
- Edge registry는 현재 in-memory connection/control view이다. durable history, audit, 정책 저장소를 이 registry에 섞지 않는다. - Edge registry는 현재 in-memory connection/control view이다. durable history, audit, 정책 저장소를 이 registry에 섞지 않는다.
- Edge status 조회는 Edge가 보고한 `EdgeStatusResponse`를 관찰한다. Control Plane에서 Node address, token, transport internals, Edge 설정 원본을 직접 소유하지 않는다. - Edge status 조회는 Edge가 보고한 `EdgeStatusResponse`를 관찰한다. Control Plane에서 Node address, token, transport internals, Edge 설정 원본을 직접 소유하지 않는다.
- `ScheduleRequest`/`ScheduleResponse`는 legacy placeholder로만 취급하고, 새 orchestration 계약은 Edge-owned runtime state를 우회하지 않도록 다시 설계한다. - `ScheduleRequest`/`ScheduleResponse`는 legacy placeholder로만 취급하고, 새 orchestration 계약은 Edge-owned runtime state를 우회하지 않도록 다시 설계한다.

View file

@ -85,6 +85,7 @@ last_rule_updated_at: 2026-06-21
- OpenAI-compatible 경계의 `model`과 A2A 경계의 `Task`/JSON-RPC 표현은 입력 표면 안에서만 유지하고, edge 내부 실행은 `service.SubmitRun()``adapter + target` 요청으로 변환한다. - 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-compatible `/v1/models``openai.models`를 우선하고, 없으면 `openai.target`을 advertised model로 사용한다. 내부 target override와 외부 model echo 정책을 혼동하지 않는다.
- OpenAI/Ollama passthrough성 옵션은 입력 표면에서 명시적으로 변환하고, node adapter의 Ollama 실행 계약을 우회하지 않는다. - 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 표면으로 직접 출력하거나 응답하지 않는다. - run/node event fanout은 `events.Bus`를 통해 수행하고, transport handler에서 console/HTTP 표면으로 직접 출력하거나 응답하지 않는다.
- 입력 서버 lifecycle은 `input.Manager`가 소유하며, bootstrap runtime이 transport server와 함께 시작/종료한다. - 입력 서버 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 connector는 disabled 설정 또는 빈 `wire_addr`에서 no-op이어야 한다. 연결 재시도와 stop은 Edge serve lifecycle에 묶으며, Control Plane attachment 변경이 Edge-owned 설정/상태의 소유권을 바꾸지 않는다.

View file

@ -58,6 +58,7 @@ Edge에 연결되어 실제 adapter execution을 수행하는 IOP 노드 에이
- `runtime` 패키지에는 도메인 타입과 인터페이스를 두고 구체 구현 의존성을 넣지 않는다. - `runtime` 패키지에는 도메인 타입과 인터페이스를 두고 구체 구현 의존성을 넣지 않는다.
- transport/proto 타입은 `node.Node` 경계에서 runtime 타입으로 변환한다. - transport/proto 타입은 `node.Node` 경계에서 runtime 타입으로 변환한다.
- 내부 실행 식별자는 `adapter + target`을 사용한다. 외부 OpenAI-compatible API나 legacy placeholder를 제외하고 `model`을 내부 실행 대표 용어로 되돌리지 않는다. - 내부 실행 식별자는 `adapter + target`을 사용한다. 외부 OpenAI-compatible API나 legacy placeholder를 제외하고 `model`을 내부 실행 대표 용어로 되돌리지 않는다.
- Edge-Node runtime wire와 Edge가 내려주는 config payload 계약 상세는 `agent-contract/inner/edge-node-runtime-wire.md``agent-contract/inner/edge-config-runtime-refresh.md`를 기준으로 확인한다.
- 어댑터 추가 시 `runtime.Adapter`를 구현하고 `adapters.BuildFromPayload()` 또는 bootstrap registry에 등록한다. - 어댑터 추가 시 `runtime.Adapter`를 구현하고 `adapters.BuildFromPayload()` 또는 bootstrap registry에 등록한다.
- field Node의 기본 시작 경로는 Edge bootstrap script가 만든 최소 config와 Edge가 RegisterResponse로 내려주는 adapter/runtime payload다. 사용자가 기본 경로에서 node config를 직접 작성하거나 adapter/provider 세부값을 명령줄에 넣는 흐름을 만들지 않는다. - field Node의 기본 시작 경로는 Edge bootstrap script가 만든 최소 config와 Edge가 RegisterResponse로 내려주는 adapter/runtime payload다. 사용자가 기본 경로에서 node config를 직접 작성하거나 adapter/provider 세부값을 명령줄에 넣는 흐름을 만들지 않는다.
- Node runtime 작업 디렉터리나 store/workspace 경로는 대상 OS에서 쓰기 가능한 기본값이어야 한다. Edge가 특정 node에 `workspace_root`를 내려줄 때 macOS/dev host 절대 경로(`/Users/...`) 같은 값을 Linux/Windows node에 재사용하지 않으며, OS별 경로가 필요하면 Edge 설정에 미리 굽는다. - Node runtime 작업 디렉터리나 store/workspace 경로는 대상 OS에서 쓰기 가능한 기본값이어야 한다. Edge가 특정 node에 `workspace_root`를 내려줄 때 macOS/dev host 절대 경로(`/Users/...`) 같은 값을 Linux/Windows node에 재사용하지 않으며, OS별 경로가 필요하면 Edge 설정에 미리 굽는다.

View file

@ -52,6 +52,7 @@ last_rule_updated_at: 2026-06-01
- `ClientHelloRequest` / `ClientHelloResponse` — Client-Control Plane hello baseline 계약 - `ClientHelloRequest` / `ClientHelloResponse` — Client-Control Plane hello baseline 계약
- `EdgeHelloRequest` / `EdgeHelloResponse` — Edge가 Control Plane으로 연결할 때 쓰는 hello baseline 계약 - `EdgeHelloRequest` / `EdgeHelloResponse` — Edge가 Control Plane으로 연결할 때 쓰는 hello baseline 계약
- `EdgeStatusRequest` / `EdgeStatusResponse` / `EdgeNodeSnapshot` — Control Plane이 Edge-owned node snapshot을 조회하는 wire 계약 - `EdgeStatusRequest` / `EdgeStatusResponse` / `EdgeNodeSnapshot` — Control Plane이 Edge-owned node snapshot을 조회하는 wire 계약
- 상세 계약 라우팅은 `agent-contract/index.md`를 따르고, schema 원본은 `proto/iop/*.proto``packages/go/config/config.go`를 우선한다.
## 유지할 패턴 ## 유지할 패턴
@ -61,6 +62,7 @@ last_rule_updated_at: 2026-06-01
- protobuf 계약 변경은 `proto/iop/*.proto`에서 시작하고 `make proto`로 Go 생성물을 갱신한다. - protobuf 계약 변경은 `proto/iop/*.proto`에서 시작하고 `make proto`로 Go 생성물을 갱신한다.
- Client가 소비하는 proto 계약을 변경하면 `make proto-dart``apps/client/lib/gen/proto/iop/*.dart` 생성물도 갱신한다. - Client가 소비하는 proto 계약을 변경하면 `make proto-dart``apps/client/lib/gen/proto/iop/*.dart` 생성물도 갱신한다.
- 생성 파일(`proto/gen/iop/*.pb.go`)은 사람이 직접 편집하지 않는다. - 생성 파일(`proto/gen/iop/*.pb.go`)은 사람이 직접 편집하지 않는다.
- Edge-Node, Control Plane-Edge, Client-Control Plane, config/runtime refresh 계약 상세는 `agent-contract/inner/**` 문서를 기준으로 확인하고 domain rule에는 소유권과 금지 사항만 둔다.
- 공통 패키지는 작고 명확한 계약을 유지하고 앱별 정책을 과도하게 끌어올리지 않는다. - 공통 패키지는 작고 명확한 계약을 유지하고 앱별 정책을 과도하게 끌어올리지 않는다.
- 공통 event helper는 envelope 생성과 상수 정의까지만 담당하고, edge 내부 fanout/replay/store 정책은 edge 도메인에 둔다. - 공통 event helper는 envelope 생성과 상수 정의까지만 담당하고, edge 내부 fanout/replay/store 정책은 edge 도메인에 둔다.
- `RunRequest`, `ExecutionSpec`, `NodeCommandRequest`, `CLIProfileConfig`, job/history 계열 계약을 변경할 때 내부 실행 용어는 `target`을 우선하고, `model`은 외부 호환 경계인지 확인한다. - `RunRequest`, `ExecutionSpec`, `NodeCommandRequest`, `CLIProfileConfig`, job/history 계열 계약을 변경할 때 내부 실행 용어는 `target`을 우선하고, `model`은 외부 호환 경계인지 확인한다.

View file

@ -1,102 +0,0 @@
---
name: agent-contract
version: 1.0.0
description: agent-contract index와 제공/소비 계약 문서를 생성하거나 갱신한다.
---
# agent-contract
## 목적
프로젝트 간 API, 런타임 호출, 요청/응답 스키마 계약을 `agent-contract/` 구조로 관리한다.
계약 원문을 한 곳에 두고, README/docs/rules에는 라우팅 포인터만 남긴다.
## 언제 호출할지
- 외부 프로젝트가 참조할 API 또는 런타임 계약을 생성하거나 갱신할 때
- 다른 프로젝트의 계약을 소비 계약으로 등록할 때
- `agent-contract/index.md`의 제공/소비 계약 라우팅을 정리할 때
- 계약 원문을 수정한 뒤 index, README, docs 포인터와 정합성을 확인할 때
## 입력
- `contract-id`: 계약 식별자, 예: `billing.public-api` 또는 `auth.session-events` (필수)
- `mode`: `provided` 또는 `consumed` (필수)
- `contract-path`: 계약 원문 경로 또는 외부 source 경로 (필수)
- `trigger-conditions`: 계약 문서를 읽어야 하는 조건 목록 (필수)
## 먼저 확인할 것
- [ ] `agent-contract/index.md`가 있는지 확인하고, 없으면 최초 생성 대상으로 본다.
- [ ] 동일 `contract-id`가 이미 제공 또는 소비 계약에 있는지 확인한다.
- [ ] 계약 원문이 `docs/`, `README`, `rules.md`에 중복 복제되어 있지 않은지 확인한다.
- [ ] agent-ops 공통 규칙에는 특정 계약명이 아니라 `agent-contract/index.md` 조건부 진입 규칙만 있는지 확인한다.
## 실행 절차
1. **초기 구조 확인**
- `agent-contract/index.md`가 없으면 생성한다.
- `agent-contract/provided/`가 없으면 생성한다.
- 소비 계약 원문을 저장하지 않는 한 `agent-contract/consumed/`는 만들지 않는다.
- index에는 읽기 규칙, 제공 계약 표, 소비 계약 표를 둔다.
2. **계약 위치 결정**
- 제공 계약은 `agent-contract/provided/<contract-name>.md`에 둔다.
- 소비 계약은 `agent-contract/index.md`의 소비 계약 표에 외부 source만 둔다.
- 소비 계약 원문을 현재 프로젝트에 복제하지 않는다.
3. **index 갱신**
- `agent-contract/index.md`의 읽기 규칙을 유지한다.
- 제공 계약 표는 `id`, `읽는 조건`, `path` 열을 유지한다.
- 소비 계약 표는 `id`, `읽는 조건`, `source` 열을 유지한다.
- 제공 계약 또는 소비 계약 표에 `id`, 읽는 조건, 경로를 추가하거나 갱신한다.
- 매칭 조건은 agent가 판단할 수 있는 API 이름, field 이름, runtime 이름, protocol 이름을 포함한다.
4. **계약 원문 갱신**
- 계약 원문에는 범위, 최소 요청/응답 형태, 필드 의미, 금지 사항, 구현 메모를 둔다.
- 사람용 설명 문서에는 계약 원문을 복제하지 않고 링크만 둔다.
- 기존 계약을 수정할 때는 index의 읽는 조건과 path/source가 수정 후 계약 원문과 여전히 맞는지 확인한다.
5. **읽기 흐름 확인**
- 계약 확인 작업은 common rule이 `agent-contract/index.md`를 조건부로 읽고, index가 매칭 계약 원문으로 라우팅한다.
- 읽기 전용 작업에서는 계약 원문이나 index를 수정하지 않는다.
- 매칭 계약이 없으면 계약을 추정하지 않고 사용자에게 확인한다.
6. **라우팅 문서 갱신**
- README/docs/rules에는 계약 원문 경로만 남긴다.
- common rule에는 특정 계약 id나 프로젝트명을 넣지 않는다.
- project rule에는 해당 프로젝트 고유 코드/도메인 규칙만 두고 agent-contract 공통 라우팅을 반복하지 않는다.
7. **결과 보고**
- 변경한 계약 index와 원문 경로를 보고한다.
- 중복 제거한 문서와 남긴 포인터를 보고한다.
## 실행 결과 검증
- [ ] `agent-contract/index.md`가 계약 id와 경로를 포함하는가
- [ ] `agent-contract/index.md`가 없던 프로젝트에서는 읽기 규칙, 제공 계약 표, 소비 계약 표가 생성되었는가
- [ ] 제공 계약 원문이 `agent-contract/provided/` 아래에 있는가
- [ ] 소비 계약 원문을 복제하지 않았는가
- [ ] 소비 계약은 `source`만 가리키는가
- [ ] 수정된 계약의 index 조건과 path/source가 계약 원문과 일치하는가
- [ ] README/docs/rules가 계약 본문을 반복하지 않고 원문 경로만 가리키는가
- [ ] common rule에 특정 계약명이 들어가지 않았는가
- [ ] project rule에 agent-contract 공통 라우팅을 반복하지 않았는가
- 검증 실패 시: 계약 원문을 한 곳으로 모으고 나머지 문서는 포인터로 축소한다.
## 출력 형식
```text
계약 정리 완료
- index: agent-contract/index.md
- contract: agent-contract/provided/<contract-name>.md
- pointers: <갱신한 README/docs/rules 경로>
```
## 금지 사항
- 같은 계약 본문을 `docs/`, `README`, `rules.md`에 복제하지 않는다.
- common rule에 특정 계약 id, 특정 프로젝트명, 특정 API 이름을 추가하지 않는다.
- 소비 계약 원문을 현재 프로젝트에 복사하지 않는다.
- 계약과 무관한 코드나 로드맵 상태를 함께 수정하지 않는다.

View file

@ -0,0 +1,121 @@
---
name: create-contract
version: 1.0.0
description: agent-contract 구조와 inner/outer 계약 문서를 생성한다. 계약 생성해, 프로젝트 계약 생성해, contract 생성, agent-contract 생성, inner/outer 계약 생성 요청에서 사용한다.
---
# create-contract
## 목적
프로젝트에 계약 관리가 필요해진 시점에 `agent-contract/` 구조를 생성하고, 흩어진 문서와 코드에서 확인한 계약을 `inner/outer` 기준으로 정리한다.
계약 문서는 schema 원본을 복제하지 않고, agent가 읽을 수 있는 라우팅, 원본 경로, 필드 의미, 변경 규칙, 검증 포인터를 한 곳에 모은다.
## 언제 호출할지
- 사용자가 계약 생성, 프로젝트 계약 생성, contract 생성, agent-contract 생성을 요청할 때
- API, runtime 호출, wire protocol, event/config schema 같은 계약을 처음 문서화할 때
- 프로젝트에 `agent-contract/`가 없고, 둘 이상의 프로젝트/프로세스/앱/도메인이 맞춰야 하는 요청/응답 경계가 확인될 때
- 기존 README/docs/rules/code에 흩어진 계약 설명을 새 계약 구조로 모아야 할 때
## 입력
- `contract-id`: 계약 식별자, kebab-case 또는 dotted id (선택, 없으면 분석으로 후보 산출)
- `boundary`: `inner` 또는 `outer` (선택, 없으면 실제 소비자와 경계로 판정)
- `scope`: 계약 범위 요약. 예: public HTTP API, worker-runtime protocol, app-server wire (선택, 없으면 코드/문서에서 산출)
- `canonical-path`: proto/OpenAPI/config/code 등 schema 원본 경로 (선택, 없으면 분석으로 찾음)
- `trigger-conditions`: 계약 문서를 읽어야 하는 조건 목록 (선택)
## 분류 기준
- `outer`: 프로젝트 바깥 caller나 다른 프로젝트가 직접 맞춰야 하는 계약이다. 예: 공개 HTTP API, webhook, 외부 SDK, 외부 agent handoff.
- `inner`: 같은 프로젝트 안이어도 프로세스, 앱, 도메인, runtime 경계를 넘는 계약이다. 예: controller-worker proto, service-service wire, app-server WebSocket, runtime request/event/config schema.
- 제외: 한 패키지 내부 private interface, 코드만 보면 충분한 DTO, 안정화되지 않은 실험 구조, 단일 구현 내부 helper.
## 먼저 확인할 것
- [ ] `agent-contract/` 존재 여부를 확인한다.
- [ ] `agent-contract/index.md`가 있으면 읽고 기존 구조와 중복 id를 확인한다.
- [ ] 요청 범위와 관련된 코드, proto, config, README/docs/rules를 읽어 원본 경로와 흩어진 계약 설명을 찾는다.
- [ ] 계약 원문을 이미 docs/README/rules에 길게 복제하고 있는지 확인한다.
## 실행 절차
1. **필요성 판정**
- 둘 이상의 프로젝트/프로세스/앱/도메인이 맞춰야 하는 안정 경계인지 확인한다.
- 단일 패키지 내부 구현이면 계약 문서를 만들지 않고 이유를 보고한다.
- 단건 `contract-id`가 없으면 코드와 문서에서 계약 후보를 수집하고, 안정 경계가 확인된 후보만 생성한다.
- 후보는 있지만 boundary나 원본 경로가 불명확하면 문서를 억지로 만들지 않고 `확인 필요`로 보고한다.
2. **구조 생성**
- `agent-contract/index.md`가 없으면 생성한다.
- `agent-contract/inner/``agent-contract/outer/`가 없으면 생성한다.
- legacy `provided/consumed/`가 있으면 덮어쓰지 않고, 이번 생성 결과와 충돌하는지 보고한다.
3. **코드와 문서 분석**
- 관련 schema 원본을 먼저 찾는다. 우선순위는 proto/OpenAPI/schema 파일, config struct, public DTO/interface, handler/parser, 테스트 fixture 순서다.
- README/docs/rules에 흩어진 계약 설명을 찾고, 계약 문서에 필요한 내용만 추린다.
- 필드 의미는 코드와 테스트에서 확인한 것만 쓴다. 추측은 `확인 필요`로 남긴다.
4. **계약 문서 작성**
- 경로는 `agent-contract/<inner|outer>/<contract-name>.md`로 둔다.
- 여러 계약을 생성해야 하면 각 문서는 독립된 경계 단위로 나누고, 공통 설명은 index가 아니라 각 계약의 원본 경로 포인터로 해결한다.
- 문서는 짧게 유지하고 다음 항목을 포함한다.
- 계약 메타: id, boundary, 원본 경로, status(필요한 경우)
- 읽는 조건
- 범위와 비범위
- 최소 요청/응답 또는 message/event 형태
- 필드 의미와 금지 사항
- 변경 시 확인할 코드/테스트
- 원본 schema 전체를 복제하지 않는다. 긴 schema는 원본 경로와 핵심 필드 의미만 둔다.
5. **index 갱신**
- `Outer Contracts``Inner Contracts` 섹션을 둔다.
- outer/inner 표는 `id`, `읽는 조건`, `원본 경로`, `path`를 둔다.
- 매칭 조건은 agent가 검색/판단할 수 있는 API 이름, message 이름, field 이름, runtime 이름, protocol 이름을 포함한다.
- 프로젝트 전용 path trigger는 공통 rule이 아니라 `agent-contract/index.md``읽는 조건`/`원본 경로` 또는 project/domain rule 포인터로 둔다.
6. **흩어진 문서 정리**
- README/docs/rules에 계약 본문이 중복되어 있으면 원문 경로 포인터로 줄인다.
- domain rule에는 소유권, 경계, 금지 사항만 남기고 상세 schema는 계약 문서 또는 원본 경로를 가리킨다.
- common rule에는 특정 프로젝트 경로, 계약 id, API 이름을 추가하지 않는다. common rule은 `agent-contract/index.md` 조건부 진입까지만 담당한다.
- 사람용 최신 가이드가 필요한 README 문구는 유지하되 계약 원문과 충돌하지 않게 축소한다.
7. **결과 보고**
- 생성한 index와 계약 문서
- boundary 판정 근거
- 원본 경로
- 중복 제거 또는 포인터화한 문서
- 확인 필요 항목
## 실행 결과 검증
- [ ] `agent-contract/index.md`가 생성되고 inner/outer 라우팅 표를 포함하는가
- [ ] 계약 문서가 `agent-contract/inner/` 또는 `agent-contract/outer/` 아래에 있는가
- [ ] 계약 id가 index와 문서 메타에서 일치하는가
- [ ] 원본 경로가 실제 존재하거나 외부 원본으로 명확히 적혀 있는가
- [ ] README/docs/rules에 계약 본문이 중복 복제되지 않고 포인터만 남았는가
- [ ] 코드/proto/config/test 분석 없이 계약을 추정하지 않았는가
- 검증 실패 시: 누락된 index, 문서 메타, 포인터, 원본 경로만 보완한다.
## 출력 형식
```md
## 계약 생성 완료
- index: agent-contract/index.md
- contracts: agent-contract/<inner|outer>/<contract-name>.md
- boundary: <inner|outer> (<근거>)
- 원본 경로: <path 또는 외부 원본>
- pointers: <갱신한 README/docs/rules 경로 또는 없음>
- 확인 필요: <항목 또는 없음>
```
## 금지 사항
- 모든 내부 interface를 계약 문서로 만들지 않는다.
- 원본 schema 전체를 계약 문서에 장황하게 복제하지 않는다.
- 코드/proto/config/test 확인 없이 필드 의미를 단정하지 않는다.
- README/docs/rules에 계약 본문을 계속 중복 유지하지 않는다.
- 프로젝트 전용 path trigger를 common rule에 넣지 않는다.
- legacy `provided/consumed/` 구조가 있어도 사용자 요청 없이 대량 이동하지 않는다.

View file

@ -18,7 +18,8 @@
| agent-ui와 코드 동기화, agent-ui와 코드 전체 동기화, 화면정의서대로 코드 반영, 화면 정의서 변경사항 구현, wireframe 변경사항 구현 | `agent-ops/skills/common/sync-agent-ui/SKILL.md` | | agent-ui와 코드 동기화, agent-ui와 코드 전체 동기화, 화면정의서대로 코드 반영, 화면 정의서 변경사항 구현, wireframe 변경사항 구현 | `agent-ops/skills/common/sync-agent-ui/SKILL.md` |
| create-test, 테스트 룰 작성, 테스트 룰 생성, 테스트 규칙 작성, 테스트 규칙 생성, 테스트 환경 생성, 상황별 테스트 문서 생성, 도메인별 테스트 문서 생성, 검증 시나리오별 테스트 문서 생성, test rule 생성, agent-test 생성 | `agent-ops/skills/common/create-test/SKILL.md` | | create-test, 테스트 룰 작성, 테스트 룰 생성, 테스트 규칙 작성, 테스트 규칙 생성, 테스트 환경 생성, 상황별 테스트 문서 생성, 도메인별 테스트 문서 생성, 검증 시나리오별 테스트 문서 생성, test rule 생성, agent-test 생성 | `agent-ops/skills/common/create-test/SKILL.md` |
| update-test, 테스트 룰 수정, 테스트 룰 갱신, 테스트 규칙 수정, 테스트 규칙 갱신, 테스트 환경 수정, 상황별 테스트 문서 수정, 도메인별 테스트 문서 수정, 검증 시나리오별 테스트 문서 수정, test rule 수정, agent-test 수정 | `agent-ops/skills/common/update-test/SKILL.md` | | update-test, 테스트 룰 수정, 테스트 룰 갱신, 테스트 규칙 수정, 테스트 규칙 갱신, 테스트 환경 수정, 상황별 테스트 문서 수정, 도메인별 테스트 문서 수정, 검증 시나리오별 테스트 문서 수정, test rule 수정, agent-test 수정 | `agent-ops/skills/common/update-test/SKILL.md` |
| agent-contract 생성, agent-contract 갱신, 계약 문서 작성, 계약 문서 정리, 제공 계약 추가, 소비 계약 추가, 외부 계약 포인터 관리 | `agent-ops/skills/common/agent-contract/SKILL.md` | | 계약 생성해, 프로젝트 계약 생성해, 프로젝트 계약 생성, contract 생성, agent-contract 생성, 계약 문서 생성, inner 계약 생성, outer 계약 생성 | `agent-ops/skills/common/create-contract/SKILL.md` |
| 계약 업데이트해, 프로젝트 계약 업데이트해, 프로젝트 계약 업데이트, 계약 갱신해, 계약 갱신, 계약 수정, 계약 정리, contract update, agent-contract 갱신, inner 계약 갱신, outer 계약 갱신 | `agent-ops/skills/common/update-contract/SKILL.md` |
| README 작성해줘, README 만들어줘, 프로젝트 설명 문서 만들어줘 | `agent-ops/skills/common/create-readme/SKILL.md` | | README 작성해줘, README 만들어줘, 프로젝트 설명 문서 만들어줘 | `agent-ops/skills/common/create-readme/SKILL.md` |
| 핸즈오프 남겨, handoff 작성, 인수인계 작성, 다른 세션에서 이어가게 정리, 작업을 이어받도록 기록 | `agent-ops/skills/common/create-handoff/SKILL.md` | | 핸즈오프 남겨, handoff 작성, 인수인계 작성, 다른 세션에서 이어가게 정리, 작업을 이어받도록 기록 | `agent-ops/skills/common/create-handoff/SKILL.md` |
| 로드맵 만들어줘, roadmap 생성, 마일스톤 설계, goal/phase 구조 잡아줘 | `agent-ops/skills/common/create-roadmap/SKILL.md` | | 로드맵 만들어줘, roadmap 생성, 마일스톤 설계, goal/phase 구조 잡아줘 | `agent-ops/skills/common/create-roadmap/SKILL.md` |

View file

@ -0,0 +1,111 @@
---
name: update-contract
version: 1.0.0
description: agent-contract inner/outer 계약 문서를 갱신하고 흩어진 계약 설명을 정리한다. 계약 업데이트해, 프로젝트 계약 업데이트해, 계약 갱신/수정/정리, contract update 요청에서 사용한다.
---
# update-contract
## 목적
기존 `agent-contract/`의 inner/outer 계약 문서를 최신 코드와 문서 기준으로 갱신한다.
계약 원문은 한 곳에 모으고, README/docs/rules에는 포인터와 경계 규칙만 남긴다.
## 언제 호출할지
- 사용자가 계약 업데이트, 프로젝트 계약 업데이트, 계약 갱신, 계약 수정, 계약 정리를 요청할 때
- API, runtime 호출, wire protocol, event/config schema 변경이 기존 계약에 영향을 줄 때
- 계약 설명이 README/docs/rules/code review 과정에서 다시 흩어진 것을 정리할 때
- legacy `provided/consumed` 계약을 `inner/outer` 모델로 점진 정리할 때
## 입력
- `contract-id`: 갱신할 계약 식별자 (선택, 없으면 index와 변경 diff에서 탐색)
- `change`: 바뀐 내용 또는 정리할 문제 요약 (선택, 없으면 최근 변경/요청 맥락에서 산출)
- `boundary`: `inner` 또는 `outer` (선택, 기존 문서 우선)
- `canonical-path`: 갱신 기준이 되는 proto/OpenAPI/config/code 원본 경로 (선택)
## 먼저 확인할 것
- [ ] `agent-contract/index.md` 존재 여부를 확인한다. 없으면 create-contract 흐름으로 전환할지 판단한다.
- [ ] index에서 대상 계약 문서를 찾는다. 없으면 새 계약 생성 대상인지 판단한다.
- [ ] 대상 계약 문서와 원본 경로를 읽는다.
- [ ] 변경 범위와 관련된 코드, proto, config, 테스트를 읽어 실제 동작을 확인한다.
- [ ] README/docs/rules에 계약 본문이 새로 중복 작성되었는지 검색한다.
- [ ] legacy `provided/consumed/` 구조가 남아 있으면 현재 요청이 구조 migration인지 단순 계약 갱신인지 구분한다.
## 실행 절차
1. **대상 확정**
- index의 `Outer Contracts`/`Inner Contracts`에서 계약을 찾는다.
- `contract-id`가 없으면 요청 키워드, 변경 파일, 코드 diff, README/docs/rules의 계약 설명을 기준으로 영향을 받는 계약을 좁힌다.
- legacy index만 있으면 `provided`는 outer 후보, 프로젝트 내부 runtime/wire 계약은 inner 후보로 분류하되 즉시 이동하지 말고 변경 범위와 함께 판단한다.
- 대상이 없고 요청이 계약 생성/정리까지 허용하면 create-contract 흐름으로 전환한다.
- 대상이 없고 사용자가 특정 기존 계약 갱신만 요청했다면 대상 부재를 보고한다.
2. **코드 우선 분석**
- 원본 경로를 먼저 확인한다.
- 실제 parser/handler/DTO/interface/test에서 필드 의미와 허용/거부 동작을 확인한다.
- 문서와 코드가 다르면 코드를 근거로 계약 문서를 갱신하고, 코드가 틀렸을 가능성이 있으면 사용자에게 후보를 제시한다.
3. **계약 문서 갱신**
- 필드 의미, 금지 사항, 읽는 조건, 변경 시 테스트를 최신 상태로 맞춘다.
- schema 원본 전체를 복제하지 않고 핵심 의미와 원본 경로를 유지한다.
- 불확실한 값은 단정하지 않고 `확인 필요`로 남긴다.
- `last updated` 같은 날짜 메타가 이미 있는 문서에서만 갱신한다. 없는 문서에 날짜 관례를 새로 만들지 않는다.
4. **index 갱신**
- 읽는 조건이 새 API/field/message/protocol 이름을 포함하는지 확인한다.
- path, 원본 경로, boundary가 실제 문서와 일치하는지 확인한다.
- 중복 id, dead path, 존재하지 않는 원본 경로를 제거하거나 수정한다.
- 프로젝트 전용 path trigger가 필요하면 `agent-contract/index.md` 또는 project/domain rule 포인터에 둔다. common rule에는 넣지 않는다.
5. **흩어진 문서 정리**
- README/docs/rules에 계약 본문이 들어간 경우 계약 문서 포인터로 축소한다.
- domain rule에는 책임 경계와 금지 사항만 남기고 상세 요청/응답 schema를 반복하지 않는다.
- 테스트 문서에는 검증 기준만 남기고 계약 본문을 복제하지 않는다.
- common rule에 특정 프로젝트 경로, 계약 id, API 이름이 새로 들어갔으면 제거하고 프로젝트 문서로 옮긴다.
6. **검증 판단**
- 계약 문서만 바꿨으면 링크/path/index 정합성을 확인한다.
- 원본 schema 또는 runtime 코드를 함께 바꿨으면 해당 domain/test rule의 검증 기준을 따른다.
- proto/config schema를 바꿨으면 생성물 갱신 명령과 관련 테스트를 실행한다.
7. **결과 보고**
- 수정한 계약 문서와 index
- 코드 분석 근거
- 중복 제거한 문서
- 실행한 검증
- 남은 확인 필요 항목
## 실행 결과 검증
- [ ] index가 대상 계약의 최신 path와 읽는 조건을 가리키는가
- [ ] 계약 문서의 원본 경로가 실제 코드/proto/config와 맞는가
- [ ] README/docs/rules에 같은 계약 본문이 중복 남아 있지 않은가
- [ ] inner/outer boundary가 계약의 실제 소비자와 맞는가
- [ ] 코드 분석 없이 문서만 추측해 갱신하지 않았는가
- [ ] 변경 범위에 필요한 테스트 또는 링크 검증을 실행했는가
- 검증 실패 시: index/path/원본 경로/중복 문서/테스트 누락을 보완한다.
## 출력 형식
```md
## 계약 업데이트 완료
- contract: agent-contract/<inner|outer>/<contract-name>.md
- index: agent-contract/index.md
- code evidence: <확인한 코드/proto/config/test>
- pointers: <갱신한 README/docs/rules 경로 또는 없음>
- verification: <실행한 명령 또는 생략 사유>
- 확인 필요: <항목 또는 없음>
```
## 금지 사항
- 코드와 원본 경로를 확인하지 않고 계약 문서만 고치지 않는다.
- README/docs/rules에 계약 본문을 새로 복제하지 않는다.
- 프로젝트 전용 path trigger를 common rule에 넣지 않는다.
- 사용자 요청 없이 전체 계약 구조를 대량 migration하지 않는다.
- 한 패키지 내부 구현 세부를 inner 계약으로 승격하지 않는다.
- 계약 갱신과 무관한 리팩터링을 함께 수행하지 않는다.

View file

@ -102,7 +102,7 @@ CLI provider agent와 목적별 agent group, 예약어 설정을 runtime이 해
## 작업 컨텍스트 ## 작업 컨텍스트
- 관련 경로: `agent-contract/provided/openai-compatible-api.md`, `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/cli`, `packages/go/config`, `configs`, `apps/edge/README.md` - 관련 경로: `agent-contract/outer/openai-compatible-api.md`, `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/cli`, `packages/go/config`, `configs`, `apps/edge/README.md`
- 표준선(선택): 내부 실행 개념은 `adapter + target`을 유지하고, OpenAI-compatible 경계의 agent group routing 문맥은 `metadata.agent_group` 아래에 둔다. 파일명은 routing 계약의 source of truth이며 prefix/lane/grade 중복 metadata는 만들지 않는다. - 표준선(선택): 내부 실행 개념은 `adapter + target`을 유지하고, OpenAI-compatible 경계의 agent group routing 문맥은 `metadata.agent_group` 아래에 둔다. 파일명은 routing 계약의 source of truth이며 prefix/lane/grade 중복 metadata는 만들지 않는다.
- 선행 작업: CLI Automation Runtime 안정화, OpenAI Responses Input Surface, OpenAI Workspace Agent Execution Contract - 선행 작업: CLI Automation Runtime 안정화, OpenAI Responses Input Surface, OpenAI Workspace Agent Execution Contract
- 후속 작업: CLI Agent 사용량 알림과 자동 이어받기 MVP, 운영 관측과 Provider 관리의 provider quota/usage 고도화 - 후속 작업: CLI Agent 사용량 알림과 자동 이어받기 MVP, 운영 관측과 Provider 관리의 provider quota/usage 고도화

View file

@ -65,7 +65,7 @@ CLI Agent와 workspace-bound execution을 이용해 원격 코딩 환경과 원
## 작업 컨텍스트 ## 작업 컨텍스트
- 관련 경로: `apps/edge`, `apps/node`, `apps/control-plane`, `apps/client`, `agent-contract/provided/openai-compatible-api.md` - 관련 경로: `apps/edge`, `apps/node`, `apps/control-plane`, `apps/client`, `agent-contract/outer/openai-compatible-api.md`
- 표준선(선택): 외부 실행 호출은 OpenAI-compatible shape와 `metadata.workspace`를 유지하고, lifecycle/artifact/approval은 IOP native 운영 표면에서 다룬다. - 표준선(선택): 외부 실행 호출은 OpenAI-compatible shape와 `metadata.workspace`를 유지하고, lifecycle/artifact/approval은 IOP native 운영 표면에서 다룬다.
- 선행 작업: OpenAI Workspace Agent Execution Contract - 선행 작업: OpenAI Workspace Agent Execution Contract
- 후속 작업: 원격 터미널/CLI 터널링 POC, 정책/이력/감사 - 후속 작업: 원격 터미널/CLI 터널링 POC, 정책/이력/감사

View file

@ -68,7 +68,7 @@
## 작업 컨텍스트 ## 작업 컨텍스트
- 관련 경로: `apps/edge`, `apps/node`, `apps/control-plane`, `packages/go/policy`, `packages/go/jobs`, `proto/iop`, `agent-contract/provided/openai-compatible-api.md` - 관련 경로: `apps/edge`, `apps/node`, `apps/control-plane`, `packages/go/policy`, `packages/go/jobs`, `proto/iop`, `agent-contract/outer/openai-compatible-api.md`
- 표준선(선택): 외부 실행 호출 계약은 OpenAI-compatible shape를 우선 유지하고, IOP 고유 문맥은 `metadata`나 IOP native endpoint의 명시 필드로 전달한다. - 표준선(선택): 외부 실행 호출 계약은 OpenAI-compatible shape를 우선 유지하고, IOP 고유 문맥은 `metadata`나 IOP native endpoint의 명시 필드로 전달한다.
- 표준선(선택): 단계 호출은 단순 provider 라우팅과 충돌하는 책임이 아니라, 사용자가 선택할 수 있는 IOP 실행 모드 후보로 본다. - 표준선(선택): 단계 호출은 단순 provider 라우팅과 충돌하는 책임이 아니라, 사용자가 선택할 수 있는 IOP 실행 모드 후보로 본다.
- 선행 작업: Edge 모델 그룹 Queue 스케줄링 전환, 운영 관측과 Provider 관리 - 선행 작업: Edge 모델 그룹 Queue 스케줄링 전환, 운영 관측과 Provider 관리

View file

@ -30,7 +30,7 @@
| 영역 | 기준 | 메모 | | 영역 | 기준 | 메모 |
|------|------|------| |------|------|------|
| Roadmap | `agent-roadmap/phase/automation-runtime-bridge/milestones/cli-agent-group-grade-routing.md` | 목표, 기능 Task, 잠금 항목, 범위 제외 기준 | | Roadmap | `agent-roadmap/phase/automation-runtime-bridge/milestones/cli-agent-group-grade-routing.md` | 목표, 기능 Task, 잠금 항목, 범위 제외 기준 |
| Contract | `agent-contract/provided/openai-compatible-api.md` | OpenAI-compatible `metadata.agent_group.task_file``metadata.agent_group.params` 계약을 추가할 원문 | | Contract | `agent-contract/outer/openai-compatible-api.md` | OpenAI-compatible `metadata.agent_group.task_file``metadata.agent_group.params` 계약을 추가할 원문 |
| Code | `packages/go/config`, `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/cli`, `configs` | config schema, OpenAI metadata parsing, routing decision, CLI adapter execution 연결 기준 | | Code | `packages/go/config`, `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/cli`, `configs` | config schema, OpenAI metadata parsing, routing decision, CLI adapter execution 연결 기준 |
| External Provider | CLI provider agent catalog | opencode/codex/claude/gemini 등 provider-specific 실행 대상은 cli provider agent id로 참조한다 | | External Provider | CLI provider agent catalog | opencode/codex/claude/gemini 등 provider-specific 실행 대상은 cli provider agent id로 참조한다 |
| User Decision | D01 | 실행 실패/중단/quota 소진 시 자동 retry/fallback/중단 정책은 사용자 결정 전까지 잠금 | | User Decision | D01 | 실행 실패/중단/quota 소진 시 자동 retry/fallback/중단 정책은 사용자 결정 전까지 잠금 |
@ -55,7 +55,7 @@
## Interface Contract ## Interface Contract
- 계약 원문: `agent-contract/provided/openai-compatible-api.md` - 계약 원문: `agent-contract/outer/openai-compatible-api.md`
- 입력: - 입력:
- `metadata.agent_group.task_file`: agent group routing에 사용할 task file 경로다. 절대 경로와 상대 경로를 모두 허용한다. OpenAI-compatible CLI route에서 상대 경로는 `metadata.workspace` 기준으로 해석하고, 상대 경로인데 `metadata.workspace`가 없으면 실패한다. - `metadata.agent_group.task_file`: agent group routing에 사용할 task file 경로다. 절대 경로와 상대 경로를 모두 허용한다. OpenAI-compatible CLI route에서 상대 경로는 `metadata.workspace` 기준으로 해석하고, 상대 경로인데 `metadata.workspace`가 없으면 실패한다.
- `metadata.agent_group.params`: 예약어 `user_params_schema`로 검증한 사용자 parameter 객체다. 예약어 prompt renderer가 CLI별 prompt 또는 argument로 변환할 수 있다. - `metadata.agent_group.params`: 예약어 `user_params_schema`로 검증한 사용자 parameter 객체다. 예약어 prompt renderer가 CLI별 prompt 또는 argument로 변환할 수 있다.

View file

@ -23,6 +23,7 @@ flutter test
### Dart Protobuf 생성 ### Dart Protobuf 생성
이 프로젝트는 Go/Dart 등 다중 언어 환경의 메시지 계약을 공유하기 위해 protobuf를 사용합니다. 이 프로젝트는 Go/Dart 등 다중 언어 환경의 메시지 계약을 공유하기 위해 protobuf를 사용합니다.
Dart proto 코드를 새로 생성하려면 루트 `Makefile`에서 `make proto-dart`를 실행하세요. Dart proto 코드를 새로 생성하려면 루트 `Makefile`에서 `make proto-dart`를 실행하세요.
Client-Control Plane wire 계약 원문은 repo root의 `agent-contract/inner/client-control-plane-wire.md`를 기준으로 합니다.
필요 조건: 필요 조건:
1. `protoc` 설치 1. `protoc` 설치

View file

@ -14,6 +14,8 @@ Control Plane은 상시 운영, multi-edge 연결/health 확인, fleet-wide 명
Control Plane-Edge wire protocol은 Edge가 소유한 operation을 원격 운영면으로 소비한다. Edge 상태 조회, node 및 후속 agent 등록 상태 조회, command 전달, event 수신, run/cancel/status, bootstrap 발급 상태처럼 CLI와 Control Plane에 모두 필요한 작업은 Edge 내부의 표면 중립 service/operation boundary로 수렴시키고, Control Plane에서 Edge-local registry, run dispatch, stream relay 구현을 복제하지 않는다. Control Plane이 보관할 수 있는 정보는 연결 view, 제어 요청/결과, audit에 필요한 최소 운영 기록으로 제한한다. Control Plane-Edge wire protocol은 Edge가 소유한 operation을 원격 운영면으로 소비한다. Edge 상태 조회, node 및 후속 agent 등록 상태 조회, command 전달, event 수신, run/cancel/status, bootstrap 발급 상태처럼 CLI와 Control Plane에 모두 필요한 작업은 Edge 내부의 표면 중립 service/operation boundary로 수렴시키고, Control Plane에서 Edge-local registry, run dispatch, stream relay 구현을 복제하지 않는다. Control Plane이 보관할 수 있는 정보는 연결 view, 제어 요청/결과, audit에 필요한 최소 운영 기록으로 제한한다.
계약 원문은 Control Plane-Edge wire는 repo root의 `agent-contract/inner/control-plane-edge-wire.md`, Client-Control Plane wire는 `agent-contract/inner/client-control-plane-wire.md`를 기준으로 한다.
## 현재 실행 표면 ## 현재 실행 표면
- `GET /healthz` - `GET /healthz`

View file

@ -24,6 +24,8 @@ ops console은 edge-local diagnostic surface이고, HTTP/API는 central/remote m
실행 요청과 이벤트는 같은 TCP 연결을 공유하지만, 메시지 타입과 내부 파이프라인은 분리한다. `RunRequest`, `CancelRequest`, `NodeCommandRequest`는 edge가 node에 보내는 command/request 계열이고, `RunEvent`, `EdgeNodeEvent`는 node와 edge 내부에서 발생한 event 계열이다. 실행 요청과 이벤트는 같은 TCP 연결을 공유하지만, 메시지 타입과 내부 파이프라인은 분리한다. `RunRequest`, `CancelRequest`, `NodeCommandRequest`는 edge가 node에 보내는 command/request 계열이고, `RunEvent`, `EdgeNodeEvent`는 node와 edge 내부에서 발생한 event 계열이다.
계약 원문은 Edge-Node runtime wire는 repo root의 `agent-contract/inner/edge-node-runtime-wire.md`, Edge config/runtime refresh는 `agent-contract/inner/edge-config-runtime-refresh.md`를 기준으로 한다.
`internal/events.Bus`는 Edge 안의 in-process fanout과 bounded replay를 담당한다. 현재 replay는 늦게 붙은 console/API handler를 위한 최근 이벤트 버퍼이지 durable history가 아니며, Node local SQLite 실행 이력과 다른 책임이다. 전역 이력 저장, audit, query API는 후속 Control Plane/Client 경계에서 별도 설계한다. `internal/events.Bus`는 Edge 안의 in-process fanout과 bounded replay를 담당한다. 현재 replay는 늦게 붙은 console/API handler를 위한 최근 이벤트 버퍼이지 durable history가 아니며, Node local SQLite 실행 이력과 다른 책임이다. 전역 이력 저장, audit, query API는 후속 Control Plane/Client 경계에서 별도 설계한다.
## 원격 CLI adapter 개발 진단 흐름 ## 원격 CLI adapter 개발 진단 흐름
@ -193,7 +195,7 @@ Edge 외부 입력은 OpenAI-compatible HTTP API와 A2A JSON-RPC HTTP API 두
이 표면은 외부 모델 클라이언트 호환을 위한 표준 경로다. Edge/Node 운영 제어, CLI logical session, background run, cancel/terminate-session, capabilities/status/session/transport command, node lifecycle event 같은 IOP 고유 기능은 OpenAI-compatible 요청에 억지로 싣지 않고 IOP native protocol(protobuf-socket) 계열에서 다룬다. 이 표면은 외부 모델 클라이언트 호환을 위한 표준 경로다. Edge/Node 운영 제어, CLI logical session, background run, cancel/terminate-session, capabilities/status/session/transport command, node lifecycle event 같은 IOP 고유 기능은 OpenAI-compatible 요청에 억지로 싣지 않고 IOP native protocol(protobuf-socket) 계열에서 다룬다.
외부 프로젝트가 참조할 요청 계약 원문은 repo root의 `agent-contract/provided/openai-compatible-api.md`에 둔다. CLI agent route에서 사용할 workspace는 OpenAI request의 `metadata.workspace`에 둔다. Workspace authoring handoff의 요청 shape도 같은 계약 원문을 기준으로 한다. 외부 프로젝트가 참조할 요청 계약 원문은 repo root의 `agent-contract/outer/openai-compatible-api.md`에 둔다. CLI agent route에서 사용할 workspace는 OpenAI request의 `metadata.workspace`에 둔다. Workspace authoring handoff의 요청 shape도 같은 계약 원문을 기준으로 한다.
```yaml ```yaml
openai: openai:
@ -253,6 +255,8 @@ vLLM 같은 OpenAI-compatible inference server는 `openai_compat` adapter와 `pr
현재 `openai.model_routes`는 외부 model id를 단일 `adapter + target`으로 연결하는 호환 catalog다. 새 provider pool 계약에서는 `models[].id`를 OpenAI-compatible model key이자 queue/routing canonical key로 유지하고, `models[].providers`가 provider id별 실제 served model name을 가리킨다. 현재 `openai.model_routes`는 외부 model id를 단일 `adapter + target`으로 연결하는 호환 catalog다. 새 provider pool 계약에서는 `models[].id`를 OpenAI-compatible model key이자 queue/routing canonical key로 유지하고, `models[].providers`가 provider id별 실제 served model name을 가리킨다.
config/provider pool 변경 계약은 repo root의 `agent-contract/inner/edge-config-runtime-refresh.md`를 기준으로 한다.
마이그레이션 기준은 1:1 route를 단일 provider를 가진 `models[]` 항목으로 표현하는 것이다. 기존 Node provider instance 설정(`openai_compat_instances`, legacy `vllm` instance 등)은 provider id, provider type/category, served models, capacity/queue policy를 채우는 입력으로 사용하고, Edge는 선택된 provider의 served model name으로 target을 rewrite한 뒤 Node에는 기존처럼 `adapter + target` 실행 요청을 전달한다. provider pool이 구현되기 전까지 `openai.model_routes`는 fallback/compat 경로로 유지한다. 마이그레이션 기준은 1:1 route를 단일 provider를 가진 `models[]` 항목으로 표현하는 것이다. 기존 Node provider instance 설정(`openai_compat_instances`, legacy `vllm` instance 등)은 provider id, provider type/category, served models, capacity/queue policy를 채우는 입력으로 사용하고, Edge는 선택된 provider의 served model name으로 target을 rewrite한 뒤 Node에는 기존처럼 `adapter + target` 실행 요청을 전달한다. provider pool이 구현되기 전까지 `openai.model_routes`는 fallback/compat 경로로 유지한다.
최신 provider pool schema 예시: 최신 provider pool schema 예시:
@ -331,6 +335,8 @@ nodes:
A2A JSON-RPC HTTP API는 NomadCode Core나 외부 agent가 Edge 실행 그룹에 작업을 위임하고 `Task` 상태, artifact, cancel/polling을 공유해야 할 때 사용하는 입력 표면이다. OpenAI-compatible API가 단순 모델/chat completion 호환에 맞는 경로라면, A2A는 agent-to-agent 작업 위임과 상태 공유에 맞는 경로다. A2A JSON-RPC HTTP API는 NomadCode Core나 외부 agent가 Edge 실행 그룹에 작업을 위임하고 `Task` 상태, artifact, cancel/polling을 공유해야 할 때 사용하는 입력 표면이다. OpenAI-compatible API가 단순 모델/chat completion 호환에 맞는 경로라면, A2A는 agent-to-agent 작업 위임과 상태 공유에 맞는 경로다.
외부 caller가 참조할 A2A 요청 계약 원문은 repo root의 `agent-contract/outer/a2a-json-rpc-api.md`를 기준으로 한다.
1차 지원 범위는 `message/send`, `tasks/get`, `tasks/cancel`이다. `message/stream`, push notification, `tasks/list`는 후속 단계에서 다룬다. 구현은 OpenAI-compatible serving과 같은 Edge input 관리 계층에서 lifecycle/config를 묶고, 내부 실행은 동일하게 `adapter + target`으로 변환한다. 1차 지원 범위는 `message/send`, `tasks/get`, `tasks/cancel`이다. `message/stream`, push notification, `tasks/list`는 후속 단계에서 다룬다. 구현은 OpenAI-compatible serving과 같은 Edge input 관리 계층에서 lifecycle/config를 묶고, 내부 실행은 동일하게 `adapter + target`으로 변환한다.
#### 설정 예시 #### 설정 예시

View file

@ -1,6 +1,6 @@
# node — Node Agent # node — Node Agent
디바이스당 1개 실행되는 IOP 노드 에이전트. 디바이스당 1개 실행되는 IOP 노드 에이전트.
Edge에 연결되어 `adapter + target` 실행을 수행하고, TCP/protobuf 소켓을 통해 요청, 명령, 이벤트 스트림을 처리한다. mTLS helper는 `packages/go/auth`에 있지만 현재 Edge-Node transport에는 아직 연결하지 않았다. Edge에 연결되어 `adapter + target` 실행을 수행하고, TCP/protobuf 소켓을 통해 요청, 명령, 이벤트 스트림을 처리한다. mTLS helper는 `packages/go/auth`에 있지만 현재 Edge-Node transport에는 아직 연결하지 않았다.
## 내부 구조 (Hexagonal Architecture) ## 내부 구조 (Hexagonal Architecture)
@ -67,6 +67,7 @@ edge에서 실행 요청을 받으면 node는 해당 입력을 선택된 adapter
## Edge-Node 메시지 경계 ## Edge-Node 메시지 경계
node는 같은 TCP/protobuf session 위에서 여러 메시지 계열을 처리한다. node는 같은 TCP/protobuf session 위에서 여러 메시지 계열을 처리한다.
계약 원문은 repo root의 `agent-contract/inner/edge-node-runtime-wire.md`를 기준으로 한다.
- `RunRequest`: adapter execution 시작. CLI adapter에서는 prompt 전달로 해석된다. - `RunRequest`: adapter execution 시작. CLI adapter에서는 prompt 전달로 해석된다.
- `CancelRequest`: 실행 취소 또는 logical session 종료. - `CancelRequest`: 실행 취소 또는 logical session 종료.

View file

@ -1,6 +1,6 @@
# OpenAI-Compatible API Contract # OpenAI-Compatible API Contract
계약 원문은 [agent-contract/provided/openai-compatible-api.md](../agent-contract/provided/openai-compatible-api.md)다. 계약 원문은 [agent-contract/outer/openai-compatible-api.md](../agent-contract/outer/openai-compatible-api.md)다.
이 문서는 사람용 안내와 기존 링크 유지를 위한 포인터다. 요청 스키마, 필드 의미, 금지 사항, 구현 메모는 계약 원문을 기준으로 한다. 이 문서는 사람용 안내와 기존 링크 유지를 위한 포인터다. 요청 스키마, 필드 의미, 금지 사항, 구현 메모는 계약 원문을 기준으로 한다.