diff --git a/docs/ko/ci.md b/docs/ko/ci.md index b08337b75..2ddc0f9ec 100644 --- a/docs/ko/ci.md +++ b/docs/ko/ci.md @@ -1,94 +1,94 @@ --- read_when: - CI 작업이 실행되었거나 실행되지 않은 이유를 이해해야 합니다 - - 실패하는 GitHub Actions 검사를 디버깅하고 있습니다 - - 릴리스 검증 실행 또는 재실행을 조정하고 있습니다 + - 실패한 GitHub Actions 검사를 디버깅하고 있습니다 + - 릴리스 검증 실행 또는 재실행을 조율하고 있습니다 - ClawSweeper 디스패치 또는 GitHub 활동 전달을 변경하는 경우 -summary: CI 작업 그래프, 범위 게이트, 릴리스 엄브렐라 및 로컬 명령 대응 항목 +summary: CI 작업 그래프, 범위 게이트, 릴리스 엄브렐라 및 이에 대응하는 로컬 명령 title: CI 파이프라인 x-i18n: - generated_at: "2026-05-02T22:17:32Z" + generated_at: "2026-05-02T23:39:33Z" model: gpt-5.5 provider: openai - source_hash: a8033b928b26adfa340200ea69fd63d339a6e65c21659b8119a68b23b8b16016 + source_hash: 321fe0a061044f75b8e1d03b4d3e76d4f8dd2dae0ebc58831887fc20af953cf1 source_path: ci.md workflow: 16 --- -OpenClaw CI는 `main`으로의 모든 푸시와 모든 풀 리퀘스트에서 실행됩니다. `preflight` 작업은 diff를 분류하고 관련 없는 영역만 변경된 경우 비용이 큰 lane을 끕니다. 수동 `workflow_dispatch` 실행은 의도적으로 스마트 스코핑을 우회하고 릴리스 후보와 광범위한 검증을 위해 전체 그래프를 확장합니다. Android lane은 `include_android`를 통해 계속 선택 사항으로 유지됩니다. 릴리스 전용 Plugin 적용 범위는 별도의 [`Plugin Prerelease`](#plugin-prerelease) workflow에 있으며 [`Full Release Validation`](#full-release-validation) 또는 명시적인 수동 dispatch에서만 실행됩니다. +OpenClaw CI는 `main`에 푸시할 때마다, 그리고 모든 풀 리퀘스트마다 실행됩니다. `preflight` 작업은 diff를 분류하고 관련 없는 영역만 변경된 경우 비용이 큰 레인을 끕니다. 수동 `workflow_dispatch` 실행은 의도적으로 스마트 범위 지정을 우회하고 릴리스 후보와 광범위한 검증을 위해 전체 그래프를 전개합니다. Android 레인은 `include_android`를 통해 옵트인 상태로 유지됩니다. 릴리스 전용 Plugin 커버리지는 별도 [`Plugin 사전 릴리스`](#plugin-prerelease) 워크플로에 있으며, [`전체 릴리스 검증`](#full-release-validation) 또는 명시적 수동 디스패치에서만 실행됩니다. ## 파이프라인 개요 | 작업 | 목적 | 실행 시점 | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | -| `preflight` | 문서 전용 변경, 변경된 scope, 변경된 확장, CI manifest를 감지합니다 | 초안이 아닌 푸시와 PR에서 항상 | -| `security-scm-fast` | `zizmor`를 통한 개인 키 감지와 workflow 감사 | 초안이 아닌 푸시와 PR에서 항상 | -| `security-dependency-audit` | npm advisory에 대한 의존성 없는 프로덕션 lockfile 감사 | 초안이 아닌 푸시와 PR에서 항상 | -| `security-fast` | 빠른 보안 작업을 위한 필수 집계 | 초안이 아닌 푸시와 PR에서 항상 | -| `check-dependencies` | 프로덕션 Knip 의존성 전용 pass와 미사용 파일 allowlist guard | Node 관련 변경 | -| `build-artifacts` | `dist/`, Control UI, 빌드 산출물 검사, 재사용 가능한 downstream artifact를 빌드합니다 | Node 관련 변경 | -| `checks-fast-core` | 번들/Plugin 계약/프로토콜 검사 같은 빠른 Linux 정확성 lane | Node 관련 변경 | -| `checks-fast-contracts-channels` | 안정적인 집계 검사 결과가 있는 sharded channel 계약 검사 | Node 관련 변경 | -| `checks-node-core-test` | channel, 번들, 계약, 확장 lane을 제외한 Core Node test shard | Node 관련 변경 | -| `check` | sharded main 로컬 gate와 동일한 항목: 프로덕션 타입, lint, guard, test type, 엄격한 smoke | Node 관련 변경 | -| `check-additional` | 아키텍처, boundary, prompt snapshot drift, extension surface guard, package boundary, gateway watch shard | Node 관련 변경 | -| `build-smoke` | 빌드된 CLI smoke test와 startup memory smoke | Node 관련 변경 | -| `checks` | 빌드 산출물 channel test용 verifier | Node 관련 변경 | -| `checks-node-compat-node22` | Node 22 호환성 빌드와 smoke lane | 릴리스용 수동 CI dispatch | -| `check-docs` | 문서 formatting, lint, broken link 검사 | 문서 변경 | +| `preflight` | 문서 전용 변경, 변경된 범위, 변경된 확장, CI 매니페스트 빌드를 감지 | 드래프트가 아닌 푸시와 PR에서 항상 | +| `security-scm-fast` | `zizmor`를 통한 개인 키 감지와 워크플로 감사 | 드래프트가 아닌 푸시와 PR에서 항상 | +| `security-dependency-audit` | npm 권고를 기준으로 종속성 없는 프로덕션 lockfile 감사 | 드래프트가 아닌 푸시와 PR에서 항상 | +| `security-fast` | 빠른 보안 작업을 위한 필수 집계 | 드래프트가 아닌 푸시와 PR에서 항상 | +| `check-dependencies` | 프로덕션 Knip 종속성 전용 패스와 미사용 파일 허용 목록 가드 | Node 관련 변경 | +| `build-artifacts` | `dist/`, Control UI, 빌드된 아티팩트 검사, 재사용 가능한 downstream 아티팩트 빌드 | Node 관련 변경 | +| `checks-fast-core` | 번들/Plugin 계약/프로토콜 검사 같은 빠른 Linux 정합성 레인 | Node 관련 변경 | +| `checks-fast-contracts-channels` | 안정적인 집계 검사 결과가 있는 샤딩된 채널 계약 검사 | Node 관련 변경 | +| `checks-node-core-test` | 채널, 번들, 계약, 확장 레인을 제외한 Core Node 테스트 샤드 | Node 관련 변경 | +| `check` | 샤딩된 기본 로컬 게이트와 동등한 검사: 프로덕션 타입, 린트, 가드, 테스트 타입, 엄격한 스모크 | Node 관련 변경 | +| `check-additional` | 아키텍처, 경계, 프롬프트 스냅샷 드리프트, 확장 표면 가드, 패키지 경계, gateway-watch 샤드 | Node 관련 변경 | +| `build-smoke` | 빌드된 CLI 스모크 테스트와 시작 메모리 스모크 | Node 관련 변경 | +| `checks` | 빌드된 아티팩트 채널 테스트용 검증기 | Node 관련 변경 | +| `checks-node-compat-node22` | Node 22 호환성 빌드와 스모크 레인 | 릴리스용 수동 CI 디스패치 | +| `check-docs` | 문서 포맷, 린트, 깨진 링크 검사 | 문서 변경 | | `skills-python` | Python 기반 Skills용 Ruff + pytest | Python Skills 관련 변경 | -| `checks-windows` | Windows 전용 process/path test와 공유 runtime import specifier 회귀 검사 | Windows 관련 변경 | -| `macos-node` | 공유 빌드 산출물을 사용하는 macOS TypeScript test lane | macOS 관련 변경 | -| `macos-swift` | macOS 앱용 Swift lint, 빌드, test | macOS 관련 변경 | -| `android` | 두 flavor의 Android unit test와 하나의 debug APK 빌드 | Android 관련 변경 | -| `test-performance-agent` | 신뢰된 활동 이후 매일 실행되는 Codex slow test 최적화 | Main CI 성공 또는 수동 dispatch | -| `openclaw-performance` | mock provider, deep profile, GPT 5.4 live lane이 포함된 일일/온디맨드 Kova runtime 성능 보고서 | 예약 실행과 수동 dispatch | +| `checks-windows` | Windows별 프로세스/경로 테스트와 공유 런타임 import 지정자 회귀 | Windows 관련 변경 | +| `macos-node` | 공유 빌드 아티팩트를 사용하는 macOS TypeScript 테스트 레인 | macOS 관련 변경 | +| `macos-swift` | macOS 앱의 Swift 린트, 빌드, 테스트 | macOS 관련 변경 | +| `android` | 두 flavor 모두의 Android 단위 테스트와 디버그 APK 빌드 하나 | Android 관련 변경 | +| `test-performance-agent` | 신뢰된 활동 이후 매일 Codex 느린 테스트 최적화 | 메인 CI 성공 또는 수동 디스패치 | +| `openclaw-performance` | mock-provider, deep-profile, GPT 5.4 라이브 레인이 포함된 일일/온디맨드 Kova 런타임 성능 보고 | 예약 및 수동 디스패치 | ## Fail-fast 순서 -1. `preflight`는 어떤 lane이 존재할지 결정합니다. `docs-scope`와 `changed-scope` 로직은 독립 실행형 작업이 아니라 이 작업 안의 단계입니다. -2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs`, `skills-python`은 더 무거운 artifact와 platform matrix 작업을 기다리지 않고 빠르게 실패합니다. -3. `build-artifacts`는 빠른 Linux lane과 겹쳐 실행되므로 공유 빌드가 준비되는 즉시 downstream consumer가 시작할 수 있습니다. -4. 이후 더 무거운 platform 및 runtime lane이 확장됩니다: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-core-test`, `checks`, `checks-windows`, `macos-node`, `macos-swift`, `android`. +1. `preflight`는 어떤 레인이 존재할지 먼저 결정합니다. `docs-scope`와 `changed-scope` 로직은 독립 실행형 작업이 아니라 이 작업 내부의 단계입니다. +2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs`, `skills-python`은 더 무거운 아티팩트 및 플랫폼 매트릭스 작업을 기다리지 않고 빠르게 실패합니다. +3. `build-artifacts`는 빠른 Linux 레인과 겹쳐 실행되어 공유 빌드가 준비되는 즉시 downstream 소비자가 시작할 수 있게 합니다. +4. 더 무거운 플랫폼 및 런타임 레인은 그 이후 전개됩니다: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-core-test`, `checks`, `checks-windows`, `macos-node`, `macos-swift`, `android`. -같은 PR 또는 `main` ref에 새 푸시가 올라오면 GitHub가 대체된 작업을 `cancelled`로 표시할 수 있습니다. 같은 ref의 최신 실행도 실패하는 경우가 아니라면 이를 CI noise로 취급하세요. 집계 shard 검사는 `!cancelled() && always()`를 사용하므로 일반 shard 실패는 계속 보고하지만 전체 workflow가 이미 대체된 뒤에는 대기열에 추가되지 않습니다. 자동 CI concurrency key는 버전이 지정되어 있으므로(`CI-v7-*`) 오래된 queue group의 GitHub 측 zombie가 더 새로운 main 실행을 무기한 막을 수 없습니다. 수동 full-suite 실행은 `CI-manual-v1-*`을 사용하며 진행 중인 실행을 취소하지 않습니다. +같은 PR 또는 `main` ref에 더 새로운 푸시가 올라오면 GitHub가 대체된 작업을 `cancelled`로 표시할 수 있습니다. 같은 ref의 최신 실행도 실패하는 경우가 아니라면 이를 CI 노이즈로 취급하세요. 집계 샤드 검사는 `!cancelled() && always()`를 사용하므로 정상적인 샤드 실패는 계속 보고하지만, 전체 워크플로가 이미 대체된 뒤에는 큐에 넣지 않습니다. 자동 CI 동시성 키는 버전화되어 있으므로(`CI-v7-*`) 이전 큐 그룹의 GitHub 측 좀비가 더 새로운 main 실행을 무기한 차단할 수 없습니다. 수동 전체 스위트 실행은 `CI-manual-v1-*`를 사용하며 진행 중인 실행을 취소하지 않습니다. -## Scope와 routing +## 범위와 라우팅 -Scope 로직은 `scripts/ci-changed-scope.mjs`에 있으며 `src/scripts/ci-changed-scope.test.ts`의 unit test로 커버됩니다. 수동 dispatch는 changed-scope 감지를 건너뛰고 모든 scoped area가 변경된 것처럼 preflight manifest가 동작하게 합니다. +범위 로직은 `scripts/ci-changed-scope.mjs`에 있으며, `src/scripts/ci-changed-scope.test.ts`의 단위 테스트로 커버됩니다. 수동 디스패치는 changed-scope 감지를 건너뛰고 preflight 매니페스트가 모든 범위 영역이 변경된 것처럼 동작하게 합니다. -- **CI workflow 편집**은 Node CI graph와 workflow linting을 검증하지만, 그 자체로 Windows, Android, macOS native build를 강제하지는 않습니다. 해당 platform lane은 platform source 변경으로 계속 scope가 제한됩니다. -- **CI routing 전용 편집, 선택된 저비용 core-test fixture 편집, 좁은 Plugin 계약 helper/test-routing 편집**은 빠른 Node 전용 manifest 경로를 사용합니다: `preflight`, security, 단일 `checks-fast-core` 작업. 이 경로는 변경이 fast task가 직접 실행하는 routing 또는 helper surface로 제한될 때 build artifact, Node 22 compatibility, channel contract, full core shard, bundled Plugin shard, additional guard matrix를 건너뜁니다. -- **Windows Node 검사**는 Windows 전용 process/path wrapper, npm/pnpm/UI runner helper, package manager config, 해당 lane을 실행하는 CI workflow surface로 scope가 제한됩니다. 관련 없는 source, Plugin, install-smoke, test-only 변경은 Linux Node lane에 유지됩니다. +- **CI 워크플로 편집**은 Node CI 그래프와 워크플로 린팅을 검증하지만, 그 자체만으로 Windows, Android, macOS 네이티브 빌드를 강제하지 않습니다. 해당 플랫폼 레인은 플랫폼 소스 변경에만 범위가 지정됩니다. +- **CI 라우팅 전용 편집, 선택된 저비용 core-test fixture 편집, 좁은 Plugin 계약 helper/test-routing 편집**은 빠른 Node 전용 매니페스트 경로를 사용합니다: `preflight`, 보안, 단일 `checks-fast-core` 작업. 변경이 빠른 작업이 직접 실행하는 라우팅 또는 helper 표면으로 제한될 때 이 경로는 빌드 아티팩트, Node 22 호환성, 채널 계약, 전체 Core 샤드, 번들 Plugin 샤드, 추가 가드 매트릭스를 건너뜁니다. +- **Windows Node 검사**는 Windows별 프로세스/경로 wrapper, npm/pnpm/UI runner helper, 패키지 관리자 config, 해당 레인을 실행하는 CI 워크플로 표면으로 범위가 지정됩니다. 관련 없는 소스, Plugin, install-smoke, 테스트 전용 변경은 Linux Node 레인에 남습니다. -가장 느린 Node test family는 각 작업이 runner를 과도하게 예약하지 않으면서 작게 유지되도록 분할되거나 균형이 맞춰집니다. channel contract는 세 개의 weighted shard로 실행되고, 작은 core unit lane은 쌍으로 묶이며, auto-reply는 네 개의 균형 잡힌 worker로 실행되고(reply subtree는 agent-runner, dispatch, commands/state-routing shard로 분할), agentic gateway/Plugin config는 빌드 산출물을 기다리지 않고 기존 source-only agentic Node 작업에 분산됩니다. 광범위한 browser, QA, media, 기타 Plugin test는 공유 Plugin catch-all 대신 전용 Vitest config를 사용합니다. Include-pattern shard는 CI shard 이름을 사용해 timing entry를 기록하므로 `.artifacts/vitest-shard-timings.json`이 전체 config와 filtered shard를 구분할 수 있습니다. `check-additional`은 package-boundary compile/canary 작업을 함께 유지하고 runtime topology architecture를 gateway watch coverage와 분리합니다. boundary guard shard는 `pnpm prompt:snapshots:check`를 포함해 작은 독립 guard들을 하나의 작업 안에서 동시에 실행하므로 Codex happy-path prompt drift가 그것을 유발한 PR에 고정됩니다. Gateway watch, channel test, core support-boundary shard는 `dist/`와 `dist-runtime/`이 이미 빌드된 뒤 `build-artifacts` 안에서 동시에 실행됩니다. +가장 느린 Node 테스트 패밀리는 각 작업이 runner를 과도하게 예약하지 않으면서 작게 유지되도록 분할되거나 균형이 맞춰집니다. 채널 계약은 세 개의 가중치 샤드로 실행되고, 작은 Core 단위 레인은 짝지어지며, auto-reply는 네 개의 균형 잡힌 worker로 실행되고(reply subtree는 agent-runner, dispatch, commands/state-routing 샤드로 분할), agentic Gateway/Plugin config는 빌드된 아티팩트를 기다리는 대신 기존 소스 전용 agentic Node 작업 전반에 분산됩니다. 광범위한 브라우저, QA, 미디어, 기타 Plugin 테스트는 공유 Plugin catch-all 대신 전용 Vitest config를 사용합니다. include-pattern 샤드는 CI 샤드 이름을 사용해 타이밍 항목을 기록하므로 `.artifacts/vitest-shard-timings.json`이 전체 config와 필터링된 샤드를 구분할 수 있습니다. `check-additional`은 package-boundary 컴파일/canary 작업을 함께 유지하고 런타임 topology 아키텍처를 gateway watch 커버리지와 분리합니다. boundary guard 샤드는 하나의 작업 안에서 작은 독립 가드들을 동시에 실행하며, 여기에는 `pnpm prompt:snapshots:check`가 포함되어 Codex 런타임 happy-path 프롬프트 드리프트가 그 원인을 만든 PR에 고정됩니다. Gateway watch, 채널 테스트, Core support-boundary 샤드는 `dist/`와 `dist-runtime/`이 이미 빌드된 뒤 `build-artifacts` 안에서 동시에 실행됩니다. -Android CI는 `testPlayDebugUnitTest`와 `testThirdPartyDebugUnitTest`를 모두 실행한 뒤 Play debug APK를 빌드합니다. third-party flavor에는 별도의 source set이나 manifest가 없습니다. 그 unit-test lane은 SMS/call-log BuildConfig flag가 적용된 flavor를 계속 컴파일하되, Android 관련 모든 푸시에서 중복 debug APK packaging 작업은 피합니다. +Android CI는 `testPlayDebugUnitTest`와 `testThirdPartyDebugUnitTest`를 모두 실행한 다음 Play 디버그 APK를 빌드합니다. third-party flavor에는 별도의 source set이나 manifest가 없습니다. 단위 테스트 레인은 여전히 SMS/call-log BuildConfig 플래그로 해당 flavor를 컴파일하면서, Android 관련 푸시마다 중복 디버그 APK 패키징 작업을 피합니다. -`check-dependencies` shard는 `pnpm deadcode:dependencies`(최신 Knip version에 고정된 프로덕션 Knip 의존성 전용 pass이며, `dlx` 설치를 위해 pnpm의 최소 release age가 비활성화됨)와 `pnpm deadcode:unused-files`를 실행합니다. 이는 Knip의 프로덕션 unused-file finding을 `scripts/deadcode-unused-files.allowlist.mjs`와 비교합니다. unused-file guard는 PR이 검토되지 않은 새 unused file을 추가하거나 오래된 allowlist entry를 남겨두면 실패하며, Knip이 정적으로 resolve할 수 없는 의도적인 dynamic Plugin, generated, build, live-test, package bridge surface는 보존합니다. +`check-dependencies` 샤드는 `pnpm deadcode:dependencies`(최신 Knip 버전에 고정된 프로덕션 Knip 종속성 전용 패스이며, `dlx` 설치를 위해 pnpm의 최소 릴리스 경과 시간이 비활성화됨)와 `pnpm deadcode:unused-files`를 실행합니다. 후자는 Knip의 프로덕션 미사용 파일 발견 결과를 `scripts/deadcode-unused-files.allowlist.mjs`와 비교합니다. 미사용 파일 가드는 PR이 검토되지 않은 새 미사용 파일을 추가하거나 오래된 허용 목록 항목을 남겨두면 실패하며, Knip이 정적으로 해석할 수 없는 의도적인 동적 Plugin, 생성물, 빌드, live-test, 패키지 bridge 표면은 보존합니다. ## ClawSweeper 활동 전달 -`.github/workflows/clawsweeper-dispatch.yml`은 OpenClaw repository 활동을 ClawSweeper로 보내는 target-side bridge입니다. 이 workflow는 신뢰할 수 없는 pull request code를 checkout하거나 실행하지 않습니다. workflow는 `CLAWSWEEPER_APP_PRIVATE_KEY`에서 GitHub App token을 만든 다음, compact `repository_dispatch` payload를 `openclaw/clawsweeper`로 dispatch합니다. +`.github/workflows/clawsweeper-dispatch.yml`은 OpenClaw 저장소 활동을 ClawSweeper로 전달하는 대상 측 bridge입니다. 신뢰할 수 없는 풀 리퀘스트 코드를 체크아웃하거나 실행하지 않습니다. 이 워크플로는 `CLAWSWEEPER_APP_PRIVATE_KEY`에서 GitHub App 토큰을 만든 다음, 압축된 `repository_dispatch` payload를 `openclaw/clawsweeper`로 디스패치합니다. -이 workflow에는 네 개의 lane이 있습니다. +워크플로에는 네 개의 레인이 있습니다. -- 정확한 issue와 pull request review request용 `clawsweeper_item`; -- issue comment의 명시적인 ClawSweeper command용 `clawsweeper_comment`; -- `main` push의 commit-level review request용 `clawsweeper_commit_review`; -- ClawSweeper agent가 검사할 수 있는 일반 GitHub activity용 `github_activity`. +- 정확한 이슈 및 풀 리퀘스트 리뷰 요청용 `clawsweeper_item`; +- 이슈 댓글의 명시적 ClawSweeper 명령용 `clawsweeper_comment`; +- `main` 푸시의 커밋 수준 리뷰 요청용 `clawsweeper_commit_review`; +- ClawSweeper agent가 검사할 수 있는 일반 GitHub 활동용 `github_activity`. -`github_activity` lane은 정규화된 metadata만 전달합니다: event type, action, actor, repository, item number, URL, title, state, 그리고 comment나 review가 있을 때 짧은 excerpt. 의도적으로 전체 webhook body는 전달하지 않습니다. `openclaw/clawsweeper`의 수신 workflow는 `.github/workflows/github-activity.yml`이며, 이 workflow는 정규화된 event를 ClawSweeper agent용 OpenClaw Gateway hook에 게시합니다. +`github_activity` 레인은 정규화된 metadata만 전달합니다: 이벤트 유형, action, actor, 저장소, 항목 번호, URL, 제목, 상태, 그리고 댓글이나 리뷰가 있을 때의 짧은 발췌. 전체 Webhook body는 의도적으로 전달하지 않습니다. `openclaw/clawsweeper`의 수신 워크플로는 `.github/workflows/github-activity.yml`이며, 정규화된 이벤트를 ClawSweeper agent용 OpenClaw Gateway hook에 게시합니다. -일반 activity는 observation이지 기본 delivery가 아닙니다. ClawSweeper agent는 prompt에서 Discord target을 받으며, event가 놀랍거나, 조치 가능하거나, 위험하거나, 운영상 유용할 때만 `#clawsweeper`에 게시해야 합니다. routine open, edit, bot churn, duplicate webhook noise, normal review traffic은 `NO_REPLY`로 이어져야 합니다. +일반 활동은 관찰이며, 기본 전달이 아닙니다. ClawSweeper agent는 프롬프트에서 Discord 대상을 받으며, 이벤트가 놀랍거나, 조치 가능하거나, 위험하거나, 운영상 유용할 때만 `#clawsweeper`에 게시해야 합니다. 일상적인 열기, 편집, bot churn, 중복 Webhook 노이즈, 일반 리뷰 트래픽은 `NO_REPLY`가 되어야 합니다. -이 경로 전체에서 GitHub title, comment, body, review text, branch name, commit message는 신뢰할 수 없는 data로 취급하세요. 이들은 summarization과 triage를 위한 input이지 workflow나 agent runtime을 위한 instruction이 아닙니다. +이 경로 전체에서 GitHub 제목, 댓글, body, 리뷰 텍스트, branch 이름, commit message를 신뢰할 수 없는 데이터로 취급하세요. 이들은 요약과 triage를 위한 입력이지, 워크플로 또는 agent 런타임에 대한 지시가 아닙니다. -## 수동 dispatch +## 수동 디스패치 -수동 CI 디스패치는 일반 CI와 동일한 작업 그래프를 실행하지만 Android가 아닌 모든 범위 지정 레인을 강제로 켭니다: Linux Node 샤드, 번들 Plugin 샤드, 채널 계약, Node 22 호환성, `check`, `check-additional`, 빌드 스모크, 문서 검사, Python Skills, Windows, macOS, Control UI i18n. 독립 실행형 수동 CI 디스패치는 `include_android=true`일 때 Android만 실행하며, 전체 릴리스 우산 워크플로는 `include_android=true`를 전달해 Android를 활성화합니다. Plugin 프리릴리스 정적 검사, 릴리스 전용 `agentic-plugins` 샤드, 전체 확장 배치 스윕, Plugin 프리릴리스 Docker 레인은 CI에서 제외됩니다. Docker 프리릴리스 제품군은 `Full Release Validation`이 릴리스 검증 게이트를 활성화한 상태로 별도의 `Plugin Prerelease` 워크플로를 디스패치할 때만 실행됩니다. +수동 CI 디스패치는 일반 CI와 동일한 작업 그래프를 실행하지만, Android가 아닌 모든 범위 지정 레인을 강제로 켭니다: Linux Node 샤드, 번들 Plugin 샤드, 채널 계약, Node 22 호환성, `check`, `check-additional`, 빌드 스모크, 문서 검사, Python Skills, Windows, macOS, Control UI i18n. 독립 실행형 수동 CI 디스패치는 `include_android=true`를 사용해 Android만 실행합니다. 전체 릴리스 엄브렐라는 `include_android=true`를 전달해 Android를 활성화합니다. Plugin 프리릴리스 정적 검사, 릴리스 전용 `agentic-plugins` 샤드, 전체 확장 배치 스윕, Plugin 프리릴리스 Docker 레인은 CI에서 제외됩니다. Docker 프리릴리스 스위트는 `Full Release Validation`이 릴리스 검증 게이트를 활성화한 상태로 별도의 `Plugin Prerelease` 워크플로를 디스패치할 때만 실행됩니다. -수동 실행은 고유한 동시성 그룹을 사용하므로 릴리스 후보 전체 제품군이 같은 ref의 다른 push 또는 PR 실행에 의해 취소되지 않습니다. 선택적 `target_ref` 입력을 사용하면 신뢰된 호출자가 선택한 디스패치 ref의 워크플로 파일을 사용하면서 브랜치, 태그 또는 전체 커밋 SHA에 대해 해당 그래프를 실행할 수 있습니다. +수동 실행은 고유한 동시성 그룹을 사용하므로 릴리스 후보 전체 스위트가 같은 ref의 다른 푸시 또는 PR 실행으로 취소되지 않습니다. 선택적 `target_ref` 입력을 사용하면 신뢰할 수 있는 호출자가 선택한 디스패치 ref의 워크플로 파일을 사용하면서 브랜치, 태그 또는 전체 커밋 SHA에 대해 해당 그래프를 실행할 수 있습니다. ```bash gh workflow run ci.yml --ref release/YYYY.M.D @@ -96,19 +96,19 @@ gh workflow run ci.yml --ref main -f target_ref= -f include_andro gh workflow run full-release-validation.yml --ref main -f ref= ``` -## 실행기 +## 러너 -| 실행기 | 작업 | +| 러너 | 작업 | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`, 빠른 보안 작업과 집계(`security-scm-fast`, `security-dependency-audit`, `security-fast`), 빠른 프로토콜/계약/번들 검사, 샤드된 채널 계약 검사, lint를 제외한 `check` 샤드, `check-additional` 샤드와 집계, Node 테스트 집계 검증기, 문서 검사, Python Skills, workflow-sanity, labeler, auto-response; install-smoke preflight도 GitHub 호스팅 Ubuntu를 사용해 Blacksmith 매트릭스가 더 일찍 큐에 들어갈 수 있도록 합니다 | -| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, 더 가벼운 확장 샤드, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types`, `check-test-types` | +| `ubuntu-24.04` | `preflight`, 빠른 보안 작업 및 집계(`security-scm-fast`, `security-dependency-audit`, `security-fast`), 빠른 프로토콜/계약/번들 검사, 샤딩된 채널 계약 검사, lint를 제외한 `check` 샤드, `check-additional` 샤드 및 집계, Node 테스트 집계 검증기, 문서 검사, Python Skills, workflow-sanity, labeler, auto-response; install-smoke 프리플라이트도 GitHub 호스팅 Ubuntu를 사용하여 Blacksmith 매트릭스가 더 일찍 대기열에 들어갈 수 있게 합니다 | +| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, 더 가벼운 확장 샤드, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types`, `check-test-types` | | `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, Linux Node 테스트 샤드, 번들 Plugin 테스트 샤드, `android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(CPU에 민감해 8 vCPU가 절약한 것보다 더 많은 비용이 들 정도임); install-smoke Docker 빌드(32-vCPU 큐 시간이 절약한 것보다 더 많은 비용이 듦) | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(CPU에 민감해 8 vCPU가 절약한 것보다 더 많은 비용이 들 정도임); install-smoke Docker 빌드(32-vCPU 대기열 시간이 절약한 것보다 더 많은 비용이 듦) | | `blacksmith-16vcpu-windows-2025` | `checks-windows` | -| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw`의 `macos-node`; fork는 `macos-latest`로 폴백합니다 | -| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw`의 `macos-swift`; fork는 `macos-latest`로 폴백합니다 | +| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw`의 `macos-node`; 포크는 `macos-latest`로 폴백합니다 | +| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw`의 `macos-swift`; 포크는 `macos-latest`로 폴백합니다 | -## 로컬 동등 명령 +## 로컬 대응 명령 ```bash pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD @@ -137,30 +137,38 @@ pnpm perf:kova:summary --report .artifacts/kova/reports/mock-provider/report.jso ## OpenClaw 성능 -`OpenClaw Performance`는 제품/런타임 성능 워크플로입니다. `main`에서 매일 실행되며 수동으로 디스패치할 수 있습니다: +`OpenClaw Performance`는 제품/런타임 성능 워크플로입니다. 매일 `main`에서 실행되며 수동으로 디스패치할 수 있습니다: ```bash gh workflow run openclaw-performance.yml --ref main -f profile=diagnostic -f repeat=3 gh workflow run openclaw-performance.yml --ref main -f profile=smoke -f repeat=1 -f deep_profile=true -f live_gpt54=true ``` -워크플로는 고정된 릴리스에서 OCM을 설치하고 고정된 `kova_ref` 입력에서 Kova를 설치한 다음, 세 개의 레인을 실행합니다: +워크플로는 고정된 릴리스에서 OCM을 설치하고 고정된 `kova_ref` 입력에서 Kova를 설치한 다음 세 개의 레인을 실행합니다: -- `mock-provider`: 결정적 가짜 OpenAI 호환 인증을 사용하는 로컬 빌드 런타임에 대한 Kova 진단 시나리오. +- `mock-provider`: 결정론적 가짜 OpenAI 호환 인증을 사용하는 로컬 빌드 런타임에 대한 Kova 진단 시나리오. - `mock-deep-profile`: 시작, Gateway, 에이전트 턴 핫스팟에 대한 CPU/힙/트레이스 프로파일링. - `live-gpt54`: 실제 OpenAI `openai/gpt-5.4` 에이전트 턴이며, `OPENAI_API_KEY`를 사용할 수 없으면 건너뜁니다. -mock-provider 레인은 Kova 패스 후 OpenClaw 네이티브 소스 프로브도 실행합니다: 기본, hook, 50-Plugin 시작 사례 전반의 Gateway 부팅 시간과 메모리; 반복되는 mock-OpenAI `channel-chat-baseline` hello 루프; 부팅된 Gateway에 대한 CLI 시작 명령. 소스 프로브 Markdown 요약은 보고서 번들의 `source/index.md`에 있으며, 원시 JSON이 그 옆에 있습니다. +mock-provider 레인은 Kova 통과 후 OpenClaw 네이티브 소스 프로브도 실행합니다: 기본, hook, 50-Plugin 시작 사례 전반의 Gateway 부팅 시간 및 메모리, 반복 mock-OpenAI `channel-chat-baseline` hello 루프, 부팅된 Gateway에 대한 CLI 시작 명령입니다. 소스 프로브 Markdown 요약은 보고서 번들의 `source/index.md`에 있으며, 원시 JSON은 그 옆에 있습니다. -모든 레인은 GitHub 아티팩트를 업로드합니다. `CLAWGRIT_REPORTS_TOKEN`이 구성되어 있으면 워크플로는 `report.json`, `report.md`, 번들, `index.md`, 소스 프로브 아티팩트도 `openclaw-performance//-//` 아래의 `openclaw/clawgrit-reports`에 커밋합니다. 현재 브랜치 포인터는 `openclaw-performance//latest-.json`으로 작성됩니다. +모든 레인은 GitHub 아티팩트를 업로드합니다. `CLAWGRIT_REPORTS_TOKEN`이 구성된 경우 워크플로는 `report.json`, `report.md`, 번들, `index.md`, 소스 프로브 아티팩트도 `openclaw-performance//-//` 아래의 `openclaw/clawgrit-reports`에 커밋합니다. 현재 브랜치 포인터는 `openclaw-performance//latest-.json`으로 작성됩니다. ## 전체 릴리스 검증 -`Full Release Validation`은 "릴리스 전에 모든 것을 실행"하기 위한 수동 우산 워크플로입니다. 브랜치, 태그 또는 전체 커밋 SHA를 받고, 해당 대상을 사용해 수동 `CI` 워크플로를 디스패치하며, 릴리스 전용 Plugin/패키지/정적/Docker 증거를 위해 `Plugin Prerelease`를 디스패치하고, install smoke, package acceptance, Docker release-path 제품군, live/E2E, OpenWebUI, QA Lab parity, Matrix, Telegram 레인을 위해 `OpenClaw Release Checks`를 디스패치합니다. `rerun_group=all` 및 `release_profile=full`을 사용하면 release checks의 `release-package-under-test` 아티팩트에 대해 `NPM Telegram Beta E2E`도 실행합니다. 게시 후에는 게시된 npm 패키지에 대해 동일한 Telegram 패키지 레인을 다시 실행하려면 `npm_telegram_package_spec`을 전달합니다. +`Full Release Validation`은 "릴리스 전 모든 것을 실행"하기 위한 수동 엄브렐라 워크플로입니다. 브랜치, 태그 또는 전체 커밋 SHA를 받아 해당 대상을 사용해 수동 `CI` 워크플로를 디스패치하고, 릴리스 전용 Plugin/패키지/정적/Docker 증명을 위해 `Plugin Prerelease`를 디스패치하며, install smoke, package acceptance, Docker 릴리스 경로 스위트, live/E2E, OpenWebUI, QA Lab parity, Matrix, Telegram 레인을 위해 `OpenClaw Release Checks`를 디스패치합니다. `rerun_group=all` 및 `release_profile=full`을 사용하면 릴리스 검사에서 나온 `release-package-under-test` 아티팩트를 대상으로 `NPM Telegram Beta E2E`도 실행합니다. 게시 후에는 `npm_telegram_package_spec`을 전달해 게시된 npm 패키지에 대해 동일한 Telegram 패키지 레인을 다시 실행합니다. -스테이지 매트릭스, 정확한 워크플로 작업 이름, 프로필 차이, 아티팩트, 집중 재실행 핸들은 [전체 릴리스 검증](/ko/reference/full-release-validation)을 참조하세요. +단계 매트릭스, 정확한 워크플로 작업 이름, 프로필 차이, 아티팩트, +집중 재실행 핸들은 [전체 릴리스 검증](/ko/reference/full-release-validation)을 +참조하세요. -`OpenClaw Release Publish`는 변경을 수행하는 수동 릴리스 워크플로입니다. 릴리스 태그가 존재하고 OpenClaw npm preflight가 성공한 뒤 `release/YYYY.M.D` 또는 `main`에서 디스패치하세요. 이 워크플로는 `pnpm plugins:sync:check`를 검증하고, 게시 가능한 모든 Plugin 패키지에 대해 `Plugin NPM Release`를 디스패치하며, 같은 릴리스 SHA에 대해 `Plugin ClawHub Release`를 디스패치한 다음에만 저장된 `preflight_run_id`로 `OpenClaw NPM Release`를 디스패치합니다. +`OpenClaw Release Publish`는 변경을 수행하는 수동 릴리스 워크플로입니다. +릴리스 태그가 존재하고 OpenClaw npm 프리플라이트가 성공한 뒤 +`release/YYYY.M.D` 또는 `main`에서 디스패치하세요. 이 워크플로는 +`pnpm plugins:sync:check`를 검증하고, 게시 가능한 모든 Plugin 패키지에 대해 +`Plugin NPM Release`를 디스패치하며, 동일한 릴리스 SHA에 대해 +`Plugin ClawHub Release`를 디스패치한 다음에야 저장된 `preflight_run_id`로 +`OpenClaw NPM Release`를 디스패치합니다. ```bash gh workflow run openclaw-release-publish.yml \ @@ -170,35 +178,43 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=beta ``` -빠르게 움직이는 브랜치에서 고정된 커밋 증거가 필요하면 `gh workflow run ... --ref main -f ref=` 대신 헬퍼를 사용하세요: +빠르게 움직이는 브랜치에서 고정 커밋 증명이 필요하면 +`gh workflow run ... --ref main -f ref=` 대신 헬퍼를 사용하세요: ```bash pnpm ci:full-release --sha ``` -GitHub 워크플로 디스패치 ref는 원시 커밋 SHA가 아니라 브랜치나 태그여야 합니다. 헬퍼는 대상 SHA에 임시 `release-ci/-...` 브랜치를 push하고, 해당 고정 ref에서 `Full Release Validation`을 디스패치하며, 모든 하위 워크플로 `headSha`가 대상과 일치하는지 검증하고, 실행이 완료되면 임시 브랜치를 삭제합니다. 우산 검증기도 하위 워크플로가 다른 SHA에서 실행된 경우 실패합니다. +GitHub 워크플로 디스패치 ref는 원시 커밋 SHA가 아니라 브랜치 또는 태그여야 합니다. +헬퍼는 대상 SHA에 임시 `release-ci/-...` 브랜치를 푸시하고, +해당 고정 ref에서 `Full Release Validation`을 디스패치하며, 모든 하위 +워크플로 `headSha`가 대상과 일치하는지 검증하고, 실행이 완료되면 임시 브랜치를 +삭제합니다. 엄브렐라 검증기는 하위 워크플로가 다른 SHA에서 실행된 경우에도 +실패합니다. -`release_profile`은 release checks에 전달되는 live/provider 범위를 제어합니다. 수동 릴리스 워크플로의 기본값은 `stable`입니다. 넓은 자문용 provider/media 매트릭스를 의도적으로 원할 때만 `full`을 사용하세요. +`release_profile`은 릴리스 검사에 전달되는 live/provider 범위를 제어합니다. +수동 릴리스 워크플로의 기본값은 `stable`입니다. 넓은 권고 provider/media +매트릭스를 의도적으로 원할 때만 `full`을 사용하세요. -- `minimum`은 가장 빠른 OpenAI/core 릴리스 핵심 레인을 유지합니다. -- `stable`은 안정적인 provider/backend 세트를 추가합니다. -- `full`은 넓은 자문용 provider/media 매트릭스를 실행합니다. +- `minimum`은 가장 빠른 OpenAI/코어 릴리스 중요 레인만 유지합니다. +- `stable`은 안정 provider/backend 세트를 추가합니다. +- `full`은 넓은 권고 provider/media 매트릭스를 실행합니다. -우산 워크플로는 디스패치된 하위 실행 ID를 기록하며, 최종 `Verify full validation` 작업은 현재 하위 실행 결론을 다시 검사하고 각 하위 실행의 가장 느린 작업 표를 추가합니다. 하위 워크플로를 다시 실행해 녹색으로 바뀌면, 우산 결과와 시간 요약을 새로 고치기 위해 부모 검증기 작업만 다시 실행하세요. +엄브렐라는 디스패치된 하위 실행 ID를 기록하며, 최종 `Verify full validation` 작업은 현재 하위 실행 결론을 다시 확인하고 각 하위 실행에 대해 가장 느린 작업 표를 덧붙입니다. 하위 워크플로를 재실행해 녹색으로 바뀐 경우, 엄브렐라 결과와 시간 요약을 새로 고치려면 부모 검증기 작업만 다시 실행하세요. -복구를 위해 `Full Release Validation`과 `OpenClaw Release Checks`는 모두 `rerun_group`을 받습니다. 릴리스 후보에는 `all`, 일반 전체 CI 자식만에는 `ci`, Plugin 사전 릴리스 자식만에는 `plugin-prerelease`, 모든 릴리스 자식에는 `release-checks`, 또는 umbrella에서 더 좁은 그룹인 `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live`, `npm-telegram`을 사용하세요. 이렇게 하면 집중 수정 후 실패한 릴리스 박스 재실행 범위를 제한할 수 있습니다. +복구의 경우 `Full Release Validation`과 `OpenClaw Release Checks`는 모두 `rerun_group`을 받습니다. 릴리스 후보에는 `all`, 일반 전체 CI 하위 항목만에는 `ci`, Plugin 사전 릴리스 하위 항목만에는 `plugin-prerelease`, 모든 릴리스 하위 항목에는 `release-checks`, 또는 umbrella에서 더 좁은 그룹인 `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live`, `npm-telegram`을 사용하세요. 이렇게 하면 집중 수정 후 실패한 릴리스 박스의 재실행 범위를 제한할 수 있습니다. -`OpenClaw Release Checks`는 신뢰된 워크플로 ref를 사용해 선택된 ref를 한 번 `release-package-under-test` tarball로 해석한 다음, 그 아티팩트를 live/E2E 릴리스 경로 Docker 워크플로와 package acceptance shard에 모두 전달합니다. 이렇게 하면 릴리스 박스 전반에서 package 바이트가 일관되게 유지되고, 여러 자식 작업에서 같은 후보를 다시 패킹하지 않아도 됩니다. +`OpenClaw Release Checks`는 신뢰된 워크플로 ref를 사용해 선택한 ref를 한 번 `release-package-under-test` tarball로 해석한 다음, 해당 아티팩트를 live/E2E 릴리스 경로 Docker 워크플로와 패키지 승인 샤드 양쪽에 전달합니다. 이렇게 하면 릴리스 박스 전반에서 패키지 바이트가 일관되게 유지되고 여러 하위 작업에서 동일한 후보를 다시 패킹하지 않아도 됩니다. -`ref=main` 및 `rerun_group=all`에 대한 중복 `Full Release Validation` 실행은 이전 umbrella를 대체합니다. 부모 모니터는 부모가 취소될 때 이미 디스패치한 모든 자식 워크플로를 취소하므로, 더 새로운 main 검증이 오래된 두 시간짜리 release-check 실행 뒤에 대기하지 않습니다. 릴리스 브랜치/태그 검증과 집중 재실행 그룹은 `cancel-in-progress: false`를 유지합니다. +`ref=main` 및 `rerun_group=all`에 대한 중복 `Full Release Validation` 실행은 이전 umbrella를 대체합니다. 상위 모니터는 상위 항목이 취소될 때 이미 디스패치한 모든 하위 워크플로를 취소하므로, 최신 main 검증이 오래된 2시간짜리 release-check 실행 뒤에서 대기하지 않습니다. 릴리스 브랜치/태그 검증과 집중 재실행 그룹은 `cancel-in-progress: false`를 유지합니다. -## Live 및 E2E shard +## Live 및 E2E 샤드 -릴리스 live/E2E 자식은 광범위한 네이티브 `pnpm test:live` 커버리지를 유지하지만, 하나의 직렬 작업 대신 `scripts/test-live-shard.mjs`를 통해 이름이 지정된 shard로 실행합니다. +릴리스 live/E2E 하위 항목은 광범위한 네이티브 `pnpm test:live` 커버리지를 유지하지만, 하나의 직렬 작업 대신 `scripts/test-live-shard.mjs`를 통해 이름이 지정된 샤드로 실행합니다. - `native-live-src-agents` - `native-live-src-gateway-core` -- 공급자 필터링된 `native-live-src-gateway-profiles` 작업 +- provider로 필터링된 `native-live-src-gateway-profiles` 작업 - `native-live-src-gateway-backends` - `native-live-test` - `native-live-extensions-a-k` @@ -206,59 +222,59 @@ GitHub 워크플로 디스패치 ref는 원시 커밋 SHA가 아니라 브랜치 - `native-live-extensions-openai` - `native-live-extensions-o-z-other` - `native-live-extensions-xai` -- 분할된 미디어 오디오/비디오 shard와 공급자 필터링된 음악 shard +- 분할된 미디어 오디오/비디오 샤드와 provider로 필터링된 음악 샤드 -이렇게 하면 같은 파일 커버리지를 유지하면서 느린 live 공급자 실패를 더 쉽게 재실행하고 진단할 수 있습니다. 집계 `native-live-extensions-o-z`, `native-live-extensions-media`, `native-live-extensions-media-music` shard 이름은 수동 일회성 재실행에도 계속 유효합니다. +이렇게 하면 동일한 파일 커버리지를 유지하면서 느린 live provider 실패를 더 쉽게 재실행하고 진단할 수 있습니다. 집계 `native-live-extensions-o-z`, `native-live-extensions-media`, `native-live-extensions-media-music` 샤드 이름은 수동 일회성 재실행에 계속 유효합니다. -네이티브 live 미디어 shard는 `Live Media Runner Image` 워크플로가 빌드한 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`에서 실행됩니다. 해당 이미지는 `ffmpeg`와 `ffprobe`를 미리 설치합니다. 미디어 작업은 설정 전에 바이너리만 확인합니다. Docker 기반 live suite는 일반 Blacksmith runner에서 유지하세요. 컨테이너 작업은 중첩 Docker 테스트를 시작하기에 적절한 위치가 아닙니다. +네이티브 live 미디어 샤드는 `Live Media Runner Image` 워크플로가 빌드한 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`에서 실행됩니다. 해당 이미지는 `ffmpeg`와 `ffprobe`를 사전 설치합니다. 미디어 작업은 설정 전에 바이너리만 확인합니다. Docker 기반 live 제품군은 일반 Blacksmith 러너에서 유지하세요. 컨테이너 작업은 중첩 Docker 테스트를 시작하기에 적합한 위치가 아닙니다. -Docker 기반 live 모델/백엔드 shard는 선택된 커밋마다 별도의 공유 `ghcr.io/openclaw/openclaw-live-test:` 이미지를 사용합니다. live 릴리스 워크플로는 해당 이미지를 한 번 빌드하고 푸시한 다음, Docker live 모델, 공급자별로 shard된 Gateway, CLI 백엔드, ACP bind, Codex harness shard가 `OPENCLAW_SKIP_DOCKER_BUILD=1`로 실행됩니다. Gateway Docker shard는 워크플로 작업 제한 시간보다 낮은 명시적 스크립트 수준 `timeout` 상한을 가지고 있어, 멈춘 컨테이너나 정리 경로가 전체 release-check 예산을 소모하는 대신 빠르게 실패합니다. 이러한 shard가 전체 소스 Docker target을 독립적으로 다시 빌드한다면 릴리스 실행이 잘못 구성된 것이며, 중복 이미지 빌드로 실제 시간을 낭비하게 됩니다. +Docker 기반 live 모델/backend 샤드는 선택한 커밋마다 별도의 공유 `ghcr.io/openclaw/openclaw-live-test:` 이미지를 사용합니다. live 릴리스 워크플로는 해당 이미지를 한 번 빌드하고 푸시한 다음, Docker live 모델, provider별로 샤딩된 Gateway, CLI backend, ACP bind, Codex harness 샤드가 `OPENCLAW_SKIP_DOCKER_BUILD=1`로 실행됩니다. Gateway Docker 샤드는 워크플로 작업 제한 시간보다 낮은 명시적 스크립트 수준 `timeout` 상한을 가지므로, 멈춘 컨테이너나 정리 경로가 전체 release-check 예산을 소모하는 대신 빠르게 실패합니다. 해당 샤드가 전체 소스 Docker 대상을 독립적으로 다시 빌드한다면, 릴리스 실행이 잘못 구성된 것이며 중복 이미지 빌드로 실제 시간을 낭비하게 됩니다. -## Package Acceptance +## 패키지 승인 -질문이 "설치 가능한 이 OpenClaw package가 제품으로 작동하는가?"라면 `Package Acceptance`를 사용하세요. 이는 일반 CI와 다릅니다. 일반 CI는 소스 트리를 검증하는 반면, package acceptance는 사용자가 설치 또는 업데이트 후 실행하는 것과 같은 Docker E2E harness를 통해 단일 tarball을 검증합니다. +"이 설치 가능한 OpenClaw 패키지가 제품으로 동작하는가?"가 질문일 때 `Package Acceptance`를 사용하세요. 이는 일반 CI와 다릅니다. 일반 CI는 소스 트리를 검증하지만, 패키지 승인은 설치 또는 업데이트 후 사용자가 실행하는 것과 동일한 Docker E2E harness를 통해 단일 tarball을 검증합니다. ### 작업 -1. `resolve_package`는 `workflow_ref`를 체크아웃하고, package 후보 하나를 해석하며, `.artifacts/docker-e2e-package/openclaw-current.tgz`를 쓰고, `.artifacts/docker-e2e-package/package-candidate.json`을 쓰고, 둘 다 `package-under-test` 아티팩트로 업로드한 다음, GitHub 단계 요약에 소스, 워크플로 ref, package ref, 버전, SHA-256, 프로필을 출력합니다. -2. `docker_acceptance`는 `ref=workflow_ref` 및 `package_artifact_name=package-under-test`로 `openclaw-live-and-e2e-checks-reusable.yml`을 호출합니다. 재사용 가능한 워크플로는 해당 아티팩트를 다운로드하고, tarball 인벤토리를 검증하며, 필요할 때 package-digest Docker 이미지를 준비하고, 워크플로 체크아웃을 패킹하는 대신 해당 package에 대해 선택된 Docker lane을 실행합니다. 프로필이 여러 개의 targeted `docker_lanes`를 선택하면, 재사용 가능한 워크플로는 package와 공유 이미지를 한 번 준비한 다음 해당 lane을 고유 아티팩트가 있는 병렬 targeted Docker 작업으로 분산합니다. -3. `package_telegram`은 선택적으로 `NPM Telegram Beta E2E`를 호출합니다. `telegram_mode`가 `none`이 아닐 때 실행되며, Package Acceptance가 package를 해석한 경우 같은 `package-under-test` 아티팩트를 설치합니다. 독립 실행형 Telegram dispatch는 여전히 게시된 npm spec을 설치할 수 있습니다. -4. `summary`는 package 해석, Docker acceptance, 또는 선택적 Telegram lane이 실패한 경우 워크플로를 실패시킵니다. +1. `resolve_package`는 `workflow_ref`를 체크아웃하고, 하나의 패키지 후보를 해석하고, `.artifacts/docker-e2e-package/openclaw-current.tgz`를 쓰고, `.artifacts/docker-e2e-package/package-candidate.json`을 쓰고, 둘 다 `package-under-test` 아티팩트로 업로드하며, GitHub 단계 요약에 소스, 워크플로 ref, 패키지 ref, 버전, SHA-256, 프로필을 출력합니다. +2. `docker_acceptance`는 `ref=workflow_ref` 및 `package_artifact_name=package-under-test`로 `openclaw-live-and-e2e-checks-reusable.yml`을 호출합니다. 재사용 가능 워크플로는 해당 아티팩트를 다운로드하고, tarball 인벤토리를 검증하고, 필요할 때 package-digest Docker 이미지를 준비하며, 워크플로 체크아웃을 패킹하는 대신 해당 패키지를 대상으로 선택된 Docker 레인을 실행합니다. 프로필이 여러 대상 `docker_lanes`를 선택하면, 재사용 가능 워크플로는 패키지와 공유 이미지를 한 번 준비한 다음 해당 레인을 고유 아티팩트가 있는 병렬 대상 Docker 작업으로 팬아웃합니다. +3. `package_telegram`은 선택적으로 `NPM Telegram Beta E2E`를 호출합니다. `telegram_mode`가 `none`이 아닐 때 실행되며 Package Acceptance가 하나를 해석한 경우 동일한 `package-under-test` 아티팩트를 설치합니다. 독립 실행형 Telegram 디스패치는 여전히 게시된 npm spec을 설치할 수 있습니다. +4. `summary`는 패키지 해석, Docker 승인, 또는 선택적 Telegram 레인이 실패한 경우 워크플로를 실패시킵니다. ### 후보 소스 -- `source=npm`은 `openclaw@alpha`, `openclaw@beta`, `openclaw@latest` 또는 `openclaw@2026.4.27-beta.2` 같은 정확한 OpenClaw 릴리스 버전만 받습니다. 게시된 사전 릴리스/안정 버전 acceptance에 사용하세요. -- `source=ref`는 신뢰된 `package_ref` 브랜치, 태그 또는 전체 커밋 SHA를 패킹합니다. resolver는 OpenClaw 브랜치/태그를 가져오고, 선택된 커밋이 저장소 브랜치 기록 또는 릴리스 태그에서 도달 가능한지 확인하며, 분리된 worktree에 deps를 설치하고, `scripts/package-openclaw-for-docker.mjs`로 패킹합니다. +- `source=npm`은 `openclaw@beta`, `openclaw@latest`, 또는 `openclaw@2026.4.27-beta.2` 같은 정확한 OpenClaw 릴리스 버전만 받습니다. 게시된 사전 릴리스/안정 버전 승인에 이것을 사용하세요. +- `source=ref`는 신뢰된 `package_ref` 브랜치, 태그 또는 전체 커밋 SHA를 패킹합니다. 해석기는 OpenClaw 브랜치/태그를 가져오고, 선택한 커밋이 저장소 브랜치 기록 또는 릴리스 태그에서 도달 가능한지 검증하며, 분리된 worktree에 deps를 설치하고, `scripts/package-openclaw-for-docker.mjs`로 패킹합니다. - `source=url`은 HTTPS `.tgz`를 다운로드합니다. `package_sha256`은 필수입니다. -- `source=artifact`는 `artifact_run_id`와 `artifact_name`에서 하나의 `.tgz`를 다운로드합니다. `package_sha256`은 선택 사항이지만 외부 공유 아티팩트에는 제공하는 것이 좋습니다. +- `source=artifact`는 `artifact_run_id` 및 `artifact_name`에서 하나의 `.tgz`를 다운로드합니다. `package_sha256`은 선택 사항이지만 외부에 공유된 아티팩트에는 제공해야 합니다. `workflow_ref`와 `package_ref`를 분리해 유지하세요. `workflow_ref`는 테스트를 실행하는 신뢰된 워크플로/harness 코드입니다. `package_ref`는 `source=ref`일 때 패킹되는 소스 커밋입니다. 이를 통해 현재 테스트 harness가 오래된 워크플로 로직을 실행하지 않고도 더 오래된 신뢰된 소스 커밋을 검증할 수 있습니다. -### Suite 프로필 +### 제품군 프로필 - `smoke` — `npm-onboard-channel-agent`, `gateway-network`, `config-reload` - `package` — `npm-onboard-channel-agent`, `doctor-switch`, `update-channel-switch`, `upgrade-survivor`, `published-upgrade-survivor`, `plugins-offline`, `plugin-update` -- `product` — `package`와 `mcp-channels`, `cron-mcp-cleanup`, `openai-web-search-minimal`, `openwebui` -- `full` — OpenWebUI가 포함된 전체 Docker 릴리스 경로 chunk +- `product` — `package`에 `mcp-channels`, `cron-mcp-cleanup`, `openai-web-search-minimal`, `openwebui` 추가 +- `full` — OpenWebUI가 포함된 전체 Docker 릴리스 경로 청크 - `custom` — 정확한 `docker_lanes`; `suite_profile=custom`일 때 필수 -`package` 프로필은 오프라인 Plugin 커버리지를 사용하므로 게시된 package 검증이 live ClawHub 가용성에 의해 차단되지 않습니다. 선택적 Telegram lane은 `NPM Telegram Beta E2E`에서 `package-under-test` 아티팩트를 재사용하며, 게시된 npm spec 경로는 독립 실행형 dispatch를 위해 유지됩니다. +`package` 프로필은 오프라인 Plugin 커버리지를 사용하므로 게시된 패키지 검증이 live ClawHub 가용성에 의해 제한되지 않습니다. 선택적 Telegram 레인은 `NPM Telegram Beta E2E`에서 `package-under-test` 아티팩트를 재사용하며, 게시된 npm spec 경로는 독립 실행형 디스패치를 위해 유지됩니다. -로컬 명령, Docker lane, Package Acceptance 입력, 릴리스 기본값, 실패 triage를 포함한 전용 업데이트 및 Plugin 테스트 정책은 [업데이트 및 Plugin 테스트](/ko/help/testing-updates-plugins)를 참조하세요. +로컬 명령, Docker 레인, Package Acceptance 입력, 릴리스 기본값, 실패 triage를 포함한 전용 업데이트 및 Plugin 테스트 정책은 [업데이트 및 Plugin 테스트](/ko/help/testing-updates-plugins)를 참조하세요. -릴리스 check는 준비된 릴리스 package 아티팩트, `suite_profile=custom`, `docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`, `published_upgrade_survivor_baselines=all-since-2026.4.23`, `published_upgrade_survivor_scenarios=reported-issues`, `telegram_mode=mock-openai`와 함께 `source=artifact`로 Package Acceptance를 호출합니다. 이렇게 하면 package migration, update, 오래된 Plugin dependency cleanup, 구성된 Plugin 설치 복구, 오프라인 Plugin, plugin-update, Telegram 검증이 모두 같은 해석된 package tarball에서 수행됩니다. SHA로 빌드된 아티팩트 대신 배포된 npm package에 대해 같은 matrix를 실행하려면 Full Release Validation 또는 OpenClaw Release Checks에서 `package_acceptance_package_spec`을 설정하세요. Cross-OS 릴리스 check는 여전히 OS별 onboarding, installer, platform 동작을 커버합니다. package/update 제품 검증은 Package Acceptance에서 시작해야 합니다. `published-upgrade-survivor` Docker lane은 실행마다 하나의 게시된 package baseline을 검증합니다. Package Acceptance에서 해석된 `package-under-test` tarball은 항상 후보이며, `published_upgrade_survivor_baseline`은 fallback으로 사용할 게시된 baseline을 선택하고 기본값은 `openclaw@latest`입니다. 실패한 lane 재실행 명령은 해당 baseline을 보존합니다. `published_upgrade_survivor_baselines=all-since-2026.4.23`을 설정하면 Full Release CI를 `2026.4.23`부터 `latest`까지 모든 안정 npm 릴리스로 확장합니다. `release-history`는 이전 pre-date anchor를 사용한 수동의 더 넓은 샘플링에도 계속 사용할 수 있습니다. `published_upgrade_survivor_scenarios=reported-issues`를 설정하면 같은 baseline을 Feishu config, 보존된 bootstrap/persona 파일, 구성된 OpenClaw Plugin 설치, tilde log 경로, 오래된 legacy Plugin dependency root에 대한 issue 형태 fixture 전반으로 확장합니다. 별도의 `Update Migration` 워크플로는 질문이 일반 Full Release CI 범위가 아니라 게시된 업데이트 정리에 대한 포괄적인 검증일 때 `all-since-2026.4.23` 및 `plugin-deps-cleanup`과 함께 `update-migration` Docker lane을 사용합니다. 로컬 집계 실행은 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS`로 정확한 package spec을 전달하거나, `openclaw@2026.4.15` 같은 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC`으로 단일 lane을 유지하거나, scenario matrix를 위해 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS`를 설정할 수 있습니다. 게시된 lane은 내장된 `openclaw config set` 명령 recipe로 baseline을 구성하고, recipe 단계를 `summary.json`에 기록하며, Gateway 시작 후 `/healthz`, `/readyz`, 그리고 RPC status를 probe합니다. Windows packaged 및 installer fresh lane은 설치된 package가 원시 절대 Windows 경로에서 browser-control override를 import할 수 있는지도 확인합니다. OpenAI cross-OS agent-turn smoke는 설정된 경우 `OPENCLAW_CROSS_OS_OPENAI_MODEL`을 기본값으로 사용하고, 그렇지 않으면 `openai/gpt-5.4`를 사용하므로, install 및 Gateway 검증이 GPT-4.x 기본값을 피하면서 GPT-5 테스트 모델에 머물게 됩니다. +릴리스 검사는 `source=artifact`, 준비된 릴리스 패키지 아티팩트, `suite_profile=custom`, `docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`, `published_upgrade_survivor_baselines=all-since-2026.4.23`, `published_upgrade_survivor_scenarios=reported-issues`, `telegram_mode=mock-openai`로 Package Acceptance를 호출합니다. 이렇게 하면 패키지 마이그레이션, 업데이트, 오래된 Plugin 의존성 정리, 구성된 Plugin 설치 복구, 오프라인 Plugin, Plugin 업데이트, Telegram 증명이 동일하게 해석된 패키지 tarball에서 유지됩니다. Full Release Validation 또는 OpenClaw Release Checks에 `package_acceptance_package_spec`을 설정하면 SHA로 빌드된 아티팩트 대신 배포된 npm 패키지를 대상으로 동일한 매트릭스를 실행합니다. Cross-OS 릴리스 검사는 여전히 OS별 온보딩, 설치 프로그램, 플랫폼 동작을 다룹니다. 패키지/업데이트 제품 검증은 Package Acceptance로 시작해야 합니다. `published-upgrade-survivor` Docker 레인은 실행당 하나의 게시된 패키지 기준선을 검증합니다. Package Acceptance에서는 해석된 `package-under-test` tarball이 항상 후보이며, `published_upgrade_survivor_baseline`은 fallback 게시 기준선을 선택하고 기본값은 `openclaw@latest`입니다. 실패한 레인 재실행 명령은 해당 기준선을 보존합니다. Full Release CI를 `2026.4.23`부터 `latest`까지의 모든 안정 npm 릴리스로 확장하려면 `published_upgrade_survivor_baselines=all-since-2026.4.23`을 설정하세요. `release-history`는 더 오래된 사전 날짜 앵커로 수동으로 더 넓게 샘플링하는 데 계속 사용할 수 있습니다. Feishu 구성, 보존된 bootstrap/persona 파일, 구성된 OpenClaw Plugin 설치, tilde 로그 경로, 오래된 레거시 Plugin 의존성 루트에 대한 이슈 형태 fixture로 동일한 기준선을 확장하려면 `published_upgrade_survivor_scenarios=reported-issues`를 설정하세요. 별도의 `Update Migration` 워크플로는 질문이 일반 Full Release CI 범위가 아니라 게시된 업데이트 정리를 철저히 확인하는 것일 때 `all-since-2026.4.23` 및 `plugin-deps-cleanup`과 함께 `update-migration` Docker 레인을 사용합니다. 로컬 집계 실행은 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS`로 정확한 패키지 spec을 전달하거나, `openclaw@2026.4.15` 같은 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC`으로 단일 레인을 유지하거나, 시나리오 매트릭스에 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS`를 설정할 수 있습니다. 게시된 레인은 구워진 `openclaw config set` 명령 레시피로 기준선을 구성하고, 레시피 단계를 `summary.json`에 기록하며, Gateway 시작 후 `/healthz`, `/readyz`와 RPC 상태를 탐색합니다. Windows 패키지 및 설치 프로그램 fresh 레인도 설치된 패키지가 원시 절대 Windows 경로에서 browser-control override를 import할 수 있는지 확인합니다. OpenAI cross-OS agent-turn smoke는 설정된 경우 기본값으로 `OPENCLAW_CROSS_OS_OPENAI_MODEL`을 사용하고, 그렇지 않으면 `openai/gpt-5.4`를 사용하므로, GPT-4.x 기본값을 피하면서 설치 및 Gateway 증명이 GPT-5 테스트 모델에 유지됩니다. ### 레거시 호환성 기간 -Package Acceptance에는 이미 게시된 package를 위한 제한된 레거시 호환성 기간이 있습니다. `2026.4.25-beta.*`를 포함해 `2026.4.25`까지의 package는 호환성 경로를 사용할 수 있습니다. +Package Acceptance에는 이미 게시된 패키지에 대해 제한된 레거시 호환성 기간이 있습니다. `2026.4.25-beta.*`를 포함해 `2026.4.25`까지의 패키지는 호환성 경로를 사용할 수 있습니다. -- `dist/postinstall-inventory.json`의 알려진 private QA entry가 tarball에서 생략된 파일을 가리킬 수 있습니다. -- package가 해당 flag를 노출하지 않는 경우 `doctor-switch`는 `gateway install --wrapper` 지속성 subcase를 건너뛸 수 있습니다. -- `update-channel-switch`는 tarball에서 파생된 fake git fixture에서 누락된 `pnpm.patchedDependencies`를 정리할 수 있으며, 지속된 `update.channel` 누락을 기록할 수 있습니다. -- Plugin smoke는 레거시 install-record 위치를 읽거나 marketplace install-record 지속성 누락을 허용할 수 있습니다. -- `plugin-update`는 install record와 no-reinstall 동작이 그대로 유지되어야 한다는 요구는 유지하면서도 config metadata migration을 허용할 수 있습니다. +- `dist/postinstall-inventory.json`의 알려진 private QA 항목은 tarball에서 생략된 파일을 가리킬 수 있습니다. +- 패키지가 해당 플래그를 노출하지 않는 경우 `doctor-switch`가 `gateway install --wrapper` 지속성 하위 사례를 건너뛸 수 있습니다. +- `update-channel-switch`가 tarball에서 파생된 가짜 git fixture에서 누락된 `pnpm.patchedDependencies`를 가지치기할 수 있으며, 누락된 지속 `update.channel`을 로그로 남길 수 있습니다. +- Plugin smoke는 레거시 설치 기록 위치를 읽거나 누락된 marketplace 설치 기록 지속성을 허용할 수 있습니다. +- `plugin-update`는 설치 기록과 no-reinstall 동작이 변경되지 않아야 한다는 요구를 유지하면서 구성 메타데이터 마이그레이션을 허용할 수 있습니다. -게시된 `2026.4.26` package는 이미 배포된 로컬 빌드 metadata stamp 파일에 대해서도 경고할 수 있습니다. 이후 package는 최신 contract를 충족해야 합니다. 같은 조건은 경고 또는 skip 대신 실패합니다. +게시된 `2026.4.26` 패키지도 이미 배포된 로컬 빌드 메타데이터 stamp 파일에 대해 경고할 수 있습니다. 이후 패키지는 최신 계약을 충족해야 합니다. 동일한 조건은 경고하거나 건너뛰는 대신 실패합니다. ### 예시 @@ -301,110 +317,110 @@ gh workflow run package-acceptance.yml \ -f docker_lanes='install-e2e plugin-update' ``` -실패한 패키지 승인 실행을 디버깅할 때는 `resolve_package` 요약에서 시작해 패키지 소스, 버전, SHA-256을 확인하세요. 그런 다음 `docker_acceptance` 하위 실행과 해당 Docker 아티팩트인 `.artifacts/docker-tests/**/summary.json`, `failures.json`, 레인 로그, 단계 타이밍, 재실행 명령을 검사하세요. 전체 릴리스 검증을 다시 실행하는 대신 실패한 패키지 프로필이나 정확한 Docker 레인을 다시 실행하는 것을 선호하세요. +실패한 패키지 수락 실행을 디버깅할 때는 `resolve_package` 요약에서 시작하여 패키지 소스, 버전, SHA-256을 확인하세요. 그런 다음 `docker_acceptance` 하위 실행과 해당 Docker 아티팩트인 `.artifacts/docker-tests/**/summary.json`, `failures.json`, 레인 로그, 단계 타이밍, 재실행 명령을 검사하세요. 전체 릴리스 검증을 다시 실행하기보다 실패한 패키지 프로필이나 정확한 Docker 레인을 다시 실행하는 것을 선호하세요. ## 설치 스모크 -별도의 `Install Smoke` 워크플로는 자체 `preflight` 작업을 통해 같은 범위 스크립트를 재사용합니다. 스모크 커버리지를 `run_fast_install_smoke`와 `run_full_install_smoke`로 나눕니다. +별도의 `Install Smoke` 워크플로는 자체 `preflight` 작업을 통해 동일한 범위 스크립트를 재사용합니다. 이 워크플로는 스모크 커버리지를 `run_fast_install_smoke`와 `run_full_install_smoke`로 나눕니다. -- **빠른 경로**는 Docker/패키지 표면, 번들 Plugin 패키지/매니페스트 변경, 또는 Docker 스모크 작업이 실행하는 코어 Plugin/채널/Gateway/Plugin SDK 표면을 건드리는 풀 리퀘스트에서 실행됩니다. 소스 전용 번들 Plugin 변경, 테스트 전용 편집, 문서 전용 편집은 Docker 워커를 예약하지 않습니다. 빠른 경로는 루트 Dockerfile 이미지를 한 번 빌드하고, CLI를 확인하고, 에이전트 삭제 공유 작업공간 CLI 스모크를 실행하고, 컨테이너 Gateway 네트워크 E2E를 실행하고, 번들 확장 빌드 인수를 검증하고, 240초 집계 명령 제한 시간 안에서 제한된 번들 Plugin Docker 프로필을 실행합니다. 각 시나리오의 Docker 실행은 별도로 제한됩니다. -- **전체 경로**는 야간 예약 실행, 수동 디스패치, workflow-call 릴리스 검사, 그리고 실제로 설치 프로그램/패키지/Docker 표면을 건드리는 풀 리퀘스트에 QR 패키지 설치와 설치 프로그램 Docker/업데이트 커버리지를 유지합니다. 전체 모드에서 install-smoke는 대상 SHA GHCR 루트 Dockerfile 스모크 이미지를 하나 준비하거나 재사용한 다음, QR 패키지 설치, 루트 Dockerfile/Gateway 스모크, 설치 프로그램/업데이트 스모크, 빠른 번들 Plugin Docker E2E를 별도 작업으로 실행하여 설치 프로그램 작업이 루트 이미지 스모크 뒤에서 대기하지 않게 합니다. +- **빠른 경로**는 Docker/패키지 표면, 번들 Plugin 패키지/매니페스트 변경, 또는 Docker 스모크 작업이 실행하는 코어 Plugin/채널/Gateway/Plugin SDK 표면을 건드리는 풀 리퀘스트에서 실행됩니다. 소스만 변경한 번들 Plugin 변경, 테스트 전용 편집, 문서 전용 편집은 Docker 워커를 예약하지 않습니다. 빠른 경로는 루트 Dockerfile 이미지를 한 번 빌드하고, CLI를 확인하며, agents delete 공유 작업공간 CLI 스모크를 실행하고, 컨테이너 Gateway 네트워크 E2E를 실행하며, 번들 확장 빌드 인수를 검증하고, 각 시나리오의 Docker 실행은 별도로 제한하면서 240초 집계 명령 타임아웃 안에서 제한된 번들 Plugin Docker 프로필을 실행합니다. +- **전체 경로**는 야간 예약 실행, 수동 디스패치, workflow-call 릴리스 확인, 그리고 실제로 설치 프로그램/패키지/Docker 표면을 건드리는 풀 리퀘스트를 위해 QR 패키지 설치와 설치 프로그램 Docker/업데이트 커버리지를 유지합니다. 전체 모드에서 install-smoke는 대상 SHA GHCR 루트 Dockerfile 스모크 이미지를 하나 준비하거나 재사용한 다음, 설치 프로그램 작업이 루트 이미지 스모크 뒤에서 기다리지 않도록 QR 패키지 설치, 루트 Dockerfile/Gateway 스모크, 설치 프로그램/업데이트 스모크, 빠른 번들 Plugin Docker E2E를 별도 작업으로 실행합니다. -`main` 푸시(merge commit 포함)는 전체 경로를 강제하지 않습니다. 변경 범위 로직이 푸시에서 전체 커버리지를 요청하더라도 워크플로는 빠른 Docker 스모크를 유지하고 전체 설치 스모크는 야간 또는 릴리스 검증에 맡깁니다. +`main` 푸시(머지 커밋 포함)는 전체 경로를 강제하지 않습니다. 변경 범위 로직이 푸시에서 전체 커버리지를 요청하더라도 워크플로는 빠른 Docker 스모크를 유지하고 전체 설치 스모크는 야간 또는 릴리스 검증에 맡깁니다. -느린 Bun 전역 설치 이미지 제공자 스모크는 `run_bun_global_install_smoke`로 별도 게이트됩니다. 이 스모크는 야간 일정과 릴리스 검사 워크플로에서 실행되며, 수동 `Install Smoke` 디스패치는 이를 선택할 수 있지만 풀 리퀘스트와 `main` 푸시에서는 실행되지 않습니다. QR 및 설치 프로그램 Docker 테스트는 자체 설치 중심 Dockerfile을 유지합니다. +느린 Bun 전역 설치 이미지 제공자 스모크는 `run_bun_global_install_smoke`로 별도 게이트됩니다. 이 스모크는 야간 일정과 릴리스 확인 워크플로에서 실행되며, 수동 `Install Smoke` 디스패치는 이를 선택할 수 있지만 풀 리퀘스트와 `main` 푸시에서는 실행되지 않습니다. QR 및 설치 프로그램 Docker 테스트는 자체 설치 중심 Dockerfile을 유지합니다. ## 로컬 Docker E2E -`pnpm test:docker:all`은 공유 라이브 테스트 이미지 하나를 미리 빌드하고, OpenClaw를 npm tarball로 한 번 패킹하며, 공유 `scripts/e2e/Dockerfile` 이미지 두 개를 빌드합니다. +`pnpm test:docker:all`은 하나의 공유 라이브 테스트 이미지를 미리 빌드하고, OpenClaw를 npm tarball로 한 번 패킹하며, 두 개의 공유 `scripts/e2e/Dockerfile` 이미지를 빌드합니다. -- 설치 프로그램/업데이트/Plugin 의존성 레인용 기본 Node/Git 실행기 -- 일반 기능 레인을 위해 같은 tarball을 `/app`에 설치하는 기능 이미지 +- 설치 프로그램/업데이트/Plugin 의존성 레인을 위한 기본 Node/Git 러너 +- 일반 기능 레인을 위해 동일한 tarball을 `/app`에 설치하는 기능 이미지 -Docker 레인 정의는 `scripts/lib/docker-e2e-scenarios.mjs`에 있고, 플래너 로직은 `scripts/lib/docker-e2e-plan.mjs`에 있으며, 실행기는 선택된 계획만 실행합니다. 스케줄러는 레인별로 `OPENCLAW_DOCKER_E2E_BARE_IMAGE`와 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`를 사용해 이미지를 선택한 다음, `OPENCLAW_SKIP_DOCKER_BUILD=1`로 레인을 실행합니다. +Docker 레인 정의는 `scripts/lib/docker-e2e-scenarios.mjs`에 있고, 플래너 로직은 `scripts/lib/docker-e2e-plan.mjs`에 있으며, 러너는 선택된 플랜만 실행합니다. 스케줄러는 `OPENCLAW_DOCKER_E2E_BARE_IMAGE`와 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`로 레인별 이미지를 선택한 다음 `OPENCLAW_SKIP_DOCKER_BUILD=1`로 레인을 실행합니다. -### 조정 가능 항목 +### 조정 가능한 값 | 변수 | 기본값 | 목적 | | -------------------------------------- | ------- | --------------------------------------------------------------------------------------------- | -| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 일반 레인을 위한 메인 풀 슬롯 수입니다. | -| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 제공자에 민감한 테일 풀 슬롯 수입니다. | -| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 제공자가 제한을 걸지 않도록 하는 동시 라이브 레인 상한입니다. | +| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 일반 레인을 위한 메인 풀 슬롯 수입니다. | +| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 제공자에 민감한 테일 풀 슬롯 수입니다. | +| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 제공자가 제한하지 않도록 하는 동시 라이브 레인 상한입니다. | | `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 동시 npm 설치 레인 상한입니다. | | `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 동시 다중 서비스 레인 상한입니다. | -| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | Docker 데몬 생성 폭주를 피하기 위한 레인 시작 간격입니다. 간격이 없게 하려면 `0`으로 설정하세요. | -| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 레인별 폴백 제한 시간(120분)입니다. 선택된 live/tail 레인은 더 엄격한 상한을 사용합니다. | -| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1`은 레인을 실행하지 않고 스케줄러 계획을 출력합니다. | -| `OPENCLAW_DOCKER_ALL_LANES` | unset | 쉼표로 구분된 정확한 레인 목록입니다. 에이전트가 실패한 레인 하나를 재현할 수 있도록 cleanup 스모크를 건너뜁니다. | +| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | Docker 데몬 생성 폭주를 피하기 위한 레인 시작 간 지연입니다. 지연이 없으면 `0`으로 설정하세요. | +| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 레인별 대체 타임아웃(120분)입니다. 선택된 라이브/테일 레인은 더 촘촘한 상한을 사용합니다. | +| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1`은 레인을 실행하지 않고 스케줄러 플랜을 출력합니다. | +| `OPENCLAW_DOCKER_ALL_LANES` | unset | 쉼표로 구분된 정확한 레인 목록입니다. 에이전트가 실패한 레인 하나를 재현할 수 있도록 정리 스모크를 건너뜁니다. | -유효 상한보다 무거운 레인도 빈 풀에서는 시작할 수 있으며, 이후 용량을 해제할 때까지 단독으로 실행됩니다. 로컬 집계는 Docker 사전 점검을 수행하고, 오래된 OpenClaw E2E 컨테이너를 제거하고, 활성 레인 상태를 내보내고, longest-first 정렬을 위해 레인 타이밍을 유지하며, 기본적으로 첫 번째 실패 이후에는 새 풀링 레인 예약을 중지합니다. +유효 상한보다 무거운 레인은 빈 풀에서 여전히 시작할 수 있으며, 이후 용량을 해제할 때까지 단독으로 실행됩니다. 로컬 집계는 Docker를 사전 점검하고, 오래된 OpenClaw E2E 컨테이너를 제거하며, 활성 레인 상태를 내보내고, longest-first 순서를 위해 레인 타이밍을 저장하며, 기본적으로 첫 실패 이후 새 풀 레인 스케줄링을 중단합니다. ### 재사용 가능한 라이브/E2E 워크플로 -재사용 가능한 라이브/E2E 워크플로는 `scripts/test-docker-all.mjs --plan-json`에 필요한 패키지, 이미지 종류, 라이브 이미지, 레인, 자격 증명 커버리지를 묻습니다. 그런 다음 `scripts/docker-e2e.mjs`가 해당 계획을 GitHub 출력과 요약으로 변환합니다. 이 워크플로는 `scripts/package-openclaw-for-docker.mjs`를 통해 OpenClaw를 패킹하거나, 현재 실행의 패키지 아티팩트를 다운로드하거나, `package_artifact_run_id`에서 패키지 아티팩트를 다운로드합니다. tarball 인벤토리를 검증하고, 계획에 패키지 설치 레인이 필요할 때 Blacksmith의 Docker 레이어 캐시를 통해 패키지 digest 태그가 지정된 bare/functional GHCR Docker E2E 이미지를 빌드하고 푸시하며, 재빌드하는 대신 제공된 `docker_e2e_bare_image`/`docker_e2e_functional_image` 입력이나 기존 패키지 digest 이미지를 재사용합니다. Docker 이미지 pull은 시도별 180초 제한 시간으로 재시도되므로 멈춘 registry/cache 스트림이 CI 주요 경로의 대부분을 소비하는 대신 빠르게 재시도됩니다. +재사용 가능한 라이브/E2E 워크플로는 `scripts/test-docker-all.mjs --plan-json`에 필요한 패키지, 이미지 종류, 라이브 이미지, 레인, 자격 증명 커버리지를 묻습니다. 그런 다음 `scripts/docker-e2e.mjs`는 해당 플랜을 GitHub 출력과 요약으로 변환합니다. 이 워크플로는 `scripts/package-openclaw-for-docker.mjs`를 통해 OpenClaw를 패킹하거나, 현재 실행 패키지 아티팩트를 다운로드하거나, `package_artifact_run_id`에서 패키지 아티팩트를 다운로드합니다. tarball 인벤토리를 검증하고, 플랜에 패키지 설치 레인이 필요할 때 Blacksmith의 Docker 레이어 캐시를 통해 패키지 다이제스트 태그가 붙은 bare/functional GHCR Docker E2E 이미지를 빌드하고 푸시하며, 다시 빌드하는 대신 제공된 `docker_e2e_bare_image`/`docker_e2e_functional_image` 입력이나 기존 패키지 다이제스트 이미지를 재사용합니다. Docker 이미지 pull은 시도당 180초로 제한된 타임아웃으로 재시도되므로 멈춘 레지스트리/캐시 스트림이 CI 주요 경로의 대부분을 소비하는 대신 빠르게 재시도됩니다. ### 릴리스 경로 청크 -릴리스 Docker 커버리지는 `OPENCLAW_SKIP_DOCKER_BUILD=1`로 더 작은 청크 작업을 실행하므로, 각 청크는 필요한 이미지 종류만 pull하고 같은 가중치 기반 스케줄러를 통해 여러 레인을 실행합니다. +릴리스 Docker 커버리지는 `OPENCLAW_SKIP_DOCKER_BUILD=1`로 더 작은 청크 작업을 실행하므로 각 청크는 필요한 이미지 종류만 pull하고 동일한 가중치 스케줄러를 통해 여러 레인을 실행합니다. - `OPENCLAW_DOCKER_ALL_PROFILE=release-path` - `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h` -현재 릴리스 Docker 청크는 `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, 그리고 `plugins-runtime-install-a`부터 `plugins-runtime-install-h`까지입니다. `plugins-runtime-core`, `plugins-runtime`, `plugins-integrations`는 집계 Plugin/runtime 별칭으로 남아 있습니다. `install-e2e` 레인 별칭은 두 제공자 설치 프로그램 레인을 위한 집계 수동 재실행 별칭으로 남아 있습니다. +현재 릴리스 Docker 청크는 `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, 그리고 `plugins-runtime-install-a`부터 `plugins-runtime-install-h`까지입니다. `plugins-runtime-core`, `plugins-runtime`, `plugins-integrations`는 집계 Plugin/런타임 별칭으로 남아 있습니다. `install-e2e` 레인 별칭은 두 제공자 설치 프로그램 레인 모두를 위한 집계 수동 재실행 별칭으로 남아 있습니다. -OpenWebUI는 전체 릴리스 경로 커버리지가 요청할 때 `plugins-runtime-services`에 포함되며, OpenWebUI 전용 디스패치에 대해서만 독립 `openwebui` 청크를 유지합니다. 번들 채널 업데이트 레인은 일시적인 npm 네트워크 실패에 대해 한 번 재시도합니다. +전체 릴리스 경로 커버리지가 요청할 때 OpenWebUI는 `plugins-runtime-services`에 포함되며, OpenWebUI 전용 디스패치에 대해서만 독립형 `openwebui` 청크를 유지합니다. 번들 채널 업데이트 레인은 일시적인 npm 네트워크 실패에 대해 한 번 재시도합니다. -각 청크는 레인 로그, 타이밍, `summary.json`, `failures.json`, 단계 타이밍, 스케줄러 계획 JSON, 느린 레인 표, 레인별 재실행 명령이 포함된 `.artifacts/docker-tests/`를 업로드합니다. 워크플로 `docker_lanes` 입력은 청크 작업 대신 준비된 이미지를 대상으로 선택된 레인을 실행합니다. 이렇게 하면 실패한 레인 디버깅이 하나의 대상 Docker 작업으로 제한되고, 해당 실행을 위한 패키지 아티팩트를 준비, 다운로드 또는 재사용합니다. 선택된 레인이 라이브 Docker 레인이면, 대상 작업은 해당 재실행을 위해 라이브 테스트 이미지를 로컬에서 빌드합니다. 생성된 레인별 GitHub 재실행 명령에는 해당 값이 있을 때 `package_artifact_run_id`, `package_artifact_name`, 준비된 이미지 입력이 포함되므로 실패한 레인이 실패한 실행의 정확한 패키지와 이미지를 재사용할 수 있습니다. +각 청크는 레인 로그, 타이밍, `summary.json`, `failures.json`, 단계 타이밍, 스케줄러 플랜 JSON, 느린 레인 표, 레인별 재실행 명령이 포함된 `.artifacts/docker-tests/`를 업로드합니다. 워크플로 `docker_lanes` 입력은 청크 작업 대신 준비된 이미지에 대해 선택한 레인을 실행하므로 실패한 레인 디버깅을 대상 Docker 작업 하나로 제한하고 해당 실행을 위한 패키지 아티팩트를 준비, 다운로드 또는 재사용합니다. 선택된 레인이 라이브 Docker 레인인 경우 대상 작업은 해당 재실행을 위해 라이브 테스트 이미지를 로컬에서 빌드합니다. 생성된 레인별 GitHub 재실행 명령은 해당 값이 존재할 때 `package_artifact_run_id`, `package_artifact_name`, 준비된 이미지 입력을 포함하므로 실패한 레인이 실패한 실행의 정확한 패키지와 이미지를 재사용할 수 있습니다. ```bash pnpm test:docker:rerun # download Docker artifacts and print combined/per-lane targeted rerun commands pnpm test:docker:timings # slow-lane and phase critical-path summaries ``` -예약된 라이브/E2E 워크플로는 전체 릴리스 경로 Docker 제품군을 매일 실행합니다. +예약된 라이브/E2E 워크플로는 전체 릴리스 경로 Docker 스위트를 매일 실행합니다. ## Plugin 사전 릴리스 -`Plugin Prerelease`는 더 비싼 제품/패키지 커버리지이므로 `Full Release Validation` 또는 명시적인 운영자가 디스패치하는 별도 워크플로입니다. 일반 풀 리퀘스트, `main` 푸시, 독립 수동 CI 디스패치에서는 해당 제품군을 꺼 둡니다. 이 워크플로는 번들 Plugin 테스트를 여덟 개 확장 워커에 분산합니다. 이러한 확장 샤드 작업은 그룹당 하나의 Vitest 워커와 더 큰 Node 힙을 사용해 한 번에 최대 두 개의 Plugin 구성 그룹을 실행하므로, import가 많은 Plugin 배치가 추가 CI 작업을 만들지 않습니다. 릴리스 전용 Docker 사전 릴리스 경로는 하나에서 세 분짜리 작업을 위해 수십 개의 실행기를 예약하지 않도록 대상 Docker 레인을 작은 그룹으로 배치합니다. +`Plugin Prerelease`는 더 비용이 큰 제품/패키지 커버리지이므로 `Full Release Validation` 또는 명시적 운영자가 디스패치하는 별도 워크플로입니다. 일반 풀 리퀘스트, `main` 푸시, 독립형 수동 CI 디스패치는 이 스위트를 꺼 둡니다. 이 워크플로는 번들 Plugin 테스트를 여덟 개의 확장 워커에 분산합니다. 해당 확장 샤드 작업은 한 번에 최대 두 개의 Plugin 구성 그룹을 실행하며, 그룹당 하나의 Vitest 워커와 더 큰 Node 힙을 사용해 import가 많은 Plugin 배치가 추가 CI 작업을 만들지 않도록 합니다. 릴리스 전용 Docker 사전 릴리스 경로는 1~3분짜리 작업을 위해 수십 개의 러너를 예약하지 않도록 대상 Docker 레인을 작은 그룹으로 배치 처리합니다. ## QA Lab -QA Lab에는 기본 smart-scoped 워크플로 밖의 전용 CI 레인이 있습니다. 에이전트 parity는 독립 PR 워크플로가 아니라 넓은 QA 및 릴리스 하네스 아래에 중첩됩니다. parity가 넓은 검증 실행과 함께 가야 할 때는 `rerun_group=qa-parity`와 함께 `Full Release Validation`을 사용하세요. +QA Lab에는 기본 스마트 범위 워크플로 외부에 전용 CI 레인이 있습니다. 에이전트 패리티는 독립형 PR 워크플로가 아니라 광범위한 QA 및 릴리스 하네스 아래에 중첩됩니다. 패리티가 광범위한 검증 실행과 함께 가야 할 때는 `rerun_group=qa-parity`와 함께 `Full Release Validation`을 사용하세요. -- `QA-Lab - All Lanes` 워크플로는 `main`에서 야간으로, 그리고 수동 디스패치에서 실행됩니다. mock parity 레인, live Matrix 레인, live Telegram 및 Discord 레인을 병렬 작업으로 분산 실행합니다. live 작업은 `qa-live-shared` 환경을 사용하며, Telegram/Discord는 Convex 임대를 사용합니다. +- `QA-Lab - All Lanes` 워크플로는 `main`에서 야간에, 그리고 수동 디스패치에서 실행됩니다. 이 워크플로는 mock 패리티 레인, 라이브 Matrix 레인, 라이브 Telegram 및 Discord 레인을 병렬 작업으로 펼칩니다. 라이브 작업은 `qa-live-shared` 환경을 사용하고, Telegram/Discord는 Convex 리스를 사용합니다. -릴리스 검사는 결정론적 mock 제공자와 mock-qualified 모델(`mock-openai/gpt-5.5` 및 `mock-openai/gpt-5.5-alt`)로 Matrix 및 Telegram live transport 레인을 실행하므로, 채널 계약이 live 모델 지연 시간과 일반 제공자 Plugin 시작에서 분리됩니다. live transport Gateway는 메모리 검색을 비활성화합니다. QA parity가 메모리 동작을 별도로 다루기 때문입니다. 제공자 연결성은 별도의 live 모델, 네이티브 제공자, Docker 제공자 제품군이 다룹니다. +릴리스 확인은 결정적 mock 제공자와 mock으로 한정된 모델(`mock-openai/gpt-5.5` 및 `mock-openai/gpt-5.5-alt`)로 Matrix 및 Telegram 라이브 전송 레인을 실행하므로 채널 계약이 라이브 모델 지연 시간과 일반 제공자 Plugin 시작으로부터 격리됩니다. 라이브 전송 Gateway는 메모리 검색을 비활성화합니다. QA 패리티가 메모리 동작을 별도로 다루기 때문입니다. 제공자 연결성은 별도의 라이브 모델, 네이티브 제공자, Docker 제공자 스위트에서 다룹니다. -Matrix는 예약 및 릴리스 게이트에 `--profile fast`를 사용하고, 체크아웃된 CLI가 지원할 때만 `--fail-fast`를 추가합니다. CLI 기본값과 수동 워크플로 입력은 `all`로 남아 있습니다. 수동 `matrix_profile=all` 디스패치는 항상 전체 Matrix 커버리지를 `transport`, `media`, `e2ee-smoke`, `e2ee-deep`, `e2ee-cli` 작업으로 샤딩합니다. +Matrix는 예약 및 릴리스 게이트에 `--profile fast`를 사용하며, 체크아웃된 CLI가 지원할 때만 `--fail-fast`를 추가합니다. CLI 기본값과 수동 워크플로 입력은 `all`로 유지됩니다. 수동 `matrix_profile=all` 디스패치는 항상 전체 Matrix 커버리지를 `transport`, `media`, `e2ee-smoke`, `e2ee-deep`, `e2ee-cli` 작업으로 샤딩합니다. -`OpenClaw Release Checks`도 릴리스 승인 전에 릴리스에 중요한 QA Lab 레인을 실행합니다. 이 QA parity 게이트는 candidate와 baseline 팩을 병렬 레인 작업으로 실행한 다음, 최종 parity 비교를 위해 두 아티팩트를 작은 보고서 작업으로 다운로드합니다. +`OpenClaw Release Checks`도 릴리스 승인 전에 릴리스에 중요한 QA Lab 레인을 실행합니다. QA 패리티 게이트는 후보 및 기준 팩을 병렬 레인 작업으로 실행한 다음, 최종 패리티 비교를 위해 두 아티팩트를 모두 작은 보고서 작업으로 다운로드합니다. -일반 PR의 경우 parity를 필수 상태로 취급하는 대신 범위가 지정된 CI/검사 증거를 따르세요. +일반 PR의 경우 패리티를 필수 상태로 취급하는 대신 범위가 지정된 CI/확인 증거를 따르세요. ## CodeQL -`CodeQL` 워크플로는 전체 저장소 스윕이 아니라 의도적으로 좁은 1차 보안 스캐너입니다. 일일, 수동, 비초안 풀 리퀘스트 가드 실행은 Actions 워크플로 코드와 가장 위험도가 높은 JavaScript/TypeScript 영역을 스캔하며, 높음/심각 `security-severity`로 필터링된 높은 신뢰도의 보안 쿼리를 사용합니다. +`CodeQL` 워크플로는 전체 저장소 스윕이 아니라 의도적으로 좁은 1차 보안 스캐너입니다. 일일, 수동, 비초안 풀 리퀘스트 보호 실행은 Actions 워크플로 코드와 가장 위험도가 높은 JavaScript/TypeScript 표면을 스캔하며, high/critical `security-severity`로 필터링된 높은 신뢰도의 보안 쿼리를 사용합니다. -풀 리퀘스트 가드는 가볍게 유지됩니다. `.github/actions`, `.github/codeql`, `.github/workflows`, `packages`, 또는 `src` 아래 변경에 대해서만 시작되며, 예약된 워크플로와 동일한 높은 신뢰도의 보안 매트릭스를 실행합니다. Android 및 macOS CodeQL은 PR 기본값에서 제외됩니다. +풀 리퀘스트 보호는 가볍게 유지됩니다. `.github/actions`, `.github/codeql`, `.github/workflows`, `packages`, 또는 `src` 아래 변경에 대해서만 시작하며, 예약 워크플로와 동일한 높은 신뢰도의 보안 매트릭스를 실행합니다. Android 및 macOS CodeQL은 PR 기본값에서 제외됩니다. ### 보안 범주 -| 범주 | 영역 | +| 범주 | 표면 | | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `/codeql-security-high/core-auth-secrets` | 인증, 시크릿, 샌드박스, Cron, Gateway 기준선 | -| `/codeql-security-high/channel-runtime-boundary` | 핵심 채널 구현 계약과 채널 Plugin 런타임, Gateway, Plugin SDK, 시크릿, 감사 접점 | -| `/codeql-security-high/network-ssrf-boundary` | 핵심 SSRF, IP 파싱, 네트워크 가드, 웹 가져오기, Plugin SDK SSRF 정책 영역 | -| `/codeql-security-high/mcp-process-tool-boundary` | MCP 서버, 프로세스 실행 헬퍼, 아웃바운드 전달, 에이전트 도구 실행 게이트 | -| `/codeql-security-high/plugin-trust-boundary` | Plugin 설치, 로더, 매니페스트, 레지스트리, 패키지 관리자 설치, 소스 로딩, Plugin SDK 패키지 계약 신뢰 영역 | +| `/codeql-security-high/core-auth-secrets` | 인증, 시크릿, 샌드박스, cron 및 gateway 기준선 | +| `/codeql-security-high/channel-runtime-boundary` | 핵심 채널 구현 계약과 채널 Plugin 런타임, gateway, Plugin SDK, 시크릿, 감사 접점 | +| `/codeql-security-high/network-ssrf-boundary` | 핵심 SSRF, IP 파싱, 네트워크 가드, 웹 가져오기 및 Plugin SDK SSRF 정책 표면 | +| `/codeql-security-high/mcp-process-tool-boundary` | MCP 서버, 프로세스 실행 헬퍼, 아웃바운드 전달 및 에이전트 도구 실행 게이트 | +| `/codeql-security-high/plugin-trust-boundary` | Plugin 설치, 로더, 매니페스트, 레지스트리, 패키지 관리자 설치, 소스 로딩 및 Plugin SDK 패키지 계약 신뢰 표면 | ### 플랫폼별 보안 샤드 -- `CodeQL Android Critical Security` — 예약된 Android 보안 샤드입니다. 워크플로 sanity에서 허용하는 가장 작은 Blacksmith Linux 러너에서 CodeQL용 Android 앱을 수동으로 빌드합니다. `/codeql-critical-security/android` 아래에 업로드합니다. -- `CodeQL macOS Critical Security` — 주간/수동 macOS 보안 샤드입니다. Blacksmith macOS에서 CodeQL용 macOS 앱을 수동으로 빌드하고, 업로드된 SARIF에서 의존성 빌드 결과를 필터링한 뒤 `/codeql-critical-security/macos` 아래에 업로드합니다. macOS 빌드는 깨끗한 상태에서도 실행 시간을 지배하므로 일일 기본값 밖에 유지됩니다. +- `CodeQL Android Critical Security` — 예약된 Android 보안 샤드입니다. 워크플로 무결성 검사가 허용하는 가장 작은 Blacksmith Linux 러너에서 CodeQL을 위해 Android 앱을 수동으로 빌드합니다. `/codeql-critical-security/android` 아래에 업로드합니다. +- `CodeQL macOS Critical Security` — 주간/수동 macOS 보안 샤드입니다. Blacksmith macOS에서 CodeQL을 위해 macOS 앱을 수동으로 빌드하고, 업로드된 SARIF에서 의존성 빌드 결과를 필터링한 뒤 `/codeql-critical-security/macos` 아래에 업로드합니다. 깨끗한 상태에서도 macOS 빌드가 런타임을 지배하므로 일일 기본값 밖에 유지됩니다. -### 중요 품질 범주 +### Critical Quality 범주 -`CodeQL Critical Quality`는 이에 대응하는 비보안 샤드입니다. 더 작은 Blacksmith Linux 러너에서 좁고 가치가 높은 영역을 대상으로 오류 심각도, 비보안 JavaScript/TypeScript 품질 쿼리만 실행합니다. 풀 리퀘스트 가드는 예약된 프로필보다 의도적으로 더 작습니다. 비초안 PR은 에이전트 명령/모델/도구 실행 및 답장 디스패치 코드, 설정 스키마/마이그레이션/IO 코드, 인증/시크릿/샌드박스/보안 코드, 핵심 채널 및 번들 채널 Plugin 런타임, Gateway 프로토콜/서버 메서드, 메모리 런타임/SDK 글루, MCP/프로세스/아웃바운드 전달, 제공자 런타임/모델 카탈로그, 세션 진단/전달 큐, Plugin 로더, Plugin SDK/패키지 계약, 또는 Plugin SDK 답장 런타임 변경에 대해 대응하는 `agent-runtime-boundary`, `config-boundary`, `core-auth-secrets`, `channel-runtime-boundary`, `gateway-runtime-boundary`, `memory-runtime-boundary`, `mcp-process-runtime-boundary`, `provider-runtime-boundary`, `session-diagnostics-boundary`, `plugin-boundary`, `plugin-sdk-package-contract`, `plugin-sdk-reply-runtime` 샤드만 실행합니다. CodeQL 설정 및 품질 워크플로 변경은 PR 품질 샤드 12개를 모두 실행합니다. +`CodeQL Critical Quality`는 이에 대응하는 비보안 샤드입니다. 더 작은 Blacksmith Linux 러너에서 좁고 가치가 높은 표면에 대해 오류 심각도만의 비보안 JavaScript/TypeScript 품질 쿼리만 실행합니다. 이 풀 리퀘스트 보호는 예약 프로필보다 의도적으로 더 작습니다. 비초안 PR은 에이전트 명령/모델/도구 실행과 응답 디스패치 코드, 구성 스키마/마이그레이션/IO 코드, 인증/시크릿/샌드박스/보안 코드, 핵심 채널 및 번들 채널 Plugin 런타임, gateway 프로토콜/서버 메서드, 메모리 런타임/SDK 연결 코드, MCP/프로세스/아웃바운드 전달, 제공자 런타임/모델 카탈로그, 세션 진단/전달 큐, Plugin 로더, Plugin SDK/패키지 계약 또는 Plugin SDK 응답 런타임 변경에 대해 대응하는 `agent-runtime-boundary`, `config-boundary`, `core-auth-secrets`, `channel-runtime-boundary`, `gateway-runtime-boundary`, `memory-runtime-boundary`, `mcp-process-runtime-boundary`, `provider-runtime-boundary`, `session-diagnostics-boundary`, `plugin-boundary`, `plugin-sdk-package-contract`, `plugin-sdk-reply-runtime` 샤드만 실행합니다. CodeQL 구성 및 품질 워크플로 변경은 12개의 PR 품질 샤드를 모두 실행합니다. 수동 디스패치는 다음을 허용합니다. @@ -412,40 +428,40 @@ Matrix는 예약 및 릴리스 게이트에 `--profile fast`를 사용하고, profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary ``` -좁은 프로필은 품질 샤드 하나를 격리해서 실행하기 위한 학습/반복 훅입니다. +좁은 프로필은 하나의 품질 샤드를 격리해 실행하기 위한 학습/반복 훅입니다. -| 범주 | 영역 | +| 범주 | 표면 | | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `/codeql-critical-quality/core-auth-secrets` | 인증, 시크릿, 샌드박스, Cron, Gateway 보안 경계 코드 | -| `/codeql-critical-quality/config-boundary` | 설정 스키마, 마이그레이션, 정규화, IO 계약 | -| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 프로토콜 스키마와 서버 메서드 계약 | +| `/codeql-critical-quality/core-auth-secrets` | 인증, 시크릿, 샌드박스, cron 및 gateway 보안 경계 코드 | +| `/codeql-critical-quality/config-boundary` | 구성 스키마, 마이그레이션, 정규화 및 IO 계약 | +| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 프로토콜 스키마 및 서버 메서드 계약 | | `/codeql-critical-quality/channel-runtime-boundary` | 핵심 채널 및 번들 채널 Plugin 구현 계약 | -| `/codeql-critical-quality/agent-runtime-boundary` | 명령 실행, 모델/제공자 디스패치, 자동 답장 디스패치와 큐, ACP 제어 평면 런타임 계약 | -| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 서버와 도구 브리지, 프로세스 감독 헬퍼, 아웃바운드 전달 계약 | -| `/codeql-critical-quality/memory-runtime-boundary` | 메모리 호스트 SDK, 메모리 런타임 파사드, 메모리 Plugin SDK 별칭, 메모리 런타임 활성화 글루, 메모리 doctor 명령 | -| `/codeql-critical-quality/session-diagnostics-boundary` | 답장 큐 내부, 세션 전달 큐, 아웃바운드 세션 바인딩/전달 헬퍼, 진단 이벤트/로그 번들 영역, 세션 doctor CLI 계약 | -| `/codeql-critical-quality/plugin-sdk-reply-runtime` | Plugin SDK 인바운드 답장 디스패치, 답장 페이로드/청킹/런타임 헬퍼, 채널 답장 옵션, 전달 큐, 세션/스레드 바인딩 헬퍼 | -| `/codeql-critical-quality/provider-runtime-boundary` | 모델 카탈로그 정규화, 제공자 인증 및 발견, 제공자 런타임 등록, 제공자 기본값/카탈로그, 웹/검색/가져오기/임베딩 레지스트리 | -| `/codeql-critical-quality/ui-control-plane` | 제어 UI 부트스트랩, 로컬 영속성, Gateway 제어 흐름, 작업 제어 평면 런타임 계약 | -| `/codeql-critical-quality/web-media-runtime-boundary` | 핵심 웹 가져오기/검색, 미디어 IO, 미디어 이해, 이미지 생성, 미디어 생성 런타임 계약 | -| `/codeql-critical-quality/plugin-boundary` | 로더, 레지스트리, 공개 영역, Plugin SDK 진입점 계약 | -| `/codeql-critical-quality/plugin-sdk-package-contract` | 게시된 패키지 측 Plugin SDK 소스와 플러그인 패키지 계약 헬퍼 | +| `/codeql-critical-quality/agent-runtime-boundary` | 명령 실행, 모델/제공자 디스패치, 자동 응답 디스패치와 큐 및 ACP 제어 평면 런타임 계약 | +| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 서버와 도구 브리지, 프로세스 감독 헬퍼 및 아웃바운드 전달 계약 | +| `/codeql-critical-quality/memory-runtime-boundary` | 메모리 호스트 SDK, 메모리 런타임 파사드, 메모리 Plugin SDK 별칭, 메모리 런타임 활성화 연결 코드 및 메모리 doctor 명령 | +| `/codeql-critical-quality/session-diagnostics-boundary` | 응답 큐 내부, 세션 전달 큐, 아웃바운드 세션 바인딩/전달 헬퍼, 진단 이벤트/로그 번들 표면 및 세션 doctor CLI 계약 | +| `/codeql-critical-quality/plugin-sdk-reply-runtime` | Plugin SDK 인바운드 응답 디스패치, 응답 페이로드/청킹/런타임 헬퍼, 채널 응답 옵션, 전달 큐 및 세션/스레드 바인딩 헬퍼 | +| `/codeql-critical-quality/provider-runtime-boundary` | 모델 카탈로그 정규화, 제공자 인증 및 검색, 제공자 런타임 등록, 제공자 기본값/카탈로그 및 웹/검색/가져오기/임베딩 레지스트리 | +| `/codeql-critical-quality/ui-control-plane` | 제어 UI 부트스트랩, 로컬 지속성, gateway 제어 흐름 및 작업 제어 평면 런타임 계약 | +| `/codeql-critical-quality/web-media-runtime-boundary` | 핵심 웹 가져오기/검색, 미디어 IO, 미디어 이해, 이미지 생성 및 미디어 생성 런타임 계약 | +| `/codeql-critical-quality/plugin-boundary` | 로더, 레지스트리, 공개 표면 및 Plugin SDK 엔트리포인트 계약 | +| `/codeql-critical-quality/plugin-sdk-package-contract` | 게시된 패키지 측 Plugin SDK 소스 및 plugin 패키지 계약 헬퍼 | -품질은 보안과 분리되어 유지되므로 품질 발견 사항을 보안 신호를 흐리지 않고 예약, 측정, 비활성화 또는 확장할 수 있습니다. Swift, Python, 번들 Plugin CodeQL 확장은 좁은 프로필의 실행 시간과 신호가 안정된 뒤에만 범위가 지정되거나 샤딩된 후속 작업으로 다시 추가해야 합니다. +품질은 보안과 분리되어 유지되므로, 보안 신호를 흐리지 않고 품질 발견 사항을 예약, 측정, 비활성화 또는 확장할 수 있습니다. Swift, Python 및 번들 Plugin CodeQL 확장은 좁은 프로필의 런타임과 신호가 안정화된 뒤에만 범위가 지정되거나 샤드화된 후속 작업으로 다시 추가해야 합니다. -## 유지관리 워크플로 +## 유지 관리 워크플로 ### Docs Agent -`Docs Agent` 워크플로는 최근 병합된 변경과 기존 문서를 맞추기 위한 이벤트 기반 Codex 유지관리 레인입니다. 순수 일정은 없습니다. `main`의 성공한 비봇 push CI 실행이 이를 트리거할 수 있으며, 수동 디스패치로 직접 실행할 수도 있습니다. 워크플로 실행 호출은 `main`이 이미 आगे 진행되었거나 지난 1시간 내에 건너뛰지 않은 다른 Docs Agent 실행이 생성된 경우 건너뜁니다. 실행될 때는 이전의 건너뛰지 않은 Docs Agent 소스 SHA부터 현재 `main`까지의 커밋 범위를 검토하므로, 한 시간에 한 번 실행으로 마지막 문서 패스 이후 누적된 모든 main 변경을 다룰 수 있습니다. +`Docs Agent` 워크플로는 최근 병합된 변경과 기존 문서를 맞춰 유지하기 위한 이벤트 기반 Codex 유지 관리 레인입니다. 순수 일정은 없습니다. `main`에서 성공한 비봇 push CI 실행이 이를 트리거할 수 있으며, 수동 디스패치로 직접 실행할 수 있습니다. 워크플로 실행 호출은 `main`이 이미 이동했거나 지난 한 시간 안에 건너뛰지 않은 다른 Docs Agent 실행이 생성된 경우 건너뜁니다. 실행되면 이전에 건너뛰지 않은 Docs Agent 소스 SHA부터 현재 `main`까지의 커밋 범위를 검토하므로, 시간당 한 번의 실행으로 마지막 문서 점검 이후 누적된 모든 main 변경을 처리할 수 있습니다. ### Test Performance Agent -`Test Performance Agent` 워크플로는 느린 테스트를 위한 이벤트 기반 Codex 유지관리 레인입니다. 순수 일정은 없습니다. `main`의 성공한 비봇 push CI 실행이 이를 트리거할 수 있지만, 해당 UTC 날짜에 다른 워크플로 실행 호출이 이미 실행되었거나 실행 중이면 건너뜁니다. 수동 디스패치는 이 일일 활동 게이트를 우회합니다. 이 레인은 전체 스위트 그룹화 Vitest 성능 보고서를 빌드하고, Codex가 광범위한 리팩터링 대신 커버리지를 보존하는 작은 테스트 성능 수정만 수행하게 한 뒤, 전체 스위트 보고서를 다시 실행하고 통과 기준 테스트 수를 줄이는 변경을 거부합니다. 기준선에 실패한 테스트가 있으면 Codex는 명백한 실패만 수정할 수 있으며, 에이전트 이후 전체 스위트 보고서는 커밋 전에 통과해야 합니다. 봇 push가 병합되기 전에 `main`이 진행되면, 레인은 검증된 패치를 리베이스하고 `pnpm check:changed`를 다시 실행한 뒤 push를 재시도합니다. 충돌하는 오래된 패치는 건너뜁니다. Codex 액션이 docs agent와 동일한 drop-sudo 안전 태세를 유지할 수 있도록 GitHub 호스팅 Ubuntu를 사용합니다. +`Test Performance Agent` 워크플로는 느린 테스트를 위한 이벤트 기반 Codex 유지 관리 레인입니다. 순수 일정은 없습니다. `main`에서 성공한 비봇 push CI 실행이 이를 트리거할 수 있지만, 해당 UTC 날짜에 다른 워크플로 실행 호출이 이미 실행되었거나 실행 중이면 건너뜁니다. 수동 디스패치는 해당 일일 활동 게이트를 우회합니다. 이 레인은 전체 스위트 그룹화 Vitest 성능 보고서를 빌드하고, Codex가 광범위한 리팩터링 대신 커버리지를 보존하는 작은 테스트 성능 수정만 수행하게 한 뒤, 전체 스위트 보고서를 다시 실행하고 통과 기준 테스트 수를 줄이는 변경을 거부합니다. 기준선에 실패하는 테스트가 있으면 Codex는 명백한 실패만 수정할 수 있으며, 에이전트 이후 전체 스위트 보고서가 통과해야만 커밋됩니다. 봇 push가 병합되기 전에 `main`이 앞서 나가면, 이 레인은 검증된 패치를 리베이스하고 `pnpm check:changed`를 다시 실행한 뒤 push를 재시도합니다. 충돌하는 오래된 패치는 건너뜁니다. Codex 액션이 문서 에이전트와 동일한 sudo 제거 안전 태세를 유지할 수 있도록 GitHub 호스팅 Ubuntu를 사용합니다. ### 병합 후 중복 PR -`Duplicate PRs After Merge` 워크플로는 병합 후 중복 정리를 위한 수동 유지관리자 워크플로입니다. 기본값은 드라이런이며 `apply=true`일 때 명시적으로 나열된 PR만 닫습니다. GitHub를 변경하기 전에, 병합된 PR이 실제로 병합되었고 각 중복 항목에 공유 참조 이슈 또는 겹치는 변경 헝크가 있는지 확인합니다. +`Duplicate PRs After Merge` 워크플로는 병합 후 중복 정리를 위한 수동 유지 관리자 워크플로입니다. 기본값은 dry-run이며 `apply=true`일 때만 명시적으로 나열된 PR을 닫습니다. GitHub를 변경하기 전에, 병합된 PR이 실제로 병합되었고 각 중복 항목에 공유 참조 이슈 또는 겹치는 변경 헝크가 있는지 검증합니다. ```bash gh workflow run duplicate-after-merge.yml \ @@ -456,27 +472,27 @@ gh workflow run duplicate-after-merge.yml \ ## 로컬 검사 게이트와 변경 라우팅 -로컬 changed-lane 로직은 `scripts/changed-lanes.mjs`에 있으며 `scripts/check-changed.mjs`가 실행합니다. 이 로컬 검사 게이트는 넓은 CI 플랫폼 범위보다 아키텍처 경계에 더 엄격합니다. +로컬 변경 레인 로직은 `scripts/changed-lanes.mjs`에 있으며 `scripts/check-changed.mjs`가 실행합니다. 이 로컬 검사 게이트는 넓은 CI 플랫폼 범위보다 아키텍처 경계에 대해 더 엄격합니다. -- 핵심 프로덕션 변경은 핵심 prod 및 핵심 test 타입검사와 핵심 린트/가드를 실행합니다. -- 핵심 test 전용 변경은 핵심 test 타입검사와 핵심 린트만 실행합니다. -- 확장 프로덕션 변경은 확장 prod 및 확장 test 타입검사와 확장 린트를 실행합니다. -- 확장 test 전용 변경은 확장 test 타입검사와 확장 린트만 실행합니다. -- 공개 Plugin SDK 또는 플러그인 계약 변경은 확장이 해당 핵심 계약에 의존하므로 확장 타입검사로 확장됩니다. Vitest 확장 스윕은 명시적 테스트 작업으로 유지됩니다. -- 릴리스 메타데이터 전용 버전 범프는 대상이 지정된 버전/설정/루트 의존성 검사를 실행합니다. -- 알 수 없는 루트/설정 변경은 안전하게 모든 검사 레인으로 실패합니다. +- 핵심 프로덕션 변경은 핵심 프로덕션 및 핵심 테스트 타입검사와 핵심 린트/가드를 실행합니다. +- 핵심 테스트 전용 변경은 핵심 테스트 타입검사와 핵심 린트만 실행합니다. +- 확장 프로덕션 변경은 확장 프로덕션 및 확장 테스트 타입검사와 확장 린트를 실행합니다. +- 확장 테스트 전용 변경은 확장 테스트 타입검사와 확장 린트만 실행합니다. +- 공개 Plugin SDK 또는 plugin 계약 변경은 확장이 해당 핵심 계약에 의존하므로 확장 타입검사로 확장됩니다. Vitest 확장 스윕은 명시적 테스트 작업으로 유지됩니다. +- 릴리스 메타데이터 전용 버전 범프는 대상 버전/구성/루트 의존성 검사를 실행합니다. +- 알 수 없는 루트/구성 변경은 안전하게 모든 검사 레인으로 실패 처리됩니다. -로컬 변경 테스트 라우팅은 `scripts/test-projects.test-support.mjs`에 있으며 의도적으로 `check:changed`보다 저렴합니다. 직접 테스트 편집은 해당 테스트를 실행하고, 소스 편집은 명시적 매핑을 우선하며, 그다음 형제 테스트와 import-graph 의존 항목을 사용합니다. 공유 그룹룸 전달 설정은 명시적 매핑 중 하나입니다. 그룹 가시 답장 설정, 소스 답장 전달 모드, 또는 message-tool 시스템 프롬프트 변경은 핵심 답장 테스트와 Discord 및 Slack 전달 회귀를 거치므로, 공유 기본값 변경은 첫 PR push 전에 실패합니다. 변경이 하네스 전반에 걸쳐 있어 저렴한 매핑 집합을 신뢰할 수 있는 프록시로 볼 수 없는 경우에만 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`를 사용하세요. +로컬 변경 테스트 라우팅은 `scripts/test-projects.test-support.mjs`에 있으며 의도적으로 `check:changed`보다 저렴합니다. 직접 테스트 편집은 자신을 실행하고, 소스 편집은 명시적 매핑을 우선한 뒤 형제 테스트와 가져오기 그래프 의존 항목을 사용합니다. 공유 그룹 방 전달 구성은 명시적 매핑 중 하나입니다. 그룹의 표시 응답 구성, 소스 응답 전달 모드 또는 메시지 도구 시스템 프롬프트 변경은 핵심 응답 테스트와 Discord 및 Slack 전달 회귀를 통과하므로, 공유 기본값 변경은 첫 PR push 전에 실패합니다. 변경이 하네스 전체에 영향을 줄 만큼 넓어 저렴한 매핑 집합을 신뢰할 수 있는 대리로 볼 수 없을 때만 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`를 사용하세요. ## Testbox 검증 -저장소 루트에서 Testbox를 실행하고, 광범위한 검증에는 새로 워밍된 박스를 선호하세요. 재사용되었거나 만료되었거나 방금 예상보다 큰 동기화를 보고한 박스에서 느린 게이트에 시간을 쓰기 전에, 먼저 박스 안에서 `pnpm testbox:sanity`를 실행하세요. +리포지토리 루트에서 Testbox를 실행하고, 광범위한 검증에는 새로 워밍된 박스를 선호하세요. 재사용되었거나 만료되었거나 방금 예상보다 큰 동기화를 보고한 박스에서 느린 게이트를 실행하기 전에, 먼저 박스 안에서 `pnpm testbox:sanity`를 실행하세요. -필수 루트 파일인 `pnpm-lock.yaml` 등이 사라졌거나 `git status --short`가 추적 중인 삭제를 200개 이상 표시하면, 이 정상성 검사는 빠르게 실패합니다. 이는 보통 원격 동기화 상태가 PR의 신뢰할 수 있는 복사본이 아니라는 뜻입니다. 제품 테스트 실패를 디버깅하는 대신 해당 박스를 중지하고 새 박스를 워밍하세요. 의도적인 대량 삭제 PR의 경우, 해당 정상성 실행에 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`을 설정하세요. +필수 루트 파일(예: `pnpm-lock.yaml`)이 사라졌거나 `git status --short`가 최소 200개의 추적된 삭제를 표시하면 sanity check가 빠르게 실패합니다. 이는 일반적으로 원격 동기화 상태가 PR의 신뢰할 수 있는 복사본이 아니라는 뜻입니다. 제품 테스트 실패를 디버깅하는 대신 해당 박스를 중지하고 새 박스를 워밍하세요. 의도적으로 대량 삭제를 포함하는 PR의 경우, 해당 sanity 실행에 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`을 설정하세요. -`pnpm testbox:run`은 동기화 후 출력 없이 동기화 단계에 5분 넘게 머무르는 로컬 Blacksmith CLI 호출도 종료합니다. 이 보호 장치를 비활성화하려면 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0`을 설정하거나, 비정상적으로 큰 로컬 diff에는 더 큰 밀리초 값을 사용하세요. +`pnpm testbox:run`은 동기화 이후 출력 없이 동기화 단계에 5분 넘게 머무르는 로컬 Blacksmith CLI 호출도 종료합니다. 해당 가드를 비활성화하려면 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0`을 설정하거나, 비정상적으로 큰 로컬 diff에는 더 큰 밀리초 값을 사용하세요. -Blacksmith를 사용할 수 없거나 소유한 클라우드 용량을 선호할 때, Crabbox는 Linux 검증을 위한 저장소 소유의 두 번째 원격 박스 경로입니다. 박스를 워밍하고 프로젝트 워크플로를 통해 하이드레이트한 다음, Crabbox CLI로 명령을 실행하세요. +Crabbox는 Blacksmith를 사용할 수 없거나 소유한 클라우드 용량을 선호할 때 Linux 검증을 위한 리포지토리 소유의 두 번째 원격 박스 경로입니다. 박스를 워밍하고, 프로젝트 워크플로를 통해 hydrate한 다음, Crabbox CLI를 통해 명령을 실행하세요. ```bash pnpm crabbox:warmup -- --idle-timeout 90m @@ -485,7 +501,7 @@ pnpm crabbox:run -- --id --shell "OPENCLAW_TESTBOX=1 pnpm check:changed pnpm crabbox:stop -- ``` -`.crabbox.yaml`은 공급자, 동기화, GitHub Actions 하이드레이션 기본값을 담당합니다. 이 파일은 로컬 `.git`을 제외하므로 하이드레이션된 Actions 체크아웃은 maintainer 로컬 원격 저장소와 객체 저장소를 동기화하는 대신 자체 원격 Git 메타데이터를 유지하며, 절대 전송되어서는 안 되는 로컬 런타임/빌드 아티팩트도 제외합니다. `.github/workflows/crabbox-hydrate.yml`은 체크아웃, Node/pnpm 설정, `origin/main` 가져오기, 그리고 이후 `crabbox run --id ` 명령이 소스로 사용하는 비밀이 아닌 환경 전달을 담당합니다. +`.crabbox.yaml`은 제공자, 동기화, GitHub Actions hydrate 기본값을 소유합니다. 로컬 `.git`은 제외하므로 hydrate된 Actions checkout은 maintainer 로컬 remote와 객체 저장소를 동기화하는 대신 자체 원격 Git 메타데이터를 유지하며, 절대 전송되어서는 안 되는 로컬 런타임/빌드 아티팩트도 제외합니다. `.github/workflows/crabbox-hydrate.yml`은 checkout, Node/pnpm 설정, `origin/main` fetch, 그리고 이후 `crabbox run --id ` 명령이 source하는 비밀이 아닌 환경 handoff를 소유합니다. ## 관련 diff --git a/docs/ko/concepts/system-prompt.md b/docs/ko/concepts/system-prompt.md index 018ae5d72..b817c1b6a 100644 --- a/docs/ko/concepts/system-prompt.md +++ b/docs/ko/concepts/system-prompt.md @@ -2,108 +2,103 @@ read_when: - 시스템 프롬프트 텍스트, 도구 목록 또는 시간/Heartbeat 섹션 편집 - 워크스페이스 부트스트랩 또는 Skills 주입 동작 변경 -summary: OpenClaw 시스템 프롬프트에 포함된 내용과 조립 방식 +summary: OpenClaw 시스템 프롬프트에 포함된 내용과 구성 방식 title: 시스템 프롬프트 x-i18n: - generated_at: "2026-05-02T22:18:12Z" + generated_at: "2026-05-02T23:39:22Z" model: gpt-5.5 provider: openai - source_hash: 3b8761a8722bb328b937e0832774be7b4e99602ae032c9a255f26843237c110c + source_hash: f8e0234453812c16cf5d273096d335049bf435ca76ade36200caf4bb344624e5 source_path: concepts/system-prompt.md workflow: 16 --- -OpenClaw는 모든 에이전트 실행마다 사용자 지정 시스템 프롬프트를 빌드합니다. 프롬프트는 **OpenClaw 소유**이며 pi-coding-agent 기본 프롬프트를 사용하지 않습니다. +OpenClaw는 모든 에이전트 실행마다 사용자 지정 시스템 프롬프트를 빌드합니다. 이 프롬프트는 **OpenClaw 소유**이며 pi-coding-agent 기본 프롬프트를 사용하지 않습니다. -프롬프트는 OpenClaw가 조립하고 각 에이전트 실행에 주입합니다. +프롬프트는 OpenClaw가 조립하여 각 에이전트 실행에 주입합니다. -Provider Plugin은 전체 OpenClaw 소유 프롬프트를 대체하지 않고도 캐시를 고려한 프롬프트 지침을 제공할 수 있습니다. Provider 런타임은 다음을 수행할 수 있습니다. +Provider Plugin은 전체 OpenClaw 소유 프롬프트를 대체하지 않고도 캐시 인식 프롬프트 지침을 제공할 수 있습니다. Provider 런타임은 다음을 할 수 있습니다. -- 명명된 소수의 코어 섹션(`interaction_style`, - `tool_call_style`, `execution_bias`) 교체 +- 명명된 소수의 핵심 섹션(`interaction_style`, `tool_call_style`, `execution_bias`) 교체 - 프롬프트 캐시 경계 위에 **안정적인 접두사** 주입 - 프롬프트 캐시 경계 아래에 **동적 접미사** 주입 모델 계열별 튜닝에는 Provider 소유 기여를 사용하세요. 레거시 -`before_prompt_build` 프롬프트 변경은 호환성 또는 진정한 전역 프롬프트 -변경에만 유지하고, 일반적인 Provider 동작에는 사용하지 마세요. +`before_prompt_build` 프롬프트 변경은 호환성 또는 진정으로 전역적인 프롬프트 +변경을 위해 유지하고, 일반적인 Provider 동작에는 사용하지 마세요. -OpenAI GPT-5 계열 오버레이는 코어 실행 규칙을 작게 유지하고 -페르소나 고정, 간결한 출력, 도구 규율, 병렬 조회, 산출물 범위, 검증, -누락된 컨텍스트, 터미널 도구 위생에 대한 모델별 지침을 추가합니다. +OpenAI GPT-5 계열 오버레이는 핵심 실행 규칙을 작게 유지하고 +페르소나 고정, 간결한 출력, 도구 규율, 병렬 조회, 산출물 범위, 검증, 누락된 컨텍스트, +터미널 도구 위생에 대한 모델별 지침을 추가합니다. ## 구조 프롬프트는 의도적으로 간결하며 고정 섹션을 사용합니다. -- **도구**: 구조화된 도구의 진실 공급원 알림과 런타임 도구 사용 지침. -- **실행 편향**: 간결한 후속 처리 지침: 실행 가능한 요청은 같은 턴에서 처리하고, - 완료되거나 차단될 때까지 계속하며, 약한 도구 결과에서 복구하고, - 변경 가능한 상태를 실시간으로 확인하며, 최종 응답 전 검증합니다. +- **도구 사용**: 구조화된 도구의 단일 진실 공급원 알림과 런타임 도구 사용 지침. +- **실행 성향**: 간결한 완수 지침: 실행 가능한 요청은 턴 안에서 수행하고, + 완료되거나 막힐 때까지 계속하며, 약한 도구 결과에서 복구하고, 변경 가능한 상태는 실시간으로 확인하며, + 최종화하기 전에 검증합니다. - **안전**: 권력 추구 행동이나 감독 우회를 피하라는 짧은 가드레일 알림. -- **Skills**(사용 가능한 경우): 필요할 때 Skills 지침을 로드하는 방법을 모델에 알려줍니다. -- **OpenClaw 자체 업데이트**: `config.schema.lookup`으로 안전하게 설정을 검사하고, - `config.patch`로 설정을 패치하며, `config.apply`로 전체 설정을 교체하고, - 명시적인 사용자 요청이 있을 때만 `update.run`을 실행하는 방법. 소유자 전용 - `gateway` 도구도 `tools.exec.ask` / `tools.exec.security`를 다시 쓰는 것을 거부하며, - 이러한 보호된 exec 경로로 정규화되는 레거시 `tools.bash.*` 별칭도 포함됩니다. -- **워크스페이스**: 작업 디렉터리(`agents.defaults.workspace`). -- **문서**: OpenClaw 문서의 로컬 경로(repo 또는 npm 패키지)와 읽어야 할 시점. -- **워크스페이스 파일(주입됨)**: 부트스트랩 파일이 아래에 포함되어 있음을 나타냅니다. -- **샌드박스**(활성화된 경우): 샌드박스 런타임, 샌드박스 경로, 권한 상승 exec 사용 가능 여부를 나타냅니다. +- **Skills**(사용 가능한 경우): 필요 시 Skills 지침을 로드하는 방법을 모델에 알려줍니다. +- **OpenClaw 자체 업데이트**: `config.schema.lookup`으로 구성을 안전하게 검사하고, + `config.patch`로 구성을 패치하며, `config.apply`로 전체 구성을 교체하고, + 명시적인 사용자 요청이 있을 때만 `update.run`을 실행하는 방법입니다. 소유자 전용 + `gateway` 도구도 보호된 exec 경로로 정규화되는 레거시 `tools.bash.*` + 별칭을 포함해 `tools.exec.ask` / `tools.exec.security` 재작성을 거부합니다. +- **작업공간**: 작업 디렉터리(`agents.defaults.workspace`). +- **문서**: OpenClaw 문서의 로컬 경로(repo 또는 npm package)와 읽어야 하는 시점. +- **작업공간 파일(주입됨)**: 부트스트랩 파일이 아래에 포함되어 있음을 나타냅니다. +- **샌드박스**(활성화된 경우): 샌드박스 런타임, 샌드박스 경로, 승격된 exec 사용 가능 여부를 나타냅니다. - **현재 날짜 및 시간**: 사용자 로컬 시간, 시간대, 시간 형식. -- **응답 태그**: 지원되는 Provider의 선택적 응답 태그 구문. -- **Heartbeats**: 기본 에이전트에 Heartbeat가 활성화된 경우 Heartbeat 프롬프트와 ack 동작. +- **응답 태그**: 지원되는 Provider를 위한 선택적 응답 태그 문법. +- **Heartbeats**: 기본 에이전트에 Heartbeat가 활성화된 경우 Heartbeat 프롬프트와 확인 동작. - **런타임**: 호스트, OS, Node, 모델, repo 루트(감지된 경우), 사고 수준(한 줄). -- **추론**: 현재 표시 수준 + /reasoning 토글 힌트. +- **추론**: 현재 가시성 수준 + /reasoning 토글 힌트. -OpenClaw는 **프로젝트 컨텍스트**를 포함한 큰 안정 콘텐츠를 내부 프롬프트 캐시 경계 위에 유지합니다. Control UI 임베드 지침, **메시징**, **음성**, **그룹 채팅 컨텍스트**, **반응**, **Heartbeats**, **런타임**처럼 변동성이 큰 채널/세션 섹션은 해당 경계 아래에 추가되어, 접두사 캐시가 있는 로컬 백엔드가 채널 턴 간 안정적인 워크스페이스 접두사를 재사용할 수 있습니다. 도구 설명도 허용되는 스키마가 이미 해당 런타임 세부 정보를 담고 있다면 현재 채널 이름을 포함하지 않아야 합니다. +OpenClaw는 **프로젝트 컨텍스트**를 포함한 큰 안정 콘텐츠를 내부 프롬프트 캐시 경계 위에 유지합니다. Control UI 임베드 지침, **메시징**, **음성**, **그룹 채팅 컨텍스트**, **반응**, **Heartbeats**, **런타임** 같은 변동성 채널/세션 섹션은 그 경계 아래에 추가되어, 접두사 캐시를 가진 로컬 백엔드가 채널 턴 전반에서 안정적인 작업공간 접두사를 재사용할 수 있게 합니다. 도구 설명도 허용된 스키마가 이미 해당 런타임 세부 정보를 담고 있다면 현재 채널 이름을 포함하지 않아야 합니다. -도구 섹션에는 장기 실행 작업을 위한 런타임 지침도 포함됩니다. +도구 사용 섹션에는 장기 실행 작업을 위한 런타임 지침도 포함됩니다. -- 향후 후속 처리(`check back later`, 알림, 반복 작업)에는 `exec` sleep 루프, +- 나중의 후속 확인(`check back later`, 알림, 반복 작업)에는 `exec` sleep 루프, `yieldMs` 지연 기법, 반복적인 `process` 폴링 대신 Cron을 사용합니다. -- `exec` / `process`는 지금 시작되어 백그라운드에서 계속 실행되는 명령에만 사용합니다. -- 자동 완료 wake가 활성화된 경우 명령을 한 번 시작하고, 출력이 발생하거나 실패할 때 push 기반 wake 경로에 의존합니다. -- 실행 중인 명령을 검사해야 할 때는 로그, 상태, 입력, 개입에 `process`를 사용합니다. -- 작업이 더 크면 `sessions_spawn`을 선호합니다. 하위 에이전트 완료는 push 기반이며 요청자에게 자동으로 알립니다. -- 완료를 기다리기 위해 `subagents list` / `sessions_list`를 루프로 폴링하지 마세요. +- 지금 시작되어 백그라운드에서 계속 실행되는 명령에만 `exec` / `process`를 사용합니다. +- 자동 완료 깨우기가 활성화된 경우 명령을 한 번 시작하고, 출력이 발생하거나 실패할 때 푸시 기반 깨우기 경로에 의존합니다. +- 실행 중인 명령을 검사해야 할 때 로그, 상태, 입력 또는 개입에는 `process`를 사용합니다. +- 작업이 더 크다면 `sessions_spawn`을 선호합니다. 하위 에이전트 완료는 푸시 기반이며 요청자에게 자동으로 알립니다. +- 완료를 기다리기 위해 `subagents list` / `sessions_list`를 루프에서 폴링하지 마세요. -실험적 `update_plan` 도구가 활성화된 경우 도구 섹션은 모델에 이를 사소하지 않은 다단계 작업에만 사용하고, 정확히 하나의 `in_progress` 단계를 유지하며, 각 업데이트 후 전체 계획을 반복하지 말라고도 알려줍니다. +실험적 `update_plan` 도구가 활성화된 경우, 도구 사용은 모델에 이를 중요도가 있는 다단계 작업에만 사용하고, 정확히 하나의 `in_progress` 단계만 유지하며, 각 업데이트 뒤에 전체 계획을 반복하지 말라고도 알려줍니다. -시스템 프롬프트의 안전 가드레일은 권고 사항입니다. 이는 모델 동작을 안내하지만 정책을 강제하지는 않습니다. 강제 적용에는 도구 정책, exec 승인, 샌드박싱, 채널 허용 목록을 사용하세요. 운영자는 설계상 이를 비활성화할 수 있습니다. +시스템 프롬프트의 안전 가드레일은 권고 사항입니다. 모델 동작을 안내하지만 정책을 강제하지는 않습니다. 강제 적용에는 도구 정책, exec 승인, 샌드박스, 채널 허용 목록을 사용하세요. 운영자는 설계상 이를 비활성화할 수 있습니다. -네이티브 승인 카드/버튼이 있는 채널에서는 이제 런타임 프롬프트가 에이전트에게 해당 네이티브 승인 UI를 먼저 사용하라고 알려줍니다. 도구 결과가 채팅 승인을 사용할 수 없다고 말하거나 수동 승인이 유일한 경로일 때만 수동 `/approve` 명령을 포함해야 합니다. +네이티브 승인 카드/버튼이 있는 채널에서는 런타임 프롬프트가 이제 에이전트에게 먼저 해당 네이티브 승인 UI에 의존하라고 알려줍니다. 도구 결과가 채팅 승인을 사용할 수 없다고 말하거나 수동 승인이 유일한 경로일 때만 수동 `/approve` 명령을 포함해야 합니다. ## 프롬프트 모드 -OpenClaw는 하위 에이전트용으로 더 작은 시스템 프롬프트를 렌더링할 수 있습니다. 런타임은 각 실행에 `promptMode`를 설정합니다(사용자 대상 설정이 아님). +OpenClaw는 하위 에이전트를 위해 더 작은 시스템 프롬프트를 렌더링할 수 있습니다. 런타임은 각 실행에 대해 `promptMode`를 설정합니다(사용자 대상 설정 아님). - `full`(기본값): 위의 모든 섹션을 포함합니다. -- `minimal`: 하위 에이전트에 사용됩니다. **Skills**, **메모리 회상**, **OpenClaw - 자체 업데이트**, **모델 별칭**, **사용자 ID**, **응답 태그**, - **메시징**, **무음 응답**, **Heartbeats**를 생략합니다. 도구, **안전**, - 워크스페이스, 샌드박스, 현재 날짜 및 시간(알려진 경우), 런타임, 주입된 - 컨텍스트는 계속 사용할 수 있습니다. +- `minimal`: 하위 에이전트에 사용됩니다. **Skills**, **메모리 회상**, **OpenClaw 자체 업데이트**, **모델 별칭**, **사용자 ID**, **응답 태그**, **메시징**, **무음 응답**, **Heartbeats**를 생략합니다. 도구 사용, **안전**, 작업공간, 샌드박스, 현재 날짜 및 시간(알려진 경우), 런타임, 주입된 컨텍스트는 계속 사용할 수 있습니다. - `none`: 기본 ID 줄만 반환합니다. `promptMode=minimal`일 때 추가로 주입된 프롬프트는 **그룹 채팅 컨텍스트** 대신 **하위 에이전트 컨텍스트**로 표시됩니다. -채널 자동 응답 실행의 경우, 직접/그룹 채팅 컨텍스트에 이미 대화별로 해석된 `NO_REPLY` 동작이 포함되어 있으면 OpenClaw는 일반 **무음 응답** 섹션을 생략할 수 있습니다. 이렇게 하면 전역 시스템 프롬프트와 채널 컨텍스트 양쪽에서 토큰 메커니즘이 반복되는 것을 피할 수 있습니다. +채널 자동 응답 실행의 경우, 직접/그룹 채팅 컨텍스트에 이미 해결된 대화별 `NO_REPLY` 동작이 포함되어 있으면 OpenClaw는 일반 **무음 응답** 섹션을 생략할 수 있습니다. 이렇게 하면 전역 시스템 프롬프트와 채널 컨텍스트 양쪽에서 토큰 메커니즘을 반복하지 않습니다. ## 프롬프트 스냅샷 -OpenClaw는 Codex/message-tool 런타임의 정상 경로 프롬프트 스냅샷을 `test/fixtures/agents/prompt-snapshots/happy-path/` 아래에 커밋해 둡니다. 이 스냅샷은 선택된 app-server 스레드/턴 매개변수와, Telegram 직접 대화, Discord 그룹, Heartbeat 턴에 대한 재구성된 모델 바인딩 프롬프트 레이어 스택을 렌더링합니다. 해당 스택에는 Codex의 모델 카탈로그/캐시 형태에서 생성된 고정 Codex `gpt-5.5` 모델 프롬프트 fixture, Codex 정상 경로 권한 개발자 텍스트, OpenClaw 개발자 지침, 사용자 턴 입력, 동적 도구 사양에 대한 참조가 포함됩니다. +OpenClaw는 Codex 런타임 정상 경로에 대한 커밋된 프롬프트 스냅샷을 `test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/` 아래에 유지합니다. 이 스냅샷은 선택된 앱 서버 스레드/턴 매개변수와 Telegram 직접 메시지, Discord 그룹, Heartbeat 턴에 대한 재구성된 모델 바인딩 프롬프트 레이어 스택을 렌더링합니다. 이 스택에는 Codex의 모델 카탈로그/캐시 형태에서 생성된 고정 Codex `gpt-5.5` 모델 프롬프트 픽스처, Codex 정상 경로 권한 개발자 텍스트, OpenClaw 개발자 지침, 사용자 턴 입력, 동적 도구 사양에 대한 참조가 포함됩니다. -고정된 Codex 모델 프롬프트 fixture는 `pnpm prompt:snapshots:sync-codex-model`로 새로 고칩니다. 기본적으로 스크립트는 Codex 런타임 캐시를 `$CODEX_HOME/models_cache.json`, 그다음 `~/.codex/models_cache.json`에서 찾고, 마지막으로 maintainer Codex checkout 관례인 `~/code/codex/codex-rs/models-manager/models.json`으로 폴백합니다. 이러한 소스가 하나도 없으면 명령은 커밋된 fixture를 변경하지 않고 종료됩니다. 특정 `models_cache.json` 또는 `models.json` 파일에서 새로 고치려면 `--catalog `를 전달하세요. +`pnpm prompt:snapshots:sync-codex-model`로 고정 Codex 모델 프롬프트 픽스처를 새로 고치세요. 기본적으로 스크립트는 Codex의 런타임 캐시를 `$CODEX_HOME/models_cache.json`에서 찾고, 그다음 `~/.codex/models_cache.json`을 찾으며, 마지막으로 유지관리자 Codex checkout 규칙인 `~/code/codex/codex-rs/models-manager/models.json`으로 폴백합니다. 이러한 소스가 하나도 없으면 명령은 커밋된 픽스처를 변경하지 않고 종료합니다. 특정 `models_cache.json` 또는 `models.json` 파일에서 새로 고치려면 `--catalog `를 전달하세요. -이 스냅샷은 여전히 원시 OpenAI 요청을 바이트 단위로 그대로 캡처한 것이 아닙니다. OpenClaw가 스레드 및 턴 매개변수를 보낸 뒤, Codex는 Codex 런타임 내부에서 `AGENTS.md`, 환경 컨텍스트, 메모리, 앱/Plugin 지침, 향후 협업 모드 지침 같은 런타임 소유 워크스페이스 컨텍스트를 추가할 수 있습니다. +이 스냅샷은 여전히 바이트 단위의 원시 OpenAI 요청 캡처가 아닙니다. OpenClaw가 스레드와 턴 매개변수를 보낸 뒤 Codex는 런타임 안에서 `AGENTS.md`, 환경 컨텍스트, 메모리, 앱/Plugin 지침, 향후 협업 모드 지침 같은 런타임 소유 작업공간 컨텍스트를 추가할 수 있습니다. -`pnpm prompt:snapshots:gen`으로 다시 생성하고 `pnpm prompt:snapshots:check`로 드리프트를 검증하세요. CI는 추가 경계 shard에서 드리프트 검사를 실행하여 프롬프트 변경과 스냅샷 업데이트가 같은 PR에 함께 포함되도록 합니다. +`pnpm prompt:snapshots:gen`으로 다시 생성하고 `pnpm prompt:snapshots:check`로 드리프트를 검증하세요. CI는 추가 경계 샤드에서 드리프트 검사를 실행하므로 프롬프트 변경과 스냅샷 업데이트가 같은 PR에 함께 유지됩니다. -## 워크스페이스 부트스트랩 주입 +## 작업공간 부트스트랩 주입 -부트스트랩 파일은 다듬어진 뒤 **프로젝트 컨텍스트** 아래에 추가되어, 모델이 명시적으로 읽지 않아도 ID와 프로필 컨텍스트를 볼 수 있게 합니다. +부트스트랩 파일은 명시적인 읽기 없이도 모델이 ID와 프로필 컨텍스트를 볼 수 있도록 **프로젝트 컨텍스트** 아래에 다듬어 추가됩니다. - `AGENTS.md` - `SOUL.md` @@ -111,32 +106,34 @@ OpenClaw는 Codex/message-tool 런타임의 정상 경로 프롬프트 스냅샷 - `IDENTITY.md` - `USER.md` - `HEARTBEAT.md` -- `BOOTSTRAP.md`(완전히 새 워크스페이스에서만) -- `MEMORY.md`가 있는 경우 +- `BOOTSTRAP.md`(완전히 새로운 작업공간에서만) +- 있는 경우 `MEMORY.md` -이 파일들은 파일별 게이트가 적용되지 않는 한 모든 턴에서 **컨텍스트 창에 주입됩니다**. 기본 에이전트에 Heartbeat가 비활성화되어 있거나 `agents.defaults.heartbeat.includeSystemPromptSection`이 false이면 일반 실행에서 `HEARTBEAT.md`는 생략됩니다. 주입되는 파일은 간결하게 유지하세요. 특히 `MEMORY.md`는 시간이 지나며 커질 수 있고 예상보다 높은 컨텍스트 사용량과 더 잦은 Compaction으로 이어질 수 있습니다. +이 모든 파일은 파일별 게이트가 적용되는 경우를 제외하고 매 턴마다 **컨텍스트 창에 주입**됩니다. 기본 에이전트에 대해 Heartbeat가 비활성화되어 있거나 `agents.defaults.heartbeat.includeSystemPromptSection`가 false이면 일반 실행에서 `HEARTBEAT.md`는 생략됩니다. 주입되는 파일은 간결하게 유지하세요. 특히 `MEMORY.md`는 시간이 지나며 커질 수 있고 예상보다 높은 컨텍스트 사용량과 더 잦은 Compaction을 초래할 수 있습니다. + +세션이 네이티브 Codex 하네스에서 실행될 때 Codex는 자체 프로젝트 문서 탐색을 통해 `AGENTS.md`를 로드합니다. OpenClaw는 여전히 나머지 부트스트랩 파일을 확인하고 Codex 구성 지침으로 전달하므로 `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`, `MEMORY.md`는 `AGENTS.md`를 중복하지 않고 같은 작업공간 컨텍스트 역할을 유지합니다. -`memory/*.md` 일일 파일은 일반 부트스트랩 프로젝트 컨텍스트의 일부가 **아닙니다**. 일반 턴에서는 `memory_search` 및 `memory_get` 도구를 통해 필요할 때 접근하므로, 모델이 명시적으로 읽지 않는 한 컨텍스트 창을 차지하지 않습니다. 예외는 단독 `/new` 및 `/reset` 턴입니다. 런타임은 해당 첫 턴에 대해 최근 일일 메모리를 일회성 시작 컨텍스트 블록으로 앞에 붙일 수 있습니다. +`memory/*.md` 일일 파일은 일반적인 부트스트랩 프로젝트 컨텍스트의 일부가 **아닙니다**. 일반 턴에서는 `memory_search` 및 `memory_get` 도구를 통해 필요할 때 접근되므로 모델이 명시적으로 읽지 않는 한 컨텍스트 창에 포함되지 않습니다. 단순 `/new` 및 `/reset` 턴은 예외입니다. 런타임은 해당 첫 턴에 최근 일일 메모리를 일회성 시작 컨텍스트 블록으로 앞에 붙일 수 있습니다. -큰 파일은 마커와 함께 잘립니다. 파일당 최대 크기는 `agents.defaults.bootstrapMaxChars`(기본값: 12000)로 제어됩니다. 파일 전체에 걸쳐 주입되는 부트스트랩 콘텐츠 총량은 `agents.defaults.bootstrapTotalMaxChars`(기본값: 60000)로 제한됩니다. 누락된 파일은 짧은 누락 파일 마커를 주입합니다. 잘림이 발생하면 OpenClaw는 프로젝트 컨텍스트에 경고 블록을 주입할 수 있습니다. 이는 `agents.defaults.bootstrapPromptTruncationWarning`(`off`, `once`, `always`; 기본값: `once`)으로 제어합니다. +큰 파일은 마커와 함께 잘립니다. 파일당 최대 크기는 `agents.defaults.bootstrapMaxChars`가 제어합니다(기본값: 12000). 파일 전체에 걸쳐 주입되는 총 부트스트랩 콘텐츠는 `agents.defaults.bootstrapTotalMaxChars`로 제한됩니다(기본값: 60000). 누락된 파일은 짧은 누락 파일 마커를 주입합니다. 잘림이 발생하면 OpenClaw는 프로젝트 컨텍스트에 경고 블록을 주입할 수 있습니다. 이는 `agents.defaults.bootstrapPromptTruncationWarning`(`off`, `once`, `always`; 기본값: `once`)로 제어합니다. 하위 에이전트 세션은 `AGENTS.md`와 `TOOLS.md`만 주입합니다(하위 에이전트 컨텍스트를 작게 유지하기 위해 다른 부트스트랩 파일은 필터링됩니다). -내부 훅은 `agent:bootstrap`을 통해 이 단계를 가로채 주입되는 부트스트랩 파일을 변경하거나 교체할 수 있습니다(예: `SOUL.md`를 대체 페르소나로 교체). +내부 훅은 `agent:bootstrap`을 통해 이 단계를 가로채 주입되는 부트스트랩 파일을 변경하거나 대체할 수 있습니다(예: `SOUL.md`를 대체 페르소나로 바꾸기). -에이전트가 덜 일반적으로 들리게 만들고 싶다면 [SOUL.md 페르소나 가이드](/ko/concepts/soul)부터 시작하세요. +에이전트가 덜 일반적으로 들리게 만들고 싶다면 [SOUL.md 성격 가이드](/ko/concepts/soul)부터 시작하세요. -주입된 각 파일이 얼마나 기여하는지(원본 vs 주입된 내용, 잘림, 도구 스키마 오버헤드 포함)를 검사하려면 `/context list` 또는 `/context detail`을 사용하세요. [컨텍스트](/ko/concepts/context)를 참조하세요. +각 주입 파일이 얼마나 기여하는지(원본 대비 주입, 잘림, 도구 스키마 오버헤드 포함)를 검사하려면 `/context list` 또는 `/context detail`을 사용하세요. [컨텍스트](/ko/concepts/context)를 참조하세요. ## 시간 처리 -시스템 프롬프트는 사용자 시간대를 알 수 있을 때 전용 **현재 날짜 및 시간** 섹션을 포함합니다. 프롬프트 캐시 안정성을 유지하기 위해 이제 **시간대**만 포함합니다(동적 시계 또는 시간 형식 없음). +시스템 프롬프트는 사용자 시간대가 알려진 경우 전용 **현재 날짜 및 시간** 섹션을 포함합니다. 프롬프트 캐시 안정성을 유지하기 위해 이제 **시간대**만 포함합니다(동적 시계 또는 시간 형식 없음). -에이전트가 현재 시간이 필요할 때는 `session_status`를 사용하세요. 상태 카드에는 타임스탬프 줄이 포함됩니다. 같은 도구로 선택적으로 세션별 모델 오버라이드도 설정할 수 있습니다(`model=default`는 이를 해제함). +에이전트에 현재 시간이 필요할 때는 `session_status`를 사용하세요. 상태 카드에는 타임스탬프 줄이 포함됩니다. 같은 도구는 선택적으로 세션별 모델 재정의를 설정할 수 있습니다(`model=default`는 이를 지웁니다). -다음으로 설정하세요. +다음으로 구성합니다. - `agents.defaults.userTimezone` - `agents.defaults.timeFormat`(`auto` | `12` | `24`) @@ -145,11 +142,11 @@ OpenClaw는 Codex/message-tool 런타임의 정상 경로 프롬프트 스냅샷 ## Skills -적격 Skills가 있으면 OpenClaw는 각 Skill의 **파일 경로**를 포함하는 간결한 **사용 가능한 Skills 목록**(`formatSkillsForPrompt`)을 주입합니다. 프롬프트는 모델에 나열된 위치(워크스페이스, 관리형 또는 번들)에서 SKILL.md를 로드하기 위해 `read`를 사용하라고 지시합니다. 적격 Skills가 없으면 Skills 섹션은 생략됩니다. +적격 Skills가 있으면 OpenClaw는 각 Skill의 **파일 경로**를 포함하는 간결한 **사용 가능한 Skills 목록**(`formatSkillsForPrompt`)을 주입합니다. 프롬프트는 모델에게 나열된 위치(작업공간, 관리형, 번들)의 SKILL.md를 로드하기 위해 `read`를 사용하라고 지시합니다. 적격 Skills가 없으면 Skills 섹션은 생략됩니다. -적격성에는 Skill 메타데이터 게이트, 런타임 환경/설정 검사, `agents.defaults.skills` 또는 `agents.list[].skills`가 설정된 경우 유효한 에이전트 Skill 허용 목록이 포함됩니다. +적격성에는 Skill 메타데이터 게이트, 런타임 환경/구성 검사, `agents.defaults.skills` 또는 `agents.list[].skills`가 구성된 경우 유효 에이전트 Skill 허용 목록이 포함됩니다. -Plugin 번들 Skills는 소유 Plugin이 활성화된 경우에만 적격입니다. 이를 통해 도구 Plugin은 모든 도구 설명에 해당 지침을 직접 포함하지 않고도 더 깊은 운영 가이드를 노출할 수 있습니다. +Plugin 번들 Skills는 해당 Skills를 소유한 Plugin이 활성화된 경우에만 적격입니다. 이를 통해 도구 Plugin은 모든 지침을 모든 도구 설명에 직접 포함하지 않고도 더 깊은 운영 가이드를 노출할 수 있습니다. ``` @@ -161,37 +158,28 @@ Plugin 번들 Skills는 소유 Plugin이 활성화된 경우에만 적격입니 ``` -이렇게 하면 기본 프롬프트를 작게 유지하면서도 대상화된 Skill 사용을 가능하게 합니다. +이렇게 하면 기본 프롬프트를 작게 유지하면서도 대상 지정 Skill 사용을 활성화할 수 있습니다. Skills 목록 예산은 Skills 하위 시스템이 소유합니다. - 전역 기본값: `skills.limits.maxSkillsPromptChars` -- 에이전트별 오버라이드: `agents.list[].skillsLimits.maxSkillsPromptChars` +- 에이전트별 재정의: `agents.list[].skillsLimits.maxSkillsPromptChars` 일반적인 제한된 런타임 발췌는 다른 표면을 사용합니다. - `agents.defaults.contextLimits.*` - `agents.list[].contextLimits.*` -이 분리는 Skills 크기 조정을 `memory_get`, 실시간 도구 결과, Compaction 후 AGENTS.md 새로 고침과 같은 런타임 읽기/주입 크기 조정과 분리합니다. +이 분리는 `memory_get`, 실시간 도구 결과, Compaction 이후 AGENTS.md 새로 고침과 같은 런타임 읽기/주입 크기 산정과 Skills 크기 산정을 분리합니다. ## 문서 -시스템 프롬프트에는 **문서** 섹션이 포함됩니다. 로컬 문서를 사용할 수 있으면 로컬 OpenClaw 문서 디렉터리(Git 체크아웃의 `docs/` 또는 번들된 npm 패키지 문서)를 -가리킵니다. 로컬 문서를 사용할 수 없으면 -[https://docs.openclaw.ai](https://docs.openclaw.ai)로 대체합니다. +시스템 프롬프트에는 **문서** 섹션이 포함됩니다. 로컬 문서가 사용 가능한 경우 로컬 OpenClaw 문서 디렉터리(Git 체크아웃의 `docs/` 또는 번들된 npm 패키지 문서)를 가리킵니다. 로컬 문서를 사용할 수 없는 경우 [https://docs.openclaw.ai](https://docs.openclaw.ai)로 대체됩니다. -동일한 섹션에는 OpenClaw 소스 위치도 포함됩니다. Git 체크아웃은 에이전트가 코드를 직접 검사할 수 있도록 로컬 -소스 루트를 노출합니다. 패키지 설치에는 GitHub -소스 URL이 포함되며, 문서가 불완전하거나 오래된 경우 에이전트에게 그곳에서 소스를 검토하라고 안내합니다. 프롬프트는 또한 공개 문서 미러, 커뮤니티 Discord, 그리고 Skills 탐색을 위한 ClawHub -([https://clawhub.ai](https://clawhub.ai))도 언급합니다. 모델에게 OpenClaw 동작, 명령, 구성 또는 아키텍처에 대해서는 -먼저 문서를 참조하고, 가능하면 `openclaw status`를 직접 실행하라고 지시합니다(접근 권한이 없을 때만 사용자에게 요청). 특히 구성의 경우, 정확한 필드 수준 문서와 제약 조건은 `gateway` 도구 액션 -`config.schema.lookup`을 참조한 다음, 더 폭넓은 안내는 -`docs/gateway/configuration.md` 및 `docs/gateway/configuration-reference.md`를 -참조하도록 에이전트에게 안내합니다. +같은 섹션에는 OpenClaw 소스 위치도 포함됩니다. Git 체크아웃은 에이전트가 코드를 직접 검사할 수 있도록 로컬 소스 루트를 노출합니다. 패키지 설치에는 GitHub 소스 URL이 포함되며, 문서가 불완전하거나 오래된 경우 에이전트에게 그곳에서 소스를 검토하라고 안내합니다. 프롬프트는 또한 공개 문서 미러, 커뮤니티 Discord, Skills 검색을 위한 ClawHub([https://clawhub.ai](https://clawhub.ai))를 언급합니다. 모델에게 OpenClaw 동작, 명령, 구성 또는 아키텍처에 대해서는 먼저 문서를 참조하고, 가능하면 `openclaw status`를 직접 실행하라고 안내합니다(접근 권한이 없을 때만 사용자에게 요청). 특히 구성의 경우 정확한 필드 수준 문서와 제약 조건을 위해 에이전트에게 `gateway` 도구 작업 `config.schema.lookup`을 가리킨 다음, 더 폭넓은 지침을 위해 `docs/gateway/configuration.md` 및 `docs/gateway/configuration-reference.md`를 안내합니다. ## 관련 항목 - [에이전트 런타임](/ko/concepts/agent) -- [에이전트 작업 공간](/ko/concepts/agent-workspace) +- [에이전트 작업 영역](/ko/concepts/agent-workspace) - [컨텍스트 엔진](/ko/concepts/context-engine) diff --git a/docs/ko/nodes/audio.md b/docs/ko/nodes/audio.md index 5af1e9aa6..a45d2b19d 100644 --- a/docs/ko/nodes/audio.md +++ b/docs/ko/nodes/audio.md @@ -1,13 +1,13 @@ --- read_when: - - 오디오 전사 또는 미디어 처리 변경하기 -summary: 수신 오디오/음성 메모가 다운로드되고, 텍스트로 변환되어, 답변에 삽입되는 방식 + - 오디오 전사 또는 미디어 처리 변경 +summary: 수신된 오디오/음성 메모가 다운로드, 전사되어 답장에 삽입되는 방식 title: 오디오 및 음성 메모 x-i18n: - generated_at: "2026-04-30T06:38:39Z" + generated_at: "2026-05-02T23:39:11Z" model: gpt-5.5 provider: openai - source_hash: 35074d79104f767ee252064462202a8ec21ac26f6db25c39e67f31f6b40edeb7 + source_hash: 91cd6951f80c6137061a7d4e82415b0872bc92c6d6ad136273a2e9ad7ec00ac1 source_path: nodes/audio.md workflow: 16 --- @@ -17,36 +17,37 @@ x-i18n: ## 작동하는 기능 - **미디어 이해(오디오)**: 오디오 이해가 활성화되어 있거나 자동 감지되면 OpenClaw는: - 1. 첫 번째 오디오 첨부 파일(로컬 경로 또는 URL)을 찾고, 필요하면 다운로드합니다. + 1. 첫 번째 오디오 첨부 파일(로컬 경로 또는 URL)을 찾고 필요하면 다운로드합니다. 2. 각 모델 항목으로 보내기 전에 `maxBytes`를 적용합니다. - 3. 순서대로 첫 번째 적격 모델 항목(Provider 또는 CLI)을 실행합니다. - 4. 실패하거나 건너뛰면(크기/시간 초과) 다음 항목을 시도합니다. + 3. 순서대로 첫 번째 적격 모델 항목(제공자 또는 CLI)을 실행합니다. + 4. 실패하거나 건너뛰면(크기/시간 초과), 다음 항목을 시도합니다. 5. 성공하면 `Body`를 `[Audio]` 블록으로 바꾸고 `{{Transcript}}`를 설정합니다. - **명령 파싱**: 전사가 성공하면 슬래시 명령이 계속 작동하도록 `CommandBody`/`RawBody`가 전사문으로 설정됩니다. -- **상세 로깅**: `--verbose`에서는 전사가 실행될 때와 본문을 바꿀 때 로그를 남깁니다. +- **상세 로깅**: `--verbose`에서는 전사가 실행될 때와 본문을 교체할 때 로그를 남깁니다. +- **Control UI 받아쓰기**: Chat 작성기는 브라우저에서 녹음한 마이크 클립을 `chat.transcribeAudio`로 보낼 수 있습니다. 해당 Gateway RPC는 클립을 임시 로컬 파일에 쓰고, 동일한 오디오 전사 파이프라인을 실행하고, 초안 텍스트를 브라우저로 반환한 뒤 임시 파일을 삭제합니다. 그 자체로 에이전트 실행을 만들지는 않습니다. ## 자동 감지(기본값) **모델을 구성하지 않았고** `tools.media.audio.enabled`가 `false`로 설정되어 있지 않으면, OpenClaw는 다음 순서로 자동 감지하고 첫 번째로 작동하는 옵션에서 멈춥니다. -1. Provider가 오디오 이해를 지원하는 경우 **활성 답장 모델**. +1. 제공자가 오디오 이해를 지원하는 경우 **활성 응답 모델**. 2. **로컬 CLI**(설치된 경우) - - `sherpa-onnx-offline`(인코더/디코더/조이너/토큰이 있는 `SHERPA_ONNX_MODEL_DIR` 필요) - - `whisper-cli`(`whisper-cpp`에서 제공, `WHISPER_CPP_MODEL` 또는 번들된 tiny 모델 사용) + - `sherpa-onnx-offline`(encoder/decoder/joiner/tokens가 포함된 `SHERPA_ONNX_MODEL_DIR` 필요) + - `whisper-cli`(`whisper-cpp` 제공, `WHISPER_CPP_MODEL` 또는 번들된 tiny 모델 사용) - `whisper`(Python CLI, 모델을 자동으로 다운로드) 3. `read_many_files`를 사용하는 **Gemini CLI**(`gemini`) -4. **Provider 인증** +4. **제공자 인증** - 오디오를 지원하는 구성된 `models.providers.*` 항목을 먼저 시도합니다 - 번들된 폴백 순서: OpenAI → Groq → xAI → Deepgram → Google → SenseAudio → ElevenLabs → Mistral 자동 감지를 비활성화하려면 `tools.media.audio.enabled: false`를 설정하세요. 사용자 지정하려면 `tools.media.audio.models`를 설정하세요. -참고: 바이너리 감지는 macOS/Linux/Windows 전반에서 최선의 방식으로 수행됩니다. CLI가 `PATH`에 있는지 확인하거나(`~`를 확장함), 전체 명령 경로가 있는 명시적 CLI 모델을 설정하세요. +참고: 바이너리 감지는 macOS/Linux/Windows 전반에서 최선의 방식으로 수행됩니다. CLI가 `PATH`에 있는지 확인하거나(`~`는 확장함), 전체 명령 경로가 포함된 명시적 CLI 모델을 설정하세요. ## 구성 예시 -### Provider + CLI 폴백(OpenAI + Whisper CLI) +### 제공자 + CLI 폴백(OpenAI + Whisper CLI) ```json5 { @@ -70,7 +71,7 @@ OpenClaw는 다음 순서로 자동 감지하고 첫 번째로 작동하는 옵 } ``` -### 범위 게이팅이 있는 Provider 전용 +### 범위 게이팅이 있는 제공자 전용 ```json5 { @@ -89,7 +90,7 @@ OpenClaw는 다음 순서로 자동 감지하고 첫 번째로 작동하는 옵 } ``` -### Provider 전용(Deepgram) +### 제공자 전용(Deepgram) ```json5 { @@ -104,7 +105,7 @@ OpenClaw는 다음 순서로 자동 감지하고 첫 번째로 작동하는 옵 } ``` -### Provider 전용(Mistral Voxtral) +### 제공자 전용(Mistral Voxtral) ```json5 { @@ -119,7 +120,7 @@ OpenClaw는 다음 순서로 자동 감지하고 첫 번째로 작동하는 옵 } ``` -### Provider 전용(SenseAudio) +### 제공자 전용(SenseAudio) ```json5 { @@ -134,7 +135,7 @@ OpenClaw는 다음 순서로 자동 감지하고 첫 번째로 작동하는 옵 } ``` -### 전사문을 채팅에 에코(선택 사항) +### 전사문을 채팅에 에코(옵트인) ```json5 { @@ -153,28 +154,28 @@ OpenClaw는 다음 순서로 자동 감지하고 첫 번째로 작동하는 옵 ## 참고 및 제한 사항 -- Provider 인증은 표준 모델 인증 순서(인증 프로필, 환경 변수, `models.providers.*.apiKey`)를 따릅니다. +- 제공자 인증은 표준 모델 인증 순서(인증 프로필, 환경 변수, `models.providers.*.apiKey`)를 따릅니다. - Groq 설정 세부 정보: [Groq](/ko/providers/groq). -- `provider: "deepgram"`을 사용하면 Deepgram이 `DEEPGRAM_API_KEY`를 가져옵니다. +- `provider: "deepgram"`이 사용되면 Deepgram은 `DEEPGRAM_API_KEY`를 가져옵니다. - Deepgram 설정 세부 정보: [Deepgram(오디오 전사)](/ko/providers/deepgram). - Mistral 설정 세부 정보: [Mistral](/ko/providers/mistral). -- `provider: "senseaudio"`를 사용하면 SenseAudio가 `SENSEAUDIO_API_KEY`를 가져옵니다. +- `provider: "senseaudio"`가 사용되면 SenseAudio는 `SENSEAUDIO_API_KEY`를 가져옵니다. - SenseAudio 설정 세부 정보: [SenseAudio](/ko/providers/senseaudio). -- 오디오 Provider는 `tools.media.audio`를 통해 `baseUrl`, `headers`, `providerOptions`를 재정의할 수 있습니다. +- 오디오 제공자는 `tools.media.audio`를 통해 `baseUrl`, `headers`, `providerOptions`를 재정의할 수 있습니다. - 기본 크기 제한은 20MB(`tools.media.audio.maxBytes`)입니다. 크기를 초과한 오디오는 해당 모델에서 건너뛰고 다음 항목을 시도합니다. -- 1024바이트 미만의 작거나 빈 오디오 파일은 Provider/CLI 전사 전에 건너뜁니다. -- 오디오의 기본 `maxChars`는 **설정되지 않음**(전체 전사문)입니다. 출력을 자르려면 `tools.media.audio.maxChars` 또는 항목별 `maxChars`를 설정하세요. +- 1024바이트 미만의 아주 작거나 빈 오디오 파일은 제공자/CLI 전사 전에 건너뜁니다. +- 오디오의 기본 `maxChars`는 **설정되지 않음**(전체 전사문)입니다. 출력을 줄이려면 `tools.media.audio.maxChars` 또는 항목별 `maxChars`를 설정하세요. - OpenAI 자동 기본값은 `gpt-4o-mini-transcribe`입니다. 더 높은 정확도를 원하면 `model: "gpt-4o-transcribe"`를 설정하세요. - 여러 음성 메모를 처리하려면 `tools.media.audio.attachments`를 사용하세요(`mode: "all"` + `maxAttachments`). - 전사문은 템플릿에서 `{{Transcript}}`로 사용할 수 있습니다. -- `tools.media.audio.echoTranscript`는 기본적으로 꺼져 있습니다. 에이전트 처리 전에 시작 채팅으로 전사 확인을 다시 보내려면 활성화하세요. +- `tools.media.audio.echoTranscript`는 기본적으로 꺼져 있습니다. 에이전트 처리 전에 원래 채팅으로 전사 확인을 보내려면 활성화하세요. - `tools.media.audio.echoFormat`은 에코 텍스트를 사용자 지정합니다(플레이스홀더: `{transcript}`). -- CLI stdout은 제한됩니다(5MB). CLI 출력을 간결하게 유지하세요. +- CLI stdout은 제한됩니다(5MB). CLI 출력은 간결하게 유지하세요. - CLI `args`는 로컬 오디오 파일 경로에 `{{MediaPath}}`를 사용해야 합니다. 이전 `audio.transcription.command` 구성의 더 이상 사용되지 않는 `{input}` 플레이스홀더를 마이그레이션하려면 `openclaw doctor --fix`를 실행하세요. ### 프록시 환경 지원 -Provider 기반 오디오 전사는 표준 아웃바운드 프록시 환경 변수를 준수합니다. +제공자 기반 오디오 전사는 표준 아웃바운드 프록시 환경 변수를 따릅니다. - `HTTPS_PROXY` - `HTTP_PROXY` @@ -183,39 +184,39 @@ Provider 기반 오디오 전사는 표준 아웃바운드 프록시 환경 변 - `http_proxy` - `all_proxy` -프록시 환경 변수가 설정되어 있지 않으면 직접 이그레스가 사용됩니다. 프록시 구성이 잘못된 경우 OpenClaw는 경고를 로그에 남기고 직접 가져오기로 폴백합니다. +프록시 환경 변수가 설정되어 있지 않으면 직접 외부 연결을 사용합니다. 프록시 구성이 잘못된 형식이면 OpenClaw는 경고를 기록하고 직접 가져오기로 폴백합니다. -## 그룹에서의 멘션 감지 +## 그룹에서 멘션 감지 -그룹 채팅에 `requireMention: true`가 설정되어 있으면, OpenClaw는 이제 멘션을 확인하기 **전에** 오디오를 전사합니다. 이를 통해 음성 메모에 멘션이 포함된 경우에도 처리할 수 있습니다. +그룹 채팅에 `requireMention: true`가 설정되어 있으면 OpenClaw는 이제 멘션을 확인하기 **전에** 오디오를 전사합니다. 이를 통해 음성 메모에 멘션이 포함되어 있으면 처리할 수 있습니다. **작동 방식:** -1. 음성 메시지에 텍스트 본문이 없고 그룹에서 멘션을 요구하는 경우, OpenClaw는 "사전 확인" 전사를 수행합니다. +1. 음성 메시지에 텍스트 본문이 없고 그룹에 멘션이 필요하면 OpenClaw는 "preflight" 전사를 수행합니다. 2. 전사문에서 멘션 패턴(예: `@BotName`, 이모지 트리거)을 확인합니다. -3. 멘션이 발견되면 메시지는 전체 답장 파이프라인을 진행합니다. +3. 멘션이 발견되면 메시지는 전체 응답 파이프라인을 진행합니다. 4. 음성 메모가 멘션 게이트를 통과할 수 있도록 전사문이 멘션 감지에 사용됩니다. **폴백 동작:** -- 사전 확인 중 전사가 실패하면(시간 초과, API 오류 등) 메시지는 텍스트 전용 멘션 감지를 기준으로 처리됩니다. -- 이렇게 하면 혼합 메시지(텍스트 + 오디오)가 잘못 누락되지 않습니다. +- preflight 중 전사가 실패하면(시간 초과, API 오류 등), 메시지는 텍스트 전용 멘션 감지를 기준으로 처리됩니다. +- 이렇게 하면 혼합 메시지(텍스트 + 오디오)가 잘못 삭제되지 않습니다. **Telegram 그룹/주제별 옵트아웃:** -- 해당 그룹의 사전 확인 전사문 멘션 검사를 건너뛰려면 `channels.telegram.groups..disableAudioPreflight: true`를 설정하세요. +- 해당 그룹의 preflight 전사문 멘션 확인을 건너뛰려면 `channels.telegram.groups..disableAudioPreflight: true`를 설정하세요. - 주제별로 재정의하려면 `channels.telegram.groups..topics..disableAudioPreflight`를 설정하세요(`true`는 건너뛰기, `false`는 강제 활성화). -- 기본값은 `false`입니다(멘션 게이트 조건이 일치하면 사전 확인 활성화). +- 기본값은 `false`입니다(멘션 게이트 조건이 일치하면 preflight 활성화). -**예시:** 사용자가 `requireMention: true`가 설정된 Telegram 그룹에서 "Hey @Claude, what's the weather?"라고 말하는 음성 메모를 보냅니다. 음성 메모가 전사되고, 멘션이 감지되며, 에이전트가 답장합니다. +**예시:** 사용자가 `requireMention: true`가 설정된 Telegram 그룹에서 "Hey @Claude, what's the weather?"라고 말하는 음성 메모를 보냅니다. 음성 메모가 전사되고, 멘션이 감지되며, 에이전트가 응답합니다. ## 주의 사항 -- 범위 규칙은 첫 번째 일치가 우선합니다. `chatType`은 `direct`, `group`, `room`으로 정규화됩니다. +- 범위 규칙은 첫 번째 일치 항목이 우선합니다. `chatType`은 `direct`, `group`, `room` 중 하나로 정규화됩니다. - CLI가 0으로 종료되고 일반 텍스트를 출력하는지 확인하세요. JSON은 `jq -r .text`를 통해 가공해야 합니다. -- `parakeet-mlx`의 경우 `--output-dir`을 전달하면, `--output-format`이 `txt`이거나 생략되었을 때 OpenClaw는 `/.txt`를 읽습니다. `txt`가 아닌 출력 형식은 stdout 파싱으로 폴백합니다. -- 답장 큐가 막히지 않도록 시간 초과(`timeoutSeconds`, 기본값 60초)를 적절하게 유지하세요. -- 사전 확인 전사는 멘션 감지를 위해 **첫 번째** 오디오 첨부 파일만 처리합니다. 추가 오디오는 기본 미디어 이해 단계에서 처리됩니다. +- `parakeet-mlx`의 경우 `--output-dir`를 전달하면 `--output-format`이 `txt`이거나 생략되었을 때 OpenClaw는 `/.txt`를 읽습니다. `txt`가 아닌 출력 형식은 stdout 파싱으로 폴백합니다. +- 응답 대기열이 막히지 않도록 시간 초과(`timeoutSeconds`, 기본값 60초)를 적절하게 유지하세요. +- preflight 전사는 멘션 감지를 위해 **첫 번째** 오디오 첨부 파일만 처리합니다. 추가 오디오는 기본 미디어 이해 단계에서 처리됩니다. ## 관련 항목 diff --git a/docs/ko/plugins/codex-harness.md b/docs/ko/plugins/codex-harness.md index 373c1cad7..d474a17e3 100644 --- a/docs/ko/plugins/codex-harness.md +++ b/docs/ko/plugins/codex-harness.md @@ -3,38 +3,38 @@ read_when: - 번들로 제공되는 Codex app-server 하네스를 사용하려는 경우 - Codex 하네스 구성 예제가 필요합니다 - Codex 전용 배포가 PI로 폴백하지 않고 실패하도록 하려는 경우 -summary: 번들로 제공되는 Codex app-server 하니스를 통해 OpenClaw 내장 에이전트 턴 실행 +summary: 번들된 Codex app-server 하네스를 통해 OpenClaw 임베디드 에이전트 턴 실행 title: Codex 하네스 x-i18n: - generated_at: "2026-05-02T20:57:22Z" + generated_at: "2026-05-02T23:39:30Z" model: gpt-5.5 provider: openai - source_hash: 107f9fc0a3e8ad6a4790fc9eb68276c81d299236f11293014d2ab9bf6e235133 + source_hash: 8ffa0cbb28422b2ed8d7c0eef6ee0222072c523d170b4b33597bb37bd3fa9700 source_path: plugins/codex-harness.md workflow: 16 --- -번들된 `codex` Plugin은 OpenClaw가 내장 PI 하네스 대신 Codex app-server를 통해 임베디드 에이전트 턴을 실행할 수 있게 합니다. +번들된 `codex` Plugin은 OpenClaw가 기본 제공 PI 하네스 대신 Codex 앱 서버를 통해 임베디드 에이전트 턴을 실행할 수 있게 합니다. -저수준 에이전트 세션을 Codex가 담당하게 하려는 경우 사용하세요. 모델 검색, 네이티브 스레드 재개, 네이티브 Compaction, app-server 실행이 여기에 포함됩니다. OpenClaw는 여전히 채팅 채널, 세션 파일, 모델 선택, 도구, 승인, 미디어 전달, 표시되는 트랜스크립트 미러를 담당합니다. +Codex가 저수준 에이전트 세션을 소유하게 하고 싶을 때 사용하세요: 모델 탐색, 네이티브 스레드 재개, 네이티브 Compaction, 앱 서버 실행. OpenClaw는 여전히 채팅 채널, 세션 파일, 모델 선택, 도구, 승인, 미디어 전달, 표시되는 transcript 미러를 소유합니다. -소스 채팅 턴이 Codex 하네스를 통해 실행될 때 배포에서 `messages.visibleReplies`를 명시적으로 구성하지 않았다면 표시되는 응답은 기본적으로 OpenClaw `message` 도구를 사용합니다. 에이전트는 여전히 Codex 턴을 비공개로 완료할 수 있으며, `message(action="send")`를 호출할 때만 채널에 게시합니다. 기존 자동 전달 경로에서 직접 채팅 최종 응답을 유지하려면 `messages.visibleReplies: "automatic"`을 설정하세요. +소스 채팅 턴이 Codex 하네스를 통해 실행될 때 배포가 `messages.visibleReplies`를 명시적으로 구성하지 않았다면 표시되는 답장은 기본적으로 OpenClaw `message` 도구를 사용합니다. 에이전트는 여전히 Codex 턴을 비공개로 완료할 수 있습니다. `message(action="send")`를 호출할 때만 채널에 게시합니다. 직접 채팅 최종 답장을 기존 자동 전달 경로에 유지하려면 `messages.visibleReplies: "automatic"`을 설정하세요. -Codex Heartbeat 턴도 기본적으로 `heartbeat_respond` 도구를 받으므로, 에이전트는 최종 텍스트에 해당 제어 흐름을 인코딩하지 않고도 깨우기를 조용히 유지할지 알림을 보낼지 기록할 수 있습니다. +Codex Heartbeat 턴도 기본적으로 `heartbeat_respond` 도구를 받으므로, 에이전트는 최종 텍스트에 해당 제어 흐름을 인코딩하지 않고도 wake를 조용히 유지할지 또는 알림을 보낼지 기록할 수 있습니다. -방향을 잡으려는 중이라면 [에이전트 런타임](/ko/concepts/agent-runtimes)부터 시작하세요. 짧게 말하면 `openai/gpt-5.5`는 모델 참조이고, `codex`는 런타임이며, Telegram, Discord, Slack 또는 다른 채널은 통신 표면으로 남습니다. +방향을 잡으려는 중이라면 [에이전트 런타임](/ko/concepts/agent-runtimes)부터 시작하세요. 짧게 말하면: `openai/gpt-5.5`는 모델 참조이고, `codex`는 런타임이며, Telegram, Discord, Slack 또는 다른 채널은 통신 표면으로 남습니다. ## 빠른 구성 -"OpenClaw 안의 Codex"를 원하는 대부분의 사용자는 이 경로를 원합니다. ChatGPT/Codex 구독으로 로그인한 다음, 네이티브 Codex app-server 런타임을 통해 임베디드 에이전트 턴을 실행합니다. 모델 참조는 여전히 `openai/gpt-*`로 정식 유지됩니다. 구독 인증은 `openai-codex/*` 모델 접두사가 아니라 Codex 계정/프로필에서 옵니다. +"OpenClaw 안의 Codex"를 원하는 대부분의 사용자는 이 경로를 원합니다: ChatGPT/Codex 구독으로 로그인한 다음, 네이티브 Codex 앱 서버 런타임을 통해 임베디드 에이전트 턴을 실행합니다. 모델 참조는 여전히 `openai/gpt-*`로 정규 상태를 유지합니다. 구독 인증은 `openai-codex/*` 모델 접두사가 아니라 Codex 계정/프로필에서 옵니다. -아직 하지 않았다면 먼저 Codex OAuth로 로그인하세요. +아직 로그인하지 않았다면 먼저 Codex OAuth로 로그인하세요: ```bash openclaw models auth login --provider openai-codex ``` -그런 다음 번들된 `codex` Plugin을 활성화하고 Codex 런타임을 강제하세요. +그런 다음 번들된 `codex` Plugin을 활성화하고 Codex 런타임을 강제하세요: ```json5 { @@ -57,7 +57,7 @@ openclaw models auth login --provider openai-codex } ``` -구성에서 `plugins.allow`를 사용한다면 거기에도 `codex`를 포함하세요. +구성이 `plugins.allow`를 사용한다면 그곳에도 `codex`를 포함하세요: ```json5 { @@ -72,104 +72,104 @@ openclaw models auth login --provider openai-codex } ``` -네이티브 Codex 런타임을 의미할 때는 `openai-codex/gpt-*`를 사용하지 마세요. 그 접두사는 명시적인 "PI를 통한 Codex OAuth" 경로입니다. 구성 변경은 새 세션 또는 재설정된 세션에 적용됩니다. 기존 세션은 기록된 런타임을 유지합니다. +네이티브 Codex 런타임을 의미할 때는 `openai-codex/gpt-*`를 사용하지 마세요. 해당 접두사는 명시적인 "PI를 통한 Codex OAuth" 경로입니다. 구성 변경은 새 세션 또는 재설정된 세션에 적용됩니다. 기존 세션은 기록된 런타임을 유지합니다. ## 이 Plugin이 변경하는 것 -번들된 `codex` Plugin은 여러 개별 기능을 제공합니다. +번들된 `codex` Plugin은 여러 별도 기능을 제공합니다: -| 기능 | 사용 방법 | 수행하는 작업 | +| 기능 | 사용 방법 | 수행 작업 | | --------------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------- | -| 네이티브 임베디드 런타임 | `agentRuntime.id: "codex"` | OpenClaw 임베디드 에이전트 턴을 Codex app-server를 통해 실행합니다. | -| 네이티브 채팅 제어 명령 | `/codex bind`, `/codex resume`, `/codex steer`, ... | 메시징 대화에서 Codex app-server 스레드를 바인딩하고 제어합니다. | -| Codex app-server 제공자/카탈로그 | `codex` 내부, 하네스를 통해 노출됨 | 런타임이 app-server 모델을 검색하고 검증할 수 있게 합니다. | -| Codex 미디어 이해 경로 | `codex/*` 이미지 모델 호환성 경로 | 지원되는 이미지 이해 모델에 대해 제한된 Codex app-server 턴을 실행합니다. | -| 네이티브 훅 릴레이 | Codex 네이티브 이벤트 주변의 Plugin 훅 | OpenClaw가 지원되는 Codex 네이티브 도구/최종화 이벤트를 관찰/차단할 수 있게 합니다. | +| 네이티브 임베디드 런타임 | `agentRuntime.id: "codex"` | OpenClaw 임베디드 에이전트 턴을 Codex 앱 서버를 통해 실행합니다. | +| 네이티브 채팅 제어 명령 | `/codex bind`, `/codex resume`, `/codex steer`, ... | 메시징 대화에서 Codex 앱 서버 스레드를 바인딩하고 제어합니다. | +| Codex 앱 서버 제공자/카탈로그 | `codex` internals, 하네스를 통해 노출됨 | 런타임이 앱 서버 모델을 탐색하고 검증할 수 있게 합니다. | +| Codex 미디어 이해 경로 | `codex/*` image-model compatibility paths | 지원되는 이미지 이해 모델에 대해 제한된 Codex 앱 서버 턴을 실행합니다. | +| 네이티브 훅 릴레이 | Codex 네이티브 이벤트 주변의 Plugin 훅 | OpenClaw가 지원되는 Codex 네이티브 도구/마무리 이벤트를 관찰/차단할 수 있게 합니다. | -Plugin을 활성화하면 이러한 기능을 사용할 수 있습니다. 다음을 수행하지는 않습니다. +Plugin을 활성화하면 이러한 기능을 사용할 수 있습니다. 이것은 다음을 **하지 않습니다**: -- 모든 OpenAI 모델에 Codex 사용 시작 +- 모든 OpenAI 모델에 대해 Codex 사용 시작 - `openai-codex/*` 모델 참조를 네이티브 런타임으로 변환 -- ACP/acpx를 기본 Codex 경로로 설정 -- 이미 PI 런타임을 기록한 기존 세션을 핫스위치 +- ACP/acpx를 기본 Codex 경로로 만들기 +- 이미 PI 런타임을 기록한 기존 세션을 핫 스위치 - OpenClaw 채널 전달, 세션 파일, 인증 프로필 저장소 또는 메시지 라우팅 대체 -같은 Plugin은 네이티브 `/codex` 채팅 제어 명령 표면도 소유합니다. Plugin이 활성화되어 있고 사용자가 채팅에서 Codex 스레드를 바인딩, 재개, 조정, 중지 또는 검사하라고 요청하면, 에이전트는 ACP보다 `/codex ...`를 선호해야 합니다. ACP는 사용자가 ACP/acpx를 요청하거나 ACP Codex 어댑터를 테스트하는 경우의 명시적 폴백으로 남습니다. +동일한 Plugin은 네이티브 `/codex` 채팅 제어 명령 표면도 소유합니다. Plugin이 활성화되어 있고 사용자가 채팅에서 Codex 스레드를 바인딩, 재개, 조정, 중지 또는 검사하라고 요청하면 에이전트는 ACP보다 `/codex ...`를 선호해야 합니다. ACP는 사용자가 ACP/acpx를 요청하거나 ACP Codex 어댑터를 테스트할 때 명시적인 폴백으로 남습니다. -네이티브 Codex 턴은 OpenClaw Plugin 훅을 공개 호환성 계층으로 유지합니다. 이것들은 Codex `hooks.json` 명령 훅이 아니라 프로세스 내 OpenClaw 훅입니다. +네이티브 Codex 턴은 OpenClaw Plugin 훅을 공개 호환성 계층으로 유지합니다. 이것들은 프로세스 내 OpenClaw 훅이며, Codex `hooks.json` 명령 훅이 아닙니다: - `before_prompt_build` - `before_compaction`, `after_compaction` - `llm_input`, `llm_output` - `before_tool_call`, `after_tool_call` -- `before_message_write` for mirrored transcript records -- `before_agent_finalize` through Codex `Stop` relay +- mirrored transcript 레코드용 `before_message_write` +- Codex `Stop` 릴레이를 통한 `before_agent_finalize` - `agent_end` -Plugin은 런타임 중립 도구 결과 미들웨어도 등록하여, OpenClaw가 도구를 실행한 뒤 결과가 Codex에 반환되기 전에 OpenClaw 동적 도구 결과를 다시 쓸 수 있습니다. 이는 OpenClaw가 소유한 트랜스크립트 도구 결과 쓰기를 변환하는 공개 `tool_result_persist` Plugin 훅과 별개입니다. +Plugin은 런타임 중립적인 도구 결과 미들웨어도 등록하여, OpenClaw가 도구를 실행한 뒤 결과가 Codex에 반환되기 전에 OpenClaw 동적 도구 결과를 다시 쓸 수 있습니다. 이것은 OpenClaw가 소유한 transcript 도구 결과 쓰기를 변환하는 공개 `tool_result_persist` Plugin 훅과 별개입니다. -Plugin 훅 의미 자체는 [Plugin 훅](/ko/plugins/hooks) 및 [Plugin 가드 동작](/ko/tools/plugin)을 참조하세요. +Plugin 훅 의미 자체는 [Plugin 훅](/ko/plugins/hooks) 및 [Plugin 가드 동작](/ko/tools/plugin)을 참고하세요. -하네스는 기본적으로 꺼져 있습니다. 새 구성은 OpenAI 모델 참조를 `openai/gpt-*`로 정식 유지하고, 네이티브 app-server 실행을 원할 때 `agentRuntime.id: "codex"` 또는 `OPENCLAW_AGENT_RUNTIME=codex`를 명시적으로 강제해야 합니다. 기존 `codex/*` 모델 참조는 호환성을 위해 여전히 하네스를 자동 선택하지만, 런타임 기반 기존 제공자 접두사는 일반 모델/제공자 선택지로 표시되지 않습니다. +하네스는 기본적으로 꺼져 있습니다. 새 구성은 OpenAI 모델 참조를 `openai/gpt-*`로 정규 유지하고 네이티브 앱 서버 실행을 원할 때 `agentRuntime.id: "codex"` 또는 `OPENCLAW_AGENT_RUNTIME=codex`를 명시적으로 강제해야 합니다. 기존 `codex/*` 모델 참조는 호환성을 위해 여전히 하네스를 자동 선택하지만, 런타임 기반 기존 제공자 접두사는 일반 모델/제공자 선택지로 표시되지 않습니다. -`codex` Plugin이 활성화되어 있지만 기본 모델이 여전히 `openai-codex/*`라면, `openclaw doctor`는 경로를 변경하는 대신 경고합니다. 이는 의도된 동작입니다. `openai-codex/*`는 PI Codex OAuth/구독 경로로 남아 있으며, 네이티브 app-server 실행은 명시적인 런타임 선택으로 유지됩니다. +`codex` Plugin이 활성화되어 있지만 기본 모델이 여전히 `openai-codex/*`라면 `openclaw doctor`는 경로를 변경하는 대신 경고합니다. 이는 의도된 동작입니다: `openai-codex/*`는 PI Codex OAuth/구독 경로로 남고, 네이티브 앱 서버 실행은 명시적인 런타임 선택으로 유지됩니다. ## 경로 맵 -구성을 변경하기 전에 이 표를 사용하세요. +구성을 변경하기 전에 이 표를 사용하세요: -| 원하는 동작 | 모델 참조 | 런타임 구성 | 인증/프로필 경로 | 예상 상태 레이블 | -| ----------------------------------------------------- | -------------------------- | -------------------------------------- | --------------------------- | ------------------------------ | -| 네이티브 Codex 런타임을 사용하는 ChatGPT/Codex 구독 | `openai/gpt-*` | `agentRuntime.id: "codex"` | Codex OAuth 또는 Codex 계정 | `Runtime: OpenAI Codex` | -| 일반 OpenClaw 러너를 통한 OpenAI API | `openai/gpt-*` | 생략 또는 `runtime: "pi"` | OpenAI API 키 | `Runtime: OpenClaw Pi Default` | -| PI를 통한 ChatGPT/Codex 구독 | `openai-codex/gpt-*` | 생략 또는 `runtime: "pi"` | OpenAI Codex OAuth 제공자 | `Runtime: OpenClaw Pi Default` | -| 보수적인 자동 모드를 사용하는 혼합 제공자 | 제공자별 참조 | `agentRuntime.id: "auto"` | 선택한 제공자별 | 선택된 런타임에 따라 다름 | -| 명시적 Codex ACP 어댑터 세션 | ACP 프롬프트/모델에 따라 다름 | `sessions_spawn` with `runtime: "acp"` | ACP 백엔드 인증 | ACP 작업/세션 상태 | +| 원하는 동작 | 모델 참조 | 런타임 구성 | 인증/프로필 경로 | 예상 상태 레이블 | +| ---------------------------------------------------- | -------------------------- | -------------------------------------- | ---------------------------- | ------------------------------ | +| 네이티브 Codex 런타임과 ChatGPT/Codex 구독 | `openai/gpt-*` | `agentRuntime.id: "codex"` | Codex OAuth 또는 Codex 계정 | `Runtime: OpenAI Codex` | +| 일반 OpenClaw 러너를 통한 OpenAI API | `openai/gpt-*` | 생략 또는 `runtime: "pi"` | OpenAI API 키 | `Runtime: OpenClaw Pi Default` | +| PI를 통한 ChatGPT/Codex 구독 | `openai-codex/gpt-*` | 생략 또는 `runtime: "pi"` | OpenAI Codex OAuth 제공자 | `Runtime: OpenClaw Pi Default` | +| 보수적 자동 모드의 혼합 제공자 | 제공자별 참조 | `agentRuntime.id: "auto"` | 선택한 제공자별 | 선택한 런타임에 따라 다름 | +| 명시적 Codex ACP 어댑터 세션 | ACP 프롬프트/모델 종속 | `sessions_spawn` with `runtime: "acp"` | ACP 백엔드 인증 | ACP 작업/세션 상태 | -중요한 구분은 제공자와 런타임입니다. +중요한 구분은 제공자와 런타임입니다: - `openai-codex/*`는 "PI가 어떤 제공자/인증 경로를 사용해야 하는가?"에 답합니다. - `agentRuntime.id: "codex"`는 "이 임베디드 턴을 어떤 루프가 실행해야 하는가?"에 답합니다. -- `/codex ...`는 "이 채팅이 어떤 네이티브 Codex 대화에 바인딩되거나 어떤 대화를 제어해야 하는가?"에 답합니다. -- ACP는 "acpx가 어떤 외부 하네스 프로세스를 시작해야 하는가?"에 답합니다. +- `/codex ...`는 "이 채팅이 어떤 네이티브 Codex 대화에 바인딩되거나 이를 제어해야 하는가?"에 답합니다. +- ACP는 "acpx가 어떤 외부 하네스 프로세스를 실행해야 하는가?"에 답합니다. ## 올바른 모델 접두사 선택 -OpenAI 계열 경로는 접두사별로 다릅니다. 일반적인 구독 및 네이티브 Codex 런타임 설정의 경우 `agentRuntime.id: "codex"`와 함께 `openai/*`를 사용하세요. 의도적으로 PI를 통한 Codex OAuth를 원할 때만 `openai-codex/*`를 사용하세요. +OpenAI 계열 경로는 접두사별로 다릅니다. 일반적인 구독과 네이티브 Codex 런타임 설정의 경우 `agentRuntime.id: "codex"`와 함께 `openai/*`를 사용하세요. PI를 통한 Codex OAuth를 의도적으로 원할 때만 `openai-codex/*`를 사용하세요: | 모델 참조 | 런타임 경로 | 사용 시점 | -| --------------------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------- | -| `openai/gpt-5.4` | OpenClaw/PI 배관을 통한 OpenAI 제공자 | `OPENAI_API_KEY`로 현재 직접 OpenAI Platform API 액세스를 원할 때. | -| `openai-codex/gpt-5.5` | OpenClaw/PI를 통한 OpenAI Codex OAuth | 기본 PI 러너로 ChatGPT/Codex 구독 인증을 원할 때. | -| `openai/gpt-5.5` + `agentRuntime.id: "codex"` | Codex app-server 하네스 | 네이티브 Codex 실행으로 ChatGPT/Codex 구독 인증을 원할 때. | +| --------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------- | +| `openai/gpt-5.4` | OpenClaw/PI 배관을 통한 OpenAI 제공자 | `OPENAI_API_KEY`로 현재 직접 OpenAI Platform API 액세스를 원할 때. | +| `openai-codex/gpt-5.5` | OpenClaw/PI를 통한 OpenAI Codex OAuth | 기본 PI 러너와 함께 ChatGPT/Codex 구독 인증을 원할 때. | +| `openai/gpt-5.5` + `agentRuntime.id: "codex"` | Codex 앱 서버 하네스 | 네이티브 Codex 실행과 함께 ChatGPT/Codex 구독 인증을 원할 때. | -GPT-5.5는 계정에서 노출하는 경우 직접 OpenAI API 키 경로와 Codex 구독 경로 모두에 나타날 수 있습니다. 네이티브 Codex 런타임에는 Codex app-server 하네스와 함께 `openai/gpt-5.5`를 사용하고, PI OAuth에는 `openai-codex/gpt-5.5`를 사용하며, 직접 API 키 트래픽에는 Codex 런타임 오버라이드 없이 `openai/gpt-5.5`를 사용하세요. +계정에서 노출하는 경우 GPT-5.5는 직접 OpenAI API 키 경로와 Codex 구독 경로 모두에 나타날 수 있습니다. 네이티브 Codex 런타임에는 Codex 앱 서버 하네스와 함께 `openai/gpt-5.5`를 사용하고, PI OAuth에는 `openai-codex/gpt-5.5`를 사용하거나, 직접 API 키 트래픽에는 Codex 런타임 재정의 없이 `openai/gpt-5.5`를 사용하세요. -기존 `codex/gpt-*` 참조는 호환성 별칭으로 계속 허용됩니다. Doctor 호환성 마이그레이션은 기존 기본 런타임 참조를 정식 모델 참조로 다시 쓰고 런타임 정책을 별도로 기록하지만, 폴백 전용 기존 참조는 런타임이 전체 에이전트 컨테이너에 대해 구성되므로 변경하지 않습니다. 새 PI Codex OAuth 구성은 `openai-codex/gpt-*`를 사용해야 하며, 새 네이티브 app-server 하네스 구성은 `agentRuntime.id: "codex"`와 함께 `openai/gpt-*`를 사용해야 합니다. +기존 `codex/gpt-*` 참조는 호환성 별칭으로 계속 허용됩니다. Doctor 호환성 마이그레이션은 기존 기본 런타임 참조를 정규 모델 참조로 다시 쓰고 런타임 정책을 별도로 기록하지만, 폴백 전용 기존 참조는 그대로 둡니다. 런타임이 전체 에이전트 컨테이너에 대해 구성되기 때문입니다. 새 PI Codex OAuth 구성은 `openai-codex/gpt-*`를 사용해야 하며, 새 네이티브 앱 서버 하네스 구성은 `openai/gpt-*`와 `agentRuntime.id: "codex"`를 함께 사용해야 합니다. -`agents.defaults.imageModel`도 같은 접두사 구분을 따릅니다. 이미지 이해가 OpenAI Codex OAuth 제공자 경로를 통해 실행되어야 하면 `openai-codex/gpt-*`를 사용하세요. 이미지 이해가 제한된 Codex app-server 턴을 통해 실행되어야 하면 `codex/gpt-*`를 사용하세요. Codex app-server 모델은 이미지 입력 지원을 알려야 합니다. 텍스트 전용 Codex 모델은 미디어 턴이 시작되기 전에 실패합니다. +`agents.defaults.imageModel`도 동일한 접두사 구분을 따릅니다. 이미지 이해가 OpenAI Codex OAuth 제공자 경로를 통해 실행되어야 하면 `openai-codex/gpt-*`를 사용하세요. 이미지 이해가 제한된 Codex 앱 서버 턴을 통해 실행되어야 하면 `codex/gpt-*`를 사용하세요. Codex 앱 서버 모델은 이미지 입력 지원을 광고해야 합니다. 텍스트 전용 Codex 모델은 미디어 턴이 시작되기 전에 실패합니다. -현재 세션의 유효 하네스를 확인하려면 `/status`를 사용하세요. 선택이 예상과 다르다면 `agents/harness` 하위 시스템의 디버그 로깅을 활성화하고 Gateway의 구조화된 `agent harness selected` 기록을 검사하세요. 여기에는 선택된 하네스 ID, 선택 이유, 런타임/폴백 정책, 그리고 `auto` 모드에서는 각 Plugin 후보의 지원 결과가 포함됩니다. +현재 세션의 유효 하네스를 확인하려면 `/status`를 사용하세요. 선택이 예상과 다르다면 `agents/harness` 하위 시스템에 대해 디버그 로깅을 활성화하고 gateway의 구조화된 `agent harness selected` 레코드를 검사하세요. 여기에는 선택된 하네스 id, 선택 이유, 런타임/폴백 정책, 그리고 `auto` 모드에서는 각 Plugin 후보의 지원 결과가 포함됩니다. ### Doctor 경고의 의미 -`openclaw doctor`는 다음이 모두 참일 때 경고합니다. +다음이 모두 참일 때 `openclaw doctor`가 경고합니다: - 번들된 `codex` Plugin이 활성화되었거나 허용됨 - 에이전트의 기본 모델이 `openai-codex/*` - 해당 에이전트의 유효 런타임이 `codex`가 아님 -이 경고는 사용자가 흔히 "Codex Plugin 활성화"가 "네이티브 Codex app-server 런타임"을 의미한다고 기대하기 때문에 존재합니다. OpenClaw는 그런 도약을 하지 않습니다. 이 경고의 의미는 다음과 같습니다. +이 경고는 사용자가 "Codex Plugin 활성화"가 "네이티브 Codex 앱 서버 런타임"을 의미한다고 기대하는 경우가 많기 때문에 존재합니다. OpenClaw는 그 비약을 하지 않습니다. 이 경고의 의미는 다음과 같습니다: -- PI를 통한 ChatGPT/Codex OAuth를 의도했다면 **변경이 필요하지 않습니다**. -- 네이티브 app-server 실행을 의도했다면 모델을 `openai/`로 변경하고 `agentRuntime.id: "codex"`를 설정하세요. +- PI를 통한 ChatGPT/Codex OAuth를 의도했다면 **변경이 필요 없습니다**. +- 네이티브 앱 서버 실행을 의도했다면 모델을 `openai/`로 변경하고 `agentRuntime.id: "codex"`를 설정하세요. - 런타임 변경 후에도 기존 세션에는 여전히 `/new` 또는 `/reset`이 필요합니다. 세션 런타임 핀은 고정적이기 때문입니다. -하네스 선택은 실시간 세션 제어가 아닙니다. 임베디드 턴이 실행될 때 OpenClaw는 해당 세션에 선택된 하네스 ID를 기록하고, 같은 세션 ID의 이후 턴에도 계속 사용합니다. 향후 세션에서 다른 하네스를 사용하려면 `agentRuntime` 구성 또는 `OPENCLAW_AGENT_RUNTIME`을 변경하세요. 기존 대화를 PI와 Codex 사이에서 전환하기 전에는 `/new` 또는 `/reset`을 사용해 새 세션을 시작하세요. 이렇게 하면 하나의 트랜스크립트를 호환되지 않는 두 네이티브 세션 시스템을 통해 재생하는 일을 피할 수 있습니다. +하네스 선택은 실시간 세션 제어가 아닙니다. 임베디드 턴이 실행될 때 OpenClaw는 해당 세션에 선택된 하네스 id를 기록하고 같은 세션 id의 이후 턴에도 계속 사용합니다. 향후 세션이 다른 하네스를 사용하게 하려면 `agentRuntime` 구성 또는 `OPENCLAW_AGENT_RUNTIME`을 변경하세요. 기존 대화를 PI와 Codex 사이에서 전환하기 전에 `/new` 또는 `/reset`을 사용해 새 세션을 시작하세요. 이렇게 하면 하나의 transcript를 호환되지 않는 두 네이티브 세션 시스템을 통해 재생하는 일을 피할 수 있습니다. -하네스 핀이 생기기 전에 생성된 기존 세션은 트랜스크립트 기록이 있으면 PI에 고정된 것으로 처리됩니다. 구성을 변경한 뒤 해당 대화를 Codex로 전환하려면 `/new` 또는 `/reset`을 사용하세요. +하네스 핀이 생기기 전에 생성된 기존 세션은 transcript 기록이 있으면 PI에 고정된 것으로 취급됩니다. 구성을 변경한 뒤 해당 대화를 Codex로 전환하려면 `/new` 또는 `/reset`을 사용하세요. -`/status`는 적용 중인 모델 런타임을 표시합니다. 기본 PI 하네스는 +`/status`는 유효한 모델 런타임을 표시합니다. 기본 PI 하네스는 `Runtime: OpenClaw Pi Default`로 표시되고, Codex app-server 하네스는 `Runtime: OpenAI Codex`로 표시됩니다. @@ -177,37 +177,50 @@ GPT-5.5는 계정에서 노출하는 경우 직접 OpenAI API 키 경로와 Code - 번들된 `codex` Plugin을 사용할 수 있는 OpenClaw. - Codex app-server `0.125.0` 이상. 번들된 Plugin은 기본적으로 호환되는 - Codex app-server 바이너리를 관리하므로, `PATH`의 로컬 `codex` 명령은 - 일반적인 하네스 시작에 영향을 주지 않습니다. -- app-server 프로세스 또는 OpenClaw의 Codex 인증 브리지에서 사용할 수 있는 Codex 인증. - 로컬 app-server 실행은 각 agent마다 OpenClaw가 관리하는 Codex 홈과 - 격리된 하위 `HOME`을 사용하므로, 기본적으로 개인 - `~/.codex` 계정, Skills, Plugin, 구성, 스레드 상태 또는 네이티브 + Codex app-server 바이너리를 관리하므로 `PATH`의 로컬 `codex` 명령은 + 일반 하네스 시작에 영향을 주지 않습니다. +- app-server 프로세스 또는 OpenClaw의 Codex 인증 브리지에서 Codex 인증 사용 가능. + 로컬 app-server 실행은 각 에이전트에 대해 OpenClaw가 관리하는 Codex 홈과 + 격리된 자식 `HOME`을 사용하므로, 기본적으로 개인 + `~/.codex` 계정, Skills, plugins, 설정, 스레드 상태 또는 네이티브 `$HOME/.agents/skills`를 읽지 않습니다. Plugin은 오래되었거나 버전이 없는 app-server 핸드셰이크를 차단합니다. 이를 통해 -OpenClaw는 테스트된 프로토콜 표면을 유지합니다. +OpenClaw는 테스트된 프로토콜 표면에 머무릅니다. -라이브 및 Docker smoke 테스트의 경우, 인증은 일반적으로 Codex CLI 계정 -또는 OpenClaw `openai-codex` 인증 프로필에서 가져옵니다. 로컬 stdio app-server 실행은 -계정이 없을 때 `CODEX_API_KEY` / `OPENAI_API_KEY`로 폴백할 수도 있습니다. +라이브 및 Docker 스모크 테스트에서는 일반적으로 인증이 Codex CLI 계정 또는 +OpenClaw `openai-codex` 인증 프로필에서 제공됩니다. 로컬 stdio app-server 실행은 +계정이 없을 때 `CODEX_API_KEY` / `OPENAI_API_KEY`로도 대체될 수 있습니다. + +## 워크스페이스 부트스트랩 파일 + +Codex는 네이티브 프로젝트 문서 검색을 통해 `AGENTS.md` 자체를 처리합니다. OpenClaw는 +합성 Codex 프로젝트 문서 파일을 작성하지 않고, 페르소나 파일에 대한 Codex 대체 +파일 이름에 의존하지 않습니다. Codex 대체 파일 이름은 `AGENTS.md`가 없을 때만 +적용되기 때문입니다. + +OpenClaw 워크스페이스 동등성을 위해 Codex 하네스는 다른 부트스트랩 파일 +(`SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, +`BOOTSTRAP.md`, 그리고 존재하는 경우 `MEMORY.md`)을 해석하고 `thread/start` 및 +`thread/resume`의 Codex 설정 지침을 통해 전달합니다. 이렇게 하면 `AGENTS.md`를 +복제하지 않고도 `SOUL.md` 및 관련 워크스페이스 페르소나/프로필 컨텍스트가 +계속 보입니다. ## 다른 모델과 함께 Codex 추가하기 -동일한 agent가 Codex와 비-Codex provider 모델 사이를 자유롭게 전환해야 한다면 -`agentRuntime.id: "codex"`를 전역으로 설정하지 마세요. 강제 런타임은 해당 agent 또는 session의 -모든 임베디드 turn에 적용됩니다. 해당 런타임이 강제된 상태에서 Anthropic 모델을 선택하면, -OpenClaw는 여전히 Codex 하네스를 시도하고, 해당 turn을 PI로 조용히 라우팅하는 대신 실패로 닫습니다. +동일한 에이전트가 Codex와 Codex가 아닌 제공자 모델 사이를 자유롭게 전환해야 한다면 +`agentRuntime.id: "codex"`를 전역으로 설정하지 마세요. 강제 런타임은 해당 에이전트나 +세션의 모든 임베디드 턴에 적용됩니다. 해당 런타임이 강제된 상태에서 Anthropic 모델을 +선택하면, OpenClaw는 여전히 Codex 하네스를 시도하고 해당 턴을 PI를 통해 조용히 +라우팅하는 대신 닫힌 방식으로 실패합니다. 대신 다음 형태 중 하나를 사용하세요. -- Codex를 `agentRuntime.id: "codex"`가 있는 전용 agent에 둡니다. -- 기본 agent는 `agentRuntime.id: "auto"`와 일반적인 혼합 provider 사용을 위한 PI 폴백으로 유지합니다. -- 레거시 `codex/*` 참조는 호환성을 위해서만 사용합니다. 새 구성은 - `openai/*`와 명시적인 Codex 런타임 정책을 선호해야 합니다. +- `agentRuntime.id: "codex"`가 있는 전용 에이전트에 Codex를 배치합니다. +- 일반적인 혼합 제공자 사용을 위해 기본 에이전트를 `agentRuntime.id: "auto"`와 PI 대체로 유지합니다. +- 기존 `codex/*` 참조는 호환성을 위해서만 사용합니다. 새 설정은 `openai/*`와 명시적인 Codex 런타임 정책을 선호해야 합니다. -예를 들어, 다음은 기본 agent를 일반 자동 선택으로 유지하고 -별도의 Codex agent를 추가합니다. +예를 들어, 다음은 기본 에이전트를 일반 자동 선택으로 유지하고 별도의 Codex 에이전트를 추가합니다. ```json5 { @@ -246,36 +259,36 @@ OpenClaw는 여전히 Codex 하네스를 시도하고, 해당 turn을 PI로 조 이 형태에서는 다음과 같습니다. -- 기본 `main` agent는 일반 provider 경로와 PI 호환성 폴백을 사용합니다. -- `codex` agent는 Codex app-server 하네스를 사용합니다. -- `codex` agent에서 Codex가 없거나 지원되지 않으면, turn은 - 조용히 PI를 사용하는 대신 실패합니다. +- 기본 `main` 에이전트는 일반 제공자 경로와 PI 호환성 대체를 사용합니다. +- `codex` 에이전트는 Codex app-server 하네스를 사용합니다. +- `codex` 에이전트에 Codex가 없거나 지원되지 않으면, PI를 조용히 사용하는 대신 + 해당 턴이 실패합니다. -## Agent 명령 라우팅 +## 에이전트 명령 라우팅 -Agent는 "Codex"라는 단어만으로가 아니라 의도에 따라 사용자 요청을 라우팅해야 합니다. +에이전트는 "Codex"라는 단어만이 아니라 의도에 따라 사용자 요청을 라우팅해야 합니다. -| 사용자가 요청하는 내용... | Agent가 사용해야 하는 것... | +| 사용자가 요청하는 내용... | 에이전트가 사용해야 하는 것... | | ------------------------------------------------------ | ------------------------------------------------ | -| "이 채팅을 Codex에 바인딩해 줘" | `/codex bind` | -| "여기에서 Codex 스레드 ``를 재개해 줘" | `/codex resume ` | -| "Codex 스레드를 보여 줘" | `/codex threads` | -| "나쁜 Codex 실행에 대한 지원 보고서를 제출해 줘" | `/diagnostics [note]` | -| "이 첨부된 스레드에 대해서만 Codex 피드백을 보내 줘" | `/codex diagnostics [note]` | -| "Codex 런타임에서 내 ChatGPT/Codex 구독을 사용해 줘" | `openai/*`와 `agentRuntime.id: "codex"` | -| "PI를 통해 내 ChatGPT/Codex 구독을 사용해 줘" | `openai-codex/*` 모델 참조 | -| "ACP/acpx를 통해 Codex를 실행해 줘" | ACP `sessions_spawn({ runtime: "acp", ... })` | -| "스레드에서 Claude Code/Gemini/OpenCode/Cursor를 시작해 줘" | ACP/acpx, `/codex`도 네이티브 하위 agent도 아님 | +| "이 채팅을 Codex에 바인딩" | `/codex bind` | +| "여기에서 Codex 스레드 `` 재개" | `/codex resume ` | +| "Codex 스레드 표시" | `/codex threads` | +| "잘못된 Codex 실행에 대한 지원 보고서 제출" | `/diagnostics [note]` | +| "첨부된 이 스레드에 대해서만 Codex 피드백 전송" | `/codex diagnostics [note]` | +| "Codex 런타임에서 내 ChatGPT/Codex 구독 사용" | `openai/*`와 `agentRuntime.id: "codex"` | +| "PI를 통해 내 ChatGPT/Codex 구독 사용" | `openai-codex/*` 모델 참조 | +| "ACP/acpx를 통해 Codex 실행" | ACP `sessions_spawn({ runtime: "acp", ... })` | +| "스레드에서 Claude Code/Gemini/OpenCode/Cursor 시작" | `/codex`도 네이티브 하위 에이전트도 아닌 ACP/acpx | -OpenClaw는 ACP가 활성화되어 있고, 디스패치 가능하며, 로드된 런타임 백엔드가 뒷받침될 때만 -agent에게 ACP spawn 안내를 알립니다. ACP를 사용할 수 없으면, -시스템 프롬프트와 Plugin Skills는 agent에게 ACP 라우팅을 가르치면 안 됩니다. +OpenClaw는 ACP가 활성화되어 있고, 디스패치 가능하며, 로드된 런타임 백엔드로 뒷받침될 때만 +에이전트에 ACP 생성 지침을 알립니다. ACP를 사용할 수 없으면 시스템 프롬프트와 Plugin Skills는 +에이전트에게 ACP 라우팅을 가르치지 않아야 합니다. ## Codex 전용 배포 -모든 임베디드 agent turn이 Codex를 사용한다는 것을 증명해야 할 때 Codex 하네스를 강제합니다. -명시적 Plugin 런타임은 기본적으로 PI 폴백이 없으므로 -`fallback: "none"`은 선택 사항이지만, 문서화 용도로 유용한 경우가 많습니다. +모든 임베디드 에이전트 턴이 Codex를 사용한다는 것을 증명해야 할 때 Codex 하네스를 강제하세요. +명시적인 Plugin 런타임은 기본적으로 PI 대체를 사용하지 않으므로 `fallback: "none"`은 선택 사항이지만 +문서화 용도로 유용한 경우가 많습니다. ```json5 { @@ -297,14 +310,13 @@ agent에게 ACP spawn 안내를 알립니다. ACP를 사용할 수 없으면, OPENCLAW_AGENT_RUNTIME=codex openclaw gateway run ``` -Codex가 강제된 상태에서는 Codex Plugin이 비활성화되어 있거나, -app-server가 너무 오래되었거나, app-server를 시작할 수 없으면 OpenClaw가 일찍 실패합니다. -누락된 하네스 선택을 PI가 의도적으로 처리하게 하려는 경우에만 -`OPENCLAW_AGENT_HARNESS_FALLBACK=pi`를 설정하세요. +Codex가 강제되면 Codex Plugin이 비활성화되어 있거나, app-server가 너무 오래되었거나, +app-server를 시작할 수 없는 경우 OpenClaw는 일찍 실패합니다. 누락된 하네스 선택을 PI가 +처리하도록 의도적으로 원할 때만 `OPENCLAW_AGENT_HARNESS_FALLBACK=pi`를 설정하세요. -## Agent별 Codex +## 에이전트별 Codex -기본 agent는 일반 자동 선택을 유지하면서 한 agent만 Codex 전용으로 만들 수 있습니다. +기본 에이전트는 일반 자동 선택을 유지하면서 하나의 에이전트만 Codex 전용으로 만들 수 있습니다. ```json5 { @@ -335,15 +347,14 @@ app-server가 너무 오래되었거나, app-server를 시작할 수 없으면 O } ``` -일반 session 명령을 사용해 agent와 모델을 전환하세요. `/new`는 새 -OpenClaw session을 만들고, Codex 하네스는 필요에 따라 사이드카 app-server -스레드를 만들거나 재개합니다. `/reset`은 해당 스레드의 OpenClaw session 바인딩을 지우고 -다음 turn이 현재 구성에서 하네스를 다시 결정하도록 합니다. +에이전트와 모델을 전환하려면 일반 세션 명령을 사용하세요. `/new`는 새로운 OpenClaw 세션을 만들고, +Codex 하네스는 필요에 따라 사이드카 app-server 스레드를 만들거나 재개합니다. `/reset`은 해당 스레드에 대한 +OpenClaw 세션 바인딩을 지우고, 다음 턴이 현재 설정에서 다시 하네스를 해석하도록 합니다. ## 모델 검색 -기본적으로 Codex Plugin은 app-server에 사용 가능한 모델을 요청합니다. 검색이 -실패하거나 시간 초과되면, 다음에 대한 번들 폴백 카탈로그를 사용합니다. +기본적으로 Codex Plugin은 app-server에 사용 가능한 모델을 요청합니다. 검색이 실패하거나 시간 초과되면 +다음에 대한 번들 대체 카탈로그를 사용합니다. - GPT-5.5 - GPT-5.4 mini @@ -369,7 +380,7 @@ OpenClaw session을 만들고, Codex 하네스는 필요에 따라 사이드카 } ``` -시작 시 Codex 탐색을 피하고 폴백 카탈로그를 유지하려면 검색을 비활성화하세요. +시작 시 Codex 탐색을 피하고 대체 카탈로그만 사용하려면 검색을 비활성화하세요. ```json5 { @@ -390,24 +401,22 @@ OpenClaw session을 만들고, Codex 하네스는 필요에 따라 사이드카 ## App-server 연결 및 정책 -기본적으로 Plugin은 다음을 사용해 OpenClaw의 관리형 Codex 바이너리를 로컬에서 시작합니다. +기본적으로 Plugin은 OpenClaw가 관리하는 Codex 바이너리를 로컬에서 다음과 같이 시작합니다. ```bash codex app-server --listen stdio:// ``` -관리형 바이너리는 `codex` Plugin 패키지와 함께 제공됩니다. 이를 통해 -app-server 버전은 로컬에 별도로 설치되어 있을 수 있는 Codex CLI가 아니라 -번들된 Plugin에 묶입니다. 다른 실행 파일을 의도적으로 실행하려는 경우에만 +관리되는 바이너리는 `codex` Plugin 패키지와 함께 제공됩니다. 이렇게 하면 app-server 버전이 로컬에 +별도로 설치된 Codex CLI가 아니라 번들된 Plugin에 묶입니다. 의도적으로 다른 실행 파일을 실행하려는 경우에만 `appServer.command`를 설정하세요. -기본적으로 OpenClaw는 로컬 Codex 하네스 session을 YOLO 모드로 시작합니다. +기본적으로 OpenClaw는 로컬 Codex 하네스 세션을 YOLO 모드로 시작합니다. `approvalPolicy: "never"`, `approvalsReviewer: "user"`, 그리고 -`sandbox: "danger-full-access"`입니다. 이는 자율 Heartbeat에 사용되는 신뢰할 수 있는 -로컬 운영자 자세입니다. Codex는 답할 사람이 없는 네이티브 승인 프롬프트에서 -멈추지 않고 shell과 네트워크 도구를 사용할 수 있습니다. +`sandbox: "danger-full-access"`입니다. 이것은 자율 Heartbeat에 사용되는 신뢰된 로컬 운영자 자세입니다. +Codex는 응답할 사람이 없는 네이티브 승인 프롬프트에서 멈추지 않고 셸 및 네트워크 도구를 사용할 수 있습니다. -Codex guardian 검토 승인을 사용하려면 `appServer.mode: +Codex 가디언 검토 승인에 옵트인하려면 `appServer.mode: "guardian"`을 설정하세요. ```json5 @@ -428,17 +437,17 @@ Codex guardian 검토 승인을 사용하려면 `appServer.mode: } ``` -Guardian 모드는 Codex의 네이티브 자동 검토 승인 경로를 사용합니다. Codex가 -sandbox를 벗어나거나, workspace 밖에 쓰거나, 네트워크 접근 같은 권한을 추가하려고 요청하면, -Codex는 해당 승인 요청을 사람 프롬프트가 아니라 네이티브 reviewer로 라우팅합니다. -reviewer는 Codex의 위험 프레임워크를 적용하고 특정 요청을 승인하거나 거부합니다. -YOLO 모드보다 더 많은 가드레일을 원하지만 무인 agent가 계속 진행해야 할 때 Guardian을 사용하세요. +가디언 모드는 Codex의 네이티브 자동 검토 승인 경로를 사용합니다. Codex가 샌드박스를 벗어나거나, +워크스페이스 밖에 쓰거나, 네트워크 액세스 같은 권한을 추가하려고 요청하면, Codex는 해당 승인 요청을 +사람 프롬프트 대신 네이티브 검토자에게 라우팅합니다. 검토자는 Codex의 위험 프레임워크를 적용하고 +특정 요청을 승인하거나 거부합니다. YOLO 모드보다 더 많은 가드레일을 원하지만 무인 에이전트가 계속 +진행해야 할 때 가디언을 사용하세요. `guardian` 프리셋은 `approvalPolicy: "on-request"`, `approvalsReviewer: "auto_review"`, 그리고 `sandbox: "workspace-write"`로 확장됩니다. -개별 정책 필드는 여전히 `mode`를 재정의하므로, 고급 배포에서는 -프리셋을 명시적 선택과 혼합할 수 있습니다. 이전 `guardian_subagent` reviewer 값은 -호환성 별칭으로 계속 허용되지만, 새 구성은 `auto_review`를 사용해야 합니다. +개별 정책 필드는 여전히 `mode`를 재정의하므로 고급 배포에서는 프리셋과 명시적 선택을 혼합할 수 있습니다. +이전 `guardian_subagent` 검토자 값은 호환성 별칭으로 계속 허용되지만, 새 설정은 `auto_review`를 +사용해야 합니다. 이미 실행 중인 app-server에는 WebSocket 전송을 사용하세요. @@ -463,42 +472,40 @@ YOLO 모드보다 더 많은 가드레일을 원하지만 무인 agent가 계속 ``` Stdio app-server 실행은 기본적으로 OpenClaw의 프로세스 환경을 상속하지만, -OpenClaw는 Codex app-server 계정 브리지를 소유하며 `CODEX_HOME`과 `HOME` 모두를 -해당 agent의 OpenClaw 상태 아래 agent별 디렉터리로 설정합니다. -Codex 자체 skill loader는 `$CODEX_HOME/skills`와 -`$HOME/.agents/skills`를 읽으므로, 로컬 app-server 실행에서는 두 값 모두 격리됩니다. -이를 통해 Codex 네이티브 Skills, Plugin, 구성, 계정, 스레드 상태가 운영자의 -개인 Codex CLI 홈에서 새어 들어오지 않고 OpenClaw agent에 한정됩니다. +OpenClaw는 Codex app-server 계정 브리지를 소유하고 `CODEX_HOME`과 `HOME`을 모두 해당 에이전트의 +OpenClaw 상태 아래 에이전트별 디렉터리로 설정합니다. Codex 자체 Skills 로더는 `$CODEX_HOME/skills`와 +`$HOME/.agents/skills`를 읽으므로, 로컬 app-server 실행에서는 두 값이 모두 격리됩니다. 이를 통해 +Codex 네이티브 Skills, plugins, 설정, 계정, 스레드 상태가 운영자의 개인 Codex CLI 홈에서 새어 들어오지 않고 +OpenClaw 에이전트로 범위가 제한됩니다. -OpenClaw Plugin과 OpenClaw skill 스냅샷은 여전히 OpenClaw 자체 -Plugin 레지스트리와 skill loader를 통해 흐릅니다. 개인 Codex CLI 자산은 그렇지 않습니다. -OpenClaw agent의 일부가 되어야 하는 유용한 Codex CLI Skills 또는 Plugin이 있다면, -명시적으로 인벤토리를 작성하세요. +OpenClaw plugins와 OpenClaw Skills 스냅샷은 여전히 OpenClaw 자체 Plugin 레지스트리와 Skills 로더를 통해 +흐릅니다. 개인 Codex CLI 자산은 그렇지 않습니다. OpenClaw 에이전트의 일부가 되어야 하는 유용한 Codex CLI +Skills나 plugins가 있다면 명시적으로 인벤토리를 작성하세요. ```bash openclaw migrate codex --dry-run openclaw migrate apply codex --yes ``` -Codex migration provider는 Skills를 현재 OpenClaw agent workspace로 복사합니다. -Codex 네이티브 Plugin, hook, 구성 파일은 명령을 실행하거나, MCP 서버를 노출하거나, -자격 증명을 포함할 수 있으므로 자동으로 활성화되는 대신 수동 검토를 위해 보고되거나 보관됩니다. +Codex 마이그레이션 제공자는 Skills를 현재 OpenClaw 에이전트 워크스페이스로 복사합니다. Codex 네이티브 +plugins, 훅, 설정 파일은 자동으로 활성화되는 대신 수동 검토를 위해 보고되거나 보관됩니다. 이들은 명령을 +실행하거나, MCP 서버를 노출하거나, 자격 증명을 포함할 수 있기 때문입니다. 인증은 다음 순서로 선택됩니다. -1. agent에 대한 명시적인 OpenClaw Codex 인증 프로필. -2. 해당 agent의 Codex 홈에 있는 app-server의 기존 계정. -3. 로컬 stdio app-server 실행에서만, app-server 계정이 없고 OpenAI 인증이 - 여전히 필요한 경우 `CODEX_API_KEY`, 그다음 `OPENAI_API_KEY`. +1. 에이전트에 대한 명시적인 OpenClaw Codex 인증 프로필. +2. 해당 에이전트의 Codex 홈에 있는 app-server의 기존 계정. +3. 로컬 stdio app-server 실행의 경우에만, app-server 계정이 없고 OpenAI 인증이 여전히 필요할 때 + `CODEX_API_KEY`, 그다음 `OPENAI_API_KEY`. -OpenClaw가 ChatGPT 구독 스타일 Codex 인증 프로필을 감지하면, 생성된 Codex 하위 프로세스에서 -`CODEX_API_KEY`와 `OPENAI_API_KEY`를 제거합니다. 이를 통해 Gateway 수준 API 키는 -embeddings 또는 직접 OpenAI 모델에 사용할 수 있으면서, 네이티브 Codex app-server turn이 -실수로 API를 통해 과금되지 않도록 합니다. 명시적 Codex API 키 프로필과 로컬 stdio env 키 폴백은 -상속된 하위 프로세스 env 대신 app-server 로그인을 사용합니다. WebSocket app-server 연결은 -Gateway env API 키 폴백을 받지 않습니다. 명시적 인증 프로필 또는 원격 app-server 자체 계정을 사용하세요. +OpenClaw가 ChatGPT 구독 방식의 Codex 인증 프로필을 발견하면 생성된 Codex 자식 프로세스에서 +`CODEX_API_KEY`와 `OPENAI_API_KEY`를 제거합니다. 이렇게 하면 Gateway 수준 API 키를 임베딩이나 직접 +OpenAI 모델에 사용할 수 있게 유지하면서, 네이티브 Codex app-server 턴이 실수로 API를 통해 과금되지 않도록 +합니다. 명시적인 Codex API 키 프로필과 로컬 stdio 환경 키 대체는 상속된 자식 프로세스 환경 대신 +app-server 로그인을 사용합니다. WebSocket app-server 연결은 Gateway 환경 API 키 대체를 받지 않습니다. +명시적인 인증 프로필이나 원격 app-server 자체 계정을 사용하세요. -배포에 추가 환경 격리가 필요하면, 해당 변수를 `appServer.clearEnv`에 추가하세요. +배포에 추가 환경 격리가 필요하면 해당 변수를 `appServer.clearEnv`에 추가하세요. ```json5 { @@ -517,53 +524,53 @@ Gateway env API 키 폴백을 받지 않습니다. 명시적 인증 프로필 } ``` -`appServer.clearEnv`는 생성된 Codex app-server 하위 프로세스에만 영향을 줍니다. +`appServer.clearEnv`는 생성된 Codex app-server 자식 프로세스에만 영향을 줍니다. Codex 동적 도구는 기본적으로 `native-first` 프로필을 사용합니다. 이 모드에서는 OpenClaw가 Codex 네이티브 workspace 작업과 중복되는 동적 도구를 노출하지 않습니다: `read`, `write`, `edit`, `apply_patch`, `exec`, `process`, 그리고 -`update_plan`. messaging, sessions, media, -cron, browser, nodes, gateway, `heartbeat_respond`, 그리고 `web_search` 같은 -OpenClaw 통합 도구는 계속 사용할 수 있습니다. +`update_plan`. 메시징, 세션, 미디어, Cron, 브라우저, Node, Gateway, +`heartbeat_respond`, `web_search` 같은 OpenClaw 통합 도구는 계속 +사용할 수 있습니다. 지원되는 최상위 Codex Plugin 필드: -| 필드 | 기본값 | 의미 | -| -------------------------- | ---------------- | ----------------------------------------------------------------------------------------- | +| 필드 | 기본값 | 의미 | +| -------------------------- | ---------------- | ------------------------------------------------------------------------------------- | | `codexDynamicToolsProfile` | `"native-first"` | Codex app-server에 전체 OpenClaw 동적 도구 세트를 노출하려면 `"openclaw-compat"`를 사용합니다. | -| `codexDynamicToolsExclude` | `[]` | Codex app-server 턴에서 생략할 추가 OpenClaw 동적 도구 이름입니다. | +| `codexDynamicToolsExclude` | `[]` | Codex app-server 턴에서 생략할 추가 OpenClaw 동적 도구 이름입니다. | 지원되는 `appServer` 필드: -| 필드 | 기본값 | 의미 | -| ------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `transport` | `"stdio"` | `"stdio"`는 Codex를 생성하고, `"websocket"`은 `url`에 연결합니다. | -| `command` | 관리되는 Codex 바이너리 | stdio 전송에 사용할 실행 파일입니다. 관리되는 바이너리를 사용하려면 설정하지 말고, 명시적으로 재정의할 때만 설정합니다. | -| `args` | `["app-server", "--listen", "stdio://"]` | stdio 전송에 사용할 인수입니다. | -| `url` | 설정되지 않음 | WebSocket app-server URL입니다. | -| `authToken` | 설정되지 않음 | WebSocket 전송에 사용할 Bearer 토큰입니다. | -| `headers` | `{}` | 추가 WebSocket 헤더입니다. | -| `clearEnv` | `[]` | OpenClaw가 상속 환경을 빌드한 뒤 생성된 stdio app-server 프로세스에서 제거할 추가 환경 변수 이름입니다. `CODEX_HOME`과 `HOME`은 로컬 실행에서 OpenClaw의 에이전트별 Codex 격리를 위해 예약되어 있습니다. | -| `requestTimeoutMs` | `60000` | app-server 제어 평면 호출의 제한 시간입니다. | -| `mode` | `"yolo"` | YOLO 또는 guardian 검토 실행을 위한 프리셋입니다. | -| `approvalPolicy` | `"never"` | 스레드 시작/재개/턴에 전송되는 네이티브 Codex 승인 정책입니다. | -| `sandbox` | `"danger-full-access"` | 스레드 시작/재개에 전송되는 네이티브 Codex 샌드박스 모드입니다. | -| `approvalsReviewer` | `"user"` | Codex가 네이티브 승인 프롬프트를 검토하게 하려면 `"auto_review"`를 사용합니다. `guardian_subagent`는 레거시 별칭으로 남아 있습니다. | -| `serviceTier` | 설정되지 않음 | 선택적 Codex app-server 서비스 티어: `"fast"`, `"flex"` 또는 `null`입니다. 유효하지 않은 레거시 값은 무시됩니다. | +| 필드 | 기본값 | 의미 | +| ------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `transport` | `"stdio"` | `"stdio"`는 Codex를 생성하고, `"websocket"`은 `url`에 연결합니다. | +| `command` | 관리형 Codex 바이너리 | stdio transport용 실행 파일입니다. 관리형 바이너리를 사용하려면 설정하지 않은 상태로 두고, 명시적으로 재정의할 때만 설정하세요. | +| `args` | `["app-server", "--listen", "stdio://"]` | stdio transport용 인수입니다. | +| `url` | 설정 안 됨 | WebSocket app-server URL입니다. | +| `authToken` | 설정 안 됨 | WebSocket transport용 Bearer 토큰입니다. | +| `headers` | `{}` | 추가 WebSocket 헤더입니다. | +| `clearEnv` | `[]` | OpenClaw가 상속 환경을 구성한 뒤 생성된 stdio app-server 프로세스에서 제거할 추가 환경 변수 이름입니다. `CODEX_HOME`과 `HOME`은 로컬 실행에서 OpenClaw의 에이전트별 Codex 격리를 위해 예약되어 있습니다. | +| `requestTimeoutMs` | `60000` | app-server 제어 플레인 호출의 제한 시간입니다. | +| `mode` | `"yolo"` | YOLO 또는 guardian 검토 실행을 위한 프리셋입니다. | +| `approvalPolicy` | `"never"` | thread 시작/재개/turn에 전송되는 네이티브 Codex 승인 정책입니다. | +| `sandbox` | `"danger-full-access"` | thread 시작/재개에 전송되는 네이티브 Codex sandbox 모드입니다. | +| `approvalsReviewer` | `"user"` | Codex가 네이티브 승인 프롬프트를 검토하도록 하려면 `"auto_review"`를 사용합니다. `guardian_subagent`는 레거시 별칭으로 남아 있습니다. | +| `serviceTier` | 설정 안 됨 | 선택적 Codex app-server 서비스 티어입니다: `"fast"`, `"flex"`, 또는 `null`. 유효하지 않은 레거시 값은 무시됩니다. | -OpenClaw 소유 동적 도구 호출은 -`appServer.requestTimeoutMs`와 독립적으로 제한됩니다. 각 Codex `item/tool/call` -요청은 30초 이내에 OpenClaw 응답을 받아야 합니다. 제한 시간이 초과되면 OpenClaw는 -지원되는 경우 도구 신호를 중단하고 실패한 동적 도구 응답을 Codex에 반환하여 -세션이 `processing`에 남아 있지 않고 턴을 계속할 수 있게 합니다. +OpenClaw 소유 동적 도구 호출은 `appServer.requestTimeoutMs`와 별도로 +제한됩니다. 각 Codex `item/tool/call` 요청은 30초 이내에 OpenClaw 응답을 +받아야 합니다. 제한 시간이 초과되면 OpenClaw는 지원되는 경우 도구 signal을 +중단하고 실패한 dynamic-tool 응답을 Codex에 반환하여 세션을 `processing`에 +남겨 두지 않고 turn을 계속할 수 있게 합니다. -OpenClaw가 Codex 턴 범위 app-server 요청에 응답한 뒤에는 하니스도 -Codex가 `turn/completed`로 네이티브 턴을 마치는 것을 기대합니다. 그 응답 후 -app-server가 60초 동안 조용하면 OpenClaw는 최선의 방식으로 Codex 턴을 -인터럽트하고, 진단 제한 시간을 기록하며, OpenClaw 세션 레인을 해제하여 -후속 채팅 메시지가 오래된 네이티브 턴 뒤에 대기하지 않게 합니다. +OpenClaw가 Codex turn 범위 app-server 요청에 응답한 뒤에는 harness도 +Codex가 `turn/completed`로 네이티브 turn을 완료할 것을 기대합니다. 해당 +응답 이후 app-server가 60초 동안 조용하면 OpenClaw는 최선의 노력으로 Codex +turn을 interrupt하고, 진단용 제한 시간 기록을 남기며, 후속 채팅 메시지가 +오래된 네이티브 turn 뒤에 큐에 쌓이지 않도록 OpenClaw session lane을 해제합니다. -로컬 테스트에는 환경 재정의를 계속 사용할 수 있습니다. +로컬 테스트용 환경 재정의는 계속 사용할 수 있습니다: - `OPENCLAW_CODEX_APP_SERVER_BIN` - `OPENCLAW_CODEX_APP_SERVER_ARGS` @@ -572,27 +579,27 @@ app-server가 60초 동안 조용하면 OpenClaw는 최선의 방식으로 Codex - `OPENCLAW_CODEX_APP_SERVER_SANDBOX` `OPENCLAW_CODEX_APP_SERVER_BIN`은 `appServer.command`가 설정되지 않았을 때 -관리되는 바이너리를 우회합니다. +관리형 바이너리를 우회합니다. `OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1`은 제거되었습니다. 대신 `plugins.entries.codex.config.appServer.mode: "guardian"`을 사용하거나, -일회성 로컬 테스트에는 `OPENCLAW_CODEX_APP_SERVER_MODE=guardian`을 사용합니다. -반복 가능한 배포에는 config를 권장합니다. 이렇게 하면 Codex 하니스 설정의 -나머지 부분과 동일한 검토 대상 파일에 Plugin 동작이 유지되기 때문입니다. +일회성 로컬 테스트에는 `OPENCLAW_CODEX_APP_SERVER_MODE=guardian`을 사용하세요. +반복 가능한 배포에는 config가 선호됩니다. 이렇게 하면 Codex harness 설정의 +나머지 부분과 같은 검토된 파일에 Plugin 동작이 유지되기 때문입니다. ## 컴퓨터 사용 -컴퓨터 사용은 별도의 설정 가이드에서 다룹니다. +컴퓨터 사용은 별도의 설정 가이드에서 다룹니다: [Codex 컴퓨터 사용](/ko/plugins/codex-computer-use). -짧게 말하면, OpenClaw는 데스크톱 제어 앱을 벤더링하거나 데스크톱 작업을 +간단히 말해, OpenClaw는 데스크톱 제어 앱을 벤더링하지 않으며 데스크톱 작업을 직접 실행하지 않습니다. OpenClaw는 Codex app-server를 준비하고, -`computer-use` MCP 서버를 사용할 수 있는지 확인한 다음, Codex 모드 턴 동안 +`computer-use` MCP 서버를 사용할 수 있는지 확인한 다음, Codex 모드 turn 중에 Codex가 네이티브 MCP 도구 호출을 처리하도록 합니다. -Codex 마켓플레이스 흐름 밖에서 TryCua 드라이버에 직접 접근하려면 +Codex marketplace 흐름 밖에서 TryCua 드라이버에 직접 접근하려면 `openclaw mcp set cua-driver '{"command":"cua-driver","args":["mcp"]}'`로 -`cua-driver mcp`를 등록합니다. Codex 소유 컴퓨터 사용과 직접 MCP 등록의 +`cua-driver mcp`를 등록하세요. Codex 소유 컴퓨터 사용과 직접 MCP 등록의 차이는 [Codex 컴퓨터 사용](/ko/plugins/codex-computer-use)을 참조하세요. 최소 config: @@ -630,19 +637,11 @@ Codex 마켓플레이스 흐름 밖에서 TryCua 드라이버에 직접 접근 - `/codex computer-use install --source ` - `/codex computer-use install --marketplace-path ` -컴퓨터 사용은 macOS 전용이며, Codex MCP 서버가 앱을 제어하기 전에 로컬 OS -권한이 필요할 수 있습니다. `computerUse.enabled`가 true이고 MCP 서버를 사용할 -수 없으면, Codex 모드 턴은 네이티브 컴퓨터 사용 도구 없이 조용히 실행되는 -대신 스레드가 시작되기 전에 실패합니다. 마켓플레이스 선택지, 원격 카탈로그 -제한, 상태 이유, 문제 해결은 [Codex 컴퓨터 사용](/ko/plugins/codex-computer-use)을 참조하세요. +Computer Use는 macOS 전용이며, Codex MCP 서버가 앱을 제어하기 전에 로컬 OS 권한이 필요할 수 있습니다. `computerUse.enabled`가 true이고 MCP 서버를 사용할 수 없으면 Codex 모드 턴은 네이티브 Computer Use 도구 없이 조용히 실행되는 대신 스레드가 시작되기 전에 실패합니다. 마켓플레이스 선택 사항, 원격 카탈로그 제한, 상태 이유, 문제 해결은 [Codex Computer Use](/ko/plugins/codex-computer-use)를 참조하세요. -`computerUse.autoInstall`이 true이면, Codex가 아직 로컬 마켓플레이스를 -발견하지 못한 경우 OpenClaw는 `/Applications/Codex.app/Contents/Resources/plugins/openai-bundled`의 -표준 번들 Codex Desktop 마켓플레이스를 등록할 수 있습니다. 런타임 또는 컴퓨터 -사용 config를 변경한 뒤에는 기존 세션이 이전 PI 또는 Codex 스레드 바인딩을 -유지하지 않도록 `/new` 또는 `/reset`을 사용하세요. +`computerUse.autoInstall`이 true이면 Codex가 아직 로컬 마켓플레이스를 발견하지 못한 경우 OpenClaw가 `/Applications/Codex.app/Contents/Resources/plugins/openai-bundled`에서 표준 번들 Codex Desktop 마켓플레이스를 등록할 수 있습니다. 런타임 또는 Computer Use 구성을 변경한 후에는 기존 세션이 오래된 PI 또는 Codex 스레드 바인딩을 유지하지 않도록 `/new` 또는 `/reset`을 사용하세요. -## 일반적인 레시피 +## 일반 레시피 기본 stdio 전송을 사용하는 로컬 Codex: @@ -702,7 +701,7 @@ Guardian 검토 Codex 승인: } ``` -명시적 헤더를 사용하는 원격 app-server: +명시적 헤더가 있는 원격 app-server: ```json5 { @@ -725,157 +724,203 @@ Guardian 검토 Codex 승인: } ``` -모델 전환은 OpenClaw가 계속 제어합니다. OpenClaw 세션이 기존 Codex 스레드에 -연결되어 있으면, 다음 턴은 현재 선택된 OpenAI 모델, 공급자, 승인 정책, -샌드박스, 서비스 티어를 app-server에 다시 전송합니다. `openai/gpt-5.5`에서 -`openai/gpt-5.2`로 전환하면 스레드 바인딩은 유지되지만, Codex에 새로 선택한 -모델로 계속 진행하도록 요청합니다. +모델 전환은 OpenClaw가 계속 제어합니다. OpenClaw 세션이 기존 Codex 스레드에 연결되어 있으면 다음 턴은 현재 선택된 OpenAI 모델, provider, 승인 정책, sandbox, service tier를 app-server에 다시 보냅니다. `openai/gpt-5.5`에서 `openai/gpt-5.2`로 전환하면 스레드 바인딩은 유지되지만 Codex에 새로 선택된 모델로 계속 진행하도록 요청합니다. ## Codex 명령 -번들 Plugin은 `/codex`를 승인된 슬래시 명령으로 등록합니다. 이 명령은 -범용이며 OpenClaw 텍스트 명령을 지원하는 모든 채널에서 작동합니다. +번들된 Plugin은 `/codex`를 승인된 slash command로 등록합니다. 이는 범용이며 OpenClaw 텍스트 명령을 지원하는 모든 채널에서 작동합니다. -일반적인 형식: +일반 형식: -- `/codex status`는 실시간 app-server 연결, 모델, 계정, 속도 제한, MCP 서버, Skills를 표시합니다. +- `/codex status`는 실시간 app-server 연결 상태, 모델, 계정, 속도 제한, MCP 서버, Skills를 표시합니다. - `/codex models`는 실시간 Codex app-server 모델을 나열합니다. - `/codex threads [filter]`는 최근 Codex 스레드를 나열합니다. - `/codex resume `는 현재 OpenClaw 세션을 기존 Codex 스레드에 연결합니다. - `/codex compact`는 Codex app-server에 연결된 스레드를 압축하도록 요청합니다. -- `/codex review`는 연결된 스레드에 대해 Codex 네이티브 검토를 시작합니다. -- `/codex diagnostics [note]`는 연결된 스레드에 대한 Codex 진단 피드백을 보내기 전에 확인합니다. -- `/codex computer-use status`는 구성된 컴퓨터 사용 Plugin과 MCP 서버를 확인합니다. -- `/codex computer-use install`은 구성된 컴퓨터 사용 Plugin을 설치하고 MCP 서버를 다시 로드합니다. +- `/codex review`는 연결된 스레드에 대해 Codex 네이티브 리뷰를 시작합니다. +- `/codex diagnostics [note]`는 연결된 스레드의 Codex 진단 피드백을 보내기 전에 확인을 요청합니다. +- `/codex computer-use status`는 구성된 Computer Use Plugin과 MCP 서버를 확인합니다. +- `/codex computer-use install`은 구성된 Computer Use Plugin을 설치하고 MCP 서버를 다시 로드합니다. - `/codex account`는 계정 및 속도 제한 상태를 표시합니다. - `/codex mcp`는 Codex app-server MCP 서버 상태를 나열합니다. - `/codex skills`는 Codex app-server Skills를 나열합니다. ### 일반적인 디버깅 워크플로 -Codex 기반 에이전트가 Telegram, Discord, Slack 또는 다른 채널에서 예상과 -다른 동작을 하면, 문제가 발생한 대화부터 시작하세요: +Codex 기반 에이전트가 Telegram, Discord, Slack, +또는 다른 채널에서 예상치 못한 동작을 할 때는 문제가 발생한 대화부터 시작하세요. -1. `/diagnostics bad tool choice after image upload` 또는 본 내용을 설명하는 다른 짧은 메모를 실행합니다. -2. 진단 요청을 한 번 승인합니다. 승인을 통해 로컬 Gateway 진단 zip이 생성되고, 세션이 Codex 하네스를 사용 중이므로 관련 Codex 피드백 번들도 OpenAI 서버로 전송됩니다. -3. 완료된 진단 응답을 버그 리포트나 지원 스레드에 복사합니다. 여기에는 로컬 번들 경로, 개인정보 요약, OpenClaw 세션 ID, Codex 스레드 ID, 각 Codex 스레드에 대한 `Inspect locally` 줄이 포함됩니다. -4. 실행을 직접 디버그하려면 출력된 `Inspect locally` 명령을 터미널에서 실행합니다. 이 명령은 `codex resume `와 같은 형태이며, 네이티브 Codex 스레드를 열어 대화를 검사하거나, 로컬에서 계속 진행하거나, Codex가 특정 도구나 계획을 선택한 이유를 물어볼 수 있습니다. +1. `/diagnostics bad tool choice after image upload`를 실행하거나, 관찰한 내용을 설명하는 다른 짧은 메모를 실행합니다. +2. 진단 요청을 한 번 승인합니다. 이 승인은 로컬 Gateway 진단 zip을 만들고, 세션이 Codex 하네스를 사용 중이므로 관련 Codex 피드백 번들도 OpenAI 서버로 보냅니다. +3. 완료된 진단 응답을 버그 보고서나 지원 스레드에 복사합니다. + 여기에는 로컬 번들 경로, 개인정보 요약, OpenClaw 세션 ID, + Codex 스레드 ID, 각 Codex 스레드의 `Inspect locally` 줄이 포함됩니다. +4. 실행을 직접 디버깅하려면 출력된 `Inspect locally` + 명령을 터미널에서 실행합니다. 이 명령은 `codex resume `와 같은 형태이며, + 네이티브 Codex 스레드를 열어 대화를 검사하거나, 로컬에서 이어서 진행하거나, + Codex가 특정 도구나 계획을 선택한 이유를 물어볼 수 있습니다. -현재 연결된 스레드에 대해 전체 OpenClaw Gateway 진단 번들 없이 Codex 피드백 업로드만 특별히 원하는 경우에만 `/codex diagnostics [note]`를 사용하세요. 대부분의 지원 리포트에서는 `/diagnostics [note]`가 더 나은 시작점입니다. 로컬 Gateway 상태와 Codex 스레드 ID를 하나의 응답으로 묶어 주기 때문입니다. 전체 개인정보 모델과 그룹 채팅 동작은 [진단 내보내기](/ko/gateway/diagnostics)를 참조하세요. +현재 연결된 스레드에 대해 전체 OpenClaw Gateway 진단 번들 없이 Codex +피드백 업로드만 특별히 원할 때만 `/codex diagnostics [note]`를 사용하세요. +대부분의 지원 보고서에서는 `/diagnostics [note]`가 더 나은 시작점입니다. +로컬 Gateway 상태와 Codex 스레드 ID를 하나의 응답으로 연결하기 때문입니다. +전체 개인정보 모델과 그룹 채팅 동작은 [진단 내보내기](/ko/gateway/diagnostics)를 참조하세요. -코어 OpenClaw는 일반 Gateway 진단 명령으로 소유자 전용 `/diagnostics [note]`도 제공합니다. 승인 프롬프트는 민감한 데이터 안내문을 표시하고, [진단 내보내기](/ko/gateway/diagnostics)로 연결하며, 매번 명시적 exec 승인을 통해 `openclaw gateway diagnostics export --json`을 요청합니다. allow-all 규칙으로 진단을 승인하지 마세요. 승인 후 OpenClaw는 로컬 번들 경로와 매니페스트 요약이 포함된 붙여넣기 가능한 리포트를 전송합니다. 활성 OpenClaw 세션이 Codex 하네스를 사용 중이면, 동일한 승인으로 관련 Codex 피드백 번들을 OpenAI 서버로 전송하는 것도 승인됩니다. 승인 프롬프트에는 Codex 피드백이 전송된다고 표시되지만, 승인 전에는 Codex 세션 또는 스레드 ID를 나열하지 않습니다. +핵심 OpenClaw는 일반 Gateway 진단 명령으로 owner 전용 `/diagnostics [note]`도 노출합니다. +승인 프롬프트는 민감한 데이터 안내문을 표시하고, +[진단 내보내기](/ko/gateway/diagnostics)로 연결하며, +매번 명시적 실행 승인을 통해 `openclaw gateway diagnostics export --json`을 요청합니다. +전체 허용 규칙으로 진단을 승인하지 마세요. 승인 후 OpenClaw는 로컬 번들 경로와 매니페스트 요약이 포함된 붙여넣기 가능한 보고서를 보냅니다. +활성 OpenClaw 세션이 Codex 하네스를 사용 중이면 같은 승인으로 관련 Codex 피드백 번들을 OpenAI 서버로 보내는 것도 허가됩니다. +승인 프롬프트는 Codex 피드백이 전송된다고 알리지만, +승인 전에는 Codex 세션 또는 스레드 ID를 나열하지 않습니다. -소유자가 그룹 채팅에서 `/diagnostics`를 호출하면 OpenClaw는 공유 채널을 깔끔하게 유지합니다. 그룹에는 짧은 알림만 전달되고, 진단 안내문, 승인 프롬프트, Codex 세션/스레드 ID는 비공개 승인 경로를 통해 소유자에게 전송됩니다. 비공개 소유자 경로가 없으면 OpenClaw는 그룹 요청을 거부하고 소유자에게 DM에서 실행하라고 요청합니다. +그룹 채팅에서 owner가 `/diagnostics`를 호출하면 OpenClaw는 +공유 채널을 깔끔하게 유지합니다. 그룹에는 짧은 알림만 전달되고, +진단 안내문, 승인 프롬프트, Codex 세션/스레드 ID는 비공개 승인 경로를 통해 owner에게 전송됩니다. +비공개 owner 경로가 없으면 OpenClaw는 그룹 요청을 거부하고 owner에게 DM에서 실행하라고 요청합니다. -승인된 Codex 업로드는 Codex app-server `feedback/upload`를 호출하고, 가능한 경우 app-server에 나열된 각 스레드와 생성된 Codex 하위 스레드의 로그를 포함하도록 요청합니다. 업로드는 Codex의 일반 피드백 경로를 통해 OpenAI 서버로 전달됩니다. 해당 app-server에서 Codex 피드백이 비활성화되어 있으면 명령은 app-server 오류를 반환합니다. 완료된 진단 응답에는 전송된 스레드의 채널, OpenClaw 세션 ID, Codex 스레드 ID, 로컬 `codex resume ` 명령이 나열됩니다. 승인을 거부하거나 무시하면 OpenClaw는 해당 Codex ID를 출력하지 않습니다. 이 업로드는 로컬 Gateway 진단 내보내기를 대체하지 않습니다. +승인된 Codex 업로드는 Codex app-server `feedback/upload`를 호출하고, +가능한 경우 나열된 각 스레드 및 생성된 Codex 하위 스레드의 로그를 포함하도록 app-server에 요청합니다. +업로드는 Codex의 일반 피드백 경로를 통해 OpenAI 서버로 전송됩니다. +해당 app-server에서 Codex 피드백이 비활성화되어 있으면 명령은 app-server 오류를 반환합니다. +완료된 진단 응답에는 전송된 스레드의 채널, +OpenClaw 세션 ID, Codex 스레드 ID, 로컬 `codex resume ` +명령이 나열됩니다. 승인을 거부하거나 무시하면 OpenClaw는 해당 Codex ID를 출력하지 않습니다. +이 업로드는 로컬 Gateway 진단 내보내기를 대체하지 않습니다. -`/codex resume`은 하네스가 일반 턴에 사용하는 것과 동일한 사이드카 바인딩 파일을 씁니다. 다음 메시지에서 OpenClaw는 해당 Codex 스레드를 재개하고, 현재 선택된 OpenClaw 모델을 app-server에 전달하며, 확장 기록을 계속 활성화합니다. +`/codex resume`은 하네스가 일반 턴에 사용하는 것과 동일한 사이드카 바인딩 파일을 작성합니다. +다음 메시지에서 OpenClaw는 해당 Codex 스레드를 재개하고, +현재 선택된 OpenClaw 모델을 app-server로 전달하며, 확장 기록을 계속 활성화합니다. -### CLI에서 Codex 스레드 검사하기 +### CLI에서 Codex 스레드 검사 -잘못된 Codex 실행을 이해하는 가장 빠른 방법은 네이티브 Codex 스레드를 직접 여는 것인 경우가 많습니다. +잘못된 Codex 실행을 이해하는 가장 빠른 방법은 네이티브 Codex +스레드를 직접 여는 것인 경우가 많습니다. ```sh codex resume ``` -채널 대화에서 버그를 발견했고 문제가 있는 Codex 세션을 검사하거나, 로컬에서 계속 진행하거나, Codex가 특정 도구 또는 추론 선택을 한 이유를 물어보고 싶을 때 사용하세요. 가장 쉬운 경로는 보통 먼저 `/diagnostics [note]`를 실행하는 것입니다. 승인한 후 완료된 리포트에는 각 Codex 스레드가 나열되고, 예를 들어 `codex resume `와 같은 `Inspect locally` 명령이 출력됩니다. 해당 명령을 터미널에 바로 복사할 수 있습니다. +채널 대화에서 버그를 발견했고 문제가 있는 Codex 세션을 검사하거나, +로컬에서 이어서 진행하거나, Codex가 특정 도구 또는 추론 선택을 한 이유를 묻고 싶을 때 사용하세요. +가장 쉬운 경로는 보통 먼저 `/diagnostics [note]`를 실행하는 것입니다. +승인 후 완료된 보고서는 각 Codex 스레드를 나열하고, +예를 들어 `codex resume ` 같은 `Inspect locally` 명령을 출력합니다. +이 명령을 터미널에 바로 복사할 수 있습니다. -현재 채팅의 경우 `/codex binding`에서, 최근 Codex app-server 스레드의 경우 `/codex threads [filter]`에서 스레드 ID를 얻은 다음 셸에서 동일한 `codex resume` 명령을 실행할 수도 있습니다. +현재 채팅의 `/codex binding` 또는 최근 Codex app-server 스레드의 +`/codex threads [filter]`에서 스레드 ID를 얻은 다음, 셸에서 같은 +`codex resume` 명령을 실행할 수도 있습니다. -이 명령 표면에는 Codex app-server `0.125.0` 이상이 필요합니다. 향후 또는 사용자 지정 app-server가 해당 JSON-RPC 메서드를 노출하지 않는 경우 개별 제어 메서드는 `unsupported by this Codex app-server`로 보고됩니다. +명령 표면에는 Codex app-server `0.125.0` 이상이 필요합니다. +향후 또는 사용자 지정 app-server가 해당 JSON-RPC 메서드를 노출하지 않으면 +개별 제어 메서드는 `unsupported by this Codex app-server`로 보고됩니다. -## 훅 경계 +## Hook 경계 -Codex 하네스에는 세 가지 훅 계층이 있습니다. +Codex 하네스에는 세 가지 Hook 계층이 있습니다. | 계층 | 소유자 | 목적 | | ------------------------------------- | ------------------------ | ------------------------------------------------------------------- | -| OpenClaw Plugin 훅 | OpenClaw | PI 및 Codex 하네스 전반의 제품/Plugin 호환성. | +| OpenClaw Plugin Hook | OpenClaw | Pi 및 Codex 하네스 전반의 제품/Plugin 호환성. | | Codex app-server 확장 미들웨어 | OpenClaw 번들 Plugin | OpenClaw 동적 도구 주변의 턴별 어댑터 동작. | -| Codex 네이티브 훅 | Codex | Codex 구성의 저수준 Codex 수명 주기 및 네이티브 도구 정책. | +| Codex 네이티브 Hook | Codex | Codex 구성에서의 저수준 Codex 수명 주기 및 네이티브 도구 정책. | -OpenClaw는 OpenClaw Plugin 동작을 라우팅하기 위해 프로젝트 또는 전역 Codex `hooks.json` 파일을 사용하지 않습니다. 지원되는 네이티브 도구 및 권한 브리지의 경우 OpenClaw는 `PreToolUse`, `PostToolUse`, `PermissionRequest`, `Stop`에 대한 스레드별 Codex 구성을 주입합니다. `SessionStart` 및 `UserPromptSubmit` 같은 다른 Codex 훅은 Codex 수준 제어로 남으며, v1 계약에서는 OpenClaw Plugin 훅으로 노출되지 않습니다. +OpenClaw는 OpenClaw Plugin 동작을 라우팅하기 위해 프로젝트 또는 전역 Codex `hooks.json` 파일을 사용하지 않습니다. +지원되는 네이티브 도구 및 권한 브리지를 위해 OpenClaw는 +`PreToolUse`, `PostToolUse`, `PermissionRequest`, `Stop`에 대한 스레드별 Codex 구성을 주입합니다. +`SessionStart` 및 `UserPromptSubmit` 같은 다른 Codex Hook은 Codex 수준 제어로 남으며, +v1 계약에서 OpenClaw Plugin Hook으로 노출되지 않습니다. -OpenClaw 동적 도구의 경우 Codex가 호출을 요청한 후 OpenClaw가 도구를 실행하므로, OpenClaw는 하네스 어댑터에서 자신이 소유한 Plugin 및 미들웨어 동작을 실행합니다. Codex 네이티브 도구의 경우 Codex가 표준 도구 레코드를 소유합니다. OpenClaw는 선택된 이벤트를 미러링할 수 있지만, Codex가 app-server 또는 네이티브 훅 콜백을 통해 해당 작업을 노출하지 않는 한 네이티브 Codex 스레드를 다시 쓸 수는 없습니다. +OpenClaw 동적 도구의 경우 Codex가 호출을 요청한 뒤 OpenClaw가 도구를 실행하므로, +OpenClaw는 하네스 어댑터에서 자신이 소유한 Plugin 및 미들웨어 동작을 실행합니다. +Codex 네이티브 도구의 경우 Codex가 정식 도구 레코드를 소유합니다. +OpenClaw는 선택된 이벤트를 미러링할 수 있지만, Codex가 app-server 또는 네이티브 Hook 콜백을 통해 해당 작업을 노출하지 않는 한 네이티브 Codex 스레드를 다시 작성할 수 없습니다. -Compaction 및 LLM 수명 주기 투영은 네이티브 Codex 훅 명령이 아니라 Codex app-server 알림과 OpenClaw 어댑터 상태에서 나옵니다. OpenClaw의 `before_compaction`, `after_compaction`, `llm_input`, `llm_output` 이벤트는 Codex의 내부 요청 또는 Compaction 페이로드를 바이트 단위로 캡처한 것이 아니라 어댑터 수준 관찰입니다. +Compaction 및 LLM 수명 주기 투영은 네이티브 Codex Hook 명령이 아니라 Codex app-server +알림과 OpenClaw 어댑터 상태에서 나옵니다. +OpenClaw의 `before_compaction`, `after_compaction`, `llm_input`, `llm_output` +이벤트는 어댑터 수준 관찰이며, Codex 내부 요청 또는 Compaction 페이로드를 바이트 단위로 캡처한 것이 아닙니다. -Codex 네이티브 `hook/started` 및 `hook/completed` app-server 알림은 궤적 및 디버깅을 위해 `codex_app_server.hook` 에이전트 이벤트로 투영됩니다. 이 알림들은 OpenClaw Plugin 훅을 호출하지 않습니다. +Codex 네이티브 `hook/started` 및 `hook/completed` app-server 알림은 +궤적과 디버깅을 위해 `codex_app_server.hook` 에이전트 이벤트로 투영됩니다. +이 알림은 OpenClaw Plugin Hook을 호출하지 않습니다. ## V1 지원 계약 -Codex 모드는 내부에서 다른 모델 호출을 사용하는 PI가 아닙니다. Codex는 네이티브 모델 루프를 더 많이 소유하며, OpenClaw는 해당 경계 주변에서 Plugin 및 세션 표면을 조정합니다. +Codex 모드는 단순히 내부의 모델 호출만 다른 Pi가 아닙니다. Codex가 +네이티브 모델 루프를 더 많이 소유하며, OpenClaw는 해당 경계에 맞춰 Plugin 및 세션 표면을 조정합니다. Codex 런타임 v1에서 지원됨: -| 표면 | 지원 | 이유 | -| --------------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Codex를 통한 OpenAI 모델 루프 | 지원됨 | Codex app-server가 OpenAI 턴, 네이티브 스레드 재개, 네이티브 도구 계속 진행을 소유합니다. | -| OpenClaw 채널 라우팅 및 전달 | 지원됨 | Telegram, Discord, Slack, WhatsApp, iMessage 및 기타 채널은 모델 런타임 외부에 남습니다. | +| 표면 | 지원 | 이유 | +| --------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Codex를 통한 OpenAI 모델 루프 | 지원됨 | Codex app-server가 OpenAI 턴, 네이티브 스레드 재개, 네이티브 도구 이어가기를 소유합니다. | +| OpenClaw 채널 라우팅 및 전달 | 지원됨 | Telegram, Discord, Slack, WhatsApp, iMessage 및 기타 채널은 모델 런타임 외부에 유지됩니다. | | OpenClaw 동적 도구 | 지원됨 | Codex가 OpenClaw에 이러한 도구 실행을 요청하므로 OpenClaw는 실행 경로에 남습니다. | -| 프롬프트 및 컨텍스트 Plugin | 지원됨 | OpenClaw는 스레드를 시작하거나 재개하기 전에 프롬프트 오버레이를 만들고 컨텍스트를 Codex 턴에 투영합니다. | -| 컨텍스트 엔진 수명 주기 | 지원됨 | 조립, 수집 또는 턴 이후 유지관리, 컨텍스트 엔진 Compaction 조정이 Codex 턴에서 실행됩니다. | -| 동적 도구 훅 | 지원됨 | `before_tool_call`, `after_tool_call`, 도구 결과 미들웨어가 OpenClaw 소유 동적 도구 주변에서 실행됩니다. | -| 수명 주기 훅 | 어댑터 관찰로 지원됨 | `llm_input`, `llm_output`, `agent_end`, `before_compaction`, `after_compaction`이 정직한 Codex 모드 페이로드와 함께 실행됩니다. | -| 최종 답변 수정 게이트 | 네이티브 훅 릴레이를 통해 지원됨 | Codex `Stop`이 `before_agent_finalize`로 릴레이됩니다. `revise`는 최종화 전에 Codex에 모델 패스를 한 번 더 요청합니다. | -| 네이티브 셸, 패치, MCP 차단 또는 관찰 | 네이티브 훅 릴레이를 통해 지원됨 | Codex `PreToolUse` 및 `PostToolUse`는 Codex app-server `0.125.0` 이상에서 MCP 페이로드를 포함한 커밋된 네이티브 도구 표면에 대해 릴레이됩니다. 차단은 지원되지만 인수 재작성은 지원되지 않습니다. | -| 네이티브 권한 정책 | 네이티브 훅 릴레이를 통해 지원됨 | 런타임이 노출하는 경우 Codex `PermissionRequest`를 OpenClaw 정책을 통해 라우팅할 수 있습니다. OpenClaw가 결정을 반환하지 않으면 Codex는 일반 guardian 또는 사용자 승인 경로를 통해 계속 진행합니다. | -| App-server 궤적 캡처 | 지원됨 | OpenClaw는 app-server에 보낸 요청과 수신한 app-server 알림을 기록합니다. | +| 프롬프트 및 컨텍스트 Plugin | 지원됨 | OpenClaw는 스레드를 시작하거나 재개하기 전에 프롬프트 오버레이를 구성하고 컨텍스트를 Codex 턴에 투영합니다. | +| 컨텍스트 엔진 수명 주기 | 지원됨 | Codex 턴에 대해 조립, 수집 또는 턴 이후 유지관리, 컨텍스트 엔진 Compaction 조정이 실행됩니다. | +| 동적 도구 Hook | 지원됨 | `before_tool_call`, `after_tool_call`, 도구 결과 미들웨어가 OpenClaw 소유 동적 도구 주변에서 실행됩니다. | +| 수명 주기 Hook | 어댑터 관찰로 지원됨 | `llm_input`, `llm_output`, `agent_end`, `before_compaction`, `after_compaction`은 정직한 Codex 모드 페이로드와 함께 발생합니다. | +| 최종 답변 수정 게이트 | 네이티브 Hook 릴레이를 통해 지원됨 | Codex `Stop`은 `before_agent_finalize`로 릴레이되고, `revise`는 최종화 전에 Codex에 모델 패스를 한 번 더 요청합니다. | +| 네이티브 셸, 패치, MCP 차단 또는 관찰 | 네이티브 Hook 릴레이를 통해 지원됨 | Codex `PreToolUse` 및 `PostToolUse`는 Codex app-server `0.125.0` 이상에서 MCP 페이로드를 포함한 커밋된 네이티브 도구 표면에 대해 릴레이됩니다. 차단은 지원되며 인수 재작성은 지원되지 않습니다. | +| 네이티브 권한 정책 | 네이티브 Hook 릴레이를 통해 지원됨 | 런타임이 노출하는 경우 Codex `PermissionRequest`를 OpenClaw 정책을 통해 라우팅할 수 있습니다. OpenClaw가 결정을 반환하지 않으면 Codex는 일반 guardian 또는 사용자 승인 경로를 통해 계속 진행합니다. | +| App-server 궤적 캡처 | 지원됨 | OpenClaw는 app-server로 보낸 요청과 수신한 app-server 알림을 기록합니다. | Codex 런타임 v1에서 지원되지 않음: -| 표면 | V1 경계 | 향후 경로 | +| 표면 | V1 경계 | 향후 경로 | | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -| 기본 도구 인수 변경 | Codex 기본 사전 도구 훅은 차단할 수 있지만, OpenClaw는 Codex 기본 도구 인수를 다시 작성하지 않습니다. | 대체 도구 입력을 위한 Codex 훅/스키마 지원이 필요합니다. | -| 편집 가능한 Codex 기본 transcript 기록 | Codex는 표준 기본 스레드 기록을 소유합니다. OpenClaw는 미러를 소유하고 향후 컨텍스트를 투사할 수 있지만, 지원되지 않는 내부를 변경해서는 안 됩니다. | 기본 스레드 수술이 필요한 경우 명시적인 Codex 앱 서버 API를 추가합니다. | -| Codex 기본 도구 레코드의 `tool_result_persist` | 해당 훅은 OpenClaw가 소유한 transcript 쓰기를 변환하며, Codex 기본 도구 레코드는 변환하지 않습니다. | 변환된 레코드를 미러링할 수는 있지만, 표준 재작성에는 Codex 지원이 필요합니다. | -| 풍부한 기본 Compaction 메타데이터 | OpenClaw는 Compaction 시작과 완료를 관찰하지만, 안정적인 유지/삭제 목록, 토큰 델타, 요약 payload는 받지 않습니다. | 더 풍부한 Codex Compaction 이벤트가 필요합니다. | -| Compaction 개입 | 현재 OpenClaw Compaction 훅은 Codex 모드에서 알림 수준입니다. | Plugin이 기본 Compaction을 거부하거나 다시 작성해야 하는 경우 Codex 사전/사후 Compaction 훅을 추가합니다. | -| 바이트 단위 모델 API 요청 캡처 | OpenClaw는 앱 서버 요청과 알림을 캡처할 수 있지만, Codex 코어는 최종 OpenAI API 요청을 내부적으로 빌드합니다. | Codex 모델 요청 추적 이벤트 또는 디버그 API가 필요합니다. | +| 네이티브 도구 인수 변경 | Codex 네이티브 사전 도구 훅은 차단할 수 있지만, OpenClaw는 Codex 네이티브 도구 인수를 다시 쓰지 않습니다. | 대체 도구 입력을 위한 Codex 훅/스키마 지원이 필요합니다. | +| 편집 가능한 Codex 네이티브 트랜스크립트 기록 | Codex는 정식 네이티브 스레드 기록을 소유합니다. OpenClaw는 미러를 소유하고 향후 컨텍스트를 투영할 수 있지만, 지원되지 않는 내부를 변경해서는 안 됩니다. | 네이티브 스레드 수술이 필요한 경우 명시적인 Codex 앱 서버 API를 추가합니다. | +| Codex 네이티브 도구 레코드용 `tool_result_persist` | 해당 훅은 OpenClaw 소유 트랜스크립트 쓰기를 변환하며, Codex 네이티브 도구 레코드는 변환하지 않습니다. | 변환된 레코드를 미러링할 수는 있지만, 정식 재작성에는 Codex 지원이 필요합니다. | +| 풍부한 네이티브 Compaction 메타데이터 | OpenClaw는 Compaction 시작과 완료를 관찰하지만, 안정적인 유지/삭제 목록, 토큰 델타 또는 요약 페이로드를 받지 않습니다. | 더 풍부한 Codex Compaction 이벤트가 필요합니다. | +| Compaction 개입 | 현재 OpenClaw Compaction 훅은 Codex 모드에서 알림 수준입니다. | Plugin이 네이티브 Compaction을 거부하거나 다시 써야 하는 경우 Codex 사전/사후 Compaction 훅을 추가합니다. | +| 바이트 단위로 동일한 모델 API 요청 캡처 | OpenClaw는 앱 서버 요청과 알림을 캡처할 수 있지만, Codex 코어는 최종 OpenAI API 요청을 내부에서 빌드합니다. | Codex 모델 요청 추적 이벤트 또는 디버그 API가 필요합니다. | -## 도구, 미디어, Compaction +## 도구, 미디어 및 Compaction -Codex 하네스는 저수준 임베디드 에이전트 실행기만 변경합니다. +Codex 하네스는 저수준 내장 에이전트 실행기만 변경합니다. -OpenClaw는 여전히 도구 목록을 빌드하고 하네스에서 동적 도구 결과를 받습니다. 텍스트, 이미지, 비디오, 음악, TTS, 승인, 메시징 도구 출력은 일반 OpenClaw 전달 경로를 계속 사용합니다. +OpenClaw는 여전히 도구 목록을 빌드하고 하네스에서 동적 도구 결과를 받습니다. 텍스트, 이미지, 비디오, 음악, TTS, 승인, 메시징 도구 출력은 일반 OpenClaw 전달 경로를 계속 통과합니다. -기본 훅 릴레이는 의도적으로 일반적이지만, v1 지원 계약은 OpenClaw가 테스트하는 Codex 기본 도구 및 권한 경로로 제한됩니다. Codex 런타임에서는 shell, patch, MCP `PreToolUse`, `PostToolUse`, `PermissionRequest` payload가 여기에 포함됩니다. 런타임 계약이 이름을 지정하기 전까지는 향후 모든 Codex 훅 이벤트를 OpenClaw Plugin 표면이라고 가정하지 마세요. +네이티브 훅 릴레이는 의도적으로 범용적이지만, v1 지원 계약은 OpenClaw가 테스트하는 Codex 네이티브 도구 및 권한 경로로 제한됩니다. Codex 런타임에서는 셸, 패치, MCP `PreToolUse`, `PostToolUse`, `PermissionRequest` 페이로드가 여기에 포함됩니다. 런타임 계약에서 이름을 지정하기 전까지는 향후 모든 Codex 훅 이벤트가 OpenClaw Plugin 표면이라고 가정하지 마세요. -`PermissionRequest`의 경우 OpenClaw는 정책이 결정할 때만 명시적인 허용 또는 거부 결정을 반환합니다. 결정 없음 결과는 허용이 아닙니다. Codex는 이를 훅 결정 없음으로 처리하고 자체 guardian 또는 사용자 승인 경로로 넘어갑니다. +`PermissionRequest`의 경우 OpenClaw는 정책이 결정할 때만 명시적인 허용 또는 거부 결정을 반환합니다. 결정 없음 결과는 허용이 아닙니다. Codex는 이를 훅 결정 없음으로 처리하고 자체 가디언 또는 사용자 승인 경로로 넘어갑니다. -Codex MCP 도구 승인 요청은 Codex가 `_meta.codex_approval_kind`를 `"mcp_tool_call"`로 표시할 때 OpenClaw의 Plugin 승인 흐름으로 라우팅됩니다. Codex `request_user_input` 프롬프트는 원래 채팅으로 다시 전송되며, 다음 대기 중인 후속 메시지는 추가 컨텍스트로 조정되지 않고 해당 기본 서버 요청에 답합니다. 다른 MCP 요청은 여전히 fail-closed됩니다. +Codex MCP 도구 승인 요청은 Codex가 `_meta.codex_approval_kind`를 `"mcp_tool_call"`로 표시할 때 OpenClaw의 Plugin 승인 흐름을 통해 라우팅됩니다. Codex `request_user_input` 프롬프트는 원래 채팅으로 다시 전송되며, 다음 대기 중인 후속 메시지는 추가 컨텍스트로 조정되는 대신 해당 네이티브 서버 요청에 응답합니다. 다른 MCP 요청은 여전히 닫힌 상태로 실패합니다. -활성 실행 큐 조정은 Codex 앱 서버 `turn/steer`에 매핑됩니다. 기본 `messages.queue.mode: "steer"`를 사용하면 OpenClaw는 구성된 quiet window 동안 대기 중인 채팅 메시지를 배치 처리하고 도착 순서대로 하나의 `turn/steer` 요청으로 전송합니다. 레거시 `queue` 모드는 별도의 `turn/steer` 요청을 전송합니다. Codex 검토 및 수동 Compaction 턴은 동일 턴 조정을 거부할 수 있으며, 이 경우 선택된 모드가 fallback을 허용하면 OpenClaw는 followup 큐를 사용합니다. [조정 큐](/ko/concepts/queue-steering)를 참조하세요. +활성 실행 큐 조정은 Codex 앱 서버 `turn/steer`에 매핑됩니다. 기본 `messages.queue.mode: "steer"`를 사용하면 OpenClaw는 구성된 대기 시간 동안 대기 중인 채팅 메시지를 일괄 처리하고 도착 순서대로 하나의 `turn/steer` 요청으로 전송합니다. 레거시 `queue` 모드는 별도의 `turn/steer` 요청을 전송합니다. Codex 검토 및 수동 Compaction 턴은 같은 턴 조정을 거부할 수 있으며, 이 경우 선택한 모드가 대체를 허용하면 OpenClaw는 후속 큐를 사용합니다. [조정 큐](/ko/concepts/queue-steering)를 참조하세요. -선택된 모델이 Codex 하네스를 사용할 때 기본 스레드 Compaction은 Codex 앱 서버에 위임됩니다. OpenClaw는 채널 기록, 검색, `/new`, `/reset`, 향후 모델 또는 하네스 전환을 위해 transcript 미러를 유지합니다. 미러에는 사용자 프롬프트, 최종 assistant 텍스트, 앱 서버가 내보낼 때의 경량 Codex reasoning 또는 계획 레코드가 포함됩니다. 현재 OpenClaw는 기본 Compaction 시작 및 완료 신호만 기록합니다. 아직 사람이 읽을 수 있는 Compaction 요약이나 Compaction 후 Codex가 유지한 항목의 감사 가능한 목록은 노출하지 않습니다. +선택한 모델이 Codex 하네스를 사용하면 네이티브 스레드 Compaction은 Codex 앱 서버에 위임됩니다. OpenClaw는 채널 기록, 검색, `/new`, `/reset`, 향후 모델 또는 하네스 전환을 위해 트랜스크립트 미러를 유지합니다. 미러에는 사용자 프롬프트, 최종 어시스턴트 텍스트, 앱 서버가 내보낼 때의 경량 Codex 추론 또는 계획 레코드가 포함됩니다. 현재 OpenClaw는 네이티브 Compaction 시작 및 완료 신호만 기록합니다. 아직 사람이 읽을 수 있는 Compaction 요약이나 Compaction 이후 Codex가 유지한 항목의 감사 가능한 목록을 노출하지 않습니다. -Codex가 표준 기본 스레드를 소유하므로, `tool_result_persist`는 현재 Codex 기본 도구 결과 레코드를 다시 작성하지 않습니다. 이는 OpenClaw가 OpenClaw 소유 세션 transcript 도구 결과를 작성할 때만 적용됩니다. +Codex가 정식 네이티브 스레드를 소유하기 때문에, `tool_result_persist`는 현재 Codex 네이티브 도구 결과 레코드를 다시 쓰지 않습니다. OpenClaw가 OpenClaw 소유 세션 트랜스크립트 도구 결과를 쓸 때만 적용됩니다. -미디어 생성에는 PI가 필요하지 않습니다. 이미지, 비디오, 음악, PDF, TTS, 미디어 이해는 `agents.defaults.imageGenerationModel`, `videoGenerationModel`, `pdfModel`, `messages.tts` 같은 일치하는 provider/model 설정을 계속 사용합니다. +미디어 생성에는 PI가 필요하지 않습니다. 이미지, 비디오, 음악, PDF, TTS, 미디어 이해는 `agents.defaults.imageGenerationModel`, `videoGenerationModel`, `pdfModel`, `messages.tts`와 같은 일치하는 제공자/모델 설정을 계속 사용합니다. ## 문제 해결 -**Codex가 일반 `/model` provider로 표시되지 않습니다:** 새 구성에서는 예상된 동작입니다. `agentRuntime.id: "codex"`가 포함된 `openai/gpt-*` 모델(또는 레거시 `codex/*` 참조)을 선택하고, `plugins.entries.codex.enabled`를 활성화한 뒤, `plugins.allow`가 `codex`를 제외하는지 확인하세요. +**Codex가 일반 `/model` 제공자로 표시되지 않음:** 새 구성에서는 예상되는 동작입니다. `agentRuntime.id: "codex"`가 있는 `openai/gpt-*` 모델(또는 레거시 `codex/*` 참조)을 선택하고, `plugins.entries.codex.enabled`를 활성화한 다음, `plugins.allow`가 `codex`를 제외하는지 확인하세요. -**OpenClaw가 Codex 대신 PI를 사용합니다:** `agentRuntime.id: "auto"`는 어떤 Codex 하네스도 실행을 claim하지 않을 때 여전히 PI를 호환성 백엔드로 사용할 수 있습니다. 테스트 중 Codex 선택을 강제하려면 `agentRuntime.id: "codex"`를 설정하세요. 강제된 Codex 런타임은 이제 명시적으로 `agentRuntime.fallback: "pi"`를 설정하지 않는 한 PI로 fallback하는 대신 실패합니다. Codex 앱 서버가 선택되면 해당 실패는 추가 fallback 구성 없이 직접 노출됩니다. +**OpenClaw가 Codex 대신 PI를 사용함:** 실행을 요청하는 Codex 하네스가 없으면 `agentRuntime.id: "auto"`는 여전히 호환성 백엔드로 PI를 사용할 수 있습니다. 테스트 중에 Codex 선택을 강제하려면 `agentRuntime.id: "codex"`를 설정하세요. 이제 강제 Codex 런타임은 `agentRuntime.fallback: "pi"`를 명시적으로 설정하지 않는 한 PI로 대체되지 않고 실패합니다. Codex 앱 서버가 선택되면 해당 실패는 추가 대체 구성 없이 직접 표면화됩니다. -**앱 서버가 거부됩니다:** 앱 서버 handshake가 버전 `0.125.0` 이상을 보고하도록 Codex를 업그레이드하세요. `0.125.0-alpha.2` 또는 `0.125.0+custom` 같은 동일 버전 prerelease 또는 build-suffixed 버전은 거부됩니다. 안정 `0.125.0` 프로토콜 하한이 OpenClaw가 테스트하는 기준이기 때문입니다. +**앱 서버가 거부됨:** 앱 서버 핸드셰이크가 버전 `0.125.0` 이상을 보고하도록 Codex를 업그레이드하세요. `0.125.0-alpha.2` 또는 `0.125.0+custom` 같은 동일 버전 프리릴리스 또는 빌드 접미사 버전은 거부됩니다. OpenClaw가 테스트하는 안정 `0.125.0` 프로토콜 하한이 기준이기 때문입니다. -**모델 탐색이 느립니다:** `plugins.entries.codex.config.discovery.timeoutMs`를 낮추거나 탐색을 비활성화하세요. +**모델 검색이 느림:** `plugins.entries.codex.config.discovery.timeoutMs`를 낮추거나 검색을 비활성화하세요. -**WebSocket 전송이 즉시 실패합니다:** `appServer.url`, `authToken`, 원격 앱 서버가 동일한 Codex 앱 서버 프로토콜 버전을 사용하는지 확인하세요. +**WebSocket 전송이 즉시 실패함:** `appServer.url`, `authToken`, 원격 앱 서버가 동일한 Codex 앱 서버 프로토콜 버전을 사용하는지 확인하세요. -**비 Codex 모델이 PI를 사용합니다:** 해당 에이전트에 대해 `agentRuntime.id: "codex"`를 강제했거나 레거시 `codex/*` 참조를 선택한 경우가 아니라면 예상된 동작입니다. 일반 `openai/gpt-*` 및 다른 provider 참조는 `auto` 모드에서 일반 provider 경로에 남아 있습니다. `agentRuntime.id: "codex"`를 강제하면 해당 에이전트의 모든 임베디드 턴은 Codex가 지원하는 OpenAI 모델이어야 합니다. +**Codex가 아닌 모델이 PI를 사용함:** 해당 에이전트에 대해 `agentRuntime.id: "codex"`를 강제했거나 레거시 `codex/*` 참조를 선택하지 않았다면 예상되는 동작입니다. 일반 `openai/gpt-*` 및 다른 제공자 참조는 `auto` 모드에서 일반 제공자 경로를 유지합니다. `agentRuntime.id: "codex"`를 강제하면 해당 에이전트의 모든 내장 턴은 Codex가 지원하는 OpenAI 모델이어야 합니다. -**Computer Use가 설치되어 있지만 도구가 실행되지 않습니다:** 새 세션에서 `/codex computer-use status`를 확인하세요. 도구가 `Native hook relay unavailable`을 보고하면 `/new` 또는 `/reset`을 사용하세요. 문제가 지속되면 gateway를 다시 시작하여 오래된 기본 훅 등록을 지우세요. `computer-use.list_apps`가 시간 초과되면 Codex Computer Use 또는 Codex Desktop을 다시 시작하고 재시도하세요. +**Computer Use가 설치되어 있지만 도구가 실행되지 않음:** 새 세션에서 `/codex computer-use status`를 확인하세요. 도구가 `Native hook relay unavailable`을 보고하면 `/new` 또는 `/reset`을 사용하세요. 계속되면 Gateway를 다시 시작하여 오래된 네이티브 훅 등록을 정리하세요. `computer-use.list_apps`가 시간 초과되면 Codex Computer Use 또는 Codex Desktop을 다시 시작하고 재시도하세요. ## 관련 항목 - [에이전트 하네스 Plugin](/ko/plugins/sdk-agent-harness) - [에이전트 런타임](/ko/concepts/agent-runtimes) -- [모델 provider](/ko/concepts/model-providers) -- [OpenAI provider](/ko/providers/openai) +- [모델 제공자](/ko/concepts/model-providers) +- [OpenAI 제공자](/ko/providers/openai) - [상태](/ko/cli/status) - [Plugin 훅](/ko/plugins/hooks) - [구성 참조](/ko/gateway/configuration-reference) diff --git a/docs/ko/providers/arcee.md b/docs/ko/providers/arcee.md index ad3a5ecfe..ddc944290 100644 --- a/docs/ko/providers/arcee.md +++ b/docs/ko/providers/arcee.md @@ -1,43 +1,43 @@ --- read_when: - - OpenClaw에서 Arcee AI를 사용하려고 합니다 + - OpenClaw와 함께 Arcee AI를 사용하려고 합니다 - API 키 환경 변수 또는 CLI 인증 선택이 필요합니다 summary: Arcee AI 설정(인증 + 모델 선택) title: Arcee AI x-i18n: - generated_at: "2026-04-24T06:29:36Z" - model: gpt-5.4 + generated_at: "2026-05-02T23:39:15Z" + model: gpt-5.5 provider: openai - source_hash: 54989e1706901fedc8a0c816ca7ee7f877fa4b973697540dd90cb9182420043f + source_hash: 622ee5288aec3ae0b45d3f06ba65fd6f972e07d7a7596ae3905d6fbdac0bf737 source_path: providers/arcee.md - workflow: 15 + workflow: 16 --- -[Arcee AI](https://arcee.ai)는 OpenAI 호환 API를 통해 Trinity 계열 mixture-of-experts 모델에 대한 접근을 제공합니다. 모든 Trinity 모델은 Apache 2.0 라이선스를 사용합니다. +[Arcee AI](https://arcee.ai)는 OpenAI 호환 API를 통해 전문가 혼합 모델 Trinity 제품군에 대한 액세스를 제공합니다. 모든 Trinity 모델에는 Apache 2.0 라이선스가 적용됩니다. -Arcee AI 모델은 Arcee 플랫폼을 통해 직접 접근하거나 [OpenRouter](/ko/providers/openrouter)를 통해 접근할 수 있습니다. +Arcee AI 모델은 Arcee 플랫폼을 통해 직접 액세스하거나 [OpenRouter](/ko/providers/openrouter)를 통해 액세스할 수 있습니다. -| Property | Value | +| 속성 | 값 | | -------- | ------------------------------------------------------------------------------------- | -| Provider | `arcee` | -| Auth | `ARCEEAI_API_KEY` (직접) 또는 `OPENROUTER_API_KEY` (OpenRouter 경유) | +| 제공자 | `arcee` | +| 인증 | `ARCEEAI_API_KEY` (직접) 또는 `OPENROUTER_API_KEY` (OpenRouter 경유) | | API | OpenAI 호환 | -| Base URL | `https://api.arcee.ai/api/v1` (직접) 또는 `https://openrouter.ai/api/v1` (OpenRouter) | +| 기본 URL | `https://api.arcee.ai/api/v1` (직접) 또는 `https://openrouter.ai/api/v1` (OpenRouter) | ## 시작하기 - + - + [Arcee AI](https://chat.arcee.ai/)에서 API 키를 생성합니다. - + ```bash openclaw onboard --auth-choice arceeai-api-key ``` - + ```json5 { agents: { @@ -51,17 +51,17 @@ Arcee AI 모델은 Arcee 플랫폼을 통해 직접 접근하거나 [OpenRouter] - + - + [OpenRouter](https://openrouter.ai/keys)에서 API 키를 생성합니다. - + ```bash openclaw onboard --auth-choice arceeai-openrouter ``` - + ```json5 { agents: { @@ -72,7 +72,7 @@ Arcee AI 모델은 Arcee 플랫폼을 통해 직접 접근하거나 [OpenRouter] } ``` - 동일한 모델 ref를 직접 설정과 OpenRouter 설정 모두에 사용할 수 있습니다(예: `arcee/trinity-large-thinking`). + 동일한 모델 참조는 직접 설정과 OpenRouter 설정 모두에서 작동합니다(예: `arcee/trinity-large-thinking`). @@ -82,7 +82,7 @@ Arcee AI 모델은 Arcee 플랫폼을 통해 직접 접근하거나 [OpenRouter] ## 비대화형 설정 - + ```bash openclaw onboard --non-interactive \ --mode local \ @@ -91,7 +91,7 @@ Arcee AI 모델은 Arcee 플랫폼을 통해 직접 접근하거나 [OpenRouter] ``` - + ```bash openclaw onboard --non-interactive \ --mode local \ @@ -103,38 +103,38 @@ Arcee AI 모델은 Arcee 플랫폼을 통해 직접 접근하거나 [OpenRouter] ## 내장 카탈로그 -현재 OpenClaw는 다음 번들 Arcee 카탈로그를 제공합니다. +OpenClaw는 현재 다음 번들 Arcee 카탈로그를 제공합니다. -| Model ref | Name | Input | Context | Cost (in/out per 1M) | Notes | -| ------------------------------ | ---------------------- | ----- | ------- | -------------------- | ---------------------------------------- | -| `arcee/trinity-large-thinking` | Trinity Large Thinking | text | 256K | $0.25 / $0.90 | 기본 모델; reasoning 활성화 | -| `arcee/trinity-large-preview` | Trinity Large Preview | text | 128K | $0.25 / $1.00 | 범용 목적; 400B params, 13B active | -| `arcee/trinity-mini` | Trinity Mini 26B | text | 128K | $0.045 / $0.15 | 빠르고 비용 효율적; function calling 지원 | +| 모델 참조 | 이름 | 입력 | 컨텍스트 | 비용(1M당 입력/출력) | 참고 | +| ------------------------------ | ---------------------- | ----- | ------- | -------------------- | ------------------------------------------ | +| `arcee/trinity-large-thinking` | Trinity Large Thinking | text | 256K | $0.25 / $0.90 | 기본 모델, 추론 활성화, 도구 없음 | +| `arcee/trinity-large-preview` | Trinity Large Preview | text | 128K | $0.25 / $1.00 | 범용, 400B 매개변수, 13B 활성 | +| `arcee/trinity-mini` | Trinity Mini 26B | text | 128K | $0.045 / $0.15 | 빠르고 비용 효율적, 함수 호출 | -온보딩 프리셋은 `arcee/trinity-large-thinking`을 기본 모델로 설정합니다. +온보딩 프리셋은 `arcee/trinity-large-thinking`을 기본 모델로 설정합니다. 이 모델은 추론/텍스트 전용이며 도구 사용이나 함수 호출을 지원하지 않습니다. -## 지원 기능 +## 지원되는 기능 -| Feature | Supported | -| --------------------------------------------- | ---------------------------- | -| Streaming | 예 | -| Tool use / function calling | 예 | -| Structured output (JSON mode and JSON schema) | 예 | -| Extended thinking | 예 (Trinity Large Thinking) | +| 기능 | 지원 | +| --------------------------------------------- | ------------------------------------------- | +| 스트리밍 | 예 | +| 도구 사용 / 함수 호출 | 모델에 따라 다름, Trinity Large Thinking 제외 | +| 구조화된 출력(JSON 모드 및 JSON 스키마) | 예 | +| 확장 사고 | 예(Trinity Large Thinking) | - - Gateway가 데몬(launchd/systemd)으로 실행되는 경우, 해당 프로세스에서 - `ARCEEAI_API_KEY`(또는 `OPENROUTER_API_KEY`)를 사용할 수 있어야 합니다(예: - `~/.openclaw/.env` 또는 `env.shellEnv`). + + Gateway가 데몬(launchd/systemd)으로 실행되는 경우 `ARCEEAI_API_KEY` + (또는 `OPENROUTER_API_KEY`)가 해당 프로세스에서 사용할 수 있는지 확인하세요(예: + `~/.openclaw/.env` 또는 `env.shellEnv`를 통해). - - OpenRouter를 통해 Arcee 모델을 사용할 때도 동일한 `arcee/*` 모델 ref가 적용됩니다. - OpenClaw는 선택한 인증 방식에 따라 라우팅을 투명하게 처리합니다. OpenRouter 전용 - 구성 세부 사항은 [OpenRouter provider 문서](/ko/providers/openrouter)를 참조하세요. + + OpenRouter를 통해 Arcee 모델을 사용할 때는 동일한 `arcee/*` 모델 참조가 적용됩니다. + OpenClaw는 인증 선택에 따라 라우팅을 투명하게 처리합니다. OpenRouter별 + 구성 세부 정보는 [OpenRouter 제공자 문서](/ko/providers/openrouter)를 참조하세요. @@ -142,9 +142,9 @@ Arcee AI 모델은 Arcee 플랫폼을 통해 직접 접근하거나 [OpenRouter] - 단일 API 키를 통해 Arcee 모델과 그 외 여러 모델에 접근합니다. + 단일 API 키를 통해 Arcee 모델 및 다른 많은 모델에 액세스합니다. - - provider, 모델 ref, failover 동작 선택하기. + + 제공자, 모델 참조, 장애 조치 동작 선택. diff --git a/docs/ko/reference/RELEASING.md b/docs/ko/reference/RELEASING.md index e74fbc7a1..3dd82dbba 100644 --- a/docs/ko/reference/RELEASING.md +++ b/docs/ko/reference/RELEASING.md @@ -1,175 +1,270 @@ --- read_when: - 공개 릴리스 채널 정의를 찾는 중 - - 릴리스 검증 또는 패키지 수락 실행 - - 버전 명명 방식과 릴리스 주기 찾기 + - 릴리스 검증 또는 패키지 승인 실행 + - 버전 명명 및 릴리스 주기 찾기 summary: 릴리스 레인, 운영자 체크리스트, 검증 박스, 버전 명명 및 주기 title: 릴리스 정책 x-i18n: - generated_at: "2026-05-02T21:12:24Z" + generated_at: "2026-05-02T23:39:28Z" model: gpt-5.5 provider: openai - source_hash: 493cb8b42f0e15f3bf5f8fb9be7d01fd626f4f16db9ac0a85e6efa747ef12d12 + source_hash: ba316d1736eae8edd2fb0a71b9a3da345f8895c3b536e9a1f619718ea12fc851 source_path: reference/RELEASING.md workflow: 16 --- -OpenClaw에는 네 가지 공개 릴리스 레인이 있습니다. +OpenClaw에는 세 가지 공개 릴리스 레인이 있습니다. -- stable: 기본적으로 npm `beta`에 게시되거나 명시적으로 요청된 경우 npm `latest`에 게시되는 태그된 릴리스 -- alpha: npm `alpha`에 게시되는 프리릴리스 태그 -- beta: npm `beta`에 게시되는 프리릴리스 태그 -- dev: `main`의 이동하는 헤드 +- 안정: 기본적으로 npm `beta`에 게시되거나 명시적으로 요청된 경우 npm `latest`에 게시되는 태그된 릴리스 +- 베타: npm `beta`에 게시되는 사전 릴리스 태그 +- 개발: `main`의 이동하는 최신 헤드 -## 버전 이름 지정 +## 버전 명명 - 안정 릴리스 버전: `YYYY.M.D` - Git 태그: `vYYYY.M.D` - 안정 수정 릴리스 버전: `YYYY.M.D-N` - Git 태그: `vYYYY.M.D-N` -- Alpha 프리릴리스 버전: `YYYY.M.D-alpha.N` - - Git 태그: `vYYYY.M.D-alpha.N` -- Beta 프리릴리스 버전: `YYYY.M.D-beta.N` +- 베타 사전 릴리스 버전: `YYYY.M.D-beta.N` - Git 태그: `vYYYY.M.D-beta.N` -- 월이나 일은 0으로 채우지 마세요 +- 월 또는 일을 0으로 채우지 마세요 - `latest`는 현재 승격된 안정 npm 릴리스를 의미합니다 -- `alpha`는 현재 alpha 설치 대상을 의미합니다 -- `beta`는 현재 beta 설치 대상을 의미합니다 -- 안정 및 안정 수정 릴리스는 기본적으로 npm `beta`에 게시됩니다. 릴리스 운영자는 `latest`를 명시적으로 대상으로 지정하거나, 검증된 beta 빌드를 나중에 승격할 수 있습니다 -- 모든 안정 OpenClaw 릴리스는 npm 패키지와 macOS 앱을 함께 제공합니다. - beta 릴리스는 일반적으로 먼저 npm/패키지 경로를 검증하고 게시하며, - mac 앱 빌드/서명/공증은 명시적으로 요청되지 않는 한 안정 릴리스용으로 남겨 둡니다 +- `beta`는 현재 베타 설치 대상을 의미합니다 +- 안정 및 안정 수정 릴리스는 기본적으로 npm `beta`에 게시됩니다. 릴리스 운영자는 명시적으로 `latest`를 대상으로 지정하거나, 검증된 베타 빌드를 나중에 승격할 수 있습니다 +- 모든 안정 OpenClaw 릴리스는 npm 패키지와 macOS 앱을 함께 제공합니다; + 베타 릴리스는 일반적으로 npm/패키지 경로를 먼저 검증하고 게시하며, + mac 앱 빌드/서명/공증은 명시적으로 요청되지 않는 한 안정 릴리스용으로 남겨둡니다 ## 릴리스 주기 -- 릴리스는 beta 우선으로 진행됩니다 -- 안정 릴리스는 최신 beta가 검증된 후에만 뒤따릅니다 -- 유지관리자는 일반적으로 현재 `main`에서 생성한 `release/YYYY.M.D` 브랜치에서 - 릴리스를 만듭니다. 따라서 릴리스 검증과 수정이 `main`의 새 - 개발을 막지 않습니다 -- beta 태그가 푸시되었거나 게시된 뒤 수정이 필요한 경우, 유지관리자는 - 이전 beta 태그를 삭제하거나 다시 만들지 않고 다음 `-beta.N` 태그를 만듭니다 -- 자세한 릴리스 절차, 승인, 자격 증명, 복구 노트는 - 유지관리자 전용입니다 +- 릴리스는 베타 우선으로 진행됩니다 +- 안정 릴리스는 최신 베타가 검증된 후에만 이어집니다 +- 관리자는 일반적으로 현재 `main`에서 생성한 `release/YYYY.M.D` 브랜치에서 릴리스를 만들므로, + 릴리스 검증과 수정이 `main`의 새 개발을 차단하지 않습니다 +- 베타 태그가 푸시되었거나 게시되었고 수정이 필요한 경우, 관리자는 이전 베타 태그를 삭제하거나 다시 만들지 않고 + 다음 `-beta.N` 태그를 만듭니다 +- 자세한 릴리스 절차, 승인, 자격 증명, 복구 참고 사항은 + 관리자 전용입니다 ## 릴리스 운영자 체크리스트 이 체크리스트는 릴리스 흐름의 공개 형태입니다. 비공개 자격 증명, -서명, 공증, dist-tag 복구, 긴급 롤백 세부 정보는 유지관리자 전용 -릴리스 런북에 보관됩니다. +서명, 공증, dist-tag 복구, 긴급 롤백 세부 정보는 +관리자 전용 릴리스 런북에 남겨둡니다. 1. 현재 `main`에서 시작합니다. 최신 변경 사항을 가져오고, 대상 커밋이 푸시되었는지 확인하며, - 현재 `main` CI가 브랜치를 만들기에 충분히 정상인지 확인합니다. -2. 실제 커밋 기록을 기반으로 `/changelog`로 최상단 `CHANGELOG.md` 섹션을 다시 작성하고, - 항목을 사용자 지향적으로 유지한 뒤 커밋하고 푸시한 다음, 브랜치하기 전에 - 한 번 더 rebase/pull합니다. + 현재 `main` CI가 브랜치를 만들기에 충분히 녹색인지 확인합니다. +2. 실제 커밋 기록을 바탕으로 `/changelog`로 최상단 `CHANGELOG.md` 섹션을 다시 작성하고, + 항목을 사용자 대상 내용으로 유지한 뒤 커밋하고 푸시하며, + 브랜치를 만들기 전에 한 번 더 리베이스/풀합니다. 3. `src/plugins/compat/registry.ts` 및 `src/commands/doctor/shared/deprecation-compat.ts`의 릴리스 호환성 기록을 검토합니다. 업그레이드 경로가 계속 보장되는 경우에만 만료된 호환성을 제거하거나, 의도적으로 유지하는 이유를 기록합니다. 4. 현재 `main`에서 `release/YYYY.M.D`를 생성합니다. 일반 릴리스 작업을 `main`에서 직접 수행하지 마세요. 5. 의도한 태그에 필요한 모든 버전 위치를 올리고, - 게시 가능한 Plugin 패키지가 릴리스 버전과 호환성 메타데이터를 공유하도록 `pnpm plugins:sync`를 실행한 다음, 로컬 결정적 사전 검사를 실행합니다: + `pnpm plugins:sync`를 실행하여 게시 가능한 Plugin 패키지가 릴리스 + 버전과 호환성 메타데이터를 공유하도록 한 다음, 로컬 결정론적 사전 점검을 실행합니다: `pnpm check:test-types`, `pnpm check:architecture`, `pnpm build && pnpm ui:build`, `pnpm plugins:sync:check`, 그리고 `pnpm release:check`. 6. `preflight_only=true`로 `OpenClaw NPM Release`를 실행합니다. 태그가 존재하기 전에는 - 검증 전용 사전 검사에 전체 40자 릴리스 브랜치 SHA를 사용할 수 있습니다. + 전체 40자 릴리스 브랜치 SHA를 검증 전용 사전 점검에 사용할 수 있습니다. 성공한 `preflight_run_id`를 저장합니다. 7. 릴리스 브랜치, 태그 또는 전체 커밋 SHA에 대해 `Full Release Validation`으로 - 모든 프리릴리스 테스트를 시작합니다. 이는 네 가지 큰 릴리스 테스트 박스인 - Vitest, Docker, QA Lab, Package의 단일 수동 진입점입니다. -8. 검증이 실패하면 릴리스 브랜치에서 수정하고, 수정을 증명하는 가장 작은 실패 - 파일, 레인, 워크플로 작업, 패키지 프로필, provider 또는 모델 허용 목록을 다시 실행합니다. - 변경된 표면 때문에 이전 증거가 오래된 경우에만 전체 umbrella를 다시 실행합니다. -9. alpha 또는 beta의 경우 `vYYYY.M.D-alpha.N` 또는 `vYYYY.M.D-beta.N`으로 태그한 다음, 일치하는 - `release/YYYY.M.D` 브랜치에서 `OpenClaw Release Publish`를 실행합니다. 이는 `pnpm plugins:sync:check`를 검증하고, - 게시 가능한 모든 Plugin 패키지를 먼저 npm에 게시하며, 같은 - 세트를 두 번째로 ClawHub에 게시한 뒤, 일치하는 dist-tag로 준비된 OpenClaw npm 사전 검사 - 아티팩트를 승격합니다. 게시 후에는 게시된 `openclaw@YYYY.M.D-alpha.N`, `openclaw@alpha`, + 모든 사전 릴리스 테스트를 시작합니다. 이는 네 개의 큰 릴리스 테스트 박스인 + Vitest, Docker, QA Lab, Package에 대한 단일 수동 진입점입니다. +8. 검증이 실패하면 릴리스 브랜치에서 수정하고, 수정을 입증하는 가장 작은 실패 + 파일, 레인, 워크플로 작업, 패키지 프로필, 제공자 또는 모델 허용 목록을 다시 실행합니다. + 변경된 표면 때문에 이전 증거가 더 이상 유효하지 않을 때만 전체 우산 작업을 다시 실행합니다. +9. 베타의 경우 `vYYYY.M.D-beta.N` 태그를 지정한 다음, 일치하는 + `release/YYYY.M.D` 브랜치에서 `OpenClaw Release Publish`를 실행합니다. 이 작업은 `pnpm plugins:sync:check`를 검증하고, + 모든 게시 가능한 Plugin 패키지를 먼저 npm에 게시하며, 동일한 세트를 + 두 번째로 ClawHub에 게시한 뒤, 준비된 OpenClaw npm 사전 점검 + 아티팩트를 일치하는 dist-tag로 승격합니다. 게시 후에는 게시된 `openclaw@YYYY.M.D-beta.N` 또는 `openclaw@beta` 패키지에 대해 게시 후 패키지 - 수락 검사를 실행합니다. 푸시되었거나 게시된 프리릴리스에 수정이 필요한 경우, - 다음으로 일치하는 프리릴리스 번호를 만드세요. - 이전 프리릴리스를 삭제하거나 다시 작성하지 마세요. -10. 안정 릴리스의 경우, 검증된 beta 또는 릴리스 후보에 필요한 - 검증 증거가 있을 때만 계속합니다. 안정 npm 게시도 - `OpenClaw Release Publish`를 통해 진행되며, `preflight_run_id`로 - 성공한 사전 검사 아티팩트를 재사용합니다. 안정 macOS 릴리스 준비 상태에는 - 패키징된 `.zip`, `.dmg`, `.dSYM.zip` 및 `main`의 업데이트된 `appcast.xml`도 필요합니다. -11. 게시 후 npm 게시 후 검증기를 실행하고, 게시 후 채널 증거가 필요할 때 선택 사항인 독립 실행형 - published-npm Telegram E2E를 실행하며, - 필요할 때 dist-tag 승격, 완전하게 일치하는 `CHANGELOG.md` 섹션의 GitHub 릴리스/프리릴리스 노트, - 그리고 릴리스 공지 - 단계를 수행합니다. + 수락 검사를 실행합니다. 푸시되었거나 게시된 사전 릴리스에 수정이 필요한 경우, + 다음 일치하는 사전 릴리스 번호를 만드세요. 이전 사전 릴리스를 삭제하거나 다시 쓰지 마세요. +10. 안정 릴리스의 경우, 검증된 베타 또는 릴리스 후보에 필요한 검증 증거가 + 확보된 후에만 계속 진행합니다. 안정 npm 게시도 + `OpenClaw Release Publish`를 통해 진행하며, 성공한 사전 점검 아티팩트를 + `preflight_run_id`로 재사용합니다. 안정 macOS 릴리스 준비 상태에는 + 패키지된 `.zip`, `.dmg`, `.dSYM.zip`, 그리고 `main`의 업데이트된 `appcast.xml`도 필요합니다. +11. 게시 후에는 npm 게시 후 검증기, 게시 후 채널 증거가 필요할 때 선택적으로 독립 실행형 + 게시된 npm Telegram E2E, 필요한 경우 dist-tag 승격, 완전하게 일치하는 + `CHANGELOG.md` 섹션에서 가져온 GitHub 릴리스/사전 릴리스 노트, 그리고 릴리스 공지 + 단계를 실행합니다. -## 릴리스 사전 검사 +## 릴리스 사전 점검 -- 릴리스 사전 점검 전에 `pnpm check:test-types`를 실행하여 테스트 TypeScript가 더 빠른 로컬 `pnpm check` 게이트 밖에서도 적용되도록 합니다. -- 릴리스 사전 점검 전에 `pnpm check:architecture`를 실행하여 더 넓은 import 사이클 및 아키텍처 경계 검사가 더 빠른 로컬 게이트 밖에서도 통과하도록 합니다. -- `pnpm release:check` 전에 `pnpm build && pnpm ui:build`를 실행하여 pack 검증 단계에 필요한 `dist/*` 릴리스 산출물과 Control UI 번들이 존재하도록 합니다. -- 루트 버전 범프 후, 태그 지정 전에 `pnpm plugins:sync`를 실행합니다. 이 명령은 게시 가능한 Plugin 패키지 버전, OpenClaw 피어/API 호환성 메타데이터, 빌드 메타데이터, Plugin 변경 로그 스텁을 핵심 릴리스 버전에 맞게 업데이트합니다. `pnpm plugins:sync:check`는 변경하지 않는 릴리스 가드입니다. 이 단계를 잊으면 게시 워크플로가 레지스트리 변경 전에 실패합니다. -- 릴리스 승인 전에 수동 `Full Release Validation` 워크플로를 실행하여 하나의 진입점에서 모든 사전 릴리스 테스트 박스를 시작합니다. 브랜치, 태그 또는 전체 커밋 SHA를 입력으로 받으며, 수동 `CI`를 디스패치하고 설치 스모크, 패키지 수락, Docker 릴리스 경로 스위트, 라이브/E2E, OpenWebUI, QA Lab parity, Matrix, Telegram 레인을 위한 `OpenClaw Release Checks`를 디스패치합니다. `release_profile=full` 및 `rerun_group=all`을 사용하면 릴리스 검사에서 생성된 `release-package-under-test` 산출물에 대해 패키지 Telegram E2E도 실행합니다. 게시 후 동일한 Telegram E2E로 게시된 npm 패키지도 검증해야 하면 `npm_telegram_package_spec`을 제공합니다. 게시 후 Package Acceptance가 SHA로 빌드한 산출물 대신 배포된 npm 패키지에 대해 패키지/업데이트 매트릭스를 실행해야 하면 `package_acceptance_package_spec`을 제공합니다. Telegram E2E를 강제하지 않고 비공개 증거 보고서가 검증 대상이 게시된 npm 패키지와 일치함을 증명해야 하면 `evidence_package_spec`을 제공합니다. 예: +- 릴리스 사전 점검 전에 `pnpm check:test-types`를 실행하여 테스트 TypeScript가 더 빠른 로컬 `pnpm check` 게이트 밖에서도 계속 적용되도록 합니다 +- 릴리스 사전 점검 전에 `pnpm check:architecture`를 실행하여 더 광범위한 import + cycle 및 아키텍처 경계 검사가 더 빠른 로컬 게이트 밖에서도 통과하도록 합니다 +- `pnpm release:check` 전에 `pnpm build && pnpm ui:build`를 실행하여 예상되는 + `dist/*` 릴리스 아티팩트와 Control UI 번들이 pack + 검증 단계에 존재하도록 합니다 +- 루트 버전 상향 후, 태그 지정 전에 `pnpm plugins:sync`를 실행합니다. 이 명령은 + 게시 가능한 Plugin 패키지 버전, OpenClaw peer/API 호환성 + 메타데이터, 빌드 메타데이터, Plugin 변경 로그 스텁을 core + 릴리스 버전에 맞게 업데이트합니다. `pnpm plugins:sync:check`는 변경을 만들지 않는 릴리스 가드입니다. + 이 단계를 잊은 경우 게시 워크플로는 registry 변경 전에 실패합니다. +- 릴리스 승인 전에 수동 `Full Release Validation` 워크플로를 실행하여 + 하나의 진입점에서 모든 사전 릴리스 테스트 박스를 시작합니다. 이 워크플로는 브랜치, + 태그 또는 전체 commit SHA를 받아 수동 `CI`를 dispatch하고, + install smoke, package acceptance, Docker + release-path suite, live/E2E, OpenWebUI, QA Lab parity, Matrix, Telegram + lane을 위한 `OpenClaw Release Checks`를 dispatch합니다. `release_profile=full` 및 `rerun_group=all`을 사용하면 릴리스 + checks의 `release-package-under-test` 아티팩트를 대상으로 package + Telegram E2E도 실행합니다. 게시 후 동일한 + Telegram E2E가 게시된 npm 패키지도 증명해야 하면 `npm_telegram_package_spec`을 제공합니다. Package Acceptance가 + SHA로 빌드한 아티팩트 대신 출시된 npm 패키지를 대상으로 + package/update matrix를 실행해야 하면 게시 후 + `package_acceptance_package_spec`을 제공합니다. + Telegram E2E를 강제하지 않고 private evidence report가 검증이 게시된 npm 패키지와 일치함을 + 증명해야 하면 `evidence_package_spec`을 제공합니다. + 예: `gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D` -- 릴리스 작업이 계속되는 동안 패키지 후보에 대한 사이드 채널 증거가 필요하면 수동 `Package Acceptance` 워크플로를 실행합니다. `openclaw@alpha`, `openclaw@beta`, `openclaw@latest` 또는 정확한 릴리스 버전에는 `source=npm`을 사용하고, 현재 `workflow_ref` 하네스로 신뢰할 수 있는 `package_ref` 브랜치/태그/SHA를 pack하려면 `source=ref`를 사용하며, 필수 SHA-256이 있는 HTTPS tarball에는 `source=url`을 사용하고, 다른 GitHub Actions 실행이 업로드한 tarball에는 `source=artifact`를 사용합니다. 이 워크플로는 후보를 `package-under-test`로 해석하고, 해당 tarball에 대해 Docker E2E 릴리스 스케줄러를 재사용하며, `telegram_mode=mock-openai` 또는 `telegram_mode=live-frontier`로 같은 tarball에 대해 Telegram QA를 실행할 수 있습니다. 선택한 Docker 레인에 `published-upgrade-survivor`가 포함되면 패키지 산출물이 후보가 되고 `published_upgrade_survivor_baseline`은 게시된 기준선을 선택합니다. +- 릴리스 작업이 계속되는 동안 패키지 후보에 대한 side-channel 증거가 + 필요하면 수동 `Package Acceptance` 워크플로를 실행합니다. `openclaw@beta`, + `openclaw@latest` 또는 정확한 릴리스 버전에는 `source=npm`을 사용합니다. 현재 + `workflow_ref` 하네스로 신뢰할 수 있는 `package_ref` 브랜치/태그/SHA를 pack하려면 `source=ref`를 사용합니다. 필수 + SHA-256이 있는 HTTPS tarball에는 `source=url`을 사용합니다. 다른 GitHub + Actions run에서 업로드한 tarball에는 `source=artifact`를 사용합니다. 이 워크플로는 후보를 + `package-under-test`로 resolve하고, 해당 tarball에 대해 Docker E2E 릴리스 scheduler를 재사용하며, + `telegram_mode=mock-openai` 또는 `telegram_mode=live-frontier`로 동일한 tarball에 대해 Telegram QA를 실행할 수 있습니다. 선택한 + Docker lane에 `published-upgrade-survivor`가 포함되면 package + 아티팩트가 후보가 되고 `published_upgrade_survivor_baseline`이 + 게시된 baseline을 선택합니다. 예: `gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f published_upgrade_survivor_baseline=openclaw@2026.4.26 -f telegram_mode=mock-openai` - 일반 프로필: - - `smoke`: 설치/채널/에이전트, Gateway 네트워크, 구성 리로드 레인 - - `package`: OpenWebUI 또는 라이브 ClawHub 없는 산출물 네이티브 패키지/업데이트/Plugin 레인 - - `product`: 패키지 프로필에 MCP 채널, cron/하위 에이전트 정리, OpenAI 웹 검색, OpenWebUI를 더한 프로필 - - `full`: OpenWebUI를 포함한 Docker 릴리스 경로 청크 + 일반 profile: + - `smoke`: install/channel/agent, gateway network, config reload lane + - `package`: OpenWebUI 또는 live ClawHub 없이 artifact-native package/update/Plugin lane + - `product`: package profile에 MCP channel, cron/subagent cleanup, + OpenAI web search, OpenWebUI 추가 + - `full`: OpenWebUI가 포함된 Docker release-path chunk - `custom`: 집중 재실행을 위한 정확한 `docker_lanes` 선택 -- 릴리스 후보에 대해 전체 일반 CI 적용 범위만 필요하면 수동 `CI` 워크플로를 직접 실행합니다. 수동 CI 디스패치는 변경 범위 지정을 우회하고 Linux Node 샤드, 번들 Plugin 샤드, 채널 계약, Node 22 호환성, `check`, `check-additional`, 빌드 스모크, 문서 검사, Python skills, Windows, macOS, Android, Control UI i18n 레인을 강제로 실행합니다. +- 릴리스 후보에 대한 전체 일반 CI coverage만 필요하면 수동 `CI` 워크플로를 + 직접 실행합니다. 수동 CI dispatch는 changed + scoping을 우회하고 Linux Node shard, bundled-Plugin shard, channel + contract, Node 22 compatibility, `check`, `check-additional`, build smoke, + docs check, Python skills, Windows, macOS, Android, Control UI i18n + lane을 강제로 실행합니다. 예: `gh workflow run ci.yml --ref release/YYYY.M.D` -- 릴리스 텔레메트리를 검증할 때 `pnpm qa:otel:smoke`를 실행합니다. 이 명령은 로컬 OTLP/HTTP 수신기를 통해 QA-lab을 실행하고, Opik, Langfuse 또는 다른 외부 collector 없이 내보낸 trace span 이름, 제한된 속성, 콘텐츠/식별자 redaction을 검증합니다. -- 모든 태그 릴리스 전에 `pnpm release:check`를 실행합니다. -- 태그가 존재한 후 변경을 수행하는 게시 순서에는 `OpenClaw Release Publish`를 실행합니다. `release/YYYY.M.D`에서 디스패치하거나, main에서 접근 가능한 태그를 게시할 때는 `main`에서 디스패치하고, 릴리스 태그와 성공한 OpenClaw npm `preflight_run_id`를 전달하며, 의도적으로 집중 복구를 실행하는 경우가 아니면 기본 Plugin 게시 범위 `all-publishable`을 유지합니다. 이 워크플로는 Plugin npm 게시, Plugin ClawHub 게시, OpenClaw npm 게시를 직렬화하여 핵심 패키지가 외부화된 Plugin보다 먼저 게시되지 않도록 합니다. +- 릴리스 telemetry를 검증할 때 `pnpm qa:otel:smoke`를 실행합니다. 이 명령은 + 로컬 OTLP/HTTP receiver를 통해 QA-lab을 실행하고, Opik, Langfuse 또는 다른 외부 collector 없이 + 내보낸 trace + span name, 제한된 attribute, content/identifier redaction을 검증합니다. +- 모든 태그된 릴리스 전에 `pnpm release:check`를 실행합니다 +- 태그가 존재한 후 변경을 수행하는 publish sequence에는 `OpenClaw Release Publish`를 실행합니다. + `release/YYYY.M.D`에서 dispatch하거나, main에서 도달 가능한 태그를 게시하는 경우 `main`에서 dispatch하고, + 릴리스 태그와 성공한 OpenClaw npm + `preflight_run_id`를 전달하며, 집중 repair를 의도적으로 실행하는 경우가 아니라면 기본 Plugin publish scope + `all-publishable`을 유지합니다. 이 워크플로는 Plugin npm publish, Plugin ClawHub publish, OpenClaw + npm publish를 직렬화하여 core 패키지가 외부화된 + Plugin보다 먼저 게시되지 않도록 합니다. - 릴리스 검사는 이제 별도의 수동 워크플로에서 실행됩니다: `OpenClaw Release Checks` -- `OpenClaw Release Checks`는 릴리스 승인 전에 QA Lab mock parity 레인과 빠른 라이브 Matrix 프로필 및 Telegram QA 레인도 실행합니다. 라이브 레인은 `qa-live-shared` 환경을 사용하며, Telegram은 Convex CI 자격 증명 lease도 사용합니다. 전체 Matrix transport, media, E2EE inventory를 병렬로 확인하려면 `matrix_profile=all` 및 `matrix_shards=true`로 수동 `QA-Lab - All Lanes` 워크플로를 실행합니다. -- 교차 OS 설치 및 업그레이드 런타임 검증은 공개 `OpenClaw Release Checks`와 `Full Release Validation`의 일부이며, 재사용 가능한 워크플로 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`을 직접 호출합니다. -- 이 분리는 의도된 것입니다. 실제 npm 릴리스 경로는 짧고 결정적이며 산출물 중심으로 유지하고, 더 느린 라이브 검사는 자체 레인에 두어 게시를 지연하거나 차단하지 않게 합니다. -- 비밀을 포함하는 릴리스 검사는 `Full Release Validation`을 통해 디스패치하거나 `main`/릴리스 워크플로 ref에서 디스패치하여 워크플로 로직과 비밀이 통제되도록 해야 합니다. -- `OpenClaw Release Checks`는 해석된 커밋이 OpenClaw 브랜치 또는 릴리스 태그에서 접근 가능하기만 하면 브랜치, 태그 또는 전체 커밋 SHA를 받습니다. -- `OpenClaw NPM Release` 검증 전용 사전 점검도 푸시된 태그를 요구하지 않고 현재 전체 40자 워크플로 브랜치 커밋 SHA를 받습니다. -- 이 SHA 경로는 검증 전용이며 실제 게시로 승격할 수 없습니다. -- SHA 모드에서 워크플로는 패키지 메타데이터 검사에만 `v`을 합성합니다. 실제 게시는 여전히 실제 릴리스 태그가 필요합니다. -- 두 워크플로 모두 실제 게시 및 승격 경로는 GitHub 호스팅 runner에 유지하고, 변경하지 않는 검증 경로는 더 큰 Blacksmith Linux runner를 사용할 수 있습니다. -- 해당 워크플로는 `OPENAI_API_KEY`와 `ANTHROPIC_API_KEY` 워크플로 비밀을 모두 사용하여 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`를 실행합니다. -- npm 릴리스 사전 점검은 더 이상 별도의 릴리스 검사 레인을 기다리지 않습니다. -- 승인 전에 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(또는 일치하는 beta/correction 태그)를 실행합니다. -- npm 게시 후, 새 임시 prefix에서 게시된 레지스트리 설치 경로를 검증하려면 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(또는 일치하는 beta/correction 버전)를 실행합니다. -- beta 게시 후, 공유 leased Telegram 자격 증명 풀을 사용하여 게시된 npm 패키지에 대한 설치 패키지 온보딩, Telegram 설정, 실제 Telegram E2E를 검증하려면 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`를 실행합니다. 로컬 maintainer 단발 실행은 Convex 변수를 생략하고 세 개의 `OPENCLAW_QA_TELEGRAM_*` env 자격 증명을 직접 전달할 수 있습니다. -- Maintainer는 수동 `NPM Telegram Beta E2E` 워크플로를 통해 GitHub Actions에서 동일한 게시 후 검사를 실행할 수 있습니다. 이는 의도적으로 수동 전용이며 모든 merge마다 실행되지 않습니다. -- Maintainer 릴리스 자동화는 이제 사전 점검 후 승격 방식을 사용합니다: - - 실제 npm 게시에는 성공한 npm `preflight_run_id`가 필요합니다. - - 실제 npm 게시는 성공한 사전 점검 실행과 동일한 `main` 또는 `release/YYYY.M.D` 브랜치에서 디스패치되어야 합니다. - - stable npm 릴리스의 기본값은 `beta`입니다. - - stable npm 게시는 워크플로 입력을 통해 명시적으로 `latest`를 대상으로 할 수 있습니다. - - 토큰 기반 npm dist-tag 변경은 이제 보안을 위해 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`에 있습니다. 공개 repo는 OIDC 전용 게시를 유지하지만 `npm dist-tag add`에는 여전히 `NPM_TOKEN`이 필요하기 때문입니다. - - 공개 `macOS Release`는 검증 전용입니다. 태그가 릴리스 브랜치에만 있지만 워크플로가 `main`에서 디스패치되는 경우 `public_release_branch=release/YYYY.M.D`를 설정합니다. - - 실제 비공개 mac 게시는 성공한 비공개 mac `preflight_run_id` 및 `validate_run_id`가 필요합니다. - - 실제 게시 경로는 산출물을 다시 빌드하는 대신 준비된 산출물을 승격합니다. -- `YYYY.M.D-N` 같은 stable correction 릴리스의 경우, 게시 후 검증기는 동일한 임시 prefix 업그레이드 경로도 `YYYY.M.D`에서 `YYYY.M.D-N`까지 검사하여 릴리스 correction이 오래된 글로벌 설치를 기본 stable payload에 조용히 남기지 못하게 합니다. -- npm 릴리스 사전 점검은 tarball에 `dist/control-ui/index.html`과 비어 있지 않은 `dist/control-ui/assets/` payload가 모두 포함되어 있지 않으면 닫힌 상태로 실패하므로 빈 브라우저 대시보드를 다시 배포하지 않습니다. -- 게시 후 검증은 설치된 레지스트리 layout에 게시된 Plugin entrypoint와 패키지 메타데이터가 있는지도 검사합니다. Plugin 런타임 payload가 누락된 릴리스는 postpublish 검증기에 실패하며 `latest`로 승격할 수 없습니다. -- `pnpm test:install:smoke`는 후보 업데이트 tarball에 대한 npm pack `unpackedSize` 예산도 적용하므로, installer e2e가 릴리스 게시 경로 전에 우발적인 pack bloat를 잡아냅니다. -- 릴리스 작업이 CI 계획, extension timing manifest 또는 extension 테스트 매트릭스를 건드렸다면 승인 전에 `.github/workflows/plugin-prerelease.yml`의 planner 소유 `plugin-prerelease-extension-shard` 매트릭스 출력을 다시 생성하고 검토하여 릴리스 노트가 오래된 CI layout을 설명하지 않게 합니다. -- stable macOS 릴리스 준비 상태에는 updater surface도 포함됩니다: - - GitHub 릴리스에는 패키징된 `.zip`, `.dmg`, `.dSYM.zip`이 최종적으로 포함되어야 합니다. - - 게시 후 `main`의 `appcast.xml`은 새 stable zip을 가리켜야 합니다. - - 패키징된 앱은 non-debug bundle id, 비어 있지 않은 Sparkle feed URL, 그리고 해당 릴리스 버전의 정식 Sparkle build floor 이상인 `CFBundleVersion`을 유지해야 합니다. +- `OpenClaw Release Checks`는 릴리스 승인 전에 QA Lab mock parity lane과 빠른 + live Matrix profile 및 Telegram QA lane도 실행합니다. live + lane은 `qa-live-shared` environment를 사용하며, Telegram은 Convex CI + credential lease도 사용합니다. 전체 Matrix + transport, media, E2EE inventory를 병렬로 실행하려면 수동 `QA-Lab - All Lanes` 워크플로를 + `matrix_profile=all` 및 `matrix_shards=true`로 실행합니다. +- Cross-OS install 및 upgrade runtime validation은 public + `OpenClaw Release Checks`와 `Full Release Validation`의 일부이며, 이들은 + reusable workflow + `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`을 직접 호출합니다 +- 이 분리는 의도된 것입니다. 실제 npm 릴리스 경로는 짧고, + 결정적이며, 아티팩트 중심으로 유지하고, 더 느린 live check는 자체 lane에 두어 + publish를 지연하거나 차단하지 않게 합니다 +- Secret을 포함하는 릴리스 검사는 workflow logic과 + secret이 계속 통제되도록 `Full Release Validation`을 통해 또는 `main`/release workflow ref에서 dispatch해야 합니다 +- `OpenClaw Release Checks`는 resolve된 commit이 OpenClaw 브랜치 또는 릴리스 태그에서 도달 가능하다면 + 브랜치, 태그 또는 전체 commit SHA를 허용합니다 +- `OpenClaw NPM Release` validation-only 사전 점검도 pushed tag 없이 현재 + 전체 40자 workflow-branch commit SHA를 허용합니다 +- 해당 SHA 경로는 validation-only이며 실제 publish로 승격할 수 없습니다 +- SHA 모드에서 워크플로는 package metadata check만을 위해 `v`을 합성합니다. + 실제 publish에는 여전히 실제 릴리스 태그가 필요합니다 +- 두 워크플로 모두 실제 publish 및 promotion 경로는 GitHub-hosted + runner에서 유지하고, 변경을 만들지 않는 validation 경로는 더 큰 + Blacksmith Linux runner를 사용할 수 있습니다 +- 해당 워크플로는 + `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`를 + `OPENAI_API_KEY` 및 `ANTHROPIC_API_KEY` workflow secret 모두와 함께 실행합니다 +- npm 릴리스 사전 점검은 더 이상 별도의 release checks lane을 기다리지 않습니다 +- 승인 전에 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts` + (또는 일치하는 beta/correction tag)를 실행합니다 +- npm publish 후에는 + `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D` + (또는 일치하는 beta/correction version)를 실행하여 fresh temp prefix에서 게시된 registry + install 경로를 검증합니다 +- beta publish 후에는 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`를 실행하여 + 공유 leased Telegram credential pool을 사용해 게시된 npm 패키지를 대상으로 installed-package onboarding, Telegram setup, 실제 Telegram E2E를 + 검증합니다. 로컬 maintainer one-off에서는 Convex var를 생략하고 세 개의 + `OPENCLAW_QA_TELEGRAM_*` env credential을 직접 전달할 수 있습니다. +- Maintainer는 GitHub Actions에서 수동 `NPM Telegram Beta E2E` 워크플로를 통해 + 동일한 post-publish check를 실행할 수 있습니다. 이 워크플로는 의도적으로 manual-only이며 + 모든 merge마다 실행되지 않습니다. +- Maintainer 릴리스 자동화는 이제 preflight-then-promote를 사용합니다: + - 실제 npm publish는 성공한 npm `preflight_run_id`를 통과해야 합니다 + - 실제 npm publish는 성공한 preflight run과 동일한 `main` 또는 + `release/YYYY.M.D` 브랜치에서 dispatch되어야 합니다 + - stable npm 릴리스는 기본적으로 `beta`로 설정됩니다 + - stable npm publish는 workflow input을 통해 명시적으로 `latest`를 대상으로 할 수 있습니다 + - token 기반 npm dist-tag 변경은 이제 + `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`에 있습니다. + 이는 보안을 위한 것으로, public repo는 OIDC-only publish를 유지하는 반면 + `npm dist-tag add`에는 여전히 `NPM_TOKEN`이 필요하기 때문입니다 + - public `macOS Release`는 validation-only입니다. 태그가 + 릴리스 브랜치에만 있지만 워크플로가 `main`에서 dispatch되는 경우 + `public_release_branch=release/YYYY.M.D`를 설정합니다 + - 실제 private mac publish는 성공한 private mac + `preflight_run_id` 및 `validate_run_id`를 통과해야 합니다 + - 실제 publish 경로는 아티팩트를 다시 빌드하는 대신 준비된 아티팩트를 promote합니다 +- `YYYY.M.D-N` 같은 stable correction 릴리스의 경우 post-publish verifier는 + 동일한 temp-prefix upgrade 경로도 `YYYY.M.D`에서 `YYYY.M.D-N`으로 확인하여 + 릴리스 correction이 기존 global install을 base stable payload에 + 조용히 남겨두지 못하게 합니다 +- npm 릴리스 사전 점검은 tarball에 `dist/control-ui/index.html`과 비어 있지 않은 `dist/control-ui/assets/` payload가 모두 포함되지 않으면 + fail closed하여 빈 browser dashboard를 다시 배포하지 않도록 합니다 +- Post-publish verification은 게시된 Plugin entrypoint와 + package metadata가 설치된 registry layout에 있는지도 확인합니다. 누락된 Plugin runtime payload를 + 포함해 릴리스하면 postpublish verifier가 실패하고 + `latest`로 승격할 수 없습니다. +- `pnpm test:install:smoke`는 candidate update tarball에 대한 npm pack `unpackedSize` budget도 + 강제하므로, installer e2e가 릴리스 publish 경로 전에 의도치 않은 pack bloat를 + 잡아냅니다 +- 릴리스 작업이 CI planning, extension timing manifest 또는 + extension test matrix를 건드렸다면, 승인 전에 + `.github/workflows/plugin-prerelease.yml`의 planner-owned + `plugin-prerelease-extension-shard` matrix output을 regenerate하고 review하여 릴리스 노트가 + stale CI layout을 설명하지 않도록 합니다 +- Stable macOS 릴리스 준비 상태에는 updater surface도 포함됩니다: + - GitHub release에는 최종적으로 packaged `.zip`, `.dmg`, `.dSYM.zip`이 포함되어야 합니다 + - `main`의 `appcast.xml`은 publish 후 새 stable zip을 가리켜야 합니다 + - packaged app은 non-debug bundle id, 비어 있지 않은 Sparkle feed + URL, 그리고 해당 릴리스 버전에 대한 canonical Sparkle build floor 이상인 `CFBundleVersion`을 유지해야 합니다 ## 릴리스 테스트 박스 -`Full Release Validation`은 운영자가 하나의 진입점에서 모든 사전 릴리스 테스트를 시작하는 방법입니다. 빠르게 변하는 브랜치에서 고정된 커밋 증거가 필요하면 helper를 사용하여 모든 하위 워크플로가 대상 SHA에 고정된 임시 브랜치에서 실행되게 합니다: +`Full Release Validation`은 운영자가 하나의 진입점에서 모든 사전 릴리스 테스트를 +시작하는 방법입니다. 빠르게 움직이는 브랜치에서 pinned commit proof가 필요하면, +모든 child workflow가 target +SHA에 고정된 임시 브랜치에서 실행되도록 helper를 사용합니다: ```bash pnpm ci:full-release --sha ``` -이 helper는 `release-ci/-...`를 푸시하고, 해당 브랜치에서 `ref=`로 `Full Release Validation`을 디스패치하며, 모든 하위 워크플로 `headSha`가 대상과 일치하는지 검증한 다음 임시 브랜치를 삭제합니다. 이렇게 하면 실수로 더 최신 `main` 하위 실행을 증명하는 일을 피할 수 있습니다. +이 helper는 `release-ci/-...`를 push하고, 해당 브랜치에서 `ref=`로 `Full Release Validation`을 +dispatch하며, 모든 child workflow `headSha`가 +target과 일치하는지 검증한 다음 임시 브랜치를 삭제합니다. 이렇게 하면 실수로 +더 최신 `main` child run을 증명하는 일을 피할 수 있습니다. -릴리스 브랜치 또는 태그 검증의 경우, 신뢰할 수 있는 `main` 워크플로 ref에서 실행하고 릴리스 브랜치 또는 태그를 `ref`로 전달합니다: +릴리스 브랜치 또는 태그 검증의 경우 신뢰할 수 있는 `main` workflow +ref에서 실행하고 릴리스 브랜치 또는 태그를 `ref`로 전달합니다: ```bash gh workflow run full-release-validation.yml \ @@ -181,19 +276,44 @@ gh workflow run full-release-validation.yml \ -f evidence_package_spec=openclaw@YYYY.M.D-beta.N ``` -워크플로는 대상 ref를 해석하고, 수동 `CI`를 `target_ref=`로 디스패치하며, `OpenClaw Release Checks`를 디스패치하고, `release_profile=full`이면서 `rerun_group=all`인 경우 또는 `npm_telegram_package_spec`이 설정된 경우 독립 실행형 패키지 Telegram E2E를 디스패치합니다. 그런 다음 `OpenClaw Release Checks`는 install smoke, cross-OS 릴리스 검사, live/E2E Docker 릴리스 경로 커버리지, Telegram 패키지 QA가 포함된 Package Acceptance, QA Lab parity, live Matrix, live Telegram으로 팬아웃됩니다. 전체 실행은 `Full Release Validation` 요약에서 `normal_ci`와 `release_checks`가 성공으로 표시될 때만 허용됩니다. full/all 모드에서는 `npm_telegram` 하위 항목도 성공해야 합니다. full/all 외부에서는 게시된 `npm_telegram_package_spec`가 제공된 경우가 아니면 건너뜁니다. 최종 검증자 요약에는 각 하위 실행의 가장 느린 작업 표가 포함되므로, 릴리스 관리자는 로그를 다운로드하지 않고도 현재 critical path를 볼 수 있습니다. -전체 단계 매트릭스, 정확한 워크플로 작업 이름, stable 프로필과 full 프로필의 차이, 아티팩트, 집중 rerun 핸들은 [전체 릴리스 검증](/ko/reference/full-release-validation)을 참고하세요. -하위 워크플로는 대상 `ref`가 더 오래된 릴리스 브랜치나 태그를 가리키는 경우에도, `Full Release Validation`을 실행하는 신뢰된 ref, 일반적으로 `--ref main`에서 디스패치됩니다. 별도의 Full Release Validation workflow-ref 입력은 없습니다. 워크플로 실행 ref를 선택하여 신뢰된 하네스를 선택하세요. -이동하는 `main`에서 정확한 커밋 증명을 위해 `--ref main -f ref=`를 사용하지 마세요. 원시 커밋 SHA는 워크플로 디스패치 ref가 될 수 없으므로, 고정된 임시 브랜치를 만들려면 `pnpm ci:full-release --sha `를 사용하세요. +워크플로는 대상 ref를 해석하고, 수동 `CI`를 +`target_ref=`로 디스패치하며, `OpenClaw Release Checks`를 디스패치하고, +`release_profile=full`이면서 `rerun_group=all`이거나 `npm_telegram_package_spec`이 설정된 경우 +독립 실행형 패키지 Telegram E2E를 디스패치합니다. 그런 다음 `OpenClaw Release +Checks`는 설치 스모크, 크로스 OS 릴리스 검사, 라이브/E2E Docker +릴리스 경로 커버리지, Telegram 패키지 QA가 포함된 Package Acceptance, QA Lab +패리티, 라이브 Matrix, 라이브 Telegram으로 팬아웃합니다. 전체 실행은 +`Full Release Validation` +요약에 `normal_ci`와 `release_checks`가 성공으로 표시될 때만 허용됩니다. full/all 모드에서는 +`npm_telegram` 자식도 성공해야 합니다. full/all 외부에서는 게시된 +`npm_telegram_package_spec`이 제공되지 않는 한 건너뜁니다. 최종 +검증기 요약에는 각 자식 실행의 가장 느린 작업 표가 포함되므로, 릴리스 +관리자가 로그를 다운로드하지 않고도 현재 중요 경로를 확인할 수 있습니다. +전체 단계 매트릭스, 정확한 워크플로 작업 이름, stable 프로필과 full 프로필의 +차이, 아티팩트, 집중 재실행 핸들은 [전체 릴리스 검증](/ko/reference/full-release-validation)을 참조하세요. +자식 워크플로는 대상 `ref`가 +이전 릴리스 브랜치나 태그를 가리키더라도 `Full Release +Validation`을 실행하는 신뢰된 ref, 일반적으로 `--ref main`에서 디스패치됩니다. +별도의 Full Release Validation workflow-ref 입력은 없습니다. 워크플로 실행 ref를 선택하여 신뢰할 수 있는 하네스를 선택하세요. +이동하는 `main`에서 정확한 커밋 증명에 `--ref main -f ref=`를 사용하지 마세요. +원시 커밋 SHA는 워크플로 디스패치 ref가 될 수 없으므로, +`pnpm ci:full-release --sha `를 사용해 고정된 임시 브랜치를 생성하세요. -live/provider 범위를 선택하려면 `release_profile`을 사용하세요. +라이브/프로바이더 범위를 선택하려면 `release_profile`을 사용하세요. -- `minimum`: 가장 빠른 릴리스 핵심 OpenAI/core live 및 Docker 경로 -- `stable`: 릴리스 승인을 위한 minimum에 stable provider/backend 커버리지 추가 -- `full`: stable에 광범위한 advisory provider/media 커버리지 추가 +- `minimum`: 가장 빠른 릴리스 핵심 OpenAI/코어 라이브 및 Docker 경로 +- `stable`: 릴리스 승인을 위한 최소 범위와 stable 프로바이더/백엔드 커버리지 +- `full`: stable에 광범위한 권고 프로바이더/미디어 커버리지 추가 -`OpenClaw Release Checks`는 신뢰된 워크플로 ref를 사용하여 대상 ref를 한 번 `release-package-under-test`로 해석하고, 해당 아티팩트를 릴리스 경로 Docker 검사와 Package Acceptance 양쪽에서 재사용합니다. 이렇게 하면 모든 package-facing box가 같은 바이트를 사용하게 되고 반복적인 패키지 빌드를 피할 수 있습니다. -cross-OS OpenAI install smoke는 repo/org 변수가 설정된 경우 `OPENCLAW_CROSS_OS_OPENAI_MODEL`을 사용하고, 그렇지 않으면 `openai/gpt-5.4`를 사용합니다. 이 lane은 가장 느린 기본 모델을 벤치마킹하는 것이 아니라 패키지 설치, 온보딩, Gateway 시작, live agent 한 턴을 증명하기 때문입니다. 더 넓은 live provider matrix가 모델별 커버리지를 담당하는 위치로 남습니다. +`OpenClaw Release Checks`는 신뢰된 워크플로 ref를 사용해 대상 +ref를 `release-package-under-test`로 한 번 해석하고, 해당 아티팩트를 +릴리스 경로 Docker 검사와 Package Acceptance 양쪽에서 재사용합니다. 이렇게 하면 모든 +패키지 대상 박스가 동일한 바이트를 사용하고 반복적인 패키지 빌드를 피할 수 있습니다. +크로스 OS OpenAI 설치 스모크는 repo/org 변수가 설정된 경우 +`OPENCLAW_CROSS_OS_OPENAI_MODEL`을 사용하고, 그렇지 않으면 `openai/gpt-5.4`를 사용합니다. 이 레인은 +가장 느린 기본 모델을 벤치마킹하는 것이 아니라 패키지 설치, 온보딩, Gateway 시작, +그리고 하나의 라이브 에이전트 턴을 증명하기 때문입니다. 더 넓은 라이브 프로바이더 +매트릭스는 모델별 커버리지를 담당합니다. 릴리스 단계에 따라 다음 변형을 사용하세요. @@ -225,24 +345,40 @@ gh workflow run full-release-validation.yml \ -f npm_telegram_provider_mode=mock-openai ``` -집중 수정 후 첫 rerun으로 full umbrella를 사용하지 마세요. 한 box가 실패하면 다음 증명에는 실패한 하위 워크플로, 작업, Docker lane, 패키지 프로필, 모델 provider 또는 QA lane을 사용하세요. 수정이 공유 릴리스 오케스트레이션을 변경했거나 이전 all-box 증거를 더 이상 유효하지 않게 만든 경우에만 full umbrella를 다시 실행하세요. umbrella의 최종 검증자는 기록된 하위 워크플로 실행 ID를 다시 확인하므로, 하위 워크플로가 성공적으로 rerun된 후에는 실패한 `Verify full validation` 상위 작업만 rerun하세요. +집중 수정 후 첫 재실행으로 전체 엄브렐러를 사용하지 마세요. 하나의 박스가 +실패하면 다음 증명에는 실패한 자식 워크플로, 작업, Docker 레인, 패키지 프로필, 모델 +프로바이더, 또는 QA 레인을 사용하세요. 수정이 공유 릴리스 오케스트레이션을 변경했거나 +이전 전체 박스 증거를 오래된 것으로 만든 경우에만 전체 엄브렐러를 다시 실행하세요. +엄브렐러의 최종 검증기는 기록된 자식 워크플로 실행 +id를 다시 검사하므로, 자식 워크플로가 성공적으로 재실행된 후에는 실패한 +`Verify full validation` 부모 작업만 재실행하세요. -제한된 복구를 위해 umbrella에 `rerun_group`을 전달하세요. `all`은 실제 릴리스 후보 실행이고, `ci`는 일반 CI 하위 항목만 실행하며, `plugin-prerelease`는 릴리스 전용 Plugin 하위 항목만 실행하고, `release-checks`는 모든 릴리스 box를 실행합니다. 더 좁은 릴리스 그룹은 `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live`, `npm-telegram`입니다. -집중 `npm-telegram` rerun에는 `npm_telegram_package_spec`가 필요합니다. `release_profile=full`인 full/all 실행은 release-checks 패키지 아티팩트를 사용합니다. +범위가 제한된 복구에는 `rerun_group`을 엄브렐러에 전달하세요. `all`은 실제 +릴리스 후보 실행이고, `ci`는 일반 CI 자식만 실행하며, `plugin-prerelease`는 +릴리스 전용 Plugin 자식만 실행하고, `release-checks`는 모든 릴리스 +박스를 실행합니다. 더 좁은 릴리스 그룹은 `install-smoke`, `cross-os`, +`live-e2e`, `package`, `qa`, `qa-parity`, `qa-live`, `npm-telegram`입니다. +집중 `npm-telegram` 재실행에는 `npm_telegram_package_spec`이 필요합니다. `release_profile=full`인 full/all 실행은 +release-checks 패키지 아티팩트를 사용합니다. ### Vitest -Vitest box는 수동 `CI` 하위 워크플로입니다. 수동 CI는 의도적으로 changed scoping을 우회하고 릴리스 후보에 대해 일반 테스트 그래프를 강제합니다. 여기에는 Linux Node shard, 번들 Plugin shard, 채널 계약, Node 22 호환성, `check`, `check-additional`, build smoke, docs checks, Python Skills, Windows, macOS, Android, Control UI i18n이 포함됩니다. +Vitest 박스는 수동 `CI` 자식 워크플로입니다. 수동 CI는 의도적으로 +변경 범위 지정을 우회하고 릴리스 후보에 대해 일반 테스트 그래프를 강제합니다: +Linux Node 샤드, 번들 Plugin 샤드, 채널 계약, Node 22 +호환성, `check`, `check-additional`, 빌드 스모크, 문서 검사, Python +Skills, Windows, macOS, Android, Control UI i18n입니다. -"소스 트리가 전체 일반 테스트 스위트를 통과했는가?"에 답하려면 이 box를 사용하세요. -이는 release-path 제품 검증과 같지 않습니다. 보관할 증거: +이 박스는 "소스 트리가 전체 일반 테스트 스위트를 통과했는가?"에 답할 때 사용하세요. +이는 릴리스 경로 제품 검증과 같지 않습니다. 보관할 증거: - 디스패치된 `CI` 실행 URL을 보여주는 `Full Release Validation` 요약 -- 정확한 대상 SHA에서 녹색인 `CI` 실행 -- 회귀를 조사할 때 CI 작업의 실패했거나 느린 shard 이름 -- 실행에 성능 분석이 필요한 경우 `.artifacts/vitest-shard-timings.json` 같은 Vitest 타이밍 아티팩트 +- 정확한 대상 SHA에서 성공한 `CI` 실행 +- 회귀를 조사할 때 CI 작업의 실패했거나 느린 샤드 이름 +- 실행에 성능 분석이 필요할 때 `.artifacts/vitest-shard-timings.json` 같은 Vitest 타이밍 아티팩트 -릴리스에 결정적인 일반 CI가 필요하지만 Docker, QA Lab, live, cross-OS 또는 package box가 필요하지 않을 때만 수동 CI를 직접 실행하세요. +릴리스에 결정적인 일반 CI가 필요하지만 Docker, QA Lab, 라이브, 크로스 OS, +또는 패키지 박스가 필요하지 않은 경우에만 수동 CI를 직접 실행하세요. ```bash gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D @@ -250,52 +386,109 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D ### Docker -Docker box는 `openclaw-live-and-e2e-checks-reusable.yml`을 통한 `OpenClaw Release Checks`와 릴리스 모드 `install-smoke` 워크플로에 있습니다. 이는 소스 수준 테스트만이 아니라 패키지화된 Docker 환경을 통해 릴리스 후보를 검증합니다. +Docker 박스는 `openclaw-live-and-e2e-checks-reusable.yml`을 통한 +`OpenClaw Release Checks`와 릴리스 모드 +`install-smoke` 워크플로에 있습니다. 이는 소스 수준 테스트만이 아니라 패키징된 +Docker 환경을 통해 릴리스 후보를 검증합니다. 릴리스 Docker 커버리지에는 다음이 포함됩니다. -- 느린 Bun global install smoke가 활성화된 전체 install smoke -- 대상 SHA별 root Dockerfile smoke 이미지 준비/재사용, QR, root/gateway, installer/Bun smoke 작업이 별도 install-smoke shard로 실행됨 -- repository E2E lane -- release-path Docker chunk: `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, `plugins-runtime-install-a`, `plugins-runtime-install-b`, `plugins-runtime-install-c`, `plugins-runtime-install-d`, `plugins-runtime-install-e`, `plugins-runtime-install-f`, `plugins-runtime-install-g`, `plugins-runtime-install-h` -- 요청된 경우 `plugins-runtime-services` chunk 내부의 OpenWebUI 커버리지 -- `bundled-plugin-install-uninstall-0`부터 `bundled-plugin-install-uninstall-23`까지 분할된 번들 Plugin 설치/제거 lane -- release checks에 live suite가 포함된 경우 live/E2E provider suite 및 Docker live 모델 커버리지 +- 느린 Bun 전역 설치 스모크가 활성화된 전체 설치 스모크 +- 대상 SHA별 루트 Dockerfile 스모크 이미지 준비/재사용, QR, + 루트/Gateway, installer/Bun 스모크 작업이 별도의 install-smoke + 샤드로 실행됨 +- 리포지토리 E2E 레인 +- 릴리스 경로 Docker 청크: `core`, `package-update-openai`, + `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, + `plugins-runtime-services`, + `plugins-runtime-install-a`, `plugins-runtime-install-b`, + `plugins-runtime-install-c`, `plugins-runtime-install-d`, + `plugins-runtime-install-e`, `plugins-runtime-install-f`, + `plugins-runtime-install-g`, `plugins-runtime-install-h` +- 요청 시 `plugins-runtime-services` 청크 내부의 OpenWebUI 커버리지 +- 분리된 번들 Plugin 설치/제거 레인 + `bundled-plugin-install-uninstall-0`부터 + `bundled-plugin-install-uninstall-23`까지 +- 릴리스 검사가 라이브 스위트를 포함할 때 라이브/E2E 프로바이더 스위트 및 Docker 라이브 모델 커버리지 -rerun하기 전에 Docker 아티팩트를 사용하세요. release-path scheduler는 lane 로그, `summary.json`, `failures.json`, phase timing, scheduler plan JSON, rerun 명령이 포함된 `.artifacts/docker-tests/`를 업로드합니다. 집중 복구에는 모든 릴리스 chunk를 rerun하는 대신 reusable live/E2E 워크플로에서 `docker_lanes=`를 사용하세요. 생성된 rerun 명령에는 사용 가능한 경우 이전 `package_artifact_run_id`와 준비된 Docker 이미지 입력이 포함되므로, 실패한 lane은 같은 tarball과 GHCR 이미지를 재사용할 수 있습니다. +재실행하기 전에 Docker 아티팩트를 사용하세요. 릴리스 경로 스케줄러는 +레인 로그, `summary.json`, `failures.json`, +단계 타이밍, 스케줄러 계획 JSON, 재실행 명령이 포함된 +`.artifacts/docker-tests/`를 업로드합니다. 집중 복구에는 +모든 릴리스 청크를 재실행하는 대신 재사용 가능한 live/E2E 워크플로에서 +`docker_lanes=`을 사용하세요. 생성된 재실행 명령에는 사용 가능한 경우 이전 +`package_artifact_run_id`와 준비된 Docker 이미지 입력이 포함되므로, +실패한 레인이 동일한 타볼과 GHCR 이미지를 재사용할 수 있습니다. ### QA Lab -QA Lab box도 `OpenClaw Release Checks`의 일부입니다. 이는 Vitest 및 Docker 패키지 메커니즘과 별개인 agentic behavior 및 채널 수준 릴리스 gate입니다. +QA Lab 박스도 `OpenClaw Release Checks`의 일부입니다. 이는 Vitest 및 Docker +패키지 메커니즘과 별개인 에이전트 동작 및 채널 수준 릴리스 게이트입니다. 릴리스 QA Lab 커버리지에는 다음이 포함됩니다. -- agentic parity pack을 사용하여 OpenAI 후보 lane을 Opus 4.6 baseline과 비교하는 mock parity lane -- `qa-live-shared` 환경을 사용하는 빠른 live Matrix QA 프로필 -- Convex CI credential lease를 사용하는 live Telegram QA lane -- 릴리스 telemetry에 명시적인 로컬 증명이 필요한 경우 `pnpm qa:otel:smoke` +- agentic 패리티 팩을 사용해 OpenAI 후보 레인을 Opus 4.6 + 기준선과 비교하는 mock 패리티 레인 +- `qa-live-shared` 환경을 사용하는 빠른 라이브 Matrix QA 프로필 +- Convex CI 자격 증명 임대를 사용하는 라이브 Telegram QA 레인 +- 릴리스 텔레메트리에 명시적인 로컬 증명이 필요할 때 `pnpm qa:otel:smoke` -"릴리스가 QA 시나리오와 live 채널 flow에서 올바르게 동작하는가?"에 답하려면 이 box를 사용하세요. 릴리스를 승인할 때 parity, Matrix, Telegram lane의 아티팩트 URL을 보관하세요. 전체 Matrix 커버리지는 기본 릴리스 핵심 lane이 아니라 수동 sharded QA-Lab 실행으로 계속 사용할 수 있습니다. +이 박스는 "릴리스가 QA 시나리오와 라이브 채널 흐름에서 올바르게 동작하는가?"에 답할 때 사용하세요. +릴리스를 승인할 때 패리티, Matrix, Telegram +레인의 아티팩트 URL을 보관하세요. 전체 Matrix 커버리지는 기본 릴리스 핵심 레인이 아니라 +수동 샤딩 QA-Lab 실행으로 계속 사용할 수 있습니다. -### Package +### 패키지 -Package box는 설치 가능한 제품 gate입니다. 이는 `Package Acceptance`와 resolver `scripts/resolve-openclaw-package-candidate.mjs`로 뒷받침됩니다. resolver는 후보를 Docker E2E가 소비하는 `package-under-test` tarball로 정규화하고, 패키지 inventory를 검증하며, 패키지 버전과 SHA-256을 기록하고, 워크플로 하네스 ref를 패키지 소스 ref와 분리해 유지합니다. +패키지 박스는 설치 가능한 제품 게이트입니다. 이는 +`Package Acceptance`와 resolver +`scripts/resolve-openclaw-package-candidate.mjs`가 뒷받침합니다. resolver는 +후보를 Docker E2E가 소비하는 `package-under-test` 타볼로 정규화하고, +패키지 인벤토리를 검증하며, 패키지 버전과 SHA-256을 기록하고, +워크플로 하네스 ref를 패키지 소스 ref와 분리해 유지합니다. 지원되는 후보 소스: -- `source=npm`: `openclaw@beta`, `openclaw@latest` 또는 정확한 OpenClaw 릴리스 버전 -- `source=ref`: 선택한 `workflow_ref` 하네스로 신뢰된 `package_ref` 브랜치, 태그 또는 전체 커밋 SHA를 pack -- `source=url`: 필수 `package_sha256`이 있는 HTTPS `.tgz` 다운로드 +- `source=npm`: `openclaw@beta`, `openclaw@latest`, 또는 정확한 OpenClaw 릴리스 + 버전 +- `source=ref`: 선택한 `workflow_ref` 하네스로 신뢰된 `package_ref` 브랜치, 태그, 또는 전체 커밋 SHA를 패키징 +- `source=url`: 필수 `package_sha256`이 포함된 HTTPS `.tgz` 다운로드 - `source=artifact`: 다른 GitHub Actions 실행이 업로드한 `.tgz` 재사용 -`OpenClaw Release Checks`는 `source=artifact`, 준비된 릴리스 패키지 아티팩트, `suite_profile=custom`, `docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`, `published_upgrade_survivor_baselines=all-since-2026.4.23`, `published_upgrade_survivor_scenarios=reported-issues`, `telegram_mode=mock-openai`로 Package Acceptance를 실행합니다. Package Acceptance는 마이그레이션, 업데이트, stale Plugin dependency cleanup, offline Plugin fixture, Plugin update, Telegram package QA를 같은 해석된 tarball에 대해 유지합니다. upgrade matrix는 `2026.4.23`부터 `latest`까지 npm에 게시된 모든 stable baseline을 포함합니다. 이미 배포된 후보에는 `source=npm`으로 Package Acceptance를 사용하고, publish 전 SHA 기반 로컬 npm tarball에는 `source=ref`/`source=artifact`를 사용하세요. 이는 이전에 Parallels가 필요했던 대부분의 package/update 커버리지를 대체하는 GitHub-native 방식입니다. Cross-OS release checks는 OS별 온보딩, installer, platform behavior에 여전히 중요하지만, package/update 제품 검증은 Package Acceptance를 우선해야 합니다. +`OpenClaw Release Checks`는 준비된 릴리스 패키지 아티팩트와 함께 `source=artifact`, +`suite_profile=custom`, +`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`, +`published_upgrade_survivor_baselines=all-since-2026.4.23`, +`published_upgrade_survivor_scenarios=reported-issues`, 그리고 +`telegram_mode=mock-openai`로 Package Acceptance를 실행합니다. Package Acceptance는 마이그레이션, 업데이트, 오래된 +Plugin 종속성 정리, 오프라인 Plugin 픽스처, Plugin 업데이트, Telegram +패키지 QA를 동일하게 해석된 타볼에 대해 유지합니다. 업그레이드 매트릭스는 `2026.4.23`부터 `latest`까지 npm에 게시된 모든 stable 기준선을 포함합니다. 이미 출하된 후보에는 +`source=npm`으로 Package Acceptance를 사용하고, 게시 전에 SHA로 뒷받침되는 로컬 npm 타볼에는 +`source=ref`/`source=artifact`를 사용하세요. 이는 이전에 +Parallels가 필요했던 대부분의 패키지/업데이트 커버리지를 대체하는 GitHub 네이티브 +대안입니다. 크로스 OS 릴리스 검사는 OS별 온보딩, +installer, 플랫폼 동작에 여전히 중요하지만, 패키지/업데이트 제품 검증에는 +Package Acceptance를 선호해야 합니다. -업데이트와 Plugin 검증을 위한 표준 체크리스트는 [업데이트 및 Plugin 테스트](/ko/help/testing-updates-plugins)입니다. Plugin 설치/업데이트, doctor cleanup 또는 published-package migration 변경을 증명하는 local, Docker, Package Acceptance 또는 release-check lane을 결정할 때 사용하세요. -모든 stable `2026.4.23+` 패키지에서 수행하는 포괄적인 published update migration은 Full Release CI의 일부가 아니라 별도의 수동 `Update Migration` 워크플로입니다. +업데이트와 Plugin 검증을 위한 표준 체크리스트는 +[업데이트 및 Plugin 테스트](/ko/help/testing-updates-plugins)입니다. Plugin 설치/업데이트, +doctor 정리, 또는 게시된 패키지 마이그레이션 변경을 어떤 로컬, Docker, +Package Acceptance, 또는 release-check 레인이 증명하는지 결정할 때 사용하세요. +모든 stable `2026.4.23+` 패키지에서 게시된 업데이트 마이그레이션을 exhaustive하게 수행하는 것은 +별도의 수동 `Update Migration` 워크플로이며, Full Release CI의 일부가 아닙니다. -Legacy package-acceptance leniency는 의도적으로 시간 제한이 있습니다. `2026.4.25`까지의 패키지는 이미 npm에 게시된 metadata gap에 대해 compatibility path를 사용할 수 있습니다. 여기에는 tarball에 없는 private QA inventory entry, 누락된 `gateway install --wrapper`, tarball에서 파생된 git fixture의 누락된 patch file, 누락된 persisted `update.channel`, legacy Plugin install-record 위치, 누락된 marketplace install-record persistence, `plugins update` 중 config metadata migration이 포함됩니다. 게시된 `2026.4.26` 패키지는 이미 배포된 local build metadata stamp file에 대해 경고할 수 있습니다. 이후 패키지는 현대적인 패키지 계약을 충족해야 합니다. 동일한 gap은 release validation을 실패시킵니다. +레거시 package-acceptance 완화는 의도적으로 시간 제한이 있습니다. `2026.4.25`까지의 패키지는 +이미 npm에 게시된 메타데이터 공백에 대해 호환성 경로를 사용할 수 있습니다: +타볼에 없는 비공개 QA 인벤토리 항목, 누락된 +`gateway install --wrapper`, 타볼에서 파생된 git +픽스처에 없는 패치 파일, 누락된 영속 `update.channel`, 레거시 Plugin 설치 기록 +위치, 누락된 marketplace 설치 기록 영속성, 그리고 `plugins update` 중 config 메타데이터 +마이그레이션입니다. 게시된 `2026.4.26` 패키지는 +이미 출하된 로컬 빌드 메타데이터 스탬프 파일에 대해 경고할 수 있습니다. 이후 패키지는 +현대적인 패키지 계약을 충족해야 합니다. 동일한 공백은 릴리스 +검증을 실패시킵니다. -릴리스 질문이 실제 설치 가능한 패키지에 관한 것일 때는 더 넓은 Package Acceptance 프로필을 사용하세요. +릴리스 질문이 실제 설치 가능한 패키지에 관한 것일 때 더 넓은 Package Acceptance 프로필을 사용하세요. ```bash gh workflow run package-acceptance.yml \ @@ -309,29 +502,32 @@ gh workflow run package-acceptance.yml \ 일반적인 패키지 프로필: -- `smoke`: 빠른 패키지 설치/채널/agent, Gateway 네트워크, config reload lane -- `package`: live ClawHub 없이 install/update/Plugin package contract; 이것이 release-check 기본값 -- `product`: `package`에 MCP channel, cron/subagent cleanup, OpenAI web search, OpenWebUI 추가 -- `full`: OpenWebUI가 포함된 Docker release-path chunk -- `custom`: 집중 rerun을 위한 정확한 `docker_lanes` 목록 +- `smoke`: 빠른 패키지 설치/채널/에이전트, Gateway 네트워크, config + reload 레인 +- `package`: 라이브 ClawHub 없는 설치/업데이트/Plugin 패키지 계약. 이것이 release-check + 기본값입니다 +- `product`: `package`에 MCP 채널, Cron/서브에이전트 정리, OpenAI 웹 + 검색, OpenWebUI 추가 +- `full`: OpenWebUI가 포함된 Docker 릴리스 경로 청크 +- `custom`: 집중 재실행을 위한 정확한 `docker_lanes` 목록 -패키지 후보 Telegram 검증의 경우 Package Acceptance에서 `telegram_mode=mock-openai` 또는 -`telegram_mode=live-frontier`를 활성화하세요. 워크플로는 확인된 -`package-under-test` tarball을 Telegram 레인에 전달합니다. 독립 실행형 -Telegram 워크플로는 게시 후 확인을 위해 게시된 npm spec도 계속 허용합니다. +패키지 후보 Telegram 검증에는 Package Acceptance에서 `telegram_mode=mock-openai` 또는 +`telegram_mode=live-frontier`를 활성화하세요. 이 워크플로는 확인된 +`package-under-test` tarball을 Telegram 레인에 전달합니다. 독립형 +Telegram 워크플로는 게시 후 검사를 위해 여전히 게시된 npm 사양을 허용합니다. ## 릴리스 게시 자동화 `OpenClaw Release Publish`는 일반적인 변경성 게시 진입점입니다. 릴리스에 필요한 순서대로 신뢰할 수 있는 게시자 워크플로를 오케스트레이션합니다. -1. 릴리스 태그를 체크아웃하고 해당 commit SHA를 확인합니다. +1. 릴리스 태그를 체크아웃하고 해당 커밋 SHA를 확인합니다. 2. 태그가 `main` 또는 `release/*`에서 도달 가능한지 확인합니다. 3. `pnpm plugins:sync:check`를 실행합니다. 4. `publish_scope=all-publishable` 및 `ref=`로 `Plugin NPM Release`를 디스패치합니다. 5. 동일한 범위와 SHA로 `Plugin ClawHub Release`를 디스패치합니다. -6. 릴리스 태그, npm dist-tag, 저장된 `preflight_run_id`로 +6. 릴리스 태그, npm 배포 태그, 저장된 `preflight_run_id`로 `OpenClaw NPM Release`를 디스패치합니다. 베타 게시 예시: @@ -344,17 +540,7 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=beta ``` -알파 게시 예시: - -```bash -gh workflow run openclaw-release-publish.yml \ - --ref release/YYYY.M.D \ - -f tag=vYYYY.M.D-alpha.N \ - -f preflight_run_id= \ - -f npm_dist_tag=alpha -``` - -기본 beta dist-tag로 안정 버전 게시: +기본 베타 배포 태그로 안정 버전 게시: ```bash gh workflow run openclaw-release-publish.yml \ @@ -364,7 +550,7 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=beta ``` -`latest`로 직접 안정 버전을 승격하는 작업은 명시적입니다. +`latest`로 직접 안정 버전 승격은 명시적으로 수행합니다. ```bash gh workflow run openclaw-release-publish.yml \ @@ -375,84 +561,62 @@ gh workflow run openclaw-release-publish.yml \ ``` 하위 수준 `Plugin NPM Release` 및 `Plugin ClawHub Release` 워크플로는 -집중적인 복구 또는 재게시 작업에만 사용하세요. 선택한 Plugin 복구의 경우 +집중 복구 또는 재게시 작업에만 사용하세요. 선택한 Plugin 복구의 경우 `plugin_publish_scope=selected` 및 `plugins=@openclaw/name`을 `OpenClaw Release Publish`에 전달하거나, OpenClaw 패키지를 게시하면 안 되는 경우 -하위 워크플로를 직접 디스패치하세요. +자식 워크플로를 직접 디스패치하세요. ## NPM 워크플로 입력 `OpenClaw NPM Release`는 다음 운영자 제어 입력을 허용합니다. -- `tag`: `v2026.4.2`, `v2026.4.2-1` 또는 - `v2026.4.2-alpha.1`이나 `v2026.4.2-beta.1` 같은 필수 릴리스 태그입니다. `preflight_only=true`인 경우, 검증 전용 사전 점검을 위해 현재 - 전체 40자 워크플로 브랜치 commit SHA도 사용할 수 있습니다. -- `preflight_only`: 검증/빌드/패키지만 수행하려면 `true`, 실제 게시 경로에는 - `false` -- `preflight_run_id`: 실제 게시 경로에서 필수이며, 워크플로가 성공한 사전 점검 실행에서 준비된 tarball을 재사용하도록 합니다. -- `npm_dist_tag`: 게시 경로의 npm 대상 태그이며, 기본값은 `beta`입니다. +- `tag`: `v2026.4.2`, `v2026.4.2-1`, `v2026.4.2-beta.1` 같은 필수 릴리스 태그입니다. `preflight_only=true`일 때는 검증 전용 사전 확인을 위해 현재 전체 40자 워크플로 브랜치 커밋 SHA도 사용할 수 있습니다. +- `preflight_only`: 검증/빌드/패키지만 수행하려면 `true`, 실제 게시 경로에는 `false`입니다. +- `preflight_run_id`: 실제 게시 경로에서 필수이며, 워크플로가 성공한 사전 확인 실행에서 준비된 tarball을 재사용하도록 합니다. +- `npm_dist_tag`: 게시 경로의 npm 대상 태그입니다. 기본값은 `beta`입니다. `OpenClaw Release Publish`는 다음 운영자 제어 입력을 허용합니다. -- `tag`: 필수 릴리스 태그이며, 이미 존재해야 합니다. -- `preflight_run_id`: 성공한 `OpenClaw NPM Release` 사전 점검 실행 id입니다. - `publish_openclaw_npm=true`일 때 필수입니다. +- `tag`: 필수 릴리스 태그입니다. 이미 존재해야 합니다. +- `preflight_run_id`: 성공한 `OpenClaw NPM Release` 사전 확인 실행 ID입니다. `publish_openclaw_npm=true`일 때 필수입니다. - `npm_dist_tag`: OpenClaw 패키지의 npm 대상 태그입니다. -- `plugin_publish_scope`: 기본값은 `all-publishable`입니다. 집중적인 복구 작업에만 - `selected`를 사용하세요. -- `plugins`: `plugin_publish_scope=selected`일 때 쉼표로 구분된 - `@openclaw/*` 패키지 이름입니다. +- `plugin_publish_scope`: 기본값은 `all-publishable`입니다. 집중 복구 작업에만 `selected`를 사용하세요. +- `plugins`: `plugin_publish_scope=selected`일 때 쉼표로 구분된 `@openclaw/*` 패키지 이름입니다. - `publish_openclaw_npm`: 기본값은 `true`입니다. 워크플로를 Plugin 전용 복구 오케스트레이터로 사용할 때만 `false`로 설정하세요. `OpenClaw Release Checks`는 다음 운영자 제어 입력을 허용합니다. -- `ref`: 검증할 브랜치, 태그 또는 전체 commit SHA입니다. Secret이 포함된 검사는 - 확인된 commit이 OpenClaw 브랜치 또는 릴리스 태그에서 도달 가능해야 합니다. +- `ref`: 검증할 브랜치, 태그 또는 전체 커밋 SHA입니다. 비밀이 필요한 검사는 확인된 커밋이 OpenClaw 브랜치 또는 릴리스 태그에서 도달 가능해야 합니다. 규칙: -- 안정 및 수정 태그는 `beta` 또는 `latest` 중 하나로 게시할 수 있습니다. -- 알파 시험판 태그는 `alpha`에만 게시할 수 있습니다. -- 베타 시험판 태그는 `beta`에만 게시할 수 있습니다. -- `OpenClaw NPM Release`의 경우 전체 commit SHA 입력은 `preflight_only=true`일 때만 허용됩니다. -- `OpenClaw Release Checks` 및 `Full Release Validation`은 항상 검증 전용입니다. -- 실제 게시 경로는 사전 점검 중 사용한 것과 동일한 `npm_dist_tag`를 사용해야 하며, - 워크플로는 게시를 계속하기 전에 해당 메타데이터를 확인합니다. +- 안정 버전 및 수정 태그는 `beta` 또는 `latest` 중 하나로 게시할 수 있습니다. +- 베타 사전 릴리스 태그는 `beta`에만 게시할 수 있습니다. +- `OpenClaw NPM Release`에서는 `preflight_only=true`일 때만 전체 커밋 SHA 입력이 허용됩니다. +- `OpenClaw Release Checks`와 `Full Release Validation`은 항상 검증 전용입니다. +- 실제 게시 경로는 사전 확인 중 사용한 것과 동일한 `npm_dist_tag`를 사용해야 합니다. 워크플로는 게시를 계속하기 전에 해당 메타데이터를 확인합니다. ## 안정 npm 릴리스 순서 안정 npm 릴리스를 만들 때: 1. `preflight_only=true`로 `OpenClaw NPM Release`를 실행합니다. - - 태그가 존재하기 전에는 사전 점검 워크플로의 검증 전용 dry run을 위해 현재 전체 워크플로 브랜치 commit - SHA를 사용할 수 있습니다. -2. 일반적인 beta 우선 흐름에는 `npm_dist_tag=beta`를 선택하고, 직접 안정 버전 게시를 의도한 경우에만 `latest`를 선택합니다. -3. 하나의 수동 워크플로에서 일반 CI와 live prompt cache, Docker, QA Lab, - Matrix, Telegram 커버리지를 원할 때는 릴리스 브랜치, 릴리스 태그 또는 전체 - commit SHA에서 `Full Release Validation`을 실행합니다. -4. 결정적 일반 테스트 그래프만 의도적으로 필요한 경우에는 대신 릴리스 ref에서 - 수동 `CI` 워크플로를 실행합니다. + - 태그가 존재하기 전에는 사전 확인 워크플로의 검증 전용 드라이런을 위해 현재 전체 워크플로 브랜치 커밋 SHA를 사용할 수 있습니다. +2. 일반적인 베타 우선 흐름에는 `npm_dist_tag=beta`를 선택하고, 직접 안정 버전 게시를 의도한 경우에만 `latest`를 선택합니다. +3. 하나의 수동 워크플로에서 일반 CI와 라이브 프롬프트 캐시, Docker, QA Lab, Matrix, Telegram 커버리지를 원할 때는 릴리스 브랜치, 릴리스 태그 또는 전체 커밋 SHA에서 `Full Release Validation`을 실행합니다. +4. 의도적으로 결정론적 일반 테스트 그래프만 필요한 경우에는 대신 릴리스 ref에서 수동 `CI` 워크플로를 실행합니다. 5. 성공한 `preflight_run_id`를 저장합니다. -6. 동일한 `tag`, 동일한 `npm_dist_tag`, 저장된 `preflight_run_id`로 - `OpenClaw Release Publish`를 실행합니다. 이 워크플로는 OpenClaw npm 패키지를 승격하기 전에 외부화된 plugins를 npm과 - ClawHub에 게시합니다. -7. 릴리스가 `beta`에 배포된 경우 비공개 - `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` - 워크플로를 사용해 해당 안정 버전을 `beta`에서 `latest`로 승격합니다. -8. 릴리스가 의도적으로 `latest`에 직접 게시되었고 `beta`도 즉시 동일한 안정 빌드를 따라야 하는 경우, 동일한 비공개 - 워크플로를 사용해 두 dist-tag가 모두 안정 버전을 가리키도록 하거나, 예약된 - 자가 복구 동기화가 나중에 `beta`를 이동하도록 둡니다. +6. 동일한 `tag`, 동일한 `npm_dist_tag`, 저장된 `preflight_run_id`로 `OpenClaw Release Publish`를 실행합니다. 이 워크플로는 OpenClaw npm 패키지를 승격하기 전에 외부화된 plugins를 npm과 ClawHub에 게시합니다. +7. 릴리스가 `beta`에 배포되었다면 비공개 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` 워크플로를 사용해 해당 안정 버전을 `beta`에서 `latest`로 승격합니다. +8. 릴리스가 의도적으로 `latest`에 직접 게시되었고 `beta`도 즉시 동일한 안정 빌드를 따라야 한다면, 동일한 비공개 워크플로를 사용해 두 배포 태그가 모두 안정 버전을 가리키게 하거나, 예약된 자체 복구 동기화가 나중에 `beta`를 이동하도록 둡니다. -dist-tag 변경은 보안상 비공개 repo에 있습니다. 여전히 `NPM_TOKEN`이 필요하기 때문이며, -공개 repo는 OIDC 전용 게시를 유지합니다. +배포 태그 변경은 여전히 `NPM_TOKEN`이 필요하므로 보안을 위해 비공개 저장소에 있습니다. 반면 공개 저장소는 OIDC 전용 게시를 유지합니다. -이렇게 하면 직접 게시 경로와 beta 우선 승격 경로가 모두 문서화되고 운영자가 볼 수 있습니다. +이를 통해 직접 게시 경로와 베타 우선 승격 경로가 모두 문서화되고 운영자에게 표시됩니다. -maintainer가 로컬 npm 인증으로 대체해야 하는 경우, 모든 1Password -CLI(`op`) 명령은 전용 tmux 세션 안에서만 실행하세요. 기본 agent shell에서 `op`를 -직접 호출하지 마세요. tmux 안에 두면 프롬프트, 알림, OTP 처리를 관찰할 수 있고 반복적인 호스트 알림을 방지할 수 있습니다. +메인테이너가 로컬 npm 인증으로 대체해야 한다면 모든 1Password CLI(`op`) 명령은 전용 tmux 세션 안에서만 실행하세요. 메인 에이전트 셸에서 `op`를 직접 호출하지 마세요. tmux 안에 유지하면 프롬프트, 알림, OTP 처리를 관찰할 수 있고 반복적인 호스트 알림을 방지할 수 있습니다. -## 공개 참조 +## 공개 참고 자료 - [`.github/workflows/full-release-validation.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/full-release-validation.yml) - [`.github/workflows/package-acceptance.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/package-acceptance.yml) @@ -464,7 +628,7 @@ CLI(`op`) 명령은 전용 tmux 세션 안에서만 실행하세요. 기본 agen - [`scripts/package-mac-dist.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-dist.sh) - [`scripts/make_appcast.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/make_appcast.sh) -maintainer는 실제 실행 절차에 비공개 릴리스 문서인 +메인테이너는 실제 실행 절차서로 비공개 릴리스 문서 [`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md)를 사용합니다. ## 관련 항목 diff --git a/docs/ko/web/control-ui.md b/docs/ko/web/control-ui.md index d97d54d8f..2130de9a4 100644 --- a/docs/ko/web/control-ui.md +++ b/docs/ko/web/control-ui.md @@ -1,46 +1,46 @@ --- read_when: - - 브라우저에서 Gateway를 운영하려는 경우 - - SSH 터널 없이 Tailnet에 액세스하려는 경우 + - 브라우저에서 Gateway를 운영하려고 합니다 + - SSH 터널 없이 Tailnet 액세스를 원합니다 sidebarTitle: Control UI -summary: Gateway용 브라우저 기반 제어 UI(채팅, 노드, 설정) +summary: Gateway용 브라우저 기반 제어 사용자 인터페이스(채팅, 노드, 설정) title: 제어 UI x-i18n: - generated_at: "2026-05-02T21:17:24Z" + generated_at: "2026-05-02T23:39:17Z" model: gpt-5.5 provider: openai - source_hash: 88959ccf435b31015039bf28c3043023d99f0b953a1489986ab2d0cbd261771c + source_hash: 50bef807915f27406e19f1c6ca7d839a610d79ba79da85d7a78523400cbf9208 source_path: web/control-ui.md workflow: 16 --- -제어 UI는 Gateway에서 제공하는 작은 **Vite + Lit** 단일 페이지 앱입니다. +Control UI는 Gateway에서 제공하는 작은 **Vite + Lit** 단일 페이지 앱입니다. - 기본값: `http://:18789/` - 선택적 접두사: `gateway.controlUi.basePath` 설정(예: `/openclaw`) 동일한 포트에서 **Gateway WebSocket에 직접** 통신합니다. -## 빠르게 열기(로컬) +## 빠른 열기(로컬) Gateway가 같은 컴퓨터에서 실행 중이면 다음을 여세요. - [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (또는 [http://localhost:18789/](http://localhost:18789/)) -페이지가 로드되지 않으면 먼저 Gateway를 시작하세요. `openclaw gateway`. +페이지를 로드하지 못하면 먼저 Gateway를 시작하세요: `openclaw gateway`. -인증은 WebSocket 핸드셰이크 중 다음을 통해 제공됩니다. +인증은 WebSocket 핸드셰이크 중에 다음을 통해 제공됩니다. - `connect.params.auth.token` - `connect.params.auth.password` - `gateway.auth.allowTailscale: true`일 때 Tailscale Serve ID 헤더 - `gateway.auth.mode: "trusted-proxy"`일 때 신뢰할 수 있는 프록시 ID 헤더 -대시보드 설정 패널은 현재 브라우저 탭 세션과 선택된 Gateway URL에 대한 토큰을 보관하며, 비밀번호는 유지하지 않습니다. 온보딩은 보통 첫 연결 시 공유 비밀 인증용 Gateway 토큰을 생성하지만, `gateway.auth.mode`가 `"password"`일 때는 비밀번호 인증도 작동합니다. +대시보드 설정 패널은 현재 브라우저 탭 세션 및 선택한 게이트웨이 URL에 대한 토큰을 보관하며, 비밀번호는 유지하지 않습니다. 온보딩은 보통 첫 연결 시 공유 비밀 인증을 위한 게이트웨이 토큰을 생성하지만, `gateway.auth.mode`가 `"password"`일 때는 비밀번호 인증도 작동합니다. ## 기기 페어링(첫 연결) -새 브라우저나 기기에서 제어 UI에 연결하면 Gateway는 보통 **일회성 페어링 승인**을 요구합니다. 이는 무단 액세스를 방지하기 위한 보안 조치입니다. +새 브라우저나 기기에서 Control UI에 연결하면 Gateway는 보통 **일회성 페어링 승인**을 요구합니다. 이는 무단 접근을 방지하기 위한 보안 조치입니다. **표시되는 내용:** "disconnected (1008): pairing required" @@ -57,15 +57,15 @@ Gateway가 같은 컴퓨터에서 실행 중이면 다음을 여세요. -브라우저가 변경된 인증 세부 정보(역할/범위/공개 키)로 페어링을 다시 시도하면, 이전 대기 중 요청은 대체되고 새 `requestId`가 생성됩니다. 승인 전에 `openclaw devices list`를 다시 실행하세요. +브라우저가 변경된 인증 세부 정보(역할/범위/공개 키)로 페어링을 다시 시도하면 이전 대기 요청은 대체되고 새 `requestId`가 생성됩니다. 승인하기 전에 `openclaw devices list`를 다시 실행하세요. -브라우저가 이미 페어링되어 있고 읽기 액세스에서 쓰기/관리자 액세스로 변경하면, 이는 조용한 재연결이 아니라 승인 업그레이드로 처리됩니다. OpenClaw는 이전 승인을 활성 상태로 유지하고, 더 넓은 범위의 재연결을 차단하며, 새 범위 집합을 명시적으로 승인하도록 요청합니다. +브라우저가 이미 페어링되어 있고 읽기 접근 권한에서 쓰기/관리자 접근 권한으로 변경하는 경우, 이는 조용한 재연결이 아니라 승인 업그레이드로 처리됩니다. OpenClaw는 기존 승인을 활성 상태로 유지하고, 더 넓은 범위의 재연결을 차단하며, 새 범위 집합을 명시적으로 승인하도록 요청합니다. -승인되면 기기가 기억되며, `openclaw devices revoke --device --role `로 취소하지 않는 한 재승인이 필요하지 않습니다. 토큰 순환 및 취소는 [기기 CLI](/ko/cli/devices)를 참조하세요. +승인되면 기기가 기억되며 `openclaw devices revoke --device --role `로 취소하지 않는 한 재승인이 필요하지 않습니다. 토큰 순환 및 취소는 [기기 CLI](/ko/cli/devices)를 참조하세요. - 직접 local loopback 브라우저 연결(`127.0.0.1` / `localhost`)은 자동 승인됩니다. -- `gateway.auth.allowTailscale: true`이고, Tailscale ID가 검증되며, 브라우저가 기기 ID를 제시하면 Tailscale Serve는 제어 UI 운영자 세션의 페어링 왕복 과정을 건너뛸 수 있습니다. +- `gateway.auth.allowTailscale: true`이고, Tailscale ID가 확인되며, 브라우저가 기기 ID를 제공하는 경우 Tailscale Serve는 Control UI 운영자 세션의 페어링 왕복을 건너뛸 수 있습니다. - 직접 Tailnet 바인딩, LAN 브라우저 연결, 기기 ID가 없는 브라우저 프로필은 여전히 명시적 승인이 필요합니다. - 각 브라우저 프로필은 고유한 기기 ID를 생성하므로, 브라우저를 전환하거나 브라우저 데이터를 지우면 다시 페어링해야 합니다. @@ -73,80 +73,81 @@ Gateway가 같은 컴퓨터에서 실행 중이면 다음을 여세요. ## 개인 ID(브라우저 로컬) -제어 UI는 공유 세션에서 출처 표시를 위해 발신 메시지에 첨부되는 브라우저별 개인 ID(표시 이름 및 아바타)를 지원합니다. 이는 브라우저 저장소에 있으며, 현재 브라우저 프로필로 범위가 제한되고, 다른 기기와 동기화되지 않으며, 실제로 보낸 메시지의 일반적인 대화 기록 작성자 메타데이터를 제외하고 서버 측에 유지되지 않습니다. 사이트 데이터를 지우거나 브라우저를 전환하면 비어 있는 상태로 재설정됩니다. +Control UI는 공유 세션에서 출처 표시를 위해 발신 메시지에 연결되는 브라우저별 개인 ID(표시 이름 및 아바타)를 지원합니다. 이는 브라우저 저장소에 저장되고 현재 브라우저 프로필로 범위가 지정되며, 실제로 보내는 메시지의 일반적인 대화록 작성자 메타데이터 외에는 다른 기기와 동기화되거나 서버 측에 유지되지 않습니다. 사이트 데이터를 지우거나 브라우저를 전환하면 비어 있는 상태로 재설정됩니다. -동일한 브라우저 로컬 패턴이 어시스턴트 아바타 재정의에도 적용됩니다. 업로드된 어시스턴트 아바타는 로컬 브라우저에서만 Gateway가 확인한 ID 위에 표시되며, `config.patch`를 통해 왕복하지 않습니다. 공유 `ui.assistant.avatar` 구성 필드는 스크립트형 Gateway나 사용자 지정 대시보드처럼 해당 필드를 직접 쓰는 비 UI 클라이언트에 계속 사용할 수 있습니다. +동일한 브라우저 로컬 패턴이 어시스턴트 아바타 재정의에도 적용됩니다. 업로드된 어시스턴트 아바타는 로컬 브라우저에서만 게이트웨이가 해석한 ID 위에 오버레이되며 `config.patch`를 통해 왕복하지 않습니다. 공유 `ui.assistant.avatar` 구성 필드는 필드를 직접 쓰는 비 UI 클라이언트(예: 스크립트 기반 게이트웨이 또는 사용자 지정 대시보드)에서 계속 사용할 수 있습니다. ## 런타임 구성 엔드포인트 -제어 UI는 `/__openclaw/control-ui-config.json`에서 런타임 설정을 가져옵니다. 해당 엔드포인트는 나머지 HTTP 표면과 동일한 Gateway 인증으로 보호됩니다. 인증되지 않은 브라우저는 이를 가져올 수 없으며, 가져오기에 성공하려면 이미 유효한 Gateway 토큰/비밀번호, Tailscale Serve ID, 또는 신뢰할 수 있는 프록시 ID 중 하나가 필요합니다. +Control UI는 `/__openclaw/control-ui-config.json`에서 런타임 설정을 가져옵니다. 해당 엔드포인트는 나머지 HTTP 표면과 동일한 게이트웨이 인증으로 보호됩니다. 인증되지 않은 브라우저는 이를 가져올 수 없으며, 성공적인 가져오기를 위해서는 이미 유효한 게이트웨이 토큰/비밀번호, Tailscale Serve ID 또는 신뢰할 수 있는 프록시 ID 중 하나가 필요합니다. ## 언어 지원 -제어 UI는 처음 로드될 때 브라우저 로캘을 기준으로 자체 지역화를 수행할 수 있습니다. 나중에 재정의하려면 **개요 -> Gateway 액세스 -> 언어**를 여세요. 로캘 선택기는 모양 아래가 아니라 Gateway 액세스 카드에 있습니다. +Control UI는 첫 로드 시 브라우저 로캘을 기준으로 자체 지역화를 수행할 수 있습니다. 나중에 재정의하려면 **개요 -> Gateway 접근 -> 언어**를 여세요. 로캘 선택기는 모양 아래가 아니라 Gateway 접근 카드에 있습니다. -- 지원 로캘: `en`, `zh-CN`, `zh-TW`, `pt-BR`, `de`, `es`, `ja-JP`, `ko`, `fr`, `ar`, `it`, `tr`, `uk`, `id`, `pl`, `th`, `vi`, `nl`, `fa` +- 지원되는 로캘: `en`, `zh-CN`, `zh-TW`, `pt-BR`, `de`, `es`, `ja-JP`, `ko`, `fr`, `ar`, `it`, `tr`, `uk`, `id`, `pl`, `th`, `vi`, `nl`, `fa` - 영어가 아닌 번역은 브라우저에서 지연 로드됩니다. -- 선택한 로캘은 브라우저 저장소에 저장되고 이후 방문에서 재사용됩니다. -- 누락된 번역 키는 영어로 폴백합니다. +- 선택한 로캘은 브라우저 저장소에 저장되고 이후 방문 시 재사용됩니다. +- 누락된 번역 키는 영어로 대체됩니다. -문서 번역도 동일한 비영어 로캘 집합으로 생성되지만, 문서 사이트에 내장된 Mintlify 언어 선택기는 Mintlify가 허용하는 로캘 코드로 제한됩니다. 태국어(`th`)와 페르시아어(`fa`) 문서는 여전히 게시 저장소에 생성되지만, Mintlify가 해당 코드를 지원할 때까지 해당 선택기에 표시되지 않을 수 있습니다. +문서 번역도 동일한 비영어 로캘 집합에 대해 생성되지만, 문서 사이트에 내장된 Mintlify 언어 선택기는 Mintlify가 허용하는 로캘 코드로 제한됩니다. 태국어(`th`) 및 페르시아어(`fa`) 문서는 게시 저장소에 계속 생성되지만, Mintlify가 해당 코드를 지원할 때까지 해당 선택기에 표시되지 않을 수 있습니다. ## 모양 테마 -모양 패널은 기본 제공 Claw, Knot, Dash 테마와 브라우저 로컬 tweakcn 가져오기 슬롯 하나를 유지합니다. 테마를 가져오려면 [tweakcn themes](https://tweakcn.com/themes)를 열고, 테마를 선택하거나 만든 다음, **공유**를 클릭하고 복사된 테마 링크를 모양에 붙여넣으세요. 가져오기 도구는 `https://tweakcn.com/r/themes/` 레지스트리 URL, `https://tweakcn.com/editor/theme?theme=amethyst-haze` 같은 편집기 URL, 상대 `/themes/` 경로, 원시 테마 ID, `amethyst-haze` 같은 기본 테마 이름도 허용합니다. +모양 패널은 내장된 Claw, Knot, Dash 테마와 브라우저 로컬 tweakcn 가져오기 슬롯 하나를 유지합니다. 테마를 가져오려면 [tweakcn themes](https://tweakcn.com/themes)를 열고, 테마를 선택하거나 만든 다음 **공유**를 클릭하고, 복사한 테마 링크를 모양에 붙여넣으세요. 가져오기 도구는 `https://tweakcn.com/r/themes/` 레지스트리 URL, `https://tweakcn.com/editor/theme?theme=amethyst-haze` 같은 편집기 URL, 상대 `/themes/` 경로, 원시 테마 ID, `amethyst-haze` 같은 기본 테마 이름도 허용합니다. -가져온 테마는 현재 브라우저 프로필에만 저장됩니다. Gateway 구성에 기록되지 않으며 기기 간에 동기화되지 않습니다. 가져온 테마를 교체하면 하나의 로컬 슬롯이 업데이트됩니다. 이를 지우면 가져온 테마가 선택되어 있었던 경우 활성 테마가 Claw로 다시 전환됩니다. +가져온 테마는 현재 브라우저 프로필에만 저장됩니다. 게이트웨이 구성에 기록되지 않으며 기기 간에 동기화되지 않습니다. 가져온 테마를 교체하면 하나의 로컬 슬롯이 업데이트됩니다. 이를 지우면 가져온 테마가 선택되어 있었던 경우 활성 테마가 Claw로 다시 전환됩니다. -## 할 수 있는 일(현재) +## 수행할 수 있는 작업(현재) - - - Gateway WS를 통해 모델과 채팅합니다(`chat.history`, `chat.send`, `chat.abort`, `chat.inject`). - - 브라우저 실시간 세션을 통해 대화합니다. OpenAI는 직접 WebRTC를 사용하고, Google Live는 WebSocket을 통한 제한된 일회용 브라우저 토큰을 사용하며, 백엔드 전용 실시간 음성 Plugin은 Gateway 릴레이 전송을 사용합니다. 릴레이는 제공자 자격 증명을 Gateway에 보관하는 동안, 브라우저는 `talk.realtime.relay*` RPC를 통해 마이크 PCM을 스트리밍하고, 더 큰 구성된 OpenClaw 모델을 위해 `chat.send`를 통해 `openclaw_agent_consult` 도구 호출을 다시 보냅니다. - - 채팅에서 도구 호출과 실시간 도구 출력 카드를 스트리밍합니다(에이전트 이벤트). + + - Gateway WS(`chat.history`, `chat.send`, `chat.abort`, `chat.inject`)를 통해 모델과 채팅합니다. + - 서버 측 STT(`chat.transcribeAudio`)로 채팅 작성기에 받아쓰기합니다. 브라우저는 짧은 마이크 클립을 녹음하여 Gateway로 보내고, Gateway는 구성된 `tools.media.audio` 전사 파이프라인을 실행한 뒤 공급자 자격 증명을 브라우저에 노출하지 않고 초안 텍스트를 반환합니다. + - 브라우저 실시간 세션을 통해 대화합니다. OpenAI는 직접 WebRTC를 사용하고, Google Live는 WebSocket을 통한 제한된 일회용 브라우저 토큰을 사용하며, 백엔드 전용 실시간 음성 Plugin은 Gateway 릴레이 전송을 사용합니다. 릴레이는 공급자 자격 증명을 Gateway에 유지하고, 브라우저는 `talk.realtime.relay*` RPC를 통해 마이크 PCM을 스트리밍하며, 더 큰 구성된 OpenClaw 모델을 위해 `openclaw_agent_consult` 도구 호출을 `chat.send`를 통해 다시 보냅니다. + - 채팅에서 도구 호출 + 라이브 도구 출력 카드를 스트리밍합니다(에이전트 이벤트). - - - 채널: 기본 제공 및 번들/외부 Plugin 채널 상태, QR 로그인, 채널별 구성(`channels.status`, `web.login.*`, `config.patch`). - - 인스턴스: 존재 목록 및 새로 고침(`system-presence`). - - 세션: 목록 및 세션별 모델/사고/빠른 응답/자세한 출력/추적/추론 재정의(`sessions.list`, `sessions.patch`). - - Dreams: Dreaming 상태, 활성화/비활성화 토글, Dream Diary 리더(`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`). + + - 채널: 내장 및 번들/외부 Plugin 채널 상태, QR 로그인, 채널별 구성(`channels.status`, `web.login.*`, `config.patch`). + - 인스턴스: 현재 상태 목록 + 새로 고침(`system-presence`). + - 세션: 목록 + 세션별 모델/생각/빠름/상세/추적/추론 재정의(`sessions.list`, `sessions.patch`). + - 꿈: Dreaming 상태, 활성화/비활성화 토글, Dream Diary 리더(`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`). - - Cron 작업: 목록/추가/편집/실행/활성화/비활성화 및 실행 기록(`cron.*`). + - Cron 작업: 목록/추가/편집/실행/활성화/비활성화 + 실행 기록(`cron.*`). - Skills: 상태, 활성화/비활성화, 설치, API 키 업데이트(`skills.*`). - - Node: 목록 및 기능(`node.list`). - - 실행 승인: `exec host=gateway/node`에 대한 Gateway 또는 Node 허용 목록 및 요청 정책 편집(`exec.approvals.*`). + - Node: 목록 + 기능(`node.list`). + - 실행 승인: `exec host=gateway/node`에 대한 게이트웨이 또는 Node 허용 목록 + 요청 정책 편집(`exec.approvals.*`). - `~/.openclaw/openclaw.json` 보기/편집(`config.get`, `config.set`). - - 유효성 검사와 함께 적용 및 재시작(`config.apply`)하고 마지막 활성 세션을 깨웁니다. - - 쓰기에는 동시 편집으로 덮어쓰는 것을 방지하는 기본 해시 가드가 포함됩니다. - - 쓰기(`config.set`/`config.apply`/`config.patch`)는 제출된 구성 페이로드의 참조에 대해 활성 SecretRef 해석을 사전 확인합니다. 해석되지 않은 활성 제출 참조는 쓰기 전에 거부됩니다. - - 스키마 및 양식 렌더링(`config.schema` / `config.schema.lookup`, 필드 `title` / `description`, 일치한 UI 힌트, 즉시 하위 요약, 중첩 객체/와일드카드/배열/컴포지션 노드의 문서 메타데이터, 사용 가능한 경우 Plugin 및 채널 스키마 포함). 원시 JSON 편집기는 스냅샷에 안전한 원시 왕복이 있을 때만 사용할 수 있습니다. - - 스냅샷이 원시 텍스트를 안전하게 왕복할 수 없으면 제어 UI는 양식 모드를 강제하고 해당 스냅샷의 원시 모드를 비활성화합니다. - - 원시 JSON 편집기 "저장된 상태로 재설정"은 평탄화된 스냅샷을 다시 렌더링하는 대신 원시로 작성된 형태(서식, 주석, `$include` 레이아웃)를 보존하므로, 스냅샷이 안전하게 왕복할 수 있을 때 외부 편집이 재설정 후에도 유지됩니다. - - 구조화된 SecretRef 객체 값은 실수로 객체가 문자열로 손상되는 것을 방지하기 위해 양식 텍스트 입력에서 읽기 전용으로 렌더링됩니다. + - 유효성 검사를 거쳐 적용 + 재시작(`config.apply`)하고 마지막 활성 세션을 깨웁니다. + - 쓰기에는 동시 편집 덮어쓰기를 방지하기 위한 기본 해시 가드가 포함됩니다. + - 쓰기(`config.set`/`config.apply`/`config.patch`)는 제출된 구성 페이로드의 참조에 대해 활성 SecretRef 해석을 사전 점검합니다. 해석되지 않은 활성 제출 참조는 쓰기 전에 거부됩니다. + - 스키마 + 폼 렌더링(`config.schema` / `config.schema.lookup`, 필드 `title` / `description`, 일치하는 UI 힌트, 즉시 하위 요약, 중첩 객체/와일드카드/배열/컴포지션 노드의 문서 메타데이터, 사용 가능한 경우 Plugin + 채널 스키마 포함); 원시 JSON 편집기는 스냅샷에 안전한 원시 왕복이 있을 때만 사용할 수 있습니다. + - 스냅샷이 원시 텍스트를 안전하게 왕복할 수 없으면 Control UI는 폼 모드를 강제하고 해당 스냅샷의 원시 모드를 비활성화합니다. + - 원시 JSON 편집기 "저장된 상태로 재설정"은 평탄화된 스냅샷을 다시 렌더링하는 대신 원시 작성 형태(서식, 주석, `$include` 레이아웃)를 보존하므로, 스냅샷이 안전하게 왕복할 수 있을 때 외부 편집이 재설정 후에도 유지됩니다. + - 구조화된 SecretRef 객체 값은 실수로 객체가 문자열로 손상되는 것을 방지하기 위해 폼 텍스트 입력에서 읽기 전용으로 렌더링됩니다. - - 디버그: 상태/상태 점검/모델 스냅샷 및 이벤트 로그, 수동 RPC 호출(`status`, `health`, `models.list`). - - 로그: 필터/내보내기를 포함한 Gateway 파일 로그의 실시간 꼬리 보기(`logs.tail`). - - 업데이트: 재시작 보고서와 함께 패키지/git 업데이트 및 재시작을 실행(`update.run`)한 다음, 재연결 후 `update.status`를 폴링하여 실행 중인 Gateway 버전을 확인합니다. + - 디버그: 상태/상태 점검/모델 스냅샷 + 이벤트 로그 + 수동 RPC 호출(`status`, `health`, `models.list`). + - 로그: 필터/내보내기가 있는 게이트웨이 파일 로그의 라이브 tail(`logs.tail`). + - 업데이트: 재시작 보고서와 함께 패키지/git 업데이트 + 재시작(`update.run`)을 실행한 다음, 재연결 후 `update.status`를 폴링하여 실행 중인 게이트웨이 버전을 확인합니다. - - - 격리된 작업의 경우 전송 기본값은 요약 공지입니다. 내부 전용 실행을 원하면 없음으로 전환할 수 있습니다. - - 공지가 선택되면 채널/대상 필드가 표시됩니다. - - Webhook 모드는 `delivery.mode = "webhook"`을 사용하며 `delivery.to`는 유효한 HTTP(S) Webhook URL로 설정됩니다. - - 기본 세션 작업의 경우 Webhook 및 없음 전송 모드를 사용할 수 있습니다. - - 고급 편집 컨트롤에는 실행 후 삭제, 에이전트 재정의 지우기, 정확/분산 Cron 옵션, 에이전트 모델/사고 재정의, 최선 노력 전송 토글이 포함됩니다. - - 양식 유효성 검사는 필드 수준 오류와 함께 인라인으로 표시됩니다. 잘못된 값은 수정될 때까지 저장 버튼을 비활성화합니다. + + - 격리된 작업의 경우 전달 기본값은 요약 알림입니다. 내부 전용 실행을 원하면 없음으로 전환할 수 있습니다. + - 알림이 선택되면 채널/대상 필드가 표시됩니다. + - Webhook 모드는 `delivery.mode = "webhook"`를 사용하며 `delivery.to`가 유효한 HTTP(S) Webhook URL로 설정됩니다. + - 메인 세션 작업의 경우 Webhook 및 없음 전달 모드를 사용할 수 있습니다. + - 고급 편집 컨트롤에는 실행 후 삭제, 에이전트 재정의 지우기, Cron 정확/분산 옵션, 에이전트 모델/생각 재정의, 최선 노력 전달 토글이 포함됩니다. + - 폼 유효성 검사는 필드 수준 오류와 함께 인라인으로 제공되며, 잘못된 값은 수정될 때까지 저장 버튼을 비활성화합니다. - 전용 bearer 토큰을 보내려면 `cron.webhookToken`을 설정하세요. 생략하면 Webhook은 인증 헤더 없이 전송됩니다. - - 사용 중단된 폴백: `notify: true`가 있는 저장된 레거시 작업은 마이그레이션될 때까지 여전히 `cron.webhook`을 사용할 수 있습니다. + - 사용 중단된 대체 경로: `notify: true`가 있는 저장된 레거시 작업은 마이그레이션될 때까지 여전히 `cron.webhook`을 사용할 수 있습니다. @@ -155,59 +156,60 @@ Gateway가 같은 컴퓨터에서 실행 중이면 다음을 여세요. - - `chat.send`는 **논블로킹**입니다. `{ runId, status: "started" }`로 즉시 확인 응답을 반환하고, 응답은 `chat` 이벤트를 통해 스트리밍됩니다. - - 채팅 업로드는 이미지와 비디오가 아닌 파일을 허용합니다. 이미지는 네이티브 이미지 경로를 유지하며, 다른 파일은 관리형 미디어로 저장되고 기록에는 첨부 파일 링크로 표시됩니다. - - 동일한 `idempotencyKey`로 다시 전송하면 실행 중에는 `{ status: "in_flight" }`를 반환하고, 완료 후에는 `{ status: "ok" }`를 반환합니다. - - `chat.history` 응답은 UI 안전을 위해 크기가 제한됩니다. 트랜스크립트 항목이 너무 크면 Gateway가 긴 텍스트 필드를 잘라내거나, 무거운 메타데이터 블록을 생략하거나, 너무 큰 메시지를 자리표시자(`[chat.history omitted: message too large]`)로 바꿀 수 있습니다. - - 어시스턴트/생성 이미지는 관리형 미디어 참조로 유지되고 인증된 Gateway 미디어 URL을 통해 다시 제공되므로, 다시 로드할 때 원시 base64 이미지 페이로드가 채팅 기록 응답에 계속 남아 있는지에 의존하지 않습니다. - - `chat.history`는 보이는 어시스턴트 텍스트에서 표시 전용 인라인 지시문 태그(예: `[[reply_to_*]]` 및 `[[audio_as_voice]]`), 일반 텍스트 도구 호출 XML 페이로드(`...`, `...`, `...`, `...` 및 잘린 도구 호출 블록 포함), 유출된 ASCII/전각 모델 제어 토큰도 제거하며, 전체 보이는 텍스트가 정확한 무음 토큰 `NO_REPLY` / `no_reply`뿐인 어시스턴트 항목은 생략합니다. - - 활성 전송 중과 최종 기록 새로 고침 중에 `chat.history`가 잠시 이전 스냅샷을 반환하더라도 채팅 보기는 로컬의 낙관적 사용자/어시스턴트 메시지를 계속 표시합니다. Gateway 기록이 따라잡으면 정식 트랜스크립트가 해당 로컬 메시지를 대체합니다. - - `chat.inject`는 세션 트랜스크립트에 어시스턴트 메모를 추가하고 UI 전용 업데이트를 위해 `chat` 이벤트를 브로드캐스트합니다(에이전트 실행 없음, 채널 전달 없음). - - 채팅 헤더의 모델 및 사고 선택기는 `sessions.patch`를 통해 활성 세션을 즉시 패치합니다. 이는 한 턴 전용 전송 옵션이 아니라 지속되는 세션 재정의입니다. - - Control UI에서 `/new`를 입력하면 New Chat과 동일한 새 대시보드 세션을 만들고 전환합니다. `/reset`을 입력하면 현재 세션에 대해 Gateway의 명시적 제자리 초기화를 유지합니다. - - 채팅 모델 선택기는 Gateway의 구성된 모델 보기를 요청합니다. `agents.defaults.models`가 있으면 해당 허용 목록이 선택기를 구동합니다. 그렇지 않으면 선택기는 명시적인 `models.providers.*.models` 항목과 사용 가능한 인증이 있는 공급자를 표시합니다. 전체 카탈로그는 디버그 `models.list` RPC에서 `view: "all"`로 계속 사용할 수 있습니다. - - 새 Gateway 세션 사용량 보고서가 높은 컨텍스트 압박을 표시하면 채팅 작성 영역에 컨텍스트 알림이 표시되며, 권장 Compaction 수준에서는 일반 세션 Compaction 경로를 실행하는 압축 버튼이 표시됩니다. 오래된 토큰 스냅샷은 Gateway가 새 사용량을 다시 보고할 때까지 숨겨집니다. + - `chat.send`는 **논블로킹**입니다. 즉시 `{ runId, status: "started" }`로 확인 응답하고, 응답은 `chat` 이벤트를 통해 스트리밍됩니다. + - `chat.transcribeAudio`는 Chat 초안용 일회성 받아쓰기 도우미입니다. 브라우저에서 녹음된 base64 오디오를 받고, 업로드를 Gateway WebSocket 프레임 제한 아래로 유지하며, 임시 로컬 파일을 쓰고, 활성 Gateway 구성으로 미디어 이해 오디오 전사를 실행하며, `{ text, provider, model }`을 반환한 뒤 임시 파일을 제거합니다. 에이전트 실행을 만들지 않으며 실시간 Talk와는 별개입니다. + - Chat 업로드는 이미지와 비동영상 파일을 받습니다. 이미지는 네이티브 이미지 경로를 유지하고, 다른 파일은 관리형 미디어로 저장되어 기록에 첨부 파일 링크로 표시됩니다. + - 같은 `idempotencyKey`로 다시 전송하면 실행 중에는 `{ status: "in_flight" }`를 반환하고, 완료 후에는 `{ status: "ok" }`를 반환합니다. + - `chat.history` 응답은 UI 안전을 위해 크기가 제한됩니다. 대화 기록 항목이 너무 크면 Gateway가 긴 텍스트 필드를 잘라내고, 무거운 메타데이터 블록을 생략하며, 크기가 너무 큰 메시지를 자리 표시자(`[chat.history omitted: message too large]`)로 대체할 수 있습니다. + - Assistant/생성 이미지는 관리형 미디어 참조로 영구 저장되고 인증된 Gateway 미디어 URL을 통해 다시 제공되므로, 다시 로드할 때 원시 base64 이미지 페이로드가 Chat 기록 응답에 계속 남아 있는 것에 의존하지 않습니다. + - `chat.history`는 보이는 Assistant 텍스트에서 표시 전용 인라인 지시 태그(예: `[[reply_to_*]]`, `[[audio_as_voice]]`), 일반 텍스트 도구 호출 XML 페이로드(`...`, `...`, `...`, `...` 및 잘린 도구 호출 블록 포함), 유출된 ASCII/전각 모델 제어 토큰도 제거하며, 전체 표시 텍스트가 정확한 무음 토큰 `NO_REPLY` / `no_reply`뿐인 Assistant 항목은 생략합니다. + - 활성 전송 중 및 최종 기록 새로 고침 동안 `chat.history`가 잠시 이전 스냅샷을 반환하더라도 Chat 뷰는 로컬의 낙관적 사용자/Assistant 메시지를 계속 표시합니다. Gateway 기록이 따라잡으면 정식 대화 기록이 해당 로컬 메시지를 대체합니다. + - `chat.inject`는 세션 대화 기록에 Assistant 메모를 추가하고 UI 전용 업데이트를 위해 `chat` 이벤트를 브로드캐스트합니다(에이전트 실행 없음, 채널 전달 없음). + - Chat 헤더의 모델 및 thinking 선택기는 `sessions.patch`를 통해 활성 세션을 즉시 패치합니다. 이는 영구 세션 오버라이드이며 한 턴 전용 전송 옵션이 아닙니다. + - Control UI에서 `/new`를 입력하면 New Chat과 동일한 새 대시보드 세션을 만들고 전환합니다. `/reset`을 입력하면 현재 세션에 대한 Gateway의 명시적 제자리 초기화를 유지합니다. + - Chat 모델 선택기는 Gateway의 구성된 모델 뷰를 요청합니다. `agents.defaults.models`가 있으면 해당 허용 목록이 선택기를 구동합니다. 그렇지 않으면 선택기에 명시적 `models.providers.*.models` 항목과 사용 가능한 인증이 있는 제공자가 표시됩니다. 전체 카탈로그는 디버그 `models.list` RPC에서 `view: "all"`로 계속 사용할 수 있습니다. + - 새 Gateway 세션 사용량 보고서가 높은 컨텍스트 압박을 나타내면 Chat 작성 영역에 컨텍스트 알림이 표시되고, 권장 Compaction 수준에서는 일반 세션 Compaction 경로를 실행하는 압축 버튼이 표시됩니다. Gateway가 새 사용량을 다시 보고할 때까지 오래된 토큰 스냅샷은 숨겨집니다. - Talk 모드는 등록된 실시간 음성 공급자를 사용합니다. OpenAI는 `talk.provider: "openai"`와 `talk.providers.openai.apiKey`로 구성하거나, Google은 `talk.provider: "google"`와 `talk.providers.google.apiKey`로 구성합니다. Voice Call 실시간 공급자 구성은 여전히 폴백으로 재사용할 수 있습니다. 브라우저는 표준 공급자 API 키를 절대 받지 않습니다. OpenAI는 WebRTC용 임시 Realtime 클라이언트 시크릿을 받습니다. Google Live는 브라우저 WebSocket 세션을 위한 일회용 제한 Live API 인증 토큰을 받으며, 지침과 도구 선언은 Gateway에 의해 토큰 안에 고정됩니다. 백엔드 실시간 브리지로만 노출되는 공급자는 Gateway 릴레이 전송을 통해 실행되므로, 브라우저 오디오는 인증된 Gateway RPC를 통해 이동하는 동안 자격 증명과 벤더 소켓은 서버 측에 유지됩니다. Realtime 세션 프롬프트는 Gateway가 조합합니다. `talk.realtime.session`은 호출자가 제공한 지침 재정의를 허용하지 않습니다. + Talk 모드는 등록된 실시간 음성 제공자를 사용합니다. OpenAI는 `talk.provider: "openai"`와 `talk.providers.openai.apiKey`로 구성하거나, Google은 `talk.provider: "google"`와 `talk.providers.google.apiKey`로 구성하세요. Voice Call 실시간 제공자 구성은 여전히 대체 수단으로 재사용할 수 있습니다. 브라우저는 표준 제공자 API 키를 절대 받지 않습니다. OpenAI는 WebRTC용 임시 Realtime 클라이언트 비밀 값을 받습니다. Google Live는 브라우저 WebSocket 세션용 일회용 제한 Live API 인증 토큰을 받으며, 지침과 도구 선언은 Gateway에 의해 토큰 안에 고정됩니다. 백엔드 실시간 브리지만 노출하는 제공자는 Gateway 릴레이 전송을 통해 실행되므로, 자격 증명과 공급업체 소켓은 서버 측에 남고 브라우저 오디오는 인증된 Gateway RPC를 통해 이동합니다. Realtime 세션 프롬프트는 Gateway가 조립하며, `talk.realtime.session`은 호출자가 제공하는 지침 오버라이드를 받지 않습니다. - 채팅 작성기에서 Talk 컨트롤은 마이크 받아쓰기 버튼 옆의 파형 버튼입니다. Talk가 시작되면 작성기 상태 행은 `Connecting Talk...`를 표시한 뒤 오디오가 연결된 동안에는 `Talk live`를, 실시간 도구 호출이 `chat.send`를 통해 구성된 더 큰 모델에 문의하는 동안에는 `Asking OpenClaw...`를 표시합니다. + Chat 작성기에서 Talk 컨트롤은 마이크 받아쓰기 버튼 옆의 파형 버튼입니다. Talk가 시작되면 작성기 상태 행에 `Connecting Talk...`가 표시된 다음, 오디오가 연결된 동안 `Talk live`가 표시되거나, 실시간 도구 호출이 `chat.send`를 통해 구성된 더 큰 모델에 문의하는 동안 `Asking OpenClaw...`가 표시됩니다. - 유지관리자 라이브 스모크: `OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts`는 OpenAI 브라우저 WebRTC SDP 교환, Google Live 제한 토큰 브라우저 WebSocket 설정, 가짜 마이크 미디어를 사용하는 Gateway 릴레이 브라우저 어댑터를 검증합니다. 이 명령은 공급자 상태만 출력하며 시크릿은 로그로 남기지 않습니다. + 유지관리자 라이브 스모크: `OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts`는 OpenAI 브라우저 WebRTC SDP 교환, Google Live 제한 토큰 브라우저 WebSocket 설정, 가짜 마이크 미디어를 사용하는 Gateway 릴레이 브라우저 어댑터를 검증합니다. 이 명령은 제공자 상태만 출력하고 비밀 값은 기록하지 않습니다. - **Stop**을 클릭합니다(`chat.abort` 호출). - - 실행이 활성 상태인 동안 일반 후속 메시지는 큐에 들어갑니다. 큐에 있는 메시지에서 **Steer**를 클릭하면 해당 후속 메시지가 실행 중인 턴에 주입됩니다. - - 대역 외에서 중단하려면 `/stop`(또는 `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop` 같은 독립 실행형 중단 문구)을 입력합니다. + - 실행이 활성 상태인 동안 일반 후속 메시지는 대기열에 들어갑니다. 대기 중인 메시지에서 **Steer**를 클릭하면 해당 후속 메시지가 실행 중인 턴에 주입됩니다. + - `/stop`을 입력하거나 `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop` 같은 독립형 중단 문구를 입력하여 대역 외로 중단합니다. - `chat.abort`는 해당 세션의 모든 활성 실행을 중단하기 위해 `{ sessionKey }`(`runId` 없음)를 지원합니다. - - 실행이 중단되면 부분 어시스턴트 텍스트가 UI에 계속 표시될 수 있습니다. - - Gateway는 버퍼링된 출력이 있을 때 중단된 부분 어시스턴트 텍스트를 트랜스크립트 기록에 유지합니다. - - 유지된 항목에는 중단 메타데이터가 포함되어 트랜스크립트 소비자가 중단 부분을 정상 완료 출력과 구분할 수 있습니다. + - 실행이 중단되면 부분 Assistant 텍스트가 UI에 계속 표시될 수 있습니다. + - Gateway는 버퍼링된 출력이 있을 때 중단된 부분 Assistant 텍스트를 대화 기록에 영구 저장합니다. + - 영구 저장된 항목에는 중단 메타데이터가 포함되어, 대화 기록 소비자가 중단 부분과 정상 완료 출력을 구분할 수 있습니다. ## PWA 설치 및 웹 푸시 -Control UI는 `manifest.webmanifest`와 서비스 워커를 제공하므로, 최신 브라우저에서 독립 실행형 PWA로 설치할 수 있습니다. Web Push를 사용하면 탭이나 브라우저 창이 열려 있지 않아도 Gateway가 알림으로 설치된 PWA를 깨울 수 있습니다. +Control UI는 `manifest.webmanifest`와 서비스 워커를 함께 제공하므로, 최신 브라우저에서 독립 실행형 PWA로 설치할 수 있습니다. Web Push를 사용하면 탭이나 브라우저 창이 열려 있지 않아도 Gateway가 알림으로 설치된 PWA를 깨울 수 있습니다. -| 표면 | 수행하는 작업 | +| 표면 | 수행하는 작업 | | ----------------------------------------------------- | ------------------------------------------------------------------ | | `ui/public/manifest.webmanifest` | PWA 매니페스트입니다. 도달 가능해지면 브라우저가 "Install app"을 제공합니다. | | `ui/public/sw.js` | `push` 이벤트와 알림 클릭을 처리하는 서비스 워커입니다. | -| `push/vapid-keys.json`(OpenClaw 상태 디렉터리 아래) | Web Push 페이로드 서명에 사용되는 자동 생성 VAPID 키 쌍입니다. | -| `push/web-push-subscriptions.json` | 유지되는 브라우저 구독 엔드포인트입니다. | +| `push/vapid-keys.json`(OpenClaw 상태 디렉터리 아래) | Web Push 페이로드 서명에 사용하는 자동 생성 VAPID 키 쌍입니다. | +| `push/web-push-subscriptions.json` | 영구 저장된 브라우저 구독 엔드포인트입니다. | -키를 고정하려는 경우(멀티 호스트 배포, 시크릿 교체 또는 테스트) Gateway 프로세스의 환경 변수로 VAPID 키 쌍을 재정의합니다. +키를 고정하려는 경우(다중 호스트 배포, 비밀 값 교체 또는 테스트) Gateway 프로세스에서 환경 변수로 VAPID 키 쌍을 오버라이드하세요. - `OPENCLAW_VAPID_PUBLIC_KEY` - `OPENCLAW_VAPID_PRIVATE_KEY` -- `OPENCLAW_VAPID_SUBJECT`(기본값: `mailto:openclaw@localhost`) +- `OPENCLAW_VAPID_SUBJECT`(기본값은 `mailto:openclaw@localhost`) Control UI는 브라우저 구독을 등록하고 테스트하기 위해 다음 범위 제한 Gateway 메서드를 사용합니다. @@ -217,22 +219,22 @@ Control UI는 브라우저 구독을 등록하고 테스트하기 위해 다음 - `push.web.test` — 호출자의 구독으로 테스트 알림을 보냅니다. -Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/gateway/configuration) 참조)와 기존 `push.test` 메서드와 독립적이며, 이들은 네이티브 모바일 페어링을 대상으로 합니다. +Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/gateway/configuration) 참조) 및 네이티브 모바일 페어링을 대상으로 하는 기존 `push.test` 메서드와 독립적입니다. ## 호스팅된 임베드 -어시스턴트 메시지는 `[embed ...]` 쇼트코드를 사용해 호스팅된 웹 콘텐츠를 인라인으로 렌더링할 수 있습니다. iframe 샌드박스 정책은 `gateway.controlUi.embedSandbox`로 제어됩니다. +Assistant 메시지는 `[embed ...]` 숏코드로 호스팅된 웹 콘텐츠를 인라인 렌더링할 수 있습니다. iframe 샌드박스 정책은 `gateway.controlUi.embedSandbox`로 제어됩니다. 호스팅된 임베드 내부의 스크립트 실행을 비활성화합니다. - - 원본 격리를 유지하면서 대화형 임베드를 허용합니다. 이것이 기본값이며 일반적으로 독립형 브라우저 게임/위젯에 충분합니다. + + 원본 격리를 유지하면서 인터랙티브 임베드를 허용합니다. 이것이 기본값이며, 일반적으로 자체 포함 브라우저 게임/위젯에 충분합니다. - 더 강한 권한이 의도적으로 필요한 동일 사이트 문서에 대해 `allow-scripts` 위에 `allow-same-origin`을 추가합니다. + 의도적으로 더 강한 권한이 필요한 동일 사이트 문서를 위해 `allow-scripts` 위에 `allow-same-origin`을 추가합니다. @@ -249,14 +251,14 @@ Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/ga ``` -임베드된 문서에 실제로 동일 출처 동작이 필요할 때만 `trusted`를 사용하세요. 대부분의 에이전트 생성 게임과 대화형 캔버스에는 `scripts`가 더 안전한 선택입니다. +임베드된 문서에 동일 원본 동작이 실제로 필요할 때만 `trusted`를 사용하세요. 대부분의 에이전트 생성 게임과 인터랙티브 캔버스에는 `scripts`가 더 안전한 선택입니다. -절대 외부 `http(s)` 임베드 URL은 기본적으로 계속 차단됩니다. 의도적으로 `[embed url="https://..."]`가 타사 페이지를 로드하도록 하려면 `gateway.controlUi.allowExternalEmbedUrls: true`를 설정하세요. +절대 외부 `http(s)` 임베드 URL은 기본적으로 계속 차단됩니다. 의도적으로 `[embed url="https://..."]`가 서드파티 페이지를 로드하도록 하려면 `gateway.controlUi.allowExternalEmbedUrls: true`를 설정하세요. -## 채팅 메시지 너비 +## Chat 메시지 너비 -그룹화된 채팅 메시지는 읽기 쉬운 기본 최대 너비를 사용합니다. 와이드 모니터 배포에서는 번들 CSS를 패치하지 않고 `gateway.controlUi.chatMessageMaxWidth`를 설정하여 재정의할 수 있습니다. +그룹화된 Chat 메시지는 읽기 쉬운 기본 최대 너비를 사용합니다. 와이드 모니터 배포에서는 번들 CSS를 패치하지 않고 `gateway.controlUi.chatMessageMaxWidth`를 설정하여 오버라이드할 수 있습니다. ```json5 { @@ -274,7 +276,7 @@ Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/ga - Gateway를 loopback에 유지하고 Tailscale Serve가 HTTPS로 프록시하게 합니다. + Gateway를 loopback에 유지하고 Tailscale Serve가 HTTPS로 프록시하도록 합니다. ```bash openclaw gateway --tailscale serve @@ -284,12 +286,12 @@ Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/ga - `https:///`(또는 구성한 `gateway.controlUi.basePath`) - 기본적으로 `gateway.auth.allowTailscale`이 `true`이면 Control UI/WebSocket Serve 요청은 Tailscale ID 헤더(`tailscale-user-login`)를 통해 인증할 수 있습니다. OpenClaw는 `x-forwarded-for` 주소를 `tailscale whois`로 확인하고 이를 헤더와 일치시켜 ID를 검증하며, 요청이 Tailscale의 `x-forwarded-*` 헤더와 함께 loopback에 도달할 때만 이를 허용합니다. 브라우저 기기 ID가 있는 Control UI 운영자 세션의 경우, 이 검증된 Serve 경로는 기기 페어링 왕복도 건너뜁니다. 기기가 없는 브라우저와 노드 역할 연결은 여전히 일반 기기 검사를 따릅니다. Serve 트래픽에도 명시적 공유 시크릿 자격 증명을 요구하려면 `gateway.auth.allowTailscale: false`를 설정하세요. 그런 다음 `gateway.auth.mode: "token"` 또는 `"password"`를 사용합니다. + 기본적으로 `gateway.auth.allowTailscale`이 `true`이면 Control UI/WebSocket Serve 요청은 Tailscale ID 헤더(`tailscale-user-login`)를 통해 인증할 수 있습니다. OpenClaw는 `x-forwarded-for` 주소를 `tailscale whois`로 해석해 해당 헤더와 일치시키는 방식으로 ID를 검증하며, 요청이 Tailscale의 `x-forwarded-*` 헤더와 함께 loopback에 도달할 때만 이를 허용합니다. 브라우저 장치 ID가 있는 Control UI 운영자 세션의 경우, 이 검증된 Serve 경로는 장치 페어링 왕복도 건너뜁니다. 장치 없는 브라우저와 노드 역할 연결은 계속 일반 장치 검사를 따릅니다. Serve 트래픽에도 명시적 공유 비밀 자격 증명을 요구하려면 `gateway.auth.allowTailscale: false`를 설정하세요. 그런 다음 `gateway.auth.mode: "token"` 또는 `"password"`를 사용하세요. - 해당 비동기 Serve ID 경로에서는 동일한 클라이언트 IP와 인증 범위에 대한 실패한 인증 시도가 속도 제한 기록 전에 직렬화됩니다. 따라서 동일한 브라우저의 동시 잘못된 재시도는 두 일반 불일치가 병렬로 경합하는 대신 두 번째 요청에서 `retry later`를 표시할 수 있습니다. + 해당 비동기 Serve ID 경로에서는 같은 클라이언트 IP와 인증 범위에 대한 실패한 인증 시도가 속도 제한 쓰기 전에 직렬화됩니다. 따라서 같은 브라우저의 동시 잘못된 재시도는 두 개의 일반 불일치가 병렬로 경쟁하는 대신 두 번째 요청에서 `retry later`를 표시할 수 있습니다. - 토큰 없는 Serve 인증은 Gateway 호스트를 신뢰할 수 있다고 가정합니다. 해당 호스트에서 신뢰할 수 없는 로컬 코드가 실행될 수 있다면 토큰/비밀번호 인증을 요구하세요. + 토큰 없는 Serve 인증은 게이트웨이 호스트를 신뢰할 수 있다고 가정합니다. 신뢰할 수 없는 로컬 코드가 해당 호스트에서 실행될 수 있다면 토큰/비밀번호 인증을 요구하세요. @@ -302,28 +304,28 @@ Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/ga - `http://:18789/`(또는 구성한 `gateway.controlUi.basePath`) - 일치하는 공유 시크릿을 UI 설정에 붙여넣습니다(`connect.params.auth.token` 또는 `connect.params.auth.password`로 전송됨). + 일치하는 공유 비밀을 UI 설정에 붙여 넣으세요(`connect.params.auth.token` 또는 `connect.params.auth.password`로 전송됨). ## 안전하지 않은 HTTP -일반 HTTP(`http://` 또는 `http://`)로 대시보드를 열면 브라우저는 **비보안 컨텍스트**에서 실행되고 WebCrypto를 차단합니다. 기본적으로 OpenClaw는 기기 ID가 없는 Control UI 연결을 **차단**합니다. +일반 HTTP(`http://` 또는 `http://`)로 대시보드를 열면 브라우저가 **비보안 컨텍스트**에서 실행되어 WebCrypto를 차단합니다. 기본적으로 OpenClaw는 장치 ID가 없는 Control UI 연결을 **차단**합니다. 문서화된 예외: -- `gateway.controlUi.allowInsecureAuth=true`를 사용하는 localhost 전용 안전하지 않은 HTTP 호환성 -- `gateway.auth.mode: "trusted-proxy"`를 통한 성공적인 운영자 Control UI 인증 +- `gateway.controlUi.allowInsecureAuth=true`를 사용하는 localhost 전용 비보안 HTTP 호환성 +- `gateway.auth.mode: "trusted-proxy"`를 통한 성공적인 운영자 제어 UI 인증 - 비상용 `gateway.controlUi.dangerouslyDisableDeviceAuth=true` -**권장 수정:** HTTPS(Tailscale Serve)를 사용하거나 UI를 로컬에서 엽니다. +**권장 수정:** HTTPS(Tailscale Serve)를 사용하거나 UI를 로컬에서 여세요. -- `https:///`(Serve) -- `http://127.0.0.1:18789/`(Gateway 호스트에서) +- `https:///` (Serve) +- `http://127.0.0.1:18789/` (Gateway 호스트에서) - + ```json5 { gateway: { @@ -336,12 +338,12 @@ Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/ga `allowInsecureAuth`는 로컬 호환성 토글일 뿐입니다. - - 비보안 HTTP 컨텍스트에서 localhost Control UI 세션이 장치 ID 없이 진행되도록 허용합니다. + - 비보안 HTTP 컨텍스트에서 localhost 제어 UI 세션이 디바이스 ID 없이 계속 진행되도록 허용합니다. - 페어링 검사를 우회하지 않습니다. - - 원격(non-localhost) 장치 ID 요구 사항을 완화하지 않습니다. + - 원격(non-localhost) 디바이스 ID 요구 사항을 완화하지 않습니다. - + ```json5 { gateway: { @@ -353,42 +355,42 @@ Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/ga ``` - `dangerouslyDisableDeviceAuth`는 Control UI 장치 ID 검사를 비활성화하며 심각한 보안 저하입니다. 긴급 사용 후에는 신속히 되돌리세요. + `dangerouslyDisableDeviceAuth`는 제어 UI 디바이스 ID 검사를 비활성화하며, 심각한 보안 수준 저하입니다. 긴급 사용 후에는 빠르게 되돌리세요. - - - 신뢰할 수 있는 프록시 인증에 성공하면 장치 ID 없이 **운영자** Control UI 세션을 허용할 수 있습니다. - - 이는 노드 역할 Control UI 세션에는 적용되지 **않습니다**. - - 같은 호스트의 루프백 리버스 프록시는 여전히 신뢰할 수 있는 프록시 인증을 충족하지 않습니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참고하세요. + + - 성공적인 trusted-proxy 인증은 디바이스 ID 없이 **운영자** 제어 UI 세션을 허용할 수 있습니다. + - 이는 노드 역할 제어 UI 세션으로 확장되지 **않습니다**. + - 동일 호스트 loopback 역방향 프록시도 trusted-proxy 인증을 충족하지 않습니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참조하세요. -HTTPS 설정 지침은 [Tailscale](/ko/gateway/tailscale)을 참고하세요. +HTTPS 설정 지침은 [Tailscale](/ko/gateway/tailscale)을 참조하세요. ## 콘텐츠 보안 정책 -Control UI는 엄격한 `img-src` 정책과 함께 제공됩니다. **동일 출처** 자산, `data:` URL, 로컬에서 생성된 `blob:` URL만 허용됩니다. 원격 `http(s)` 및 프로토콜 상대 이미지 URL은 브라우저에서 거부되며 네트워크 fetch를 발생시키지 않습니다. +제어 UI는 엄격한 `img-src` 정책과 함께 제공됩니다. **동일 출처** 자산, `data:` URL, 로컬에서 생성된 `blob:` URL만 허용됩니다. 원격 `http(s)` 및 프로토콜 상대 이미지 URL은 브라우저에서 거부되며 네트워크 가져오기를 발생시키지 않습니다. 실제로는 다음을 의미합니다. -- 상대 경로(예: `/avatars/`) 아래에서 제공되는 아바타와 이미지는 계속 렌더링됩니다. 여기에는 UI가 가져와 로컬 `blob:` URL로 변환하는 인증된 아바타 라우트도 포함됩니다. -- 인라인 `data:image/...` URL은 계속 렌더링됩니다. 프로토콜 내 페이로드에 유용합니다. -- Control UI가 생성한 로컬 `blob:` URL은 계속 렌더링됩니다. -- 채널 메타데이터가 내보낸 원격 아바타 URL은 Control UI의 아바타 헬퍼에서 제거되고 내장 로고/배지로 대체됩니다. 따라서 손상되었거나 악의적인 채널이 운영자 브라우저에서 임의의 원격 이미지 fetch를 강제할 수 없습니다. +- 상대 경로(예: `/avatars/`) 아래에서 제공되는 아바타와 이미지는 계속 렌더링됩니다. 여기에는 UI가 가져와 로컬 `blob:` URL로 변환하는 인증된 아바타 경로도 포함됩니다. +- 인라인 `data:image/...` URL은 계속 렌더링됩니다(프로토콜 내 페이로드에 유용). +- 제어 UI가 만든 로컬 `blob:` URL은 계속 렌더링됩니다. +- 채널 메타데이터가 내보내는 원격 아바타 URL은 제어 UI의 아바타 헬퍼에서 제거되고 내장 로고/배지로 대체되므로, 손상되었거나 악의적인 채널이 운영자 브라우저에서 임의의 원격 이미지 가져오기를 강제할 수 없습니다. -이 동작을 얻기 위해 아무것도 변경할 필요가 없습니다. 항상 켜져 있으며 구성할 수 없습니다. +이 동작을 얻기 위해 변경할 것은 없습니다. 항상 켜져 있으며 구성할 수 없습니다. -## 아바타 라우트 인증 +## 아바타 경로 인증 -Gateway 인증이 구성된 경우 Control UI 아바타 엔드포인트는 API의 나머지 부분과 동일한 Gateway 토큰을 요구합니다. +Gateway 인증이 구성되어 있으면 제어 UI 아바타 엔드포인트는 API의 나머지 부분과 동일한 Gateway 토큰을 요구합니다. -- `GET /avatar/`는 인증된 호출자에게만 아바타 이미지를 반환합니다. `GET /avatar/?meta=1`은 동일한 규칙에 따라 아바타 메타데이터를 반환합니다. -- 두 라우트 중 하나에 대한 인증되지 않은 요청은 거부됩니다. 이는 형제 assistant-media 라우트와 일치합니다. 이렇게 하면 그 외에는 보호되는 호스트에서 아바타 라우트가 에이전트 ID를 유출하는 것을 방지합니다. -- Control UI 자체는 아바타를 가져올 때 Gateway 토큰을 bearer 헤더로 전달하고, 인증된 blob URL을 사용하므로 이미지가 대시보드에서 계속 렌더링됩니다. +- `GET /avatar/`는 인증된 호출자에게만 아바타 이미지를 반환합니다. `GET /avatar/?meta=1`은 같은 규칙에 따라 아바타 메타데이터를 반환합니다. +- 두 경로 중 하나에 대한 인증되지 않은 요청은 거부됩니다(형제 assistant-media 경로와 동일). 이를 통해 그 외에는 보호되는 호스트에서 아바타 경로가 에이전트 ID를 유출하지 않도록 합니다. +- 제어 UI 자체는 아바타를 가져올 때 Gateway 토큰을 bearer 헤더로 전달하고, 이미지가 대시보드에서 계속 렌더링되도록 인증된 blob URL을 사용합니다. -Gateway 인증을 비활성화하면(공유 호스트에서는 권장하지 않음) 아바타 라우트도 Gateway의 나머지 부분과 마찬가지로 인증되지 않은 상태가 됩니다. +Gateway 인증을 비활성화하면(공유 호스트에서는 권장하지 않음) Gateway의 나머지 부분과 마찬가지로 아바타 경로도 인증되지 않은 상태가 됩니다. ## UI 빌드 @@ -398,13 +400,13 @@ Gateway는 `dist/control-ui`에서 정적 파일을 제공합니다. 다음으 pnpm ui:build ``` -선택적 절대 base(고정 자산 URL을 원할 때): +선택적 절대 기본 경로(고정 자산 URL을 원할 때): ```bash OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build ``` -로컬 개발용(별도 dev 서버): +로컬 개발용(별도 개발 서버): ```bash pnpm ui:dev @@ -412,17 +414,17 @@ pnpm ui:dev 그런 다음 UI가 Gateway WS URL(예: `ws://127.0.0.1:18789`)을 가리키도록 하세요. -## 디버깅/테스트: dev 서버 + 원격 Gateway +## 디버깅/테스트: 개발 서버 + 원격 Gateway -Control UI는 정적 파일입니다. WebSocket 대상은 구성할 수 있으며 HTTP 출처와 다를 수 있습니다. 로컬에서 Vite dev 서버를 사용하고 Gateway는 다른 곳에서 실행하려는 경우 유용합니다. +제어 UI는 정적 파일이며, WebSocket 대상은 구성 가능하고 HTTP 출처와 다를 수 있습니다. 로컬에서는 Vite 개발 서버를 사용하고 Gateway는 다른 곳에서 실행하려는 경우 유용합니다. - + ```bash pnpm ui:dev ``` - + ```text http://localhost:5173/?gatewayUrl=ws%3A%2F%2F%3A18789 ``` @@ -437,18 +439,18 @@ Control UI는 정적 파일입니다. WebSocket 대상은 구성할 수 있으 - + - `gatewayUrl`은 로드 후 localStorage에 저장되고 URL에서 제거됩니다. - `gatewayUrl`을 통해 전체 `ws://` 또는 `wss://` 엔드포인트를 전달하는 경우, 브라우저가 쿼리 문자열을 올바르게 파싱하도록 `gatewayUrl` 값을 URL 인코딩하세요. - - 가능하면 `token`은 URL 프래그먼트(`#token=...`)를 통해 전달해야 합니다. 프래그먼트는 서버로 전송되지 않으므로 요청 로그 및 Referer 유출을 피할 수 있습니다. 레거시 `?token=` 쿼리 매개변수는 호환성을 위해 여전히 한 번 가져오지만, fallback으로만 사용되며 부트스트랩 직후 제거됩니다. + - 가능하면 `token`은 URL 프래그먼트(`#token=...`)를 통해 전달해야 합니다. 프래그먼트는 서버로 전송되지 않으므로 요청 로그 및 Referer 유출을 방지합니다. 레거시 `?token=` 쿼리 매개변수는 호환성을 위해 여전히 한 번 가져오지만, fallback으로만 사용되며 bootstrap 직후 즉시 제거됩니다. - `password`는 메모리에만 유지됩니다. - - `gatewayUrl`이 설정되면 UI는 config 또는 환경 credentials로 fallback하지 않습니다. `token`(또는 `password`)을 명시적으로 제공하세요. 명시적 credentials가 없으면 오류입니다. - - Gateway가 TLS 뒤에 있는 경우(Tailscale Serve, HTTPS 프록시 등) `wss://`를 사용하세요. - - `gatewayUrl`은 clickjacking을 방지하기 위해 최상위 창(임베드되지 않음)에서만 허용됩니다. - - 비루프백 Control UI 배포는 `gateway.controlUi.allowedOrigins`를 명시적으로 설정해야 합니다(전체 출처). 여기에는 원격 dev 설정도 포함됩니다. - - Gateway 시작 시 유효한 런타임 bind와 포트에서 `http://localhost:` 및 `http://127.0.0.1:` 같은 로컬 출처를 시드할 수 있지만, 원격 브라우저 출처에는 여전히 명시적 항목이 필요합니다. - - 엄격하게 제어되는 로컬 테스트를 제외하고는 `gateway.controlUi.allowedOrigins: ["*"]`를 사용하지 마세요. 이는 "내가 사용하는 호스트와 일치"가 아니라 모든 브라우저 출처를 허용한다는 의미입니다. - - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true`는 Host-header 출처 fallback 모드를 활성화하지만, 위험한 보안 모드입니다. + - `gatewayUrl`이 설정되면 UI는 구성 또는 환경 자격 증명으로 fallback하지 않습니다. `token`(또는 `password`)을 명시적으로 제공하세요. 명시적 자격 증명이 없으면 오류입니다. + - Gateway가 TLS(Tailscale Serve, HTTPS 프록시 등) 뒤에 있을 때는 `wss://`를 사용하세요. + - 클릭재킹을 방지하기 위해 `gatewayUrl`은 최상위 창(임베드되지 않음)에서만 허용됩니다. + - non-loopback 제어 UI 배포는 `gateway.controlUi.allowedOrigins`를 명시적으로 설정해야 합니다(전체 출처). 여기에는 원격 개발 설정도 포함됩니다. + - Gateway 시작 시 유효한 런타임 바인드 및 포트에서 `http://localhost:` 및 `http://127.0.0.1:` 같은 로컬 출처를 시드할 수 있지만, 원격 브라우저 출처에는 여전히 명시적 항목이 필요합니다. + - 엄격하게 제어되는 로컬 테스트를 제외하고 `gateway.controlUi.allowedOrigins: ["*"]`를 사용하지 마세요. 이는 "내가 사용하는 호스트와 일치"가 아니라 모든 브라우저 출처를 허용한다는 뜻입니다. + - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true`는 Host 헤더 출처 fallback 모드를 활성화하지만, 위험한 보안 모드입니다. diff --git a/docs/ko/web/webchat.md b/docs/ko/web/webchat.md index 5702805c8..e1280b524 100644 --- a/docs/ko/web/webchat.md +++ b/docs/ko/web/webchat.md @@ -1,68 +1,70 @@ --- read_when: - WebChat 액세스 디버깅 또는 구성 -summary: 채팅 UI용 루프백 WebChat 정적 호스트 및 Gateway WS 사용 +summary: 채팅 UI를 위한 Loopback WebChat 정적 호스트 및 Gateway WS 사용법 title: 웹 채팅 x-i18n: - generated_at: "2026-05-02T21:17:55Z" + generated_at: "2026-05-02T23:39:09Z" model: gpt-5.5 provider: openai - source_hash: fe6d3cb30ed18d651b0d0ca8fd188b47c5f1d186410ee340deb79315f194ed8d + source_hash: ad3a09c8962e3a6dda83716d319df7ba27e18105cee50721278b5cba0a85c52f source_path: web/webchat.md workflow: 16 --- -상태: macOS/iOS SwiftUI 채팅 UI는 Gateway 웹소켓과 직접 통신합니다. +상태: macOS/iOS SwiftUI 채팅 UI는 Gateway WebSocket과 직접 통신합니다. -## 정의 +## 개요 -- Gateway를 위한 네이티브 채팅 UI입니다(임베디드 브라우저와 로컬 정적 서버 없음). +- 게이트웨이를 위한 네이티브 채팅 UI입니다(임베디드 브라우저와 로컬 정적 서버 없음). - 다른 채널과 동일한 세션 및 라우팅 규칙을 사용합니다. -- 결정적 라우팅: 답장은 항상 WebChat으로 돌아갑니다. +- 결정적 라우팅: 응답은 항상 WebChat으로 돌아갑니다. ## 빠른 시작 -1. Gateway를 시작합니다. +1. 게이트웨이를 시작합니다. 2. WebChat UI(macOS/iOS 앱) 또는 Control UI 채팅 탭을 엽니다. -3. 유효한 Gateway 인증 경로가 구성되어 있는지 확인합니다(기본값은 공유 시크릿이며, +3. 유효한 게이트웨이 인증 경로가 구성되어 있는지 확인합니다(기본값은 공유 비밀이며, 루프백에서도 동일). ## 작동 방식(동작) -- UI는 Gateway 웹소켓에 연결하고 `chat.history`, `chat.send`, `chat.inject`를 사용합니다. -- `chat.history`는 안정성을 위해 제한됩니다. Gateway는 긴 텍스트 필드를 잘라내고, 무거운 메타데이터를 생략하며, 너무 큰 항목을 `[chat.history omitted: message too large]`로 대체할 수 있습니다. -- `chat.history`는 최신 추가 전용 세션 파일에서 활성 전사 분기를 따르므로, 폐기된 재작성 분기와 대체된 프롬프트 복사본은 WebChat에 렌더링되지 않습니다. -- Control UI는 `chat.history`가 반환한 기반 Gateway `sessionId`를 기억하고 후속 `chat.send` 호출에 포함하므로, 사용자가 세션을 시작하거나 재설정하지 않는 한 재연결 및 페이지 새로 고침 후에도 동일한 저장된 대화가 계속됩니다. -- Control UI는 새 `chat.send` 실행 ID를 생성하기 전에 동일한 세션, 메시지, 첨부 파일에 대한 중복 진행 중 제출을 병합합니다. Gateway는 여전히 동일한 멱등성 키를 재사용하는 반복 요청을 중복 제거합니다. +- UI는 Gateway WebSocket에 연결하고 `chat.history`, `chat.send`, `chat.inject`, `chat.transcribeAudio`를 사용합니다. +- 안정성을 위해 `chat.history`에는 제한이 있습니다. Gateway는 긴 텍스트 필드를 잘라내고, 무거운 메타데이터를 생략하며, 지나치게 큰 항목을 `[chat.history omitted: message too large]`로 대체할 수 있습니다. +- `chat.history`는 최신 append-only 세션 파일의 활성 트랜스크립트 브랜치를 따르므로, 폐기된 재작성 브랜치와 대체된 프롬프트 복사본은 WebChat에 렌더링되지 않습니다. +- Control UI는 `chat.history`가 반환한 기반 Gateway `sessionId`를 기억하고 후속 `chat.send` 호출에 포함하므로, 사용자가 세션을 시작하거나 재설정하지 않는 한 재연결과 페이지 새로 고침 후에도 동일한 저장된 대화를 계속합니다. +- Control UI는 새 `chat.send` 실행 id를 생성하기 전에 같은 세션, 메시지, 첨부 파일에 대한 중복 진행 중 제출을 병합합니다. Gateway는 여전히 동일한 멱등성 키를 재사용하는 반복 요청을 중복 제거합니다. - `chat.history`는 표시용으로도 정규화됩니다. 런타임 전용 OpenClaw 컨텍스트, - 인바운드 엔벌로프 래퍼, `[[reply_to_*]]` 및 `[[audio_as_voice]]` 같은 인라인 전달 지시 태그, 일반 텍스트 도구 호출 XML - 페이로드(`...`, + 인바운드 엔벌로프 래퍼, `[[reply_to_*]]` 및 `[[audio_as_voice]]` 같은 + 인라인 전달 지시 태그, `...`, `...`, `...`, - `...` 및 잘린 도구 호출 블록 포함), 그리고 - 누출된 ASCII/전각 모델 제어 토큰은 표시 텍스트에서 제거되며, - 전체 표시 텍스트가 정확히 무음 토큰 `NO_REPLY` / `no_reply`뿐인 어시스턴트 항목은 생략됩니다. -- 추론 플래그가 지정된 답장 페이로드(`isReasoning: true`)는 WebChat 어시스턴트 콘텐츠, 전사 재생 텍스트, 오디오 콘텐츠 블록에서 제외되므로, 생각 전용 페이로드는 표시되는 어시스턴트 메시지나 재생 가능한 오디오로 노출되지 않습니다. -- `chat.inject`는 어시스턴트 메모를 전사에 직접 추가하고 UI로 브로드캐스트합니다(에이전트 실행 없음). + `...` 및 잘린 도구 호출 블록을 포함한 + 일반 텍스트 도구 호출 XML 페이로드, 그리고 누출된 ASCII/전각 모델 제어 토큰은 + 보이는 텍스트에서 제거되며, 전체 표시 텍스트가 정확한 무음 토큰 + `NO_REPLY` / `no_reply`뿐인 어시스턴트 항목은 생략됩니다. +- 추론 플래그가 지정된 응답 페이로드(`isReasoning: true`)는 WebChat 어시스턴트 콘텐츠, 트랜스크립트 재생 텍스트, 오디오 콘텐츠 블록에서 제외되므로, 생각 전용 페이로드는 보이는 어시스턴트 메시지나 재생 가능한 오디오로 표시되지 않습니다. +- `chat.transcribeAudio`는 Control UI 채팅 작성기의 서버 측 받아쓰기를 구동합니다. 브라우저가 마이크 오디오를 녹음하여 base64로 Gateway에 보내면, Gateway가 구성된 `tools.media.audio` 파이프라인을 실행합니다. 반환된 트랜스크립트는 초안에 삽입되며, 사용자가 전송하기 전까지 에이전트 실행은 시작되지 않습니다. +- `chat.inject`는 어시스턴트 메모를 트랜스크립트에 직접 추가하고 UI에 브로드캐스트합니다(에이전트 실행 없음). - 중단된 실행은 부분 어시스턴트 출력을 UI에 계속 표시할 수 있습니다. -- Gateway는 버퍼링된 출력이 있을 때 중단된 부분 어시스턴트 텍스트를 전사 기록에 유지하고, 해당 항목에 중단 메타데이터를 표시합니다. -- 기록은 항상 Gateway에서 가져옵니다(로컬 파일 감시 없음). -- Gateway에 연결할 수 없으면 WebChat은 읽기 전용입니다. +- Gateway는 버퍼링된 출력이 있을 때 중단된 부분 어시스턴트 텍스트를 트랜스크립트 기록에 유지하고, 해당 항목에 중단 메타데이터를 표시합니다. +- 기록은 항상 게이트웨이에서 가져옵니다(로컬 파일 감시 없음). +- 게이트웨이에 연결할 수 없으면 WebChat은 읽기 전용입니다. ## Control UI 에이전트 도구 패널 - Control UI `/agents` 도구 패널에는 두 개의 별도 보기가 있습니다. - **지금 사용 가능**은 `tools.effective(sessionKey=...)`를 사용하며 현재 - 세션이 런타임에 실제로 사용할 수 있는 항목을 표시합니다. 여기에는 코어, Plugin, 채널 소유 도구가 포함됩니다. + 세션이 런타임에 실제로 사용할 수 있는 항목을 보여줍니다. 여기에는 코어, Plugin, 채널 소유 도구가 포함됩니다. - **도구 구성**은 `tools.catalog`를 사용하며 프로필, 재정의, 카탈로그 의미 체계에 집중합니다. -- 런타임 사용 가능 여부는 세션 범위입니다. 같은 에이전트에서 세션을 전환하면 +- 런타임 가용성은 세션 범위입니다. 같은 에이전트에서 세션을 전환하면 **지금 사용 가능** 목록이 바뀔 수 있습니다. -- 구성 편집기는 런타임 사용 가능 여부를 의미하지 않습니다. 유효한 접근 권한은 여전히 정책 - 우선순위(`allow`/`deny`, 에이전트별 및 제공자/채널 재정의)를 따릅니다. +- 구성 편집기가 런타임 가용성을 의미하지는 않습니다. 유효 접근 권한은 여전히 정책 + 우선순위(`allow`/`deny`, 에이전트별 및 공급자/채널 재정의)를 따릅니다. ## 원격 사용 -- 원격 모드는 SSH/Tailscale을 통해 Gateway 웹소켓을 터널링합니다. +- 원격 모드는 SSH/Tailscale을 통해 게이트웨이 WebSocket을 터널링합니다. - 별도의 WebChat 서버를 실행할 필요가 없습니다. ## 구성 참조(WebChat) @@ -71,20 +73,20 @@ x-i18n: WebChat 옵션: -- `gateway.webchat.chatHistoryMaxChars`: `chat.history` 응답의 텍스트 필드에 대한 최대 문자 수입니다. 전사 항목이 이 제한을 초과하면 Gateway는 긴 텍스트 필드를 잘라내고 너무 큰 메시지를 플레이스홀더로 대체할 수 있습니다. 클라이언트는 단일 `chat.history` 호출에 대해 이 기본값을 재정의하도록 요청별 `maxChars`도 보낼 수 있습니다. +- `gateway.webchat.chatHistoryMaxChars`: `chat.history` 응답의 텍스트 필드에 대한 최대 문자 수입니다. 트랜스크립트 항목이 이 제한을 초과하면 Gateway는 긴 텍스트 필드를 잘라내고 지나치게 큰 메시지를 자리 표시자로 대체할 수 있습니다. 클라이언트는 단일 `chat.history` 호출에 대해 이 기본값을 재정의하도록 요청별 `maxChars`도 보낼 수 있습니다. 관련 전역 옵션: -- `gateway.port`, `gateway.bind`: 웹소켓 호스트/포트. +- `gateway.port`, `gateway.bind`: WebSocket 호스트/포트. - `gateway.auth.mode`, `gateway.auth.token`, `gateway.auth.password`: - 공유 시크릿 웹소켓 인증. -- `gateway.auth.allowTailscale`: 활성화된 경우 브라우저 Control UI 채팅 탭은 Tailscale + 공유 비밀 WebSocket 인증. +- `gateway.auth.allowTailscale`: 활성화되면 브라우저 Control UI 채팅 탭이 Tailscale Serve ID 헤더를 사용할 수 있습니다. -- `gateway.auth.mode: "trusted-proxy"`: ID 인식 **비루프백** 프록시 소스 뒤에 있는 브라우저 클라이언트를 위한 리버스 프록시 인증입니다([신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth) 참조). -- `gateway.remote.url`, `gateway.remote.token`, `gateway.remote.password`: 원격 Gateway 대상. -- `session.*`: 세션 저장소 및 기본 키 기본값. +- `gateway.auth.mode: "trusted-proxy"`: ID 인식 **비루프백** 프록시 소스 뒤의 브라우저 클라이언트를 위한 역방향 프록시 인증입니다([신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth) 참조). +- `gateway.remote.url`, `gateway.remote.token`, `gateway.remote.password`: 원격 게이트웨이 대상. +- `session.*`: 세션 저장소와 기본 키 기본값. -## 관련 항목 +## 관련 - [Control UI](/ko/web/control-ui) - [대시보드](/ko/web/dashboard)