update domain rules and roadmap
This commit is contained in:
parent
99cc06767f
commit
5cecc55905
13 changed files with 286 additions and 59 deletions
|
|
@ -1,21 +1,21 @@
|
||||||
---
|
---
|
||||||
domain: agent
|
domain: agent
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# agent
|
# agent
|
||||||
|
|
||||||
## 목적 / 책임
|
## 목적 / 책임
|
||||||
|
|
||||||
OTO Edge 서버에 CLI 기반 agent 노드를 등록하고, agent 실행에 필요한 config 파싱, Edge endpoint 해석, protobuf 등록 요청, bootstrap 스크립트를 담당한다.
|
OTO Server에 CLI 기반 runner agent를 등록하고, agent config 파싱, 등록/heartbeat/disconnect, remote job claim, remote pipeline 실행, 실행 결과/로그/artifact 보고, bootstrap 스크립트를 담당한다.
|
||||||
파이프라인 실행 엔진이나 scheduler 등록 정책이 아니라 `oto agent run --config <path>` 실행 흐름과 Edge 연결 초기화가 이 도메인의 책임이다.
|
파이프라인 실행 엔진이나 scheduler 등록 정책이 아니라 `oto agent run --config <path>` 실행 흐름과 OTO Server runner 세션 초기화가 이 도메인의 책임이다.
|
||||||
|
|
||||||
## 포함 경로
|
## 포함 경로
|
||||||
|
|
||||||
- `apps/runner/lib/cli/commands/command_agent.dart` — `agent run --config <path>` CLI 표면과 오류 출력
|
- `apps/runner/lib/cli/commands/command_agent.dart` — `agent run --config <path>` CLI 표면과 오류 출력
|
||||||
- `apps/runner/lib/oto/agent/` — agent config, runner, Edge 등록 client, generated protobuf 런타임 코드
|
- `apps/runner/lib/oto/agent/` — agent config, runner, OTO Server 등록/job client, remote run executor, legacy iop Edge compatibility client, generated protobuf 런타임 코드
|
||||||
- `apps/runner/assets/script/shell/oto_agent_bootstrap.sh` — Linux agent 다운로드, config 생성, background 실행 bootstrap
|
- `apps/runner/assets/script/shell/oto_agent_bootstrap.sh` — Linux agent 다운로드, server config 생성, background 실행 bootstrap
|
||||||
|
|
||||||
## 제외 경로
|
## 제외 경로
|
||||||
|
|
||||||
|
|
@ -23,51 +23,67 @@ OTO Edge 서버에 CLI 기반 agent 노드를 등록하고, agent 실행에 필
|
||||||
- `apps/runner/lib/cli/commands/command_catalog.dart` — command catalog 출력 (`cli` 도메인)
|
- `apps/runner/lib/cli/commands/command_catalog.dart` — command catalog 출력 (`cli` 도메인)
|
||||||
- `apps/runner/lib/cli/commands/command_validate.dart` — pipeline YAML 검증 (`cli`/`core` 도메인)
|
- `apps/runner/lib/cli/commands/command_validate.dart` — pipeline YAML 검증 (`cli`/`core` 도메인)
|
||||||
- `apps/runner/lib/cli/commands/command_scheduler.dart` — scheduler 명령 진입 (`scheduler` 도메인)
|
- `apps/runner/lib/cli/commands/command_scheduler.dart` — scheduler 명령 진입 (`scheduler` 도메인)
|
||||||
- `apps/runner/lib/oto/application.dart` — pipeline build 오케스트레션 (`core` 도메인)
|
- `apps/runner/lib/oto/application.dart` — pipeline build 오케스트레이션 (`core` 도메인)
|
||||||
|
- `apps/runner/lib/oto/core/build_result.dart` — 실행 결과/step event/artifact 결과 모델 (`core` 도메인)
|
||||||
|
- `apps/runner/lib/oto/core/output_port.dart` — runner 출력 포트 추상화 (`core` 도메인)
|
||||||
|
- `apps/runner/lib/cli/runner_output_adapter.dart` — CLI 출력 포트 adapter (`cli` 도메인)
|
||||||
- `apps/runner/lib/oto/pipeline/` — pipeline workflow 실행 (`pipeline` 도메인)
|
- `apps/runner/lib/oto/pipeline/` — pipeline workflow 실행 (`pipeline` 도메인)
|
||||||
- `apps/runner/lib/oto/commands/` — pipeline에서 호출되는 커맨드 구현체 (`command` 도메인)
|
- `apps/runner/lib/oto/commands/` — pipeline에서 호출되는 커맨드 구현체 (`command` 도메인)
|
||||||
|
- `apps/runner/lib/oto/commands/runner_command_capability_provider.dart` — agent 등록용 command catalog capability provider (`command` 도메인)
|
||||||
- `apps/runner/assets/script/`의 기타 build/package helper — CLI/배포 보조 asset (`cli` 도메인)
|
- `apps/runner/assets/script/`의 기타 build/package helper — CLI/배포 보조 asset (`cli` 도메인)
|
||||||
|
|
||||||
## 주요 구성 요소
|
## 주요 구성 요소
|
||||||
|
|
||||||
- `CommandAgent` — `agent` CLI subcommand 파싱, config 로딩, runner 호출, exit code 처리
|
- `CommandAgent` — `agent` CLI subcommand 파싱, config 로딩, runner 호출, exit code 처리
|
||||||
- `AgentConfig` / `AgentIdentityConfig` / `EdgeConnectionConfig` / `AgentRuntimeConfig` — agent bootstrap YAML 구조와 필수 필드 검증
|
- `AgentConfig` / `AgentIdentityConfig` / `ServerConnectionConfig` / `EdgeConnectionConfig` / `AgentRuntimeConfig` — agent bootstrap YAML 구조와 필수 필드 검증
|
||||||
- `AgentConfigException` — config 파일/필드/타입 오류 표현
|
- `AgentConfigException` — config 파일/필드/타입 오류 표현
|
||||||
- `AgentRunner` / `DefaultAgentRunner` — Edge 등록 workflow 실행과 결과 로그 출력
|
- `AgentRunner` / `DefaultAgentRunner` — OTO Server 등록 workflow, remote job loop, 결과 로그 출력
|
||||||
- `RegistrationException` — Edge 등록 거절 또는 연결 실패 표현
|
- `RegistrationException` — OTO Server 등록 거절 또는 연결 실패 표현
|
||||||
- `EdgeEndpoint` — Edge URL host/port 정규화와 기본 포트 결정
|
- `RegistrationClient` / `AgentSession` / `OtoServerJobSession` — 등록 transport와 세션 수명주기 추상화
|
||||||
- `EdgeRegistrationClient` — `proto_socket` 기반 RegisterRequest 전송
|
- `OtoServerRegistrationClient` — HTTP 기반 runner register, heartbeat, disconnect 요청
|
||||||
- `RegistrationResult` — RegisterResponse accepted/rejected 결과 변환
|
- `OtoServerJobClient` — job claim, execution report, log append, artifact report, cancel, status, self-update 요청
|
||||||
- `_OtoIopClient` — agent iop protobuf message registry를 가진 proto_socket client
|
- `RemoteRunExecutor` / `RunRequestParser` / `RemoteRunInput` — OTO Server `RunRequest`를 workspace-confined YAML 실행 입력으로 변환하고 `Application.build()` 결과를 보고
|
||||||
- `apps/runner/lib/oto/agent/iop/*.pb*.dart` — `iop/runtime.proto` generated protobuf 코드
|
- `RunnerCapabilityProvider` / `RunnerCapabilitySnapshot` — 등록 시 runner capability와 command catalog 요약 제공 계약
|
||||||
- `apps/runner/lib/oto/agent/google/protobuf/*.pb*.dart` — `google/protobuf/struct.proto` generated protobuf 코드
|
- `RegistrationResult` — OTO Server/iop response의 accepted/rejected 결과 변환
|
||||||
|
- `EdgeEndpoint` / `EdgeRegistrationClient` / `_OtoIopClient` — legacy iop Edge compatibility 경로. 기본 runner 경로에서는 `OtoServerRegistrationClient`를 사용
|
||||||
|
- `apps/runner/lib/oto/agent/oto/*.pb*.dart` — `proto/oto/runner.proto` generated Dart protobuf 코드
|
||||||
|
- `apps/runner/lib/oto/agent/iop/*.pb*.dart` — legacy `iop/runtime.proto` generated protobuf 코드
|
||||||
- `oto_agent_bootstrap.sh` — agent config 파일 생성, 권한 설정, background 실행 bootstrap
|
- `oto_agent_bootstrap.sh` — agent config 파일 생성, 권한 설정, background 실행 bootstrap
|
||||||
|
|
||||||
## 유지할 패턴
|
## 유지할 패턴
|
||||||
|
|
||||||
- `CommandAgent`는 subcommand/argument 파싱과 출력만 담당하고, config 파싱은 `AgentConfig`, 등록 실행은 `AgentRunner`에 위임한다.
|
- `CommandAgent`는 subcommand/argument 파싱과 출력만 담당하고, config 파싱은 `AgentConfig`, 등록 실행은 `AgentRunner`에 위임한다.
|
||||||
- `--config <path>`와 `--config=<path>` 형식을 모두 유지하고, 누락/알 수 없는 인자는 실행 전에 오류 처리한다.
|
- `--config <path>`와 `--config=<path>` 형식을 모두 유지하고, 누락/알 수 없는 인자는 실행 전에 오류 처리한다.
|
||||||
- `AgentConfig`는 YAML root와 `agent`, `edge`, `runtime` section이 map인지 확인한 뒤 required string을 검증한다.
|
- `AgentConfig`는 YAML root와 `agent`, `server`(또는 legacy `edge`), `runtime` section이 map인지 확인한 뒤 required string을 검증한다.
|
||||||
- agent config의 required field는 빈 문자열을 거부하고, optional `agent.alias`는 누락 시 `null`, 빈 문자열이면 빈 문자열로 보존한다.
|
- agent config의 required field는 빈 문자열을 거부하고, optional `agent.alias`는 누락 시 `null`, 빈 문자열이면 빈 문자열로 보존한다.
|
||||||
- `EdgeEndpoint.parse()`는 scheme 없는 host도 허용하고, port가 없으면 https는 443, 그 외는 80을 기본값으로 둔다.
|
- OTO Server URL은 scheme 없는 host도 허용하고, HTTP endpoint 생성 시 기본 `http://`로 해석한다.
|
||||||
- Edge 등록 통신은 `EdgeRegistrationClient.register()`에서 열고 `finally`에서 client를 닫는다.
|
- OTO Server 등록 세션은 `openSession()`에서 열고 세션 소유자가 `finally`에서 `AgentSession.close()`를 호출해 heartbeat timer와 HTTP client를 정리한다.
|
||||||
- RegisterResponse 변환은 `RegistrationResult.fromResponse()`에 모아 accepted/rejected와 runtime config 추출을 한 곳에서 처리한다.
|
- 기본 agent loop는 job claim 실패를 "대기할 작업 없음"으로 보고 polling을 계속하고, claim된 `RunRequest`는 `RemoteRunExecutor.runOnce()`로 실행한다.
|
||||||
|
- remote YAML path는 `workspaceRoot` 아래로 confinement를 강제하고, inline YAML이 있으면 path보다 우선한다.
|
||||||
|
- remote variables는 YAML `property` map 위에 overlay하되, 기존 `property`가 map이 아니면 원본 YAML을 유지해 `Application.build()` 검증이 실패하게 한다.
|
||||||
|
- `property.artifacts` 선언은 `name`/`path` map list만 허용하고, artifact path도 workspace confinement를 통과해야 한다.
|
||||||
|
- RegisterResponse/JSON 변환은 `RegistrationResult`에 모아 accepted/rejected와 runner id/alias 추출을 한 곳에서 처리한다.
|
||||||
- generated protobuf 파일은 직접 수정하지 않고 원본 proto와 생성 절차를 확인해 재생성한다.
|
- generated protobuf 파일은 직접 수정하지 않고 원본 proto와 생성 절차를 확인해 재생성한다.
|
||||||
|
- bootstrap 스크립트는 `--server-url`을 기본 인자로 사용하고 legacy `--edge-url`도 server URL로 받는다.
|
||||||
- bootstrap 스크립트는 `--release-base-url`에 https만 허용하고, 생성한 config 파일은 `chmod 600`을 유지한다.
|
- bootstrap 스크립트는 `--release-base-url`에 https만 허용하고, 생성한 config 파일은 `chmod 600`을 유지한다.
|
||||||
- agent 변경 후 `dart analyze`와 agent 관련 테스트(`apps/runner/test/oto_agent_*`, 필요 시 `apps/runner/test/oto_iop_connection_smoke_test.dart`)를 확인한다.
|
- legacy iop Edge 경로는 `edge_registration_client.dart` 안에 격리하고, 기본 production runner 경로에서 직접 import하지 않는다.
|
||||||
|
- agent 변경 후 `dart analyze`와 agent 관련 테스트(`apps/runner/test/oto_agent_*`, `apps/runner/test/oto_server_connection_smoke_test.dart`, 필요 시 `apps/runner/test/oto_iop_connection_smoke_test.dart`)를 확인한다.
|
||||||
|
|
||||||
## 다른 도메인과의 경계
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
- **cli**: `apps/runner/bin/main.dart` 등록과 일반 출력/스타일은 cli 도메인이다. `CommandAgent` 내부의 agent subcommand 정책부터는 agent 도메인이다.
|
- **cli**: `apps/runner/bin/main.dart` 등록, 일반 출력/스타일, `CliRunnerOutputPort` adapter는 cli 도메인이다. `CommandAgent` 내부의 agent subcommand 정책부터는 agent 도메인이다.
|
||||||
- **core/pipeline/command**: agent 등록은 pipeline build 실행과 별개다. agent 도메인에서 `Application.build()`, `Pipeline.pipelineInitialize()`, `Command.byType()`을 직접 호출하지 않는다.
|
- **core/pipeline/command**: agent 등록은 pipeline build 실행과 별개다. remote job 실행은 `Application.build()` 진입점까지만 호출하고, `Pipeline.pipelineInitialize()`나 `Command.byType()`을 직접 호출하지 않는다.
|
||||||
|
- **core**: remote run 실행 결과를 담는 `BuildResult`, `StepEvent`, `BuildArtifact`, `RunnerOutputPort`는 core 도메인이다. agent 도메인은 이를 서버 보고 payload로 변환해 전송한다.
|
||||||
|
- **command**: runner capability의 command catalog 계산은 command 도메인의 `CommandCatalogRunnerCapabilityProvider`가 담당한다. agent 도메인은 provider interface만 소비한다.
|
||||||
- **scheduler**: scheduler는 YAML 파이프라인을 cron/interval로 실행한다. agent bootstrap의 background 실행과 scheduler 등록/로그 정책을 섞지 않는다.
|
- **scheduler**: scheduler는 YAML 파이프라인을 cron/interval로 실행한다. agent bootstrap의 background 실행과 scheduler 등록/로그 정책을 섞지 않는다.
|
||||||
- **framework**: `proto_socket`, `protobuf`, `fixnum` dependency 선언은 framework 도메인에서 관리하고, Edge protocol 사용 방식은 agent 도메인에서 관리한다.
|
- **framework**: `http`, `proto_socket`, `protobuf`, `fixnum` dependency 선언과 `proto/oto/runner.proto` 생성 절차는 framework 도메인에서 관리하고, OTO Server/iop protocol 사용 방식은 agent 도메인에서 관리한다.
|
||||||
- **sample**: agent config YAML은 pipeline sample YAML이 아니다. `apps/runner/assets/yaml/sample/**`에 agent bootstrap config를 섞지 않는다.
|
- **sample**: agent config YAML은 pipeline sample YAML이 아니다. `apps/runner/assets/yaml/sample/**`에 agent bootstrap config를 섞지 않는다.
|
||||||
|
|
||||||
## 금지 사항
|
## 금지 사항
|
||||||
|
|
||||||
- agent 도메인에서 pipeline workflow나 command catalog를 직접 실행/해석하지 않는다.
|
- agent 도메인에서 pipeline workflow나 command catalog를 직접 해석하지 않는다. remote job 실행은 `Application.build()` 진입점까지만 호출한다.
|
||||||
- enrollment token, generated config, Edge 응답 중 민감 정보가 로그에 노출되도록 하지 않는다.
|
- enrollment token, generated config, server/Edge 응답 중 민감 정보가 로그에 노출되도록 하지 않는다.
|
||||||
- generated protobuf 파일을 수동 편집하지 않는다.
|
- generated protobuf 파일을 수동 편집하지 않는다.
|
||||||
|
- remote run의 YAML path나 artifact path가 `workspaceRoot` 밖으로 빠져나가도록 허용하지 않는다.
|
||||||
- bootstrap 스크립트에서 사용자가 지정한 config/log/workspace 경로 외 임의의 프로젝트 파일을 수정하지 않는다.
|
- bootstrap 스크립트에서 사용자가 지정한 config/log/workspace 경로 외 임의의 프로젝트 파일을 수정하지 않는다.
|
||||||
- agent background 실행 정책을 scheduler 등록/해제 로직에 섞지 않는다.
|
- agent background 실행 정책을 scheduler 등록/해제 로직에 섞지 않는다.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
domain: cli
|
domain: cli
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# cli
|
# cli
|
||||||
|
|
@ -17,6 +17,7 @@ last_rule_updated_at: 2026-06-01
|
||||||
- `apps/runner/lib/cli/cli.dart` — CLI 루트 객체, 출력/스타일 처리
|
- `apps/runner/lib/cli/cli.dart` — CLI 루트 객체, 출력/스타일 처리
|
||||||
- `apps/runner/lib/cli/printer.dart` — OS별 콘솔 출력과 ANSI 스타일 처리
|
- `apps/runner/lib/cli/printer.dart` — OS별 콘솔 출력과 ANSI 스타일 처리
|
||||||
- `apps/runner/lib/cli/cli_style.dart` — 콘솔 색상/스타일 enum
|
- `apps/runner/lib/cli/cli_style.dart` — 콘솔 색상/스타일 enum
|
||||||
|
- `apps/runner/lib/cli/runner_output_adapter.dart` — core `RunnerOutputPort`를 CLI 출력으로 연결하는 adapter
|
||||||
- `apps/runner/lib/cli/commands/command_base.dart` — CLI 커맨드 공통 베이스
|
- `apps/runner/lib/cli/commands/command_base.dart` — CLI 커맨드 공통 베이스
|
||||||
- `apps/runner/lib/cli/commands/command_manager.dart` — CLI 커맨드 라우팅
|
- `apps/runner/lib/cli/commands/command_manager.dart` — CLI 커맨드 라우팅
|
||||||
- `apps/runner/lib/cli/commands/command_const.dart` — OS별 설치 경로 상수
|
- `apps/runner/lib/cli/commands/command_const.dart` — OS별 설치 경로 상수
|
||||||
|
|
@ -35,10 +36,11 @@ last_rule_updated_at: 2026-06-01
|
||||||
## 제외 경로
|
## 제외 경로
|
||||||
|
|
||||||
- `apps/runner/lib/oto/` — 비즈니스 로직·파이프라인 엔진 (cli는 진입만 담당)
|
- `apps/runner/lib/oto/` — 비즈니스 로직·파이프라인 엔진 (cli는 진입만 담당)
|
||||||
- `apps/runner/lib/cli/commands/command_agent.dart` — OTO Edge agent 실행 명령 (`agent` 도메인)
|
- `apps/runner/lib/cli/commands/command_agent.dart` — OTO Server runner agent 실행 명령 (`agent` 도메인)
|
||||||
- `apps/runner/lib/cli/commands/command_scheduler.dart` — scheduler 명령 파싱과 등록/실행 진입점 (`scheduler` 도메인)
|
- `apps/runner/lib/cli/commands/command_scheduler.dart` — scheduler 명령 파싱과 등록/실행 진입점 (`scheduler` 도메인)
|
||||||
- `apps/runner/lib/cli/commands/scheduler/` — 스케줄러 실행/등록/OS별 백그라운드 처리 (`scheduler` 도메인)
|
- `apps/runner/lib/cli/commands/scheduler/` — 스케줄러 실행/등록/OS별 백그라운드 처리 (`scheduler` 도메인)
|
||||||
- `apps/runner/lib/oto/agent/` — agent 설정/등록/Edge 통신 (`agent` 도메인)
|
- `apps/runner/lib/oto/agent/` — agent 설정, OTO Server 등록/job 통신, legacy iop Edge compatibility (`agent` 도메인)
|
||||||
|
- `apps/runner/lib/oto/core/output_port.dart` — runner 출력 포트 추상화 (`core` 도메인)
|
||||||
- `apps/runner/assets/script/shell/oto_agent_bootstrap.sh` — agent 설치/실행 bootstrap (`agent` 도메인)
|
- `apps/runner/assets/script/shell/oto_agent_bootstrap.sh` — agent 설치/실행 bootstrap (`agent` 도메인)
|
||||||
- `apps/runner/assets/template/` — 커맨드 실행 중 사용하는 템플릿 (`command` 도메인)
|
- `apps/runner/assets/template/` — 커맨드 실행 중 사용하는 템플릿 (`command` 도메인)
|
||||||
|
|
||||||
|
|
@ -57,6 +59,7 @@ last_rule_updated_at: 2026-06-01
|
||||||
- `CommandTemplate` — 템플릿 출력
|
- `CommandTemplate` — 템플릿 출력
|
||||||
- `CommandManager` — CLI 커맨드 등록 관리
|
- `CommandManager` — CLI 커맨드 등록 관리
|
||||||
- `RegistPath` — OS별 PATH 등록/해제
|
- `RegistPath` — OS별 PATH 등록/해제
|
||||||
|
- `CliRunnerOutputPort` / `setCliOutputLogHandler()` — `Application.build()` 출력 포트를 CLI 출력과 log handler에 연결
|
||||||
- `apps/runner/bin/main.dart` — CLI 초기화 시 등록할 top-level 명령 목록을 정의
|
- `apps/runner/bin/main.dart` — CLI 초기화 시 등록할 top-level 명령 목록을 정의
|
||||||
|
|
||||||
## 유지할 패턴
|
## 유지할 패턴
|
||||||
|
|
@ -67,6 +70,7 @@ last_rule_updated_at: 2026-06-01
|
||||||
- `CommandExe`는 `BuildType` 선택과 YAML 파일 읽기까지만 담당
|
- `CommandExe`는 `BuildType` 선택과 YAML 파일 읽기까지만 담당
|
||||||
- `catalog`/`validate`처럼 JSON 출력을 지원하는 CLI는 stdout에 구조화 결과만 쓰고 일반 실행 로그는 억제한다
|
- `catalog`/`validate`처럼 JSON 출력을 지원하는 CLI는 stdout에 구조화 결과만 쓰고 일반 실행 로그는 억제한다
|
||||||
- 콘솔 출력은 `CLI.print*`, `CLI.style`, `Printer`, 또는 `CommandBase` 출력 헬퍼를 사용
|
- 콘솔 출력은 `CLI.print*`, `CLI.style`, `Printer`, 또는 `CommandBase` 출력 헬퍼를 사용
|
||||||
|
- `Application.build()`에 CLI 출력을 연결할 때는 `RunnerOutputPort`를 직접 구현하지 말고 `CliRunnerOutputPort` adapter를 우선 사용한다.
|
||||||
- CLI 변경 후 `dart analyze`를 실행하고, CLI 진입 변경이면 최소 `dart run apps/runner/bin/main.dart` 수준의 스모크 실행 가능 여부를 확인
|
- CLI 변경 후 `dart analyze`를 실행하고, CLI 진입 변경이면 최소 `dart run apps/runner/bin/main.dart` 수준의 스모크 실행 가능 여부를 확인
|
||||||
- 배포/설치 asset 변경 시 관련 CLI 설치/패키징 경로가 실제 파일명을 참조하는지 확인
|
- 배포/설치 asset 변경 시 관련 CLI 설치/패키징 경로가 실제 파일명을 참조하는지 확인
|
||||||
|
|
||||||
|
|
@ -74,7 +78,8 @@ last_rule_updated_at: 2026-06-01
|
||||||
|
|
||||||
- **pipeline/command**: cli는 `Application.build()`만 호출. 파이프라인·커맨드 내부를 직접 참조하지 않는다
|
- **pipeline/command**: cli는 `Application.build()`만 호출. 파이프라인·커맨드 내부를 직접 참조하지 않는다
|
||||||
- **core**: DataComposer 호출은 Application 내부에서 이루어지며 cli는 관여하지 않는다
|
- **core**: DataComposer 호출은 Application 내부에서 이루어지며 cli는 관여하지 않는다
|
||||||
- **agent**: `agent` 명령과 `CommandAgent`는 agent 도메인이다. 일반 CLI 변경에서 Edge 등록/agent config 정책을 함께 수정하지 않는다
|
- **core output**: `RunnerOutputPort` 계약은 core 도메인이고, CLI 색상/출력으로 변환하는 adapter만 cli 도메인이다
|
||||||
|
- **agent**: `agent` 명령과 `CommandAgent`는 agent 도메인이다. 일반 CLI 변경에서 OTO Server 등록/agent config 정책을 함께 수정하지 않는다
|
||||||
- **scheduler**: `CommandScheduler`, `apps/runner/lib/cli/commands/command_scheduler.dart`, `apps/runner/lib/cli/commands/scheduler/**`는 scheduler 도메인이다. 일반 CLI 변경에서 scheduler 내부 동작을 함께 수정하지 않는다
|
- **scheduler**: `CommandScheduler`, `apps/runner/lib/cli/commands/command_scheduler.dart`, `apps/runner/lib/cli/commands/scheduler/**`는 scheduler 도메인이다. 일반 CLI 변경에서 scheduler 내부 동작을 함께 수정하지 않는다
|
||||||
- **framework**: `apps/runner/bin/main.dart`는 외부 framework Application을 소비하지만 framework 의존성 자체는 framework 도메인에서 다룬다
|
- **framework**: `apps/runner/bin/main.dart`는 외부 framework Application을 소비하지만 framework 의존성 자체는 framework 도메인에서 다룬다
|
||||||
|
|
||||||
|
|
@ -82,5 +87,6 @@ last_rule_updated_at: 2026-06-01
|
||||||
|
|
||||||
- cli 레이어에서 Pipeline 또는 Command를 직접 인스턴스화하지 않는다
|
- cli 레이어에서 Pipeline 또는 Command를 직접 인스턴스화하지 않는다
|
||||||
- 비즈니스 로직을 cli 커맨드 핸들러에 넣지 않는다
|
- 비즈니스 로직을 cli 커맨드 핸들러에 넣지 않는다
|
||||||
- 일반 CLI 변경에 agent 등록, Edge 연결, bootstrap 스크립트 정책을 섞지 않는다
|
- core `RunnerOutputPort` 계약 자체를 cli 도메인에서 변경하지 않는다
|
||||||
|
- 일반 CLI 변경에 agent 등록, OTO Server/legacy Edge 연결, bootstrap 스크립트 정책을 섞지 않는다
|
||||||
- 일반 CLI 변경에 scheduler 명령, 등록 파일, 로그 파일, OS 시작 프로그램 로직을 섞지 않는다
|
- 일반 CLI 변경에 scheduler 명령, 등록 파일, 로그 파일, OS 시작 프로그램 로직을 섞지 않는다
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
domain: command
|
domain: command
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# command
|
# command
|
||||||
|
|
@ -31,6 +31,7 @@ last_rule_updated_at: 2026-06-01
|
||||||
- `registerAllCommands()` (`command_registry.dart`) — 카테고리별 register 함수를 호출해 CommandType → Command 매핑 구성
|
- `registerAllCommands()` (`command_registry.dart`) — 카테고리별 register 함수를 호출해 CommandType → Command 매핑 구성
|
||||||
- `CommandCatalog` / `CommandCatalogEntry` (`command_catalog.dart`) — 등록된 CommandSpec 목록과 sample 존재 여부 조회
|
- `CommandCatalog` / `CommandCatalogEntry` (`command_catalog.dart`) — 등록된 CommandSpec 목록과 sample 존재 여부 조회
|
||||||
- `CommandRuntime` / `DefaultCommandRuntime` (`command_runtime.dart`) — 커맨드 외부 프로세스 실행 추상화
|
- `CommandRuntime` / `DefaultCommandRuntime` (`command_runtime.dart`) — 커맨드 외부 프로세스 실행 추상화
|
||||||
|
- `CommandCatalogRunnerCapabilityProvider` (`runner_command_capability_provider.dart`) — agent 등록 시 현재 command catalog를 runner capability summary로 변환
|
||||||
- `DataParam` (`base_data.dart`) — 모든 커맨드 파라미터의 베이스
|
- `DataParam` (`base_data.dart`) — 모든 커맨드 파라미터의 베이스
|
||||||
- `DataBuild` / `DataScheduler` (`command_data.dart`) — YAML 최상위 build/scheduler 데이터
|
- `DataBuild` / `DataScheduler` (`command_data.dart`) — YAML 최상위 build/scheduler 데이터
|
||||||
- `DataCommand` (`command_data.dart`) — 모든 커맨드에 전달되는 통합 컨테이너
|
- `DataCommand` (`command_data.dart`) — 모든 커맨드에 전달되는 통합 컨테이너
|
||||||
|
|
@ -50,6 +51,9 @@ last_rule_updated_at: 2026-06-01
|
||||||
| infra / external tool | `apps/runner/lib/oto/commands/aws/`, `apps/runner/lib/oto/commands/docker/`, `apps/runner/lib/oto/commands/gradle/`, `apps/runner/lib/oto/commands/infra/`, `apps/runner/lib/oto/commands/proto/` | `apps/runner/lib/oto/data/infra_data.dart`, `apps/runner/lib/oto/data/util_data.dart` |
|
| infra / external tool | `apps/runner/lib/oto/commands/aws/`, `apps/runner/lib/oto/commands/docker/`, `apps/runner/lib/oto/commands/gradle/`, `apps/runner/lib/oto/commands/infra/`, `apps/runner/lib/oto/commands/proto/` | `apps/runner/lib/oto/data/infra_data.dart`, `apps/runner/lib/oto/data/util_data.dart` |
|
||||||
| shell / process / util | `apps/runner/lib/oto/commands/shell/`, `apps/runner/lib/oto/commands/process/`, `apps/runner/lib/oto/commands/util/` | `apps/runner/lib/oto/data/util_data.dart` |
|
| shell / process / util | `apps/runner/lib/oto/commands/shell/`, `apps/runner/lib/oto/commands/process/`, `apps/runner/lib/oto/commands/util/` | `apps/runner/lib/oto/data/util_data.dart` |
|
||||||
|
|
||||||
|
현재 등록된 command type은 `CommandType` enum과 `registerAllCommands()`를 기준으로 한다.
|
||||||
|
대표 신규/확장 type은 `BuildDart`, `BuildDartCompile`, `CreateAppData`, `PublishiOS`, `TestflightStatusCheck`, `XcodeprojAddFile`, `Notarize`, `Files`, `GitPull`, `GitCheckout`, `GitReset`, `GitStashPush`, `GitStashApply`, `StringReplacePattern`, `StringIndex`를 포함한다.
|
||||||
|
|
||||||
커맨드 asset:
|
커맨드 asset:
|
||||||
|
|
||||||
| asset | 사용처 |
|
| asset | 사용처 |
|
||||||
|
|
@ -63,6 +67,7 @@ last_rule_updated_at: 2026-06-01
|
||||||
- `Command.register()`에는 `CommandSpec`을 함께 전달해 category, dataModel, samplePath를 기록
|
- `Command.register()`에는 `CommandSpec`을 함께 전달해 category, dataModel, samplePath를 기록
|
||||||
- 파라미터 모델은 `DataParam` 상속 + `@JsonSerializable`
|
- 파라미터 모델은 `DataParam` 상속 + `@JsonSerializable`
|
||||||
- `CommandCatalog`와 CLI `catalog` 출력은 `CommandSpec`을 기준으로 하므로 신규 커맨드의 category/dataModel/samplePath 누락 여부를 함께 확인한다
|
- `CommandCatalog`와 CLI `catalog` 출력은 `CommandSpec`을 기준으로 하므로 신규 커맨드의 category/dataModel/samplePath 누락 여부를 함께 확인한다
|
||||||
|
- agent runner capability는 `CommandCatalogRunnerCapabilityProvider`가 `registerAllCommands()`와 `Command.catalogRows`를 통해 생성하므로, command type 추가/삭제 시 capability 노출도 함께 바뀐다
|
||||||
- `*.g.dart`는 `dart run build_runner build`로 생성한다. 생성 파일 직접 수정은 생성 불가한 긴급 상황에서만 한다
|
- `*.g.dart`는 `dart run build_runner build`로 생성한다. 생성 파일 직접 수정은 생성 불가한 긴급 상황에서만 한다
|
||||||
- `getWorkspace()`: workspace 필드 → `property['workspace']` → `commonData.workspace` 순으로 resolve
|
- `getWorkspace()`: workspace 필드 → `property['workspace']` → `commonData.workspace` 순으로 resolve
|
||||||
- 커맨드 파라미터는 `getParam(command)`를 통해 태그 치환과 workspace resolve를 거친 뒤 `Data*` 모델로 파싱한다
|
- 커맨드 파라미터는 `getParam(command)`를 통해 태그 치환과 workspace resolve를 거친 뒤 `Data*` 모델로 파싱한다
|
||||||
|
|
@ -78,6 +83,7 @@ last_rule_updated_at: 2026-06-01
|
||||||
- **core**: 태그 치환은 core가 완료한 후 DataCommand가 커맨드에 전달됨
|
- **core**: 태그 치환은 core가 완료한 후 DataCommand가 커맨드에 전달됨
|
||||||
- **cli**: CLI `catalog`/`validate`는 command/core 정보를 읽어 출력하거나 검증하지만 커맨드 실행 로직은 command 도메인에 남긴다
|
- **cli**: CLI `catalog`/`validate`는 command/core 정보를 읽어 출력하거나 검증하지만 커맨드 실행 로직은 command 도메인에 남긴다
|
||||||
- **sample**: YAML 사용 예시는 sample 도메인이 담당한다. 커맨드 파라미터 변경 시 sample 도메인과 동기화한다
|
- **sample**: YAML 사용 예시는 sample 도메인이 담당한다. 커맨드 파라미터 변경 시 sample 도메인과 동기화한다
|
||||||
|
- **agent**: agent 등록 payload에 들어가는 command catalog summary는 command 도메인이 제공하고, agent 도메인은 `RunnerCapabilityProvider` interface를 소비한다
|
||||||
- **framework**: `dart_framework`의 `ProcessExecutor`, path/system 유틸은 외부 런타임 의존성으로 사용한다. OTO 비즈니스 로직을 framework 의존성 쪽으로 옮기지 않는다
|
- **framework**: `dart_framework`의 `ProcessExecutor`, path/system 유틸은 외부 런타임 의존성으로 사용한다. OTO 비즈니스 로직을 framework 의존성 쪽으로 옮기지 않는다
|
||||||
|
|
||||||
## 금지 사항
|
## 금지 사항
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
---
|
---
|
||||||
domain: core
|
domain: core
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# core
|
# core
|
||||||
|
|
||||||
## 목적 / 책임
|
## 목적 / 책임
|
||||||
|
|
||||||
파이프라인 실행 전 단계에서 YAML 파싱, Jenkins 환경 변수 합성, 태그 치환, 실행 컨텍스트 생성을 담당하는 공통 인프라 레이어다. `Application` 싱글턴이 전체 빌드 흐름을 오케스트레이션한다.
|
파이프라인 실행 전 단계에서 YAML 파싱, Jenkins 환경 변수 합성, 태그 치환, 실행 컨텍스트 생성, 빌드 결과/step event/artifact 결과 모델을 담당하는 공통 인프라 레이어다. `Application` 싱글턴이 전체 빌드 흐름을 오케스트레이션한다.
|
||||||
런타임 property, command state, build data 생성처럼 pipeline/command가 공유하는 실행 컨텍스트도 이 도메인에서 시작된다.
|
런타임 property, command state, build data, output port처럼 pipeline/command/agent가 공유하는 실행 컨텍스트도 이 도메인에서 시작된다.
|
||||||
|
|
||||||
## 포함 경로
|
## 포함 경로
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ last_rule_updated_at: 2026-06-01
|
||||||
|
|
||||||
- `apps/runner/lib/oto/pipeline/` — 실행 흐름 (core 처리 이후)
|
- `apps/runner/lib/oto/pipeline/` — 실행 흐름 (core 처리 이후)
|
||||||
- `apps/runner/lib/oto/commands/` — 커맨드 구현체 (core 결과물을 소비)
|
- `apps/runner/lib/oto/commands/` — 커맨드 구현체 (core 결과물을 소비)
|
||||||
- `apps/runner/lib/oto/agent/` — OTO Edge agent 설정/등록/통신 (`agent` 도메인)
|
- `apps/runner/lib/oto/agent/` — OTO Server runner agent 설정/등록/remote job 통신 (`agent` 도메인)
|
||||||
- `apps/runner/assets/script/`의 빌드/패키징 보조 스크립트 — CLI/배포 보조 asset이며 core가 직접 해석하지 않는다
|
- `apps/runner/assets/script/`의 빌드/패키징 보조 스크립트 — CLI/배포 보조 asset이며 core가 직접 해석하지 않는다
|
||||||
|
|
||||||
## 주요 구성 요소
|
## 주요 구성 요소
|
||||||
|
|
@ -33,6 +33,9 @@ last_rule_updated_at: 2026-06-01
|
||||||
- `DefinedData` (`defined_data.dart`) — 내장 YAML 템플릿 (빌트인 정의)
|
- `DefinedData` (`defined_data.dart`) — 내장 YAML 템플릿 (빌트인 정의)
|
||||||
- `ExecutionContext` (`execution_context.dart`) — commonData, property, command state, command map 런타임 컨테이너
|
- `ExecutionContext` (`execution_context.dart`) — commonData, property, command state, command map 런타임 컨테이너
|
||||||
- `BuildResult` (`build_result.dart`) — CLI 진입점에 전달되는 빌드 성공/실패 결과
|
- `BuildResult` (`build_result.dart`) — CLI 진입점에 전달되는 빌드 성공/실패 결과
|
||||||
|
- `BuildArtifact` (`build_result.dart`) — remote consumer에 보고할 artifact 선언 metadata
|
||||||
|
- `RunnerOutputPort` / `RunnerOutputStyle` / `NoopRunnerOutputPort` (`output_port.dart`) — CLI/agent가 교체할 수 있는 runner 출력 포트 계약
|
||||||
|
- `StepEvent` (`execution_context.dart`) — pipeline step started/completed/failed event 직렬화 모델
|
||||||
- `YamlValidationResult` (`application.dart`) — YAML 검증 CLI가 사용하는 구조화 검증 결과
|
- `YamlValidationResult` (`application.dart`) — YAML 검증 CLI가 사용하는 구조화 검증 결과
|
||||||
- `SystemRuntime` / `DefaultSystemRuntime` (`system_runtime.dart`) — OS 환경·프로세스 실행 추상화
|
- `SystemRuntime` / `DefaultSystemRuntime` (`system_runtime.dart`) — OS 환경·프로세스 실행 추상화
|
||||||
- `MattermostSender` / `MattermostData` (`utils/mattermost/`) — 공통 알림 헬퍼
|
- `MattermostSender` / `MattermostData` (`utils/mattermost/`) — 공통 알림 헬퍼
|
||||||
|
|
@ -46,6 +49,9 @@ last_rule_updated_at: 2026-06-01
|
||||||
- 커맨드 등록은 `registerAllCommands()` 호출 이후 command catalog validation과 pipeline validate를 수행
|
- 커맨드 등록은 `registerAllCommands()` 호출 이후 command catalog validation과 pipeline validate를 수행
|
||||||
- 실행 없는 YAML 검증은 `Application.validateYamlContent()`에서 build map, command list, command map, pipeline 초기화 순서로 확인한다
|
- 실행 없는 YAML 검증은 `Application.validateYamlContent()`에서 build map, command list, command map, pipeline 초기화 순서로 확인한다
|
||||||
- property 기본값에 `workspace`가 없으면 `Application.current`를 채우는 흐름을 유지
|
- property 기본값에 `workspace`가 없으면 `Application.current`를 채우는 흐름을 유지
|
||||||
|
- `Application.build()` 시작 시 `ExecutionContext.output`, step event, command map, command state를 새 실행 단위에 맞게 초기화한다
|
||||||
|
- `BuildResult`는 `ExecutionContext.stepEvents`와 전달받은 artifact 선언을 복사해서 반환한다
|
||||||
|
- 출력은 직접 `print`를 추가하기보다 `RunnerOutputPort` 또는 기존 `Application.log()` 경로를 사용한다
|
||||||
- 테스트 가능한 OS/프로세스 의존 로직은 `SystemRuntime`을 통해 주입 가능한 구조를 유지
|
- 테스트 가능한 OS/프로세스 의존 로직은 `SystemRuntime`을 통해 주입 가능한 구조를 유지
|
||||||
- Jenkins env helper script 변경 시 `DataComposer`의 호출 경로와 환경 변수 파싱 결과를 함께 확인한다
|
- Jenkins env helper script 변경 시 `DataComposer`의 호출 경로와 환경 변수 파싱 결과를 함께 확인한다
|
||||||
- core 변경 후 `dart analyze`를 실행하고, 태그/파싱 변경이면 관련 단위 테스트 또는 최소 샘플 YAML 파싱 검증을 추가/확인한다
|
- core 변경 후 `dart analyze`를 실행하고, 태그/파싱 변경이면 관련 단위 테스트 또는 최소 샘플 YAML 파싱 검증을 추가/확인한다
|
||||||
|
|
@ -53,15 +59,17 @@ last_rule_updated_at: 2026-06-01
|
||||||
## 다른 도메인과의 경계
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
- **pipeline**: DataComposer가 DataCommand 리스트 생성을 완료한 후 Pipeline이 실행 시작
|
- **pipeline**: DataComposer가 DataCommand 리스트 생성을 완료한 후 Pipeline이 실행 시작
|
||||||
|
- **pipeline events**: pipeline은 step event를 기록하지만 event 모델과 저장 위치는 core `ExecutionContext`다
|
||||||
- **command**: 커맨드 실행 중 쓰기 태그(`<@...>`) 처리는 TagSystem에 위임
|
- **command**: 커맨드 실행 중 쓰기 태그(`<@...>`) 처리는 TagSystem에 위임
|
||||||
- **cli/scheduler**: build type, YAML content, scheduler build data는 cli/scheduler에서 넘기지만 실제 build 흐름과 `BuildResult` 생성은 Application이 담당
|
- **cli/scheduler**: build type, YAML content, scheduler build data는 cli/scheduler에서 넘기지만 실제 build 흐름과 `BuildResult` 생성은 Application이 담당
|
||||||
- **agent**: agent config 파싱과 Edge 등록은 core가 아니라 agent 도메인이다. core의 YAML 파싱/검증 흐름과 agent bootstrap config를 섞지 않는다
|
- **cli output**: CLI 색상/출력 adapter는 cli 도메인이고, output port interface는 core 도메인이다
|
||||||
|
- **agent**: agent config 파싱, OTO Server 등록, remote job claim/report는 core가 아니라 agent 도메인이다. core의 YAML 파싱/검증 흐름과 agent bootstrap config를 섞지 않는다
|
||||||
- **sample**: 태그 문법이나 YAML 구조가 변경되면 sample 도메인의 YAML 예시를 함께 점검
|
- **sample**: 태그 문법이나 YAML 구조가 변경되면 sample 도메인의 YAML 예시를 함께 점검
|
||||||
|
|
||||||
## 금지 사항
|
## 금지 사항
|
||||||
|
|
||||||
- core에서 외부 시스템(Git, Jenkins API 등)을 직접 호출하지 않는다
|
- core에서 외부 시스템(Git, Jenkins API 등)을 직접 호출하지 않는다
|
||||||
- core에서 OTO Edge agent 등록 또는 proto socket 통신을 수행하지 않는다
|
- core에서 OTO Server/iop Edge agent 등록, HTTP job polling, proto socket 통신을 수행하지 않는다
|
||||||
- 커맨드별 파싱 로직을 DataComposer에 넣지 않는다
|
- 커맨드별 파싱 로직을 DataComposer에 넣지 않는다
|
||||||
- pipeline 흐름 제어(if/foreach/switch 등)를 core에 넣지 않는다
|
- pipeline 흐름 제어(if/foreach/switch 등)를 core에 넣지 않는다
|
||||||
- command별 실행 결과 처리 로직을 `Application`에 추가하지 않는다
|
- command별 실행 결과 처리 로직을 `Application`에 추가하지 않는다
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
domain: framework
|
domain: framework
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# framework
|
# framework
|
||||||
|
|
@ -9,17 +9,23 @@ last_rule_updated_at: 2026-06-01
|
||||||
## 목적 / 책임
|
## 목적 / 책임
|
||||||
|
|
||||||
현재 프로젝트에는 `lib/framework/` 모듈이 없다.
|
현재 프로젝트에는 `lib/framework/` 모듈이 없다.
|
||||||
이 도메인은 runner, client, console, core service의 패키지 선언(manifest), 분석기(analyzer/lint), protobuf 계약 정의 및 생성 코드 관리, 외부 의존성 경계와 빌드 도구 설정을 기록한다.
|
이 도메인은 runner, client, console, core service의 패키지 선언(manifest), lockfile, 분석기(analyzer/lint), protobuf 계약 정의 및 생성 코드 관리, 외부 의존성 경계와 빌드 도구 설정을 기록한다.
|
||||||
단, 전용 도메인 규칙(dedicated domain rule)이 아직 존재하지 않는 `apps/client/lib/**`, `packages/flutter/oto_console/lib/**`, `services/core/internal/**` 등의 구현 코드가 가진 구체적인 비즈니스 동작 규칙은 이 framework 도메인이나 기존 runner 도메인 규칙으로 무리하게 확장하여 단정하지 않고, 추후 별도 도메인 규칙 생성 또는 후속 milestone 작업을 통해 정리한다.
|
단, 전용 도메인 규칙(dedicated domain rule)이 아직 존재하지 않는 `apps/client/lib/**`, `packages/flutter/oto_console/lib/**`, `services/core/internal/**` 등의 구현 코드가 가진 구체적인 비즈니스 동작 규칙은 이 framework 도메인이나 기존 runner 도메인 규칙으로 무리하게 확장하여 단정하지 않고, 추후 별도 도메인 규칙 생성 또는 후속 milestone 작업을 통해 정리한다.
|
||||||
|
|
||||||
## 포함 경로
|
## 포함 경로
|
||||||
|
|
||||||
|
- `Makefile` — runner/client/core 검증 명령, proto 생성 명령, 로컬 실행 포트 기본값
|
||||||
- `apps/runner/pubspec.yaml` — runner Dart dependency와 `dart_framework` Git 의존성 선언
|
- `apps/runner/pubspec.yaml` — runner Dart dependency와 `dart_framework` Git 의존성 선언
|
||||||
|
- `apps/runner/pubspec.lock` — runner dependency resolution snapshot
|
||||||
- `apps/runner/analysis_options.yaml` — runner Dart analyzer/lint 기준
|
- `apps/runner/analysis_options.yaml` — runner Dart analyzer/lint 기준
|
||||||
- `apps/client/pubspec.yaml` — Flutter client dependency 선언
|
- `apps/client/pubspec.yaml` — Flutter client dependency 선언
|
||||||
|
- `apps/client/pubspec.lock` — Flutter client dependency resolution snapshot
|
||||||
- `apps/client/analysis_options.yaml` — Flutter client analyzer/lint 기준
|
- `apps/client/analysis_options.yaml` — Flutter client analyzer/lint 기준
|
||||||
- `packages/flutter/oto_console/pubspec.yaml` — embeddable console package dependency 선언
|
- `packages/flutter/oto_console/pubspec.yaml` — embeddable console package dependency 선언
|
||||||
|
- `packages/flutter/oto_console/analysis_options.yaml` — console package analyzer/lint 기준
|
||||||
- `services/core/go.mod` — Go core service dependency 선언
|
- `services/core/go.mod` — Go core service dependency 선언
|
||||||
|
- `services/core/go.sum` — Go core service dependency checksum
|
||||||
|
- `services/core/oto/` — `proto/oto/runner.proto`에서 생성된 Go protobuf 코드
|
||||||
- `proto/` — runner/server protobuf 계약 정의
|
- `proto/` — runner/server protobuf 계약 정의
|
||||||
|
|
||||||
## 제외 경로
|
## 제외 경로
|
||||||
|
|
@ -35,17 +41,22 @@ last_rule_updated_at: 2026-06-01
|
||||||
- `dart_framework/platform/isolate_manager.dart` — CLI 실행/스케줄러 isolate 처리에서 사용
|
- `dart_framework/platform/isolate_manager.dart` — CLI 실행/스케줄러 isolate 처리에서 사용
|
||||||
- `dart_framework/utils/*` — `simpleFuture`, path/system/string/os startup 유틸 사용
|
- `dart_framework/utils/*` — `simpleFuture`, path/system/string/os startup 유틸 사용
|
||||||
- `dart_framework/log/log.dart` — `Application.logWithType()`의 로그 타입에 사용
|
- `dart_framework/log/log.dart` — `Application.logWithType()`의 로그 타입에 사용
|
||||||
- `proto_socket` — agent Edge 등록 통신에서 사용하는 workspace 상위 path dependency
|
- `proto_socket` — legacy iop Edge compatibility 경로에서 사용하는 workspace 상위 path dependency
|
||||||
- `protobuf` / `fixnum` — generated protobuf 코드 런타임 의존성
|
- `protobuf` / `fixnum` — generated protobuf 코드 런타임 의존성
|
||||||
- `resource_importer` — `apps/runner/lib/resources.resource_importer.dart` 생성 파일과 asset 임베딩 설정
|
- `resource_importer` — `apps/runner/lib/resources.resource_importer.dart` 생성 파일과 asset 임베딩 설정
|
||||||
|
- `proto/oto/runner.proto` — OTO Server runner 등록, heartbeat, bootstrap, job claim, execution/log/artifact report, cancel/status/self-update 계약
|
||||||
|
- `services/core/oto/runner.pb.go` — `make proto-go` 생성물
|
||||||
|
- `apps/runner/lib/oto/agent/oto/*.pb*.dart` — `make proto-dart` 생성물
|
||||||
|
|
||||||
## 유지할 패턴
|
## 유지할 패턴
|
||||||
|
|
||||||
- 프로세스 실행은 `ProcessExecutor.start()` (스트리밍, stdout/stderr 실시간 수신) 또는 `ProcessExecutor.run()` (블로킹, 결과만 필요) 중 목적에 맞게 선택
|
- 프로세스 실행은 `ProcessExecutor.start()` (스트리밍, stdout/stderr 실시간 수신) 또는 `ProcessExecutor.run()` (블로킹, 결과만 필요) 중 목적에 맞게 선택
|
||||||
- `dart_framework` API 사용 시 기존 import 패턴을 따른다
|
- `dart_framework` API 사용 시 기존 import 패턴을 따른다
|
||||||
- 외부 의존성 ref 변경은 각 `pubspec.yaml` 또는 `go.mod`에서 수행하고, 변경 후 패키지 갱신 및 `dart analyze` 또는 빌드 확인을 한다
|
- 외부 의존성 ref 변경은 각 `pubspec.yaml` 또는 `go.mod`에서 수행하고, 변경 후 패키지 갱신 및 `dart analyze` 또는 빌드 확인을 한다
|
||||||
|
- tracked lockfile이 있는 package의 dependency 변경은 대응하는 `pubspec.lock` 또는 `go.sum` 갱신 여부를 확인한다
|
||||||
- analyzer/lint 기준 변경은 기존 코드 전체에 영향을 줄 수 있으므로 `dart analyze` 결과와 필요한 수정 범위를 함께 확인한다
|
- analyzer/lint 기준 변경은 기존 코드 전체에 영향을 줄 수 있으므로 `dart analyze` 결과와 필요한 수정 범위를 함께 확인한다
|
||||||
- generated protobuf lint 예외는 `analysis_options.yaml`의 analyzer exclude 또는 파일 생성 주석으로 관리한다
|
- generated protobuf lint 예외는 `analysis_options.yaml`의 analyzer exclude 또는 파일 생성 주석으로 관리한다
|
||||||
|
- protobuf 계약 변경 후 `make proto-go`와 `make proto-dart`를 실행해 Go/Dart 생성물을 함께 갱신한다
|
||||||
- 로컬에 `lib/framework/`를 되살리는 대신 필요한 OTO 로직은 `apps/runner/lib/oto/` 또는 `apps/runner/lib/cli/`의 해당 도메인에 둔다
|
- 로컬에 `lib/framework/`를 되살리는 대신 필요한 OTO 로직은 `apps/runner/lib/oto/` 또는 `apps/runner/lib/cli/`의 해당 도메인에 둔다
|
||||||
|
|
||||||
## 다른 도메인과의 경계
|
## 다른 도메인과의 경계
|
||||||
|
|
@ -53,7 +64,8 @@ last_rule_updated_at: 2026-06-01
|
||||||
- **core**: `apps/runner/lib/oto/application.dart`는 OTO 오케스트레이터이며 외부 framework의 Application과 별개다
|
- **core**: `apps/runner/lib/oto/application.dart`는 OTO 오케스트레이터이며 외부 framework의 Application과 별개다
|
||||||
- **cli/scheduler**: isolate, process, OS startup 유틸을 소비하지만 스케줄러 정책은 scheduler 도메인에 둔다
|
- **cli/scheduler**: isolate, process, OS startup 유틸을 소비하지만 스케줄러 정책은 scheduler 도메인에 둔다
|
||||||
- **command**: 커맨드들은 `ProcessExecutor`를 소비하지만 커맨드별 비즈니스 로직은 command 도메인에 둔다
|
- **command**: 커맨드들은 `ProcessExecutor`를 소비하지만 커맨드별 비즈니스 로직은 command 도메인에 둔다
|
||||||
- **agent**: `proto_socket`, `protobuf`, `fixnum` 의존성은 framework 도메인에서 관리하지만 Edge 등록 프로토콜과 agent 정책은 agent 도메인에 둔다
|
- **agent**: `http`, `proto_socket`, `protobuf`, `fixnum` 의존성은 framework 도메인에서 관리하지만 OTO Server/legacy iop protocol 사용 방식과 agent 정책은 agent 도메인에 둔다
|
||||||
|
- **services/core/internal**: Go core service business logic은 아직 dedicated domain rule이 없다. framework 도메인은 `go.mod`, `go.sum`, generated proto, build/test command 경계만 다룬다
|
||||||
|
|
||||||
## 금지 사항
|
## 금지 사항
|
||||||
|
|
||||||
|
|
@ -61,3 +73,4 @@ last_rule_updated_at: 2026-06-01
|
||||||
- 외부 `dart_framework` 내부 코드를 이 저장소의 도메인 rule 기준으로 직접 수정한다고 가정하지 않는다
|
- 외부 `dart_framework` 내부 코드를 이 저장소의 도메인 rule 기준으로 직접 수정한다고 가정하지 않는다
|
||||||
- OTO 비즈니스 로직(파이프라인, 커맨드 등록 등)을 framework 의존성 변경으로 해결하려 하지 않는다
|
- OTO 비즈니스 로직(파이프라인, 커맨드 등록 등)을 framework 의존성 변경으로 해결하려 하지 않는다
|
||||||
- generated dependency/runtime 코드를 수동 수정으로 문제 해결하려 하지 않는다
|
- generated dependency/runtime 코드를 수동 수정으로 문제 해결하려 하지 않는다
|
||||||
|
- dedicated domain rule이 없는 `apps/client/lib/**`, `packages/flutter/oto_console/lib/**`, `services/core/internal/**`의 비즈니스 동작을 framework 규칙으로 단정하지 않는다
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
domain: pipeline
|
domain: pipeline
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# pipeline
|
# pipeline
|
||||||
|
|
@ -35,6 +35,7 @@ YAML에서 파싱된 `DataCommand` 리스트를 순차 실행하고, 조건 분
|
||||||
- `PipelineContain` — 중첩 파이프라인
|
- `PipelineContain` — 중첩 파이프라인
|
||||||
- `PipelineWaitUntil` / `PipelineWaitUntilSeconds` — 조건 기반 또는 초 단위 대기 흐름
|
- `PipelineWaitUntil` / `PipelineWaitUntilSeconds` — 조건 기반 또는 초 단위 대기 흐름
|
||||||
- `DataPipeline`, `DataIf`, `DataForeach`, `DataWhile`, `DataSwitch`, `DataExeHandle` — pipeline YAML 구조 검증/파싱 모델
|
- `DataPipeline`, `DataIf`, `DataForeach`, `DataWhile`, `DataSwitch`, `DataExeHandle` — pipeline YAML 구조 검증/파싱 모델
|
||||||
|
- `StepEvent` 기록 — `Pipeline.execute()`가 각 workflow task의 started/completed/failed event를 core `ExecutionContext`에 기록
|
||||||
|
|
||||||
## 유지할 패턴
|
## 유지할 패턴
|
||||||
|
|
||||||
|
|
@ -43,6 +44,7 @@ YAML에서 파싱된 `DataCommand` 리스트를 순차 실행하고, 조건 분
|
||||||
- 새 흐름 제어 유형은 `Pipeline.exeMap`에 등록하고, 필요한 데이터 모델은 `apps/runner/lib/oto/data/pipeline_data.dart`에 둔다
|
- 새 흐름 제어 유형은 `Pipeline.exeMap`에 등록하고, 필요한 데이터 모델은 `apps/runner/lib/oto/data/pipeline_data.dart`에 둔다
|
||||||
- 파이프라인 validate 단계에서 workflow task key, command ID 존재 여부, 하위 task 구조를 가능한 한 먼저 확인한다
|
- 파이프라인 validate 단계에서 workflow task key, command ID 존재 여부, 하위 task 구조를 가능한 한 먼저 확인한다
|
||||||
- 조건식은 `PipelineCondition`의 type caster와 `Command.replaceTagValue()` 흐름을 유지한다
|
- 조건식은 `PipelineCondition`의 type caster와 `Command.replaceTagValue()` 흐름을 유지한다
|
||||||
|
- workflow task 실행 전후 event는 core `ExecutionContext.addStepEvent()`에 기록하고, event schema 자체는 core 도메인에서 관리한다
|
||||||
- pipeline 변경 후 `dart analyze`를 실행하고, if/foreach/while/switch/wait-until 중 영향을 받는 샘플 YAML 파싱 또는 실행 테스트를 확인한다
|
- pipeline 변경 후 `dart analyze`를 실행하고, if/foreach/while/switch/wait-until 중 영향을 받는 샘플 YAML 파싱 또는 실행 테스트를 확인한다
|
||||||
|
|
||||||
## 다른 도메인과의 경계
|
## 다른 도메인과의 경계
|
||||||
|
|
@ -50,6 +52,7 @@ YAML에서 파싱된 `DataCommand` 리스트를 순차 실행하고, 조건 분
|
||||||
- **command**: `Pipeline`이 `Command.byType()`을 호출하는 시점이 경계. 커맨드 내부 로직은 pipeline이 모른다
|
- **command**: `Pipeline`이 `Command.byType()`을 호출하는 시점이 경계. 커맨드 내부 로직은 pipeline이 모른다
|
||||||
- **command data**: `DataCommand`와 커맨드 파라미터 모델은 command 도메인이고, workflow 흐름 모델인 `pipeline_data.dart`만 pipeline 도메인이다
|
- **command data**: `DataCommand`와 커맨드 파라미터 모델은 command 도메인이고, workflow 흐름 모델인 `pipeline_data.dart`만 pipeline 도메인이다
|
||||||
- **core**: `DataComposer`가 YAML → `DataCommand` 변환을 마친 후 pipeline이 실행 시작
|
- **core**: `DataComposer`가 YAML → `DataCommand` 변환을 마친 후 pipeline이 실행 시작
|
||||||
|
- **core events**: step event 저장소와 `BuildResult` 직렬화는 core 도메인이다. pipeline은 실행 지점에서 event를 추가만 한다
|
||||||
- **sample**: workflow 문법 변경 시 `apps/runner/assets/yaml/sample/02_*`~`05_*`와 README 흐름 제어 예시를 함께 점검
|
- **sample**: workflow 문법 변경 시 `apps/runner/assets/yaml/sample/02_*`~`05_*`와 README 흐름 제어 예시를 함께 점검
|
||||||
|
|
||||||
## 금지 사항
|
## 금지 사항
|
||||||
|
|
@ -58,3 +61,4 @@ YAML에서 파싱된 `DataCommand` 리스트를 순차 실행하고, 조건 분
|
||||||
- 커맨드별 비즈니스 로직을 pipeline에 넣지 않는다
|
- 커맨드별 비즈니스 로직을 pipeline에 넣지 않는다
|
||||||
- pipeline에서 파일 시스템, 네트워크, shell 실행을 직접 수행하지 않는다
|
- pipeline에서 파일 시스템, 네트워크, shell 실행을 직접 수행하지 않는다
|
||||||
- command param의 세부 필드를 pipeline에서 해석하지 않는다
|
- command param의 세부 필드를 pipeline에서 해석하지 않는다
|
||||||
|
- step event schema나 build result JSON schema를 pipeline 도메인에서 바꾸지 않는다
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
domain: sample
|
domain: sample
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# sample
|
# sample
|
||||||
|
|
@ -35,17 +35,17 @@ AI가 파이프라인 YAML을 작성하거나 검토할 때 가장 먼저 읽는
|
||||||
| `03_pipeline_foreach.yaml` | foreach (List·Map 순회, 중첩) |
|
| `03_pipeline_foreach.yaml` | foreach (List·Map 순회, 중첩) |
|
||||||
| `04_pipeline_exe_handle.yaml` | exe-handle (on-success / on-fail) |
|
| `04_pipeline_exe_handle.yaml` | exe-handle (on-success / on-fail) |
|
||||||
| `05_pipeline_while_switch.yaml` | while, switch, wait-until |
|
| `05_pipeline_while_switch.yaml` | while, switch, wait-until |
|
||||||
| `06_git.yaml` | Git, GitCommit, GitPush, GitRev, GitCount, GitBranch |
|
| `06_git.yaml` | Git, GitPull, GitCheckout, GitCommit, GitPush, GitRev, GitCount, GitBranch, GitStashPush, GitStashApply, GitReset |
|
||||||
| `07_file.yaml` | Copy, Delete, FileRead, FileWrite, Zip, FileInfo |
|
| `07_file.yaml` | Copy, Delete, FileRead, FileWrite, Zip, FileInfo |
|
||||||
| `07_file_utils.yaml` | DirectoryCreate, Rename 등 파일 보조 커맨드 |
|
| `07_file_utils.yaml` | DirectoryCreate, Files, Rename 등 파일 보조 커맨드 |
|
||||||
| `08_notification.yaml` | Slack, SlackBuild, Mattermost, MattermostBuild |
|
| `08_notification.yaml` | Slack, SlackBuild, Mattermost, MattermostBuild |
|
||||||
| `09_network.yaml` | WebRequest, WebFile, Upload(FTP), Download(FTP) |
|
| `09_network.yaml` | WebRequest, WebFile, Upload(FTP), Download(FTP), GitHub, GitHubPullRequestCreate, GitHubPullRequestList, GitHubPullRequestClose |
|
||||||
| `10_build_ios.yaml` | BuildiOS, ArchiveiOS, ExportiOS, TestflightUpload, TestflightDistribute |
|
| `10_build_ios.yaml` | BuildiOS, ArchiveiOS, ExportiOS, TestflightUpload, TestflightStatusCheck, TestflightDistribute, CodeSign, ProductBuild, Notarize |
|
||||||
| `10_build_tools.yaml` | BuildDotNet, BuildMSBuild, CodeSign, ProductBuild 등 빌드 보조 도구 |
|
| `10_build_tools.yaml` | XcodeprojAddFile, BuildDotNet, BuildMSBuild, PublishiOS 등 빌드 보조 도구 |
|
||||||
| `11_build_flutter.yaml` | BuildFlutter (멀티플랫폼) |
|
| `11_build_flutter.yaml` | BuildFlutter (멀티플랫폼) |
|
||||||
| `11_utils.yaml` | URLInfo, Delay |
|
| `11_utils.yaml` | URLInfo, Delay |
|
||||||
| `12_scheduler.yaml` | scheduler 섹션 (cron / interval) |
|
| `12_scheduler.yaml` | scheduler 섹션 (cron / interval) |
|
||||||
| `13_string_json.yaml` | StringSub, StringReplace, JsonReader, JsonReaderFile, JsonWriterFile |
|
| `13_string_json.yaml` | StringSub, StringReplace, StringReplacePattern, StringIndex, JsonReader, JsonReaderFile, JsonWriterFile |
|
||||||
| `14_shell_process.yaml` | Shell, ShellFile, ProcessRun, ProcessKill, ProcessPortUse |
|
| `14_shell_process.yaml` | Shell, ShellFile, ProcessRun, ProcessKill, ProcessPortUse |
|
||||||
| `15_smb_auth.yaml` | SMBAuth |
|
| `15_smb_auth.yaml` | SMBAuth |
|
||||||
| `16_docker.yaml` | Docker |
|
| `16_docker.yaml` | Docker |
|
||||||
|
|
@ -93,7 +93,7 @@ AI가 파이프라인 YAML을 작성하거나 검토할 때 가장 먼저 읽는
|
||||||
## 유지할 패턴
|
## 유지할 패턴
|
||||||
|
|
||||||
- 파일명은 `NN_카테고리.yaml` 형식 (번호 + 언더스코어 + 카테고리)
|
- 파일명은 `NN_카테고리.yaml` 형식 (번호 + 언더스코어 + 카테고리)
|
||||||
- 각 파일 상단에 `# [샘플] 제목` 주석으로 목적 명시
|
- 각 파일은 YAML document marker `---`로 시작하고, 바로 아래 `# [샘플] 제목` 주석으로 목적을 명시한다
|
||||||
- 실제 작동 가능한 파라미터 구조를 유지한다 (추측 값 사용 금지)
|
- 실제 작동 가능한 파라미터 구조를 유지한다 (추측 값 사용 금지)
|
||||||
- 새 커맨드가 추가되면 관련 샘플 파일도 함께 갱신한다
|
- 새 커맨드가 추가되면 관련 샘플 파일도 함께 갱신한다
|
||||||
- 샘플은 placeholder 값을 사용하고 실제 토큰·비밀번호·API 키를 넣지 않는다
|
- 샘플은 placeholder 값을 사용하고 실제 토큰·비밀번호·API 키를 넣지 않는다
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
domain: scheduler
|
domain: scheduler
|
||||||
last_rule_review_commit: 67d7b6e411b8a28d6d42cac550a29872a7ef6b7e
|
last_rule_review_commit: 99cc06767f82a32a9106f3a483bce2b6aeed5872
|
||||||
last_rule_updated_at: 2026-06-01
|
last_rule_updated_at: 2026-06-13
|
||||||
---
|
---
|
||||||
|
|
||||||
# scheduler
|
# scheduler
|
||||||
|
|
|
||||||
|
|
@ -152,12 +152,18 @@ proto/ # OTO runner/server protobuf contract
|
||||||
| `apps/runner/assets/bin/**` | cli | `agent-ops/rules/project/domain/cli/rules.md` |
|
| `apps/runner/assets/bin/**` | cli | `agent-ops/rules/project/domain/cli/rules.md` |
|
||||||
| `apps/runner/assets/script/shell/oto_agent_bootstrap.sh` | agent | `agent-ops/rules/project/domain/agent/rules.md` |
|
| `apps/runner/assets/script/shell/oto_agent_bootstrap.sh` | agent | `agent-ops/rules/project/domain/agent/rules.md` |
|
||||||
| `apps/runner/assets/script/**` | cli | `agent-ops/rules/project/domain/cli/rules.md` |
|
| `apps/runner/assets/script/**` | cli | `agent-ops/rules/project/domain/cli/rules.md` |
|
||||||
|
| `Makefile` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
| `apps/runner/pubspec.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
| `apps/runner/pubspec.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
|
| `apps/runner/pubspec.lock` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
| `apps/runner/analysis_options.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
| `apps/runner/analysis_options.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
| `apps/client/pubspec.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
| `apps/client/pubspec.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
|
| `apps/client/pubspec.lock` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
| `apps/client/analysis_options.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
| `apps/client/analysis_options.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
| `packages/flutter/oto_console/pubspec.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
| `packages/flutter/oto_console/pubspec.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
|
| `packages/flutter/oto_console/analysis_options.yaml` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
| `services/core/go.mod` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
| `services/core/go.mod` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
|
| `services/core/go.sum` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
|
| `services/core/oto/**` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
| `proto/**` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
| `proto/**` | framework | `agent-ops/rules/project/domain/framework/rules.md` |
|
||||||
|
|
||||||
`test/**`는 별도 도메인으로 고정하지 않는다. 테스트 변경 시 검증 대상 production 경로의 domain rule을 읽고, 여러 도메인을 검증하는 테스트면 관련 domain rule을 함께 읽는다.
|
`test/**`는 별도 도메인으로 고정하지 않는다. 테스트 변경 시 검증 대상 production 경로의 domain rule을 읽고, 여러 도메인을 검증하는 테스트면 관련 domain rule을 함께 읽는다.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ OTO는 YAML 기반 빌드/배포 파이프라인을 실행하는 Dart CLI에서
|
||||||
- [완료] 메시지 기반 빌드 에이전트
|
- [완료] 메시지 기반 빌드 에이전트
|
||||||
- 경로: `agent-roadmap/archive/phase/message-based-build-agent/PHASE.md`
|
- 경로: `agent-roadmap/archive/phase/message-based-build-agent/PHASE.md`
|
||||||
- 요약: `oto agent` 또는 `oto daemon` 모드에서 OTO Server와 양방향 메시지 통신을 사용하는 build/deploy 전용 runner 경계를 정리하고 archive로 이동했다.
|
- 요약: `oto agent` 또는 `oto daemon` 모드에서 OTO Server와 양방향 메시지 통신을 사용하는 build/deploy 전용 runner 경계를 정리하고 archive로 이동했다.
|
||||||
|
- [계획] Control Plane 제품 표면 완성
|
||||||
|
- 경로: `agent-roadmap/phase/control-plane-product-surface/PHASE.md`
|
||||||
|
- 요약: 현재 분리된 Core API, Flutter client, runner bootstrap 경계를 실제 운영 가능한 UI 스켈레톤과 OS별 설치 흐름으로 연결한다.
|
||||||
|
|
||||||
## 로딩 정책
|
## 로딩 정책
|
||||||
|
|
||||||
|
|
|
||||||
30
agent-roadmap/phase/control-plane-product-surface/PHASE.md
Normal file
30
agent-roadmap/phase/control-plane-product-surface/PHASE.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Phase: Control Plane 제품 표면 완성
|
||||||
|
|
||||||
|
## 상태
|
||||||
|
|
||||||
|
[계획]
|
||||||
|
|
||||||
|
## 목표
|
||||||
|
|
||||||
|
현재 분리된 OTO Core API 서버, Flutter client, runner bootstrap 경계를 실제 사용자가 조작할 수 있는 Control Plane 제품 표면으로 끌어올린다.
|
||||||
|
먼저 Flutter UI 스켈레톤을 만들어 Control Plane의 주요 화면과 연결 지점을 고정하고, 이어서 OTO Core bootstrap 흐름이 Linux, macOS, Windows 대상 runner 설치를 지원하도록 확장한다.
|
||||||
|
|
||||||
|
## Milestone 흐름
|
||||||
|
|
||||||
|
완료된 Milestone은 archive 경로를 가리키고, 검토중, 진행중, 계획, 스케치 또는 보류 Milestone은 이 Phase 하위 `milestones/` 경로를 가리킨다.
|
||||||
|
완료, 검토중, 진행중, 계획, 스케치 순서로 두어 아래로 갈수록 미래 작업에 가까워지게 정렬한다.
|
||||||
|
스케치 Milestone은 아직 구현 가능한 계획이 아니므로 계획 Milestone보다 아래에 둔다.
|
||||||
|
|
||||||
|
- [계획] Flutter 콘솔 스켈레톤
|
||||||
|
- 경로: `agent-roadmap/phase/control-plane-product-surface/milestones/flutter-console-skeleton.md`
|
||||||
|
- 요약: `apps/client`와 `packages/flutter/oto_console`에 Control Plane 주요 화면, 상태 표시, 빈 상태, Core 연결 기준을 갖춘 UI 스켈레톤을 만든다.
|
||||||
|
- [계획] OS별 runner bootstrap 설치 지원
|
||||||
|
- 경로: `agent-roadmap/phase/control-plane-product-surface/milestones/cross-os-runner-bootstrap.md`
|
||||||
|
- 요약: OTO Core bootstrap command와 bootstrap asset이 Linux, macOS, Windows에서 OTO runner를 내려받고 설정/실행할 수 있도록 확장한다.
|
||||||
|
|
||||||
|
## Phase 경계
|
||||||
|
|
||||||
|
- 이 Phase는 기존 `services/core`, `apps/client`, `packages/flutter/oto_console`, `apps/runner` 경계를 유지하면서 제품 표면과 bootstrap 실행성을 보강한다.
|
||||||
|
- Jenkins 전체 기능, 장기 권한/감사 모델, durable artifact storage 운영 정책은 이 Phase의 기본 범위가 아니다.
|
||||||
|
- iop Edge 직접 연결 경로는 복원하지 않는다. OTO Core와 OTO runner의 독립 Control Plane 경로를 기준으로 한다.
|
||||||
|
- private release host, enrollment token, credential 원문은 tracked 문서에 남기지 않는다.
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Milestone: OS별 runner bootstrap 설치 지원
|
||||||
|
|
||||||
|
## 위치
|
||||||
|
|
||||||
|
- Roadmap: `agent-roadmap/ROADMAP.md`
|
||||||
|
- Phase: `agent-roadmap/phase/control-plane-product-surface/PHASE.md`
|
||||||
|
|
||||||
|
## 목표
|
||||||
|
|
||||||
|
OTO Core가 발급하는 bootstrap 흐름을 Linux 단일 shell script 기준에서 확장해 Linux, macOS, Windows 대상 runner 설치를 지원한다.
|
||||||
|
완료 후 대상 머신은 OTO가 미리 설치되어 있지 않아도 OS별 bootstrap command로 release asset을 내려받고, agent 설정을 만들고, `oto agent run` 실행 준비 또는 시작까지 진행할 수 있어야 한다.
|
||||||
|
|
||||||
|
## 상태
|
||||||
|
|
||||||
|
[계획]
|
||||||
|
|
||||||
|
## 승격 조건
|
||||||
|
|
||||||
|
- 없음
|
||||||
|
|
||||||
|
## 구현 잠금
|
||||||
|
|
||||||
|
- 상태: 해제
|
||||||
|
- 결정 필요: 없음
|
||||||
|
|
||||||
|
## 범위
|
||||||
|
|
||||||
|
- OTO Core bootstrap command/API와 embedded bootstrap asset 제공 경로를 OS별로 확장한다.
|
||||||
|
- Linux와 macOS는 POSIX shell 기반 설치 흐름을 우선 재사용하고, Windows는 PowerShell 기반 설치 흐름을 둔다.
|
||||||
|
- release asset 이름, OS/arch 감지, 설치 경로, config 경로, log/workspace 경로를 OS별 표준선으로 정리한다.
|
||||||
|
- bootstrap script와 server handler 테스트를 OS별 케이스로 확장한다.
|
||||||
|
|
||||||
|
## 기능
|
||||||
|
|
||||||
|
### Epic: [bootstrap-platforms] Cross-OS bootstrap contract
|
||||||
|
|
||||||
|
OS별 bootstrap command와 release asset 선택 기준을 OTO Core와 runner asset이 같은 의미로 해석하도록 만든다.
|
||||||
|
|
||||||
|
- [ ] [platform-matrix] Linux, macOS, Windows의 우선 지원 OS/arch와 release asset naming 규칙을 정리한다. 검증: 문서와 테스트 fixture가 동일한 asset 이름을 사용한다.
|
||||||
|
- [ ] [core-command] OTO Core bootstrap command 요청/응답이 대상 OS 또는 script 종류를 표현하고 올바른 bootstrap URL/command를 반환한다. 검증: `cd services/core && go test ./...`가 OS별 command 케이스를 포함해 통과한다.
|
||||||
|
- [ ] [unix-bootstrap] Linux/macOS shell bootstrap이 OS/arch를 감지해 올바른 release asset을 내려받고 config/runtime 경로를 생성한다. 검증: `cd apps/runner && dart test test/oto_agent_bootstrap_script_test.dart` 또는 대응 smoke가 통과한다.
|
||||||
|
- [ ] [windows-bootstrap] Windows PowerShell bootstrap이 release asset 다운로드, 압축 해제, config 생성, agent 실행 안내 또는 시작 흐름을 제공한다. 검증: script parsing/fixture 테스트가 Windows 경로와 quoting을 검증한다.
|
||||||
|
- [ ] [docs-smoke] README와 `agent-test/local/agent-smoke.md`가 OS별 bootstrap command, secret 기록 금지, release URL 검증 기준을 최신화한다.
|
||||||
|
|
||||||
|
## 완료 리뷰
|
||||||
|
|
||||||
|
- 상태: 없음
|
||||||
|
- 요청일: 없음
|
||||||
|
- 완료 근거: 없음
|
||||||
|
- 리뷰 필요:
|
||||||
|
- [ ] 사용자가 완료 결과를 확인했다
|
||||||
|
- [ ] archive 이동을 승인했다
|
||||||
|
- 리뷰 코멘트: 없음
|
||||||
|
|
||||||
|
## 범위 제외
|
||||||
|
|
||||||
|
- checksum/signature 검증, certificate pinning, enrollment token rotation은 기본 구현을 막지 않는 후속 보안 강화로 둔다.
|
||||||
|
- OS별 system service 설치를 완성형 daemon 관리까지 확대하지 않는다. 필요하면 user-level background 실행 또는 수동 실행 안내를 먼저 둔다.
|
||||||
|
- private release host, credential, token 원문을 tracked 문서에 기록하지 않는다.
|
||||||
|
|
||||||
|
## 작업 컨텍스트
|
||||||
|
|
||||||
|
- 관련 경로: `services/core/internal/httpserver/**`, `apps/runner/assets/script/**`, `apps/runner/test/**`, `README.md`, `agent-test/local/**`
|
||||||
|
- 표준선(선택): 우선 지원 OS는 Linux, macOS, Windows로 보고, 각 OS의 x64/arm64 지원 여부는 release asset 존재와 테스트 fixture로 명시한다.
|
||||||
|
- 표준선(선택): Linux/macOS는 shell, Windows는 PowerShell을 사용하며, 공통 설정 의미는 `agent.id`, `agent.alias`, `agent.enrollment_token`, `server.url`, `runtime.install_dir`, `runtime.workspace_root`, `runtime.log_dir`를 유지한다.
|
||||||
|
- 선행 작업: `독립 Control Plane 분리 마이그레이션`의 bootstrap command, `워크스페이스 포트/환경 표준화`의 release URL 기준, 폐기된 `Edge bootstrap 계약`의 Linux 설치 근거
|
||||||
|
- 후속 작업: release packaging 자동화, checksum/signature 검증, OS별 service manager 통합
|
||||||
|
- 확인 필요: 없음
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
# Milestone: Flutter 콘솔 스켈레톤
|
||||||
|
|
||||||
|
## 위치
|
||||||
|
|
||||||
|
- Roadmap: `agent-roadmap/ROADMAP.md`
|
||||||
|
- Phase: `agent-roadmap/phase/control-plane-product-surface/PHASE.md`
|
||||||
|
|
||||||
|
## 목표
|
||||||
|
|
||||||
|
현재 endpoint 표시와 placeholder 중심인 Flutter client를 Control Plane 작업 표면의 스켈레톤으로 확장한다.
|
||||||
|
완료 후 사용자는 OTO Core 연결 상태, runner, pipeline/job, execution, log/artifact, settings 영역의 기본 화면 구조와 빈 상태를 확인할 수 있고, 후속 API 연동을 넣을 위치가 명확해야 한다.
|
||||||
|
|
||||||
|
## 상태
|
||||||
|
|
||||||
|
[계획]
|
||||||
|
|
||||||
|
## 승격 조건
|
||||||
|
|
||||||
|
- 없음
|
||||||
|
|
||||||
|
## 구현 잠금
|
||||||
|
|
||||||
|
- 상태: 해제
|
||||||
|
- 결정 필요: 없음
|
||||||
|
|
||||||
|
## 범위
|
||||||
|
|
||||||
|
- `apps/client` host app과 `packages/flutter/oto_console` 패키지의 현재 shell/contract 경계를 유지한다.
|
||||||
|
- Overview, Runners, Pipelines/Jobs, Executions, Artifacts, Settings 화면의 스켈레톤과 상태 표현을 만든다.
|
||||||
|
- OTO Core HTTP URL 설정값을 기준으로 health/readiness 연결 상태를 표시할 수 있는 최소 adapter 또는 port를 둔다.
|
||||||
|
- 실제 API 데이터가 없거나 비어 있을 때의 empty/loading/error 상태를 제품 표면에 맞게 정리한다.
|
||||||
|
|
||||||
|
## 기능
|
||||||
|
|
||||||
|
### Epic: [ui-skeleton] Control Plane UI skeleton
|
||||||
|
|
||||||
|
OTO Console이 placeholder가 아니라 후속 기능을 얹을 수 있는 제품 화면 골격을 갖추도록 한다.
|
||||||
|
|
||||||
|
- [ ] [overview-status] Overview가 `OTO_SERVER_HTTP_URL` 기준 Core health/readiness 상태를 보여줄 수 있는 구조를 갖춘다. 검증: `make client-test` 또는 `cd apps/client && flutter test`에서 상태 표시 위젯 테스트가 통과한다.
|
||||||
|
- [ ] [section-surfaces] Runners, Pipelines/Jobs, Executions, Artifacts, Settings 섹션이 각각 독립 화면 스켈레톤과 빈 상태를 가진다. 검증: `cd packages/flutter/oto_console && flutter test`에서 navigation/section 렌더링 테스트가 통과한다.
|
||||||
|
- [ ] [api-port] Flutter UI가 Core API를 직접 호출할 구현 위치를 contract/adapter로 분리하고, 브라우저 CORS 또는 same-origin proxy 필요성을 작업 컨텍스트에 드러낸다.
|
||||||
|
- [ ] [preview-flow] 원격 preview 명령 `make client-run-web OTO_SERVER_HTTP_URL=http://toki-labs.com:18020` 기준으로 첫 화면이 Core API endpoint와 UI 스켈레톤을 안정적으로 렌더링한다. 검증: 원격 runner 또는 local smoke에서 Flutter web preview 접속 확인을 남긴다.
|
||||||
|
|
||||||
|
## 완료 리뷰
|
||||||
|
|
||||||
|
- 상태: 없음
|
||||||
|
- 요청일: 없음
|
||||||
|
- 완료 근거: 없음
|
||||||
|
- 리뷰 필요:
|
||||||
|
- [ ] 사용자가 완료 결과를 확인했다
|
||||||
|
- [ ] archive 이동을 승인했다
|
||||||
|
- 리뷰 코멘트: 없음
|
||||||
|
|
||||||
|
## 범위 제외
|
||||||
|
|
||||||
|
- runner/job/execution 전체 CRUD와 고급 운영 정책을 한 번에 완성하지 않는다.
|
||||||
|
- auth, 권한, 감사 로그, durable persistence UI를 완성하지 않는다.
|
||||||
|
- production 정적 웹 배포 파이프라인은 이 Milestone의 필수 산출물이 아니다.
|
||||||
|
|
||||||
|
## 작업 컨텍스트
|
||||||
|
|
||||||
|
- 관련 경로: `apps/client/**`, `packages/flutter/oto_console/**`, `services/core/internal/httpserver/**`, `agent-test/local/**`
|
||||||
|
- 표준선(선택): 현재 `OtoConsoleShell`과 `OtoConsoleConfig`를 유지하고, 화면별 구현은 `oto_console` 패키지 안에 둔다.
|
||||||
|
- 표준선(선택): 현재 Core는 CORS 헤더를 제공하지 않으므로 브라우저 직접 API 호출을 붙일 때 CORS middleware 또는 same-origin proxy 정책을 함께 판단한다.
|
||||||
|
- 선행 작업: `oto_console 계약 경계 정리`, `워크스페이스 포트/환경 표준화`
|
||||||
|
- 후속 작업: 실제 runner/job/execution API 데이터 바인딩, 인증/권한, 운영 대시보드 고도화
|
||||||
|
- 확인 필요: 없음
|
||||||
Loading…
Reference in a new issue