From 9851a7742882d8bfda241cef566337c6a048e471 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Wed, 29 Apr 2026 05:00:02 +0000 Subject: [PATCH] chore(i18n): refresh uk translations --- docs/uk/ci.md | 407 +++++++++++++------------ docs/uk/gateway/protocol.md | 588 ++++++++++++++++++------------------ 2 files changed, 507 insertions(+), 488 deletions(-) diff --git a/docs/uk/ci.md b/docs/uk/ci.md index d25cf668d..b29851f12 100644 --- a/docs/uk/ci.md +++ b/docs/uk/ci.md @@ -1,138 +1,144 @@ --- read_when: - - Вам потрібно зрозуміти, чому завдання CI виконалося або не виконалося - - Ви налагоджуєте перевірки GitHub Actions, що не проходять + - Потрібно зрозуміти, чому завдання CI було або не було запущено + - Ви налагоджуєте перевірки GitHub Actions, що завершуються помилкою summary: Граф завдань CI, перевірки за областю дії та локальні еквіваленти команд -title: Конвеєр CI +title: CI-конвеєр x-i18n: - generated_at: "2026-04-29T04:29:34Z" + generated_at: "2026-04-29T04:57:35Z" model: gpt-5.5 provider: openai - source_hash: 80e4eb0d3713a353a9b5e3d75a7c94435587d66ac45aad5d906bf6700ddd57fc + source_hash: 5315d80962cfce8e894fca23fe0eaf74c5d1f30638612b50d329946c7a6b0fb0 source_path: ci.md workflow: 16 --- -CI запускається під час кожного push до `main` і кожного pull request. Він використовує розумне визначення області, щоб пропускати дорогі завдання, коли змінено лише непов’язані ділянки. Ручні запуски `workflow_dispatch` навмисно обходять розумне визначення області та розгортають повний звичайний граф CI для реліз-кандидатів або широкої валідації. +CI запускається під час кожного push до `main` і кожного pull request. Він використовує розумне обмеження області, щоб пропускати дорогі завдання, коли змінено лише непов’язані ділянки. Ручні запуски `workflow_dispatch` навмисно обходять розумне обмеження області та розгортають повний звичайний граф CI для кандидатів на реліз або широкої валідації. `Full Release Validation` — це ручний парасольковий workflow для "запустити все -перед релізом". Він приймає гілку, тег або повний SHA коміту, запускає ручний +перед релізом." Він приймає гілку, тег або повний SHA коміту, запускає ручний workflow `CI` із цією ціллю та запускає `OpenClaw Release Checks` -для smoke-перевірки встановлення, приймання пакета, наборів release-path для Docker, -live/E2E, OpenWebUI, паритету QA Lab, Matrix і Telegram-напрямів. Він також може запускати +для smoke-перевірки встановлення, приймання пакета, наборів Docker release-path, +live/E2E, OpenWebUI, паритету QA Lab, Matrix і Telegram lanes. Він також може запускати післяпублікаційний workflow `NPM Telegram Beta E2E`, коли надано специфікацію опублікованого пакета. `release_profile=minimum|stable|full` керує шириною -live/provider, що передається до release checks: `minimum` залишає найшвидші -критичні для релізу напрями OpenAI/core, `stable` додає стабільний набір provider/backend, -а `full` запускає широку консультативну матрицю provider/media. Парасольковий workflow записує -ідентифікатори запущених дочірніх запусків, а фінальне завдання `Verify full validation` повторно перевіряє -поточні висновки дочірніх запусків і додає таблиці найповільніших завдань для кожного дочірнього -запуску. Якщо дочірній workflow перезапущено і він став зеленим, перезапустіть лише батьківське -завдання verifier, щоб оновити результат парасолькового workflow і підсумок таймінгів. +live/provider, що передається в release checks: `minimum` залишає найшвидші +критично важливі для релізу lanes OpenAI/core, `stable` додає стабільний набір +provider/backend, а `full` запускає широку advisory-матрицю provider/media. +Парасольковий workflow записує id запущених дочірніх запусків, а фінальне +завдання `Verify full validation` повторно перевіряє поточні висновки дочірніх +запусків і додає таблиці найповільніших завдань для кожного дочірнього запуску. +Якщо дочірній workflow перезапущено і він став зеленим, перезапустіть лише +батьківське verifier-завдання, щоб оновити результат парасолькового workflow і +підсумок часу виконання. Для відновлення `Full Release Validation` і `OpenClaw Release Checks` обидва -приймають `rerun_group`. Використовуйте `all` для реліз-кандидата, `ci` лише для -звичайного повного дочірнього CI, `release-checks` для кожного релізного дочірнього запуску або вужчу -релізну групу: `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, -`qa-parity`, `qa-live` або `npm-telegram` у парасольковому workflow. Це утримує перезапуск -невдалого релізного блока в межах після сфокусованого виправлення. +приймають `rerun_group`. Використовуйте `all` для кандидата на реліз, `ci` лише +для звичайного повного дочірнього CI, `release-checks` для кожного дочірнього +релізного workflow або вужчу релізну групу: `install-smoke`, `cross-os`, +`live-e2e`, `package`, `qa`, `qa-parity`, `qa-live` або `npm-telegram` у +парасольковому workflow. Це утримує перезапуск невдалого release box обмеженим +після цільового виправлення. -Дочірній release live/E2E зберігає широке нативне покриття `pnpm test:live`, але +Дочірній release live/E2E зберігає широке native-покриття `pnpm test:live`, але запускає його як іменовані shards (`native-live-src-agents`, `native-live-src-gateway-core`, відфільтровані за provider завдання `native-live-src-gateway-profiles`, `native-live-src-gateway-backends`, `native-live-test`, `native-live-extensions-a-k`, `native-live-extensions-l-n`, `native-live-extensions-openai`, `native-live-extensions-o-z-other`, -`native-live-extensions-xai`, розділені audio/video shards для media та -відфільтровані за provider music shards) через `scripts/test-live-shard.mjs` замість -одного послідовного завдання. Це зберігає те саме покриття файлів, водночас спрощуючи перезапуск -і діагностику повільних збоїв live provider. Агреговані назви shards -`native-live-extensions-o-z`, `native-live-extensions-media` і -`native-live-extensions-media-music` залишаються чинними для ручних -одноразових перезапусків. +`native-live-extensions-xai`, розділені media shards для аудіо/відео та +відфільтровані за provider music shards) через `scripts/test-live-shard.mjs` +замість одного послідовного завдання. Це зберігає те саме файлове покриття, +водночас спрощуючи повторний запуск і діагностику повільних live-збоїв provider. +Агреговані назви shards `native-live-extensions-o-z`, +`native-live-extensions-media` і `native-live-extensions-media-music` +залишаються чинними для ручних одноразових перезапусків. -Нативні live media shards запускаються в -`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`, зібраному workflow +Native live media shards запускаються в +`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`, який збирає workflow `Live Media Runner Image`. Цей образ попередньо встановлює `ffmpeg` і -`ffprobe`; media-завдання лише перевіряють наявність бінарників перед налаштуванням. Тримайте Docker-backed -live-набори на звичайних Blacksmith runners, бо container jobs — неправильне -місце для запуску вкладених Docker-тестів. +`ffprobe`; media-завдання лише перевіряють бінарні файли перед налаштуванням. +Тримайте Docker-backed live-набори на звичайних Blacksmith runners, бо container +jobs — неправильне місце для запуску вкладених Docker tests. -Docker-backed shards для live model/backend використовують окремий спільний -образ `ghcr.io/openclaw/openclaw-live-test:` для кожного вибраного коміту. Live -release workflow збирає та публікує цей образ один раз, після чого shards Docker live model, -gateway, CLI backend, ACP bind і Codex harness запускаються з -`OPENCLAW_SKIP_DOCKER_BUILD=1`. Якщо ці shards самостійно перебирають повну source Docker -ціль, релізний запуск неправильно налаштований і марнуватиме wall clock на дубльовані збірки образів. +Docker-backed live model/backend shards використовують окремий спільний образ +`ghcr.io/openclaw/openclaw-live-test:` для кожного вибраного коміту. Live +release workflow один раз збирає й публікує цей образ, після чого Docker live +model, gateway, CLI backend, ACP bind і Codex harness shards запускаються з +`OPENCLAW_SKIP_DOCKER_BUILD=1`. Якщо ці shards самостійно перебудовують повну +source Docker target, release run налаштовано неправильно, і він марнуватиме +час виконання на дубльовані збірки образів. -`OpenClaw Release Checks` використовує довірений workflow ref, щоб один раз розв’язати вибраний -ref у tarball `release-package-under-test`, а потім передає цей артефакт -і до live/E2E release-path Docker workflow, і до package acceptance -shard. Це зберігає байти пакета узгодженими між релізними блоками та уникає +`OpenClaw Release Checks` використовує trusted workflow ref, щоб один раз +розв’язати вибраний ref у tarball `release-package-under-test`, а потім передає +цей artifact і до live/E2E release-path Docker workflow, і до package acceptance +shard. Це зберігає байти пакета узгодженими між release boxes і уникає повторного пакування того самого кандидата в кількох дочірніх завданнях. -`Package Acceptance` — це побічний workflow для валідації артефакта пакета -без блокування релізного workflow. Він розв’язує одного кандидата з -опублікованої npm-специфікації, довіреного `package_ref`, зібраного за допомогою вибраного -`workflow_ref` harness, HTTPS URL tarball із SHA-256 або tarball-артефакта -з іншого запуску GitHub Actions, завантажує його як `package-under-test`, а потім повторно використовує -Docker release/E2E scheduler із цим tarball замість повторного пакування -checkout workflow. Профілі покривають smoke, package, product, full і custom -вибори Docker lanes. Профіль `package` використовує офлайн-покриття plugin, щоб -валідація опублікованого пакета не залежала від live-доступності ClawHub. Опційний -Telegram-напрям повторно використовує артефакт -`package-under-test` у workflow `NPM Telegram Beta E2E`, а шлях -опублікованої npm-специфікації збережено для standalone dispatches. +`Package Acceptance` — це побічний workflow для валідації package artifact без +блокування release workflow. Він розв’язує одного кандидата з опублікованої npm +spec, trusted `package_ref`, зібраного вибраним `workflow_ref` harness, HTTPS +tarball URL із SHA-256 або tarball artifact з іншого запуску GitHub Actions, +завантажує його як `package-under-test`, а потім повторно використовує Docker +release/E2E scheduler із цим tarball замість повторного пакування workflow +checkout. Профілі покривають smoke, package, product, full і custom +Docker lane selections. Профіль `package` використовує offline plugin-покриття, +щоб валідація опублікованого пакета не залежала від доступності live ClawHub. +Необов’язковий Telegram lane повторно використовує artifact +`package-under-test` у workflow `NPM Telegram Beta E2E`, а шлях опублікованої +npm spec зберігається для standalone dispatches. ## Приймання пакета -Використовуйте `Package Acceptance`, коли питання звучить як "чи працює цей встановлюваний пакет OpenClaw -як продукт?" Це відрізняється від звичайного CI: звичайний CI валідує -дерево вихідного коду, тоді як package acceptance валідує один tarball через той самий -Docker E2E harness, який користувачі виконують після встановлення або оновлення. +Використовуйте `Package Acceptance`, коли питання звучить як "чи працює цей +інстальований пакет OpenClaw як продукт?" Це відрізняється від звичайного CI: +звичайний CI валідує дерево вихідного коду, тоді як package acceptance валідує +один tarball через той самий Docker E2E harness, який користувачі задіюють +після встановлення або оновлення. Workflow має чотири завдання: -1. `resolve_package` виконує checkout `workflow_ref`, розв’язує одного кандидата пакета, - записує `.artifacts/docker-e2e-package/openclaw-current.tgz`, записує +1. `resolve_package` виконує checkout `workflow_ref`, розв’язує одного кандидата + пакета, записує `.artifacts/docker-e2e-package/openclaw-current.tgz`, записує `.artifacts/docker-e2e-package/package-candidate.json`, завантажує обидва як - артефакт `package-under-test` і виводить джерело, workflow ref, package - ref, версію, SHA-256 і профіль у підсумку кроку GitHub. + artifact `package-under-test` і друкує джерело, workflow ref, package ref, + версію, SHA-256 і профіль у GitHub step summary. 2. `docker_acceptance` викликає `openclaw-live-and-e2e-checks-reusable.yml` з `ref=workflow_ref` і - `package_artifact_name=package-under-test`. Reusable workflow завантажує - цей артефакт, валідує інвентар tarball, готує package-digest - Docker-образи за потреби та запускає вибрані Docker lanes проти цього - пакета замість пакування checkout workflow. Коли профіль вибирає - кілька цільових `docker_lanes`, reusable workflow готує пакет - і спільні образи один раз, а потім розгортає ці lanes як паралельні цільові Docker - завдання з унікальними артефактами. -3. `package_telegram` опційно викликає `NPM Telegram Beta E2E`. Він запускається, коли - `telegram_mode` не є `none`, і встановлює той самий артефакт `package-under-test`, - якщо Package Acceptance розв’язав його; standalone Telegram dispatch - все ще може встановити опубліковану npm-специфікацію. + `package_artifact_name=package-under-test`. Reusable workflow завантажує цей + artifact, валідує інвентар tarball, за потреби готує package-digest + Docker images і запускає вибрані Docker lanes проти цього пакета замість + пакування workflow checkout. Коли профіль вибирає кілька цільових + `docker_lanes`, reusable workflow один раз готує пакет і спільні образи, а + потім розгортає ці lanes як паралельні цільові Docker jobs з унікальними + artifacts. +3. `package_telegram` необов’язково викликає `NPM Telegram Beta E2E`. Він + запускається, коли `telegram_mode` не дорівнює `none`, і встановлює той самий + artifact `package-under-test`, коли Package Acceptance розв’язав його; + standalone Telegram dispatch все ще може встановити опубліковану npm spec. 4. `summary` провалює workflow, якщо розв’язання пакета, Docker acceptance або - опційний Telegram-напрям завершилися невдало. + необов’язковий Telegram lane зазнали невдачі. Джерела кандидатів: - `source=npm`: приймає лише `openclaw@beta`, `openclaw@latest` або точну - релізну версію OpenClaw, наприклад `openclaw@2026.4.27-beta.2`. Використовуйте це для - приймання опублікованих beta/stable. -- `source=ref`: пакує довірену гілку, тег або повний SHA коміту `package_ref`. - Resolver отримує гілки/теги OpenClaw, перевіряє, що вибраний коміт - досяжний з історії гілки репозиторію або релізного тегу, встановлює залежності у - від’єднаному worktree і пакує його за допомогою `scripts/package-openclaw-for-docker.mjs`. -- `source=url`: завантажує HTTPS `.tgz`; `package_sha256` обов’язковий. + версію релізу OpenClaw, наприклад `openclaw@2026.4.27-beta.2`. Використовуйте + це для приймання опублікованих beta/stable. +- `source=ref`: пакує trusted `package_ref` branch, tag або full commit SHA. + Resolver отримує branches/tags OpenClaw, перевіряє, що вибраний коміт + досяжний з історії repository branch або release tag, встановлює залежності в + detached worktree і пакує його за допомогою + `scripts/package-openclaw-for-docker.mjs`. +- `source=url`: завантажує HTTPS `.tgz`; `package_sha256` є обов’язковим. - `source=artifact`: завантажує один `.tgz` з `artifact_run_id` і - `artifact_name`; `package_sha256` опційний, але його варто надати для - зовнішньо поширюваних артефактів. + `artifact_name`; `package_sha256` необов’язковий, але його варто надати для + artifacts, поширених зовні. -Тримайте `workflow_ref` і `package_ref` окремо. `workflow_ref` — це довірений -код workflow/harness, який запускає тест. `package_ref` — це вихідний коміт, -який пакується, коли `source=ref`. Це дає змогу поточному test harness валідувати -старіші довірені коміти вихідного коду без запуску старої workflow-логіки. +Тримайте `workflow_ref` і `package_ref` окремо. `workflow_ref` — це trusted +workflow/harness code, який виконує тест. `package_ref` — це source commit, який +пакується, коли `source=ref`. Це дає змогу поточному test harness валідувати +старіші trusted source commits без запуску старої workflow logic. Профілі відповідають Docker-покриттю: @@ -143,36 +149,37 @@ Workflow має чотири завдання: - `product`: `package` плюс `mcp-channels`, `cron-mcp-cleanup`, `openai-web-search-minimal`, `openwebui` - `full`: повні Docker release-path chunks з OpenWebUI -- `custom`: точні `docker_lanes`; обов’язковий, коли `suite_profile=custom` +- `custom`: точні `docker_lanes`; обов’язково, коли `suite_profile=custom` Release checks викликають Package Acceptance з `source=ref`, `package_ref=`, `workflow_ref=`, `suite_profile=custom`, `docker_lanes='bundled-channel-deps-compat plugins-offline'` і -`telegram_mode=mock-openai`. Docker -chunks release-path покривають перетин package/update/plugin lanes, тоді як Package -Acceptance зберігає artifact-native bundled-channel compat, offline plugin і -Telegram-доказ проти того самого розв’язаного package tarball. -Cross-OS release checks і далі покривають OS-specific onboarding, installer і -platform behavior; валідацію package/update product слід починати з Package -Acceptance. Windows packaged і installer fresh lanes також перевіряють, що -встановлений пакет може імпортувати browser-control override із сирого абсолютного -Windows-шляху. +`telegram_mode=mock-openai`. Release-path Docker +chunks покривають перетин package/update/plugin lanes, тоді як Package +Acceptance зберігає artifact-native proof для bundled-channel compat, offline +plugin і Telegram проти того самого розв’язаного package tarball. +Cross-OS release checks все ще покривають специфічні для ОС onboarding, +installer і platform behavior; валідацію package/update product слід починати з +Package Acceptance. Windows packaged і installer fresh lanes також перевіряють, +що встановлений пакет може імпортувати browser-control override з raw absolute +Windows path. -Package Acceptance має обмежені вікна legacy-сумісності для вже -опублікованих пакетів. Пакети до `2026.4.25` включно, зокрема `2026.4.25-beta.*`, -можуть використовувати шлях сумісності для відомих приватних QA entries у -`dist/postinstall-inventory.json`, які вказують на файли, пропущені tarball, -`doctor-switch` може пропустити підвипадок персистентності `gateway install --wrapper`, -коли пакет не надає цей прапорець, `update-channel-switch` може обрізати -відсутні `pnpm.patchedDependencies` із fake git fixture, похідного від tarball, і -може логувати відсутній збережений `update.channel`, plugin smokes можуть читати legacy -розташування install-record або приймати відсутню персистентність marketplace install-record, -а `plugin-update` може дозволити міграцію metadata конфігурації, водночас усе ще -вимагаючи, щоб install record і поведінка no-reinstall залишалися незмінними. Опублікований -пакет `2026.4.26` також може попереджати про stamp-файли локальних build metadata, -які вже були поставлені. Пізніші пакети мають відповідати сучасним контрактам; ті самі -умови завершуються помилкою замість попередження або пропуску. +Package Acceptance має обмежені вікна legacy-сумісності для вже опублікованих +пакетів. Пакети до `2026.4.25` включно, зокрема `2026.4.25-beta.*`, можуть +використовувати compatibility path для відомих private QA entries у +`dist/postinstall-inventory.json`, які вказують на файли, пропущені в tarball; +`doctor-switch` може пропустити підвипадок persistence для +`gateway install --wrapper`, коли пакет не відкриває цей flag; +`update-channel-switch` може prune відсутні `pnpm.patchedDependencies` з +tarball-derived fake git fixture і може логувати відсутній persisted +`update.channel`; plugin smokes можуть читати legacy install-record locations +або приймати відсутню marketplace install-record persistence; а `plugin-update` +може дозволити міграцію config metadata, водночас і надалі вимагаючи, щоб +install record і no-reinstall behavior залишалися незмінними. Опублікований +пакет `2026.4.26` також може попереджати про local build metadata stamp files, +які вже було випущено. Пізніші пакети мають задовольняти сучасні contracts; ті +самі умови призводять до failure замість warning або skip. Приклади: @@ -215,29 +222,44 @@ gh workflow run package-acceptance.yml \ -f docker_lanes='install-e2e plugin-update' ``` -Під час налагодження невдалого запуску package acceptance починайте з підсумку `resolve_package`, -щоб підтвердити джерело пакета, версію та SHA-256. Потім перевірте -дочірній запуск `docker_acceptance` і його Docker-артефакти: +Під час налагодження невдалого запуску package acceptance почніть із підсумку +`resolve_package`, щоб підтвердити джерело пакета, версію та SHA-256. Потім +перегляньте дочірній запуск `docker_acceptance` і його Docker artifacts: `.artifacts/docker-tests/**/summary.json`, `failures.json`, lane logs, phase -timings і команди перезапуску. Надавайте перевагу перезапуску невдалого профілю пакета або -точних Docker lanes замість перезапуску full release validation. +timings і rerun commands. Надавайте перевагу перезапуску невдалого package +profile або точних Docker lanes замість повторного запуску full release +validation. -Лабораторія QA має окремі CI-лінії поза основним workflow із розумною областю дії. Workflow `Parity gate` запускається для відповідних змін у PR і через ручний запуск; він збирає приватне середовище виконання QA та порівнює agentic-пакети mock GPT-5.5 і Opus 4.6. Workflow `QA-Lab - All Lanes` запускається щоночі на `main` і через ручний запуск; він розгортає mock parity gate, live-лінію Matrix, а також live-лінії Telegram і Discord як паралельні завдання. Live-завдання використовують середовище `qa-live-shared`, а Telegram/Discord використовують оренди Convex. Перевірки релізу запускають live-лінії транспорту Matrix і Telegram із детермінованим mock-провайдером і mock-кваліфікованими моделями (`mock-openai/gpt-5.5` і `mock-openai/gpt-5.5-alt`), щоб контракт каналу був ізольований від затримки live-моделі та звичайного запуску provider-plugin. Live transport Gateway також вимикає пошук у пам’яті, оскільки parity QA окремо покриває поведінку пам’яті; підключення провайдерів покривають окремі набори live model, native provider і Docker provider. Matrix використовує `--profile fast` для запланованих і релізних gate-перевірок, додаючи `--fail-fast` лише коли checked-out CLI це підтримує. Стандартне значення CLI і ручний вхід workflow залишаються `all`; ручний dispatch `matrix_profile=all` завжди розбиває повне покриття Matrix на завдання `transport`, `media`, `e2ee-smoke`, `e2ee-deep` і `e2ee-cli`. `OpenClaw Release Checks` також запускає критично важливі для релізу лінії QA Lab перед схваленням релізу; його gate parity QA запускає candidate і baseline пакети як паралельні завдання ліній, а потім завантажує обидва артефакти в невелике звітне завдання для фінального порівняння parity. -Не ставте шлях приземлення PR за `Parity gate`, якщо зміна насправді не торкається середовища виконання QA, parity model-pack або поверхні, якою володіє parity workflow. Для звичайних виправлень каналів, конфігурації, документації або unit-тестів розглядайте це як необов’язковий сигнал і натомість спирайтеся на докази зі scoped CI/check. +QA Lab має окремі CI-доріжки поза основним workflow із розумним визначенням області. Workflow `Parity gate` запускається для відповідних змін у PR і ручного запуску; він збирає приватне QA-середовище виконання та порівнює агентні пакети mock GPT-5.5 і Opus 4.6. Workflow `QA-Lab - All Lanes` запускається щоночі на `main` і під час ручного запуску; він розгортає mock parity gate, live-доріжку Matrix, а також live-доріжки Telegram і Discord як паралельні завдання. Live-завдання використовують середовище `qa-live-shared`, а Telegram/Discord використовують Convex-оренди. Release-перевірки запускають live-доріжки транспорту Matrix і Telegram із детермінованим mock-провайдером і mock-кваліфікованими моделями (`mock-openai/gpt-5.5` і `mock-openai/gpt-5.5-alt`), щоб контракт каналу був ізольований від затримки live-моделі та звичайного запуску provider-plugin. Live transport gateway також вимикає пошук у пам’яті, оскільки QA parity окремо покриває поведінку пам’яті; підключення провайдера покривають окремі набори live model, native provider і Docker provider. Matrix використовує `--profile fast` для запланованих і release-gate перевірок, додаючи `--fail-fast` лише тоді, коли checkout-нутий CLI це підтримує. Стандартне значення CLI і ручний workflow-ввід залишаються `all`; ручний запуск із `matrix_profile=all` завжди розбиває повне покриття Matrix на завдання `transport`, `media`, `e2ee-smoke`, `e2ee-deep` і `e2ee-cli`. `OpenClaw Release Checks` також запускає критичні для релізу доріжки QA Lab перед затвердженням релізу; його QA parity gate запускає кандидатний і baseline-пакети як паралельні lane-завдання, а потім завантажує обидва артефакти в невелике report-завдання для фінального parity-порівняння. Не ставте шлях landing PR за `Parity gate`, якщо зміна насправді не торкається QA runtime, parity пакетів моделей або поверхні, якою володіє parity workflow. Для звичайних виправлень каналів, конфігурації, документації або unit-тестів вважайте це опціональним сигналом і натомість дотримуйтеся scoped CI/check доказів. -Workflow `Duplicate PRs After Merge` — це ручний maintainer workflow для очищення дублікатів після приземлення. За замовчуванням він працює в режимі dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перед змінами в GitHub він перевіряє, що приземлений PR змерджено і що кожен дублікат має або спільну referenced issue, або перекривані змінені hunks. +Workflow `Duplicate PRs After Merge` — це ручний maintainer workflow для очищення дублікатів після landing. За замовчуванням він працює в dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перед зміною GitHub він перевіряє, що landed PR змерджено і що кожен дублікат має або спільне referenced issue, або перетин змінених hunks. -Workflow `CodeQL` навмисно є вузьким security scanner першого проходу, а не повним скануванням репозиторію. Щоденні та ручні запуски сканують код Actions workflow плюс поверхні найвищого ризику JavaScript/TypeScript для auth, secrets, sandbox, cron і gateway за допомогою високоточних security queries. Завдання channel-runtime-boundary окремо сканує контракти core channel implementation разом із channel plugin runtime, Gateway, Plugin SDK, secrets і audit touchpoints у категорії `/codeql-critical-security/channel-runtime-boundary`, щоб сигнал безпеки каналів міг масштабуватися без розширення базової категорії JS/TS. +Workflow `CodeQL` навмисно є вузьким security scanner першого проходу, а не повним sweep репозиторію. Щоденні й ручні запуски сканують код Actions workflow, а також найризикованіші JavaScript/TypeScript-поверхні auth, secrets, sandbox, cron і gateway з високоточними security queries. Завдання channel-runtime-boundary окремо сканує core channel implementation contracts, а також channel plugin runtime, gateway, Plugin SDK, secrets і audit touchpoints у категорії `/codeql-critical-security/channel-runtime-boundary`, щоб security-сигнал каналів міг масштабуватися без розширення baseline JS/TS-категорії. Workflow `CodeQL Android Critical Security` — це запланований Android security shard. Він вручну збирає Android app для CodeQL на найменшій мітці Blacksmith Linux runner, яку приймає workflow sanity, і завантажує результати в категорію `/codeql-critical-security/android`. -Workflow `CodeQL macOS Critical Security` — це щотижневий/ручний macOS security shard. Він вручну збирає macOS app для CodeQL на Blacksmith macOS, відфільтровує результати збірки залежностей із завантаженого SARIF і завантажує результати в категорію `/codeql-critical-security/macos`. Тримайте його поза щоденним стандартним workflow, бо збірка macOS домінує за часом виконання навіть коли все чисто. +Workflow `CodeQL macOS Critical Security` — це щотижневий/ручний macOS security shard. Він вручну збирає macOS app для CodeQL на Blacksmith macOS, фільтрує результати dependency build із завантаженого SARIF і завантажує результати в категорію `/codeql-critical-security/macos`. Тримайте його поза щоденним workflow за замовчуванням, оскільки macOS build домінує за runtime навіть коли чистий. -Workflow `CodeQL Critical Quality` — це відповідний non-security shard. Він запускає лише error-severity, non-security JavaScript/TypeScript quality queries по вузьких високовартісних поверхнях на меншому Blacksmith Linux runner. Його baseline job сканує ту саму поверхню auth, secrets, sandbox, cron і gateway, що й security workflow. Завдання config-boundary сканує config schema, migration, normalization і IO contracts в окремій категорії `/codeql-critical-quality/config-boundary`. Завдання gateway-runtime-boundary сканує gateway protocol schemas і server method contracts в окремій категорії `/codeql-critical-quality/gateway-runtime-boundary`. Завдання channel-runtime-boundary сканує core channel implementation contracts в окремій категорії `/codeql-critical-quality/channel-runtime-boundary`. Завдання agent-runtime-boundary сканує command execution, model/provider dispatch, auto-reply dispatch and queues, а також ACP control-plane runtime contracts в окремій категорії `/codeql-critical-quality/agent-runtime-boundary`. Завдання ui-control-plane сканує Control UI bootstrap, local persistence, gateway control flows і task control-plane runtime contracts в окремій категорії `/codeql-critical-quality/ui-control-plane`. Завдання plugin-boundary сканує loader, registry, public-surface і Plugin SDK entrypoint contracts в окремій категорії `/codeql-critical-quality/plugin-boundary`. Тримайте workflow окремо від security, щоб quality findings можна було планувати, вимірювати, вимикати або розширювати без затемнення security signal. Розширення CodeQL для Swift, Python і bundled-plugin слід додавати назад як scoped або sharded follow-up work лише після того, як вузькі profiles матимуть стабільні runtime і signal. +Workflow `CodeQL Critical Quality` — це відповідний не-security shard. Він запускає лише JavaScript/TypeScript quality queries із severity error і без security над вузькими цінними поверхнями на меншому Blacksmith Linux runner. Його baseline-завдання сканує ту саму поверхню auth, secrets, sandbox, cron і gateway, що й security workflow. Завдання config-boundary сканує контракти config schema, migration, normalization і IO в окремій категорії `/codeql-critical-quality/config-boundary`. Завдання gateway-runtime-boundary сканує схеми gateway protocol і контракти server method в окремій категорії `/codeql-critical-quality/gateway-runtime-boundary`. Завдання channel-runtime-boundary сканує core channel implementation contracts в окремій категорії `/codeql-critical-quality/channel-runtime-boundary`. Завдання agent-runtime-boundary сканує command execution, model/provider dispatch, auto-reply dispatch і queues, а також runtime-контракти ACP control-plane в окремій категорії `/codeql-critical-quality/agent-runtime-boundary`. Завдання ui-control-plane сканує Control UI bootstrap, local persistence, gateway control flows і runtime-контракти task control-plane в окремій категорії `/codeql-critical-quality/ui-control-plane`. Завдання plugin-boundary сканує loader, registry, public-surface і entrypoint-контракти Plugin SDK в окремій категорії `/codeql-critical-quality/plugin-boundary`. Тримайте workflow окремо від security, щоб quality-знахідки можна було планувати, вимірювати, вимикати або розширювати без затемнення security-сигналу. Розширення CodeQL для Swift, Python і bundled-plugin слід додавати назад лише як scoped або sharded follow-up work після того, як вузькі профілі матимуть стабільні runtime і signal. -Workflow `Docs Agent` — це подієво-керована лінія підтримки Codex для збереження наявної документації узгодженою з нещодавно приземленими змінами. Він не має чистого schedule: успішний non-bot push CI run на `main` може його запустити, а manual dispatch може запускати його напряму. Workflow-run invocations пропускаються, коли `main` уже просунувся далі або коли інший non-skipped Docs Agent run було створено за останню годину. Коли він запускається, він переглядає діапазон комітів від попереднього non-skipped Docs Agent source SHA до поточного `main`, тож один погодинний запуск може покрити всі зміни main, накопичені від останнього проходу документації. +Workflow `Docs Agent` — це подієво-керована maintenance-доріжка Codex для підтримання наявної документації у відповідності з нещодавно landed changes. Він не має чистого розкладу: успішний non-bot push CI run на `main` може його запустити, а ручний dispatch може запустити його напряму. Workflow-run виклики пропускаються, коли `main` уже зсунувся далі або коли за останню годину було створено інший non-skipped Docs Agent run. Коли він запускається, він переглядає commit range від попереднього non-skipped Docs Agent source SHA до поточного `main`, тож один погодинний run може покрити всі зміни main, накопичені з останнього docs pass. -Workflow `Test Performance Agent` — це подієво-керована лінія підтримки Codex для повільних тестів. Він не має чистого schedule: успішний non-bot push CI run на `main` може його запустити, але він пропускається, якщо інший workflow-run invocation уже запускався або виконується цього UTC-дня. Manual dispatch обходить цей daily activity gate. Лінія створює full-suite grouped Vitest performance report, дозволяє Codex вносити лише невеликі coverage-preserving виправлення продуктивності тестів замість широких рефакторингів, потім повторно запускає full-suite report і відхиляє зміни, які зменшують baseline count пройдених тестів. Якщо baseline має failing tests, Codex може виправляти лише очевидні failures, а after-agent full-suite report має пройти перед будь-яким комітом. Коли `main` просувається до того, як bot push приземлиться, лінія робить rebase перевіреного patch, повторно запускає `pnpm check:changed` і повторює push; конфліктні stale patches пропускаються. Він використовує GitHub-hosted Ubuntu, щоб Codex action міг зберегти ту саму drop-sudo safety posture, що й docs agent. +The `Test Performance Agent` workflow — це подієво-керована лінія супроводу Codex +для повільних тестів. Вона не має суто розкладу: успішний CI-запуск після push +не від бота в `main` може її запустити, але вона пропускається, якщо інший +виклик через workflow-run уже виконувався або виконується цього UTC-дня. Ручний +запуск обходить цей щоденний шлюз активності. Лінія створює згрупований звіт +Vitest про продуктивність для повного набору тестів, дозволяє Codex вносити +лише невеликі виправлення продуктивності тестів зі збереженням покриття замість +широких рефакторингів, потім повторно запускає звіт для повного набору тестів і +відхиляє зміни, що зменшують базову кількість успішних тестів. Якщо в базовому +стані є тести, що падають, Codex може виправляти лише очевидні збої, а звіт для +повного набору тестів після агента має пройти перед будь-яким комітом. Коли +`main` просувається до того, як bot push потрапить у репозиторій, лінія ребейзить +перевірений патч, повторно запускає `pnpm check:changed` і повторює push; +конфліктні застарілі патчі пропускаються. Вона використовує Ubuntu на GitHub, +щоб дія Codex могла зберегти ту саму безпечну позицію drop-sudo, що й агент +документації. ```bash gh workflow run duplicate-after-merge.yml \ @@ -248,31 +270,40 @@ gh workflow run duplicate-after-merge.yml \ ## Огляд завдань -| Завдання | Призначення | Коли запускається | -| -------------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------- | -| `preflight` | Виявляє зміни лише документації, змінені області, змінені extensions і збирає CI manifest | Завжди для non-draft push і PR | -| `security-scm-fast` | Виявлення private key і audit workflow через `zizmor` | Завжди для non-draft push і PR | -| `security-dependency-audit` | Audit production lockfile без залежностей щодо npm advisories | Завжди для non-draft push і PR | -| `security-fast` | Обов’язковий aggregate для швидких security jobs | Завжди для non-draft push і PR | -| `build-artifacts` | Збирає `dist/`, Control UI, перевірки built-artifact і reusable downstream artifacts | Зміни, релевантні Node | -| `checks-fast-core` | Швидкі Linux correctness lanes, як-от bundled/plugin-contract/protocol checks | Зміни, релевантні Node | -| `checks-fast-contracts-channels` | Sharded channel contract checks зі стабільним aggregate check result | Зміни, релевантні Node | -| `checks-node-extensions` | Повні bundled-plugin test shards для всього extension suite | Зміни, релевантні Node | -| `checks-node-core-test` | Core Node test shards, без channel, bundled, contract і extension lanes | Зміни, релевантні Node | -| `check` | Sharded equivalent main local gate: prod types, lint, guards, test types і strict smoke | Зміни, релевантні Node | -| `check-additional` | Architecture, boundary, extension-surface guards, package-boundary і gateway-watch shards | Зміни, релевантні Node | -| `build-smoke` | Built-CLI smoke tests і startup-memory smoke | Зміни, релевантні Node | -| `checks` | Verifier для built-artifact channel tests | Зміни, релевантні Node | -| `checks-node-compat-node22` | Node 22 compatibility build і smoke lane | Manual CI dispatch для релізів | -| `check-docs` | Форматування документації, lint і перевірки broken-link | Змінено документацію | -| `skills-python` | Ruff + pytest для Python-backed skills | Зміни, релевантні Python-skill | -| `checks-windows` | Windows-specific process/path tests плюс shared runtime import specifier regressions | Зміни, релевантні Windows | -| `macos-node` | macOS TypeScript test lane із використанням shared built artifacts | Зміни, релевантні macOS | -| `macos-swift` | Swift lint, build і tests для macOS app | Зміни, релевантні macOS | -| `android` | Android unit tests для обох flavors плюс одна debug APK build | Зміни, релевантні Android | -| `test-performance-agent` | Щоденна Codex slow-test optimization після trusted activity | Main CI success або manual dispatch | +| Завдання | Призначення | Коли запускається | +| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- | +| `preflight` | Виявляє зміни лише в документації, змінені області, змінені розширення та будує CI-маніфест | Завжди для недрафтових push і PR | +| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для недрафтових push і PR | +| `security-dependency-audit` | Аудит production lockfile без залежностей щодо npm advisory | Завжди для недрафтових push і PR | +| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для недрафтових push і PR | +| `build-artifacts` | Збирає `dist/`, Control UI, перевірки зібраних артефактів і повторно використовувані downstream-артефакти | Зміни, релевантні Node | +| `checks-fast-core` | Швидкі Linux-лінії коректності, як-от bundled/plugin-contract/protocol перевірки | Зміни, релевантні Node | +| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом перевірки | Зміни, релевантні Node | +| `checks-node-extensions` | Повні шарди тестів bundled-plugin для всього набору розширень | Зміни, релевантні Node | +| `checks-node-core-test` | Шарди основних Node-тестів, за винятком каналів, bundled, contract і extension ліній | Зміни, релевантні Node | +| `check` | Шардований еквівалент основного локального шлюзу: prod types, lint, guards, test types і strict smoke | Зміни, релевантні Node | +| `check-additional` | Шарди архітектури, меж, захистів surface розширень, package-boundary і gateway-watch | Зміни, релевантні Node | +| `build-smoke` | Smoke-тести зібраного CLI і startup-memory smoke | Зміни, релевантні Node | +| `checks` | Верифікатор для тестів каналів зібраних артефактів | Зміни, релевантні Node | +| `checks-node-compat-node22` | Лінія збірки й smoke для сумісності з Node 22 | Ручний CI-запуск для релізів | +| `plugin-prerelease-suite` | Агрегат для prerelease статичних перевірок Plugin і Docker product ліній | Ручний CI-запуск для релізів | +| `check-docs` | Форматування документації, lint і перевірки битих посилань | Змінено документацію | +| `skills-python` | Ruff + pytest для Skills на базі Python | Зміни, релевантні Python Skills | +| `checks-windows` | Специфічні для Windows тести процесів/шляхів плюс спільні регресії runtime import specifier | Зміни, релевантні Windows | +| `macos-node` | Лінія тестів TypeScript для macOS із використанням спільних зібраних артефактів | Зміни, релевантні macOS | +| `macos-swift` | Swift lint, збірка й тести для застосунку macOS | Зміни, релевантні macOS | +| `android` | Android unit-тести для обох варіантів плюс одна debug APK збірка | Зміни, релевантні Android | +| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після довіреної активності | Успішний CI на main або ручний запуск | -Manual CI dispatches запускають той самий job graph, що й звичайний CI, але примусово вмикають кожну scoped lane: Linux Node shards, bundled-plugin shards, channel contracts, Node 22 compatibility, `check`, `check-additional`, build smoke, docs checks, Python skills, Windows, macOS, Android і Control UI i18n. Manual runs використовують унікальну concurrency group, щоб release-candidate full suite не скасовувався іншим push або PR run на тому самому ref. Необов’язковий вхід `target_ref` дає trusted caller змогу запустити цей graph проти branch, tag або full commit SHA, використовуючи workflow file з вибраного dispatch ref. +Ручні CI-запуски виконують той самий граф завдань, що й звичайний CI, але +примусово вмикають кожну scoped лінію: Linux Node shards, bundled-plugin shards, +контракти каналів, сумісність із Node 22, prerelease покриття Plugin, `check`, +`check-additional`, build smoke, перевірки документації, Python Skills, Windows, +macOS, Android і Control UI i18n. Ручні запуски використовують унікальну групу +конкурентності, щоб повний набір release-candidate не скасовувався іншим push +або PR-запуском на тому самому ref. Необов’язковий вхід `target_ref` дає змогу +довіреному виклику запустити цей граф для гілки, тегу або повного SHA коміту, +використовуючи файл workflow з вибраного dispatch ref. ```bash gh workflow run ci.yml --ref release/YYYY.M.D @@ -284,60 +315,60 @@ gh workflow run full-release-validation.yml --ref main -f ref= Завдання впорядковано так, щоб дешеві перевірки падали до запуску дорогих: -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, щоб низхідні споживачі могли стартувати, щойно спільна збірка буде готова. -4. Важчі платформні та runtime-лінії розгалужуються після цього: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `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-лініями, щоб нижчі споживачі могли почати, щойно спільна збірка буде готова. +4. Після цього розгалужуються важчі платформні та runtime-лінії: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. -Логіка області дії міститься в `scripts/ci-changed-scope.mjs` і покрита unit-тестами в `src/scripts/ci-changed-scope.test.ts`. -Ручний запуск пропускає виявлення changed-scope і змушує preflight-маніфест -поводитися так, ніби змінилася кожна область з окремою областю дії. -Редагування CI workflow перевіряють граф Node CI плюс лінтинг workflow, але самі собою не примушують виконувати нативні збірки Windows, Android або macOS; ці платформні лінії залишаються прив’язаними до змін у платформному source. -Редагування лише маршрутизації CI, вибрані дешеві редагування core-test fixture, а також вузькі редагування helper/test-routing для контрактів плагінів використовують швидкий маніфестний шлях лише для Node: preflight, security і одне завдання `checks-fast-core`. Цей шлях уникає build artifacts, сумісності Node 22, контрактів каналів, повних core shards, shards вбудованих плагінів і додаткових guard matrices, коли змінені файли обмежені поверхнями маршрутизації або helper, які швидке завдання перевіряє напряму. -Перевірки Windows Node обмежені специфічними для Windows обгортками process/path, helper для npm/pnpm/UI runner, конфігурацією package manager і поверхнями CI workflow, які виконують цю лінію; непов’язані зміни source, плагінів, install-smoke і test-only залишаються на лініях Linux Node, щоб вони не резервували 16-vCPU Windows worker для покриття, яке вже перевіряється звичайними test shards. -Окремий workflow `install-smoke` повторно використовує той самий scope script через власне завдання `preflight`. Він розділяє smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Pull requests запускають швидкий шлях для поверхонь Docker/package, змін package/manifest вбудованих плагінів, а також поверхонь core plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke jobs. Зміни лише source у вбудованих плагінах, редагування лише тестів і редагування лише документації не резервують Docker workers. Швидкий шлях один раз збирає образ кореневого Dockerfile, перевіряє CLI, запускає smoke CLI для agents delete shared-workspace, запускає container gateway-network e2e, перевіряє build arg вбудованого розширення і запускає обмежений Docker profile вбудованого плагіна під 240-секундним aggregate command timeout, причому Docker run кожного сценарію обмежений окремо. Повний шлях зберігає QR package install і installer Docker/update coverage для нічних запланованих запусків, ручних dispatches, workflow-call release checks і pull requests, які справді зачіпають installer/package/Docker поверхні. Pushes у `main`, включно з merge commits, не примушують виконувати повний шлях; коли логіка changed-scope на push вимагала б повного покриття, workflow зберігає швидкий Docker smoke і залишає full install smoke для нічної або release validation. Повільний Bun global install image-provider smoke окремо керується `run_bun_global_install_smoke`; він запускається за нічним розкладом і з release checks workflow, а ручні dispatches `install-smoke` можуть увімкнути його, але pull requests і pushes у `main` його не запускають. QR і installer Docker tests зберігають власні install-focused Dockerfiles. Локальний `test:docker:all` попередньо збирає один спільний live-test image, один раз пакує OpenClaw як npm tarball і збирає два спільні образи `scripts/e2e/Dockerfile`: bare Node/Git runner для ліній installer/update/plugin-dependency і functional image, який встановлює той самий tarball у `/app` для звичайних functionality lanes. Визначення Docker lanes містяться в `scripts/lib/docker-e2e-scenarios.mjs`, логіка planner міститься в `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний plan. Scheduler вибирає образ для кожної лінії за допомогою `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, а потім запускає лінії з `OPENCLAW_SKIP_DOCKER_BUILD=1`; налаштовуйте стандартну кількість слотів main-pool, що дорівнює 10, через `OPENCLAW_DOCKER_ALL_PARALLELISM`, а чутливу до провайдерів кількість слотів tail-pool, що дорівнює 10, через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Обмеження важких ліній за замовчуванням становлять `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб npm install і multi-service lanes не перевантажували Docker, поки легші лінії все ще заповнюють доступні слоти. Одна лінія, важча за ефективні обмеження, все одно може стартувати з порожнього pool, а потім працює сама, доки не звільнить capacity. Старти ліній за замовчуванням рознесені на 2 секунди, щоб уникнути штормів create у локальному Docker daemon; перевизначайте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний aggregate виконує preflight Docker, видаляє застарілі OpenClaw E2E containers, виводить статус активних ліній, зберігає timings ліній для впорядкування longest-first і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для перевірки scheduler. За замовчуванням він припиняє планувати нові pooled lanes після першого failure, і кожна лінія має 120-хвилинний fallback timeout, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; вибрані live/tail lanes використовують жорсткіші per-lane caps. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні scheduler lanes, включно з release-only lanes, такими як `install-e2e`, і split bundled update lanes, такими як `bundled-channel-update-acpx`, пропускаючи cleanup smoke, щоб agents могли відтворити одну failed lane. Reusable live/E2E workflow запитує `scripts/test-docker-all.mjs --plan-json`, яке package, image kind, live image, lane і credential coverage потрібні, а потім `scripts/docker-e2e.mjs` перетворює цей plan на GitHub outputs і summaries. Він або пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, завантажує package artifact поточного run, або завантажує package artifact з `package_artifact_run_id`; перевіряє tarball inventory; збирає й публікує package-digest-tagged bare/functional GHCR Docker E2E images через Docker layer cache Blacksmith, коли plan потребує package-installed lanes; і повторно використовує надані inputs `docker_e2e_bare_image`/`docker_e2e_functional_image` або наявні package-digest images замість повторної збірки. Workflow `Package Acceptance` є високорівневим package gate: він визначає candidate з npm, довіреного `package_ref`, HTTPS tarball плюс SHA-256 або попереднього workflow artifact, а потім передає цей єдиний artifact `package-under-test` у reusable Docker E2E workflow. Він тримає `workflow_ref` окремо від `package_ref`, щоб поточна acceptance logic могла перевіряти старіші довірені commits без checkout старого workflow code. Release checks запускають custom Package Acceptance delta для target ref: сумісність bundled-channel, offline plugin fixtures і Telegram package QA проти resolved tarball. Docker suite release path запускає менші chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk тягнув лише потрібний йому image kind і виконував кілька lanes через той самий weighted scheduler (`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|plugins-runtime-install-b|plugins-runtime-install-c|plugins-runtime-install-d|bundled-channels`). OpenWebUI входить до `plugins-runtime-services`, коли цього вимагає повне release-path coverage, і зберігає окремий chunk `openwebui` лише для OpenWebUI-only dispatches. Legacy aggregate chunk names `package-update`, `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` все ще працюють для manual reruns, але release workflow використовує split chunks, щоб installer E2E і bundled plugin install/uninstall sweeps не домінували в critical path. Lane alias `install-e2e` залишається aggregate manual rerun alias для обох provider installer lanes. Chunk `bundled-channels` запускає split `bundled-channel-*` і `bundled-channel-update-*` lanes замість serial all-in-one lane `bundled-channel-deps`. Кожен chunk завантажує `.artifacts/docker-tests/` з lane logs, timings, `summary.json`, `failures.json`, phase timings, scheduler plan JSON, slow-lane tables і per-lane rerun commands. Input workflow `docker_lanes` запускає вибрані lanes проти підготовлених images замість chunk jobs, що утримує debugging failed-lane в межах одного targeted Docker job і готує, завантажує або повторно використовує package artifact для цього run; якщо вибрана lane є live Docker lane, targeted job локально збирає live-test image для цього rerun. Згенеровані per-lane GitHub rerun commands містять `package_artifact_run_id`, `package_artifact_name` і prepared image inputs, коли ці значення існують, щоб failed lane могла повторно використати точний package і images з failed run. Використовуйте `pnpm test:docker:rerun `, щоб завантажити Docker artifacts з GitHub run і вивести combined/per-lane targeted rerun commands; використовуйте `pnpm test:docker:timings ` для summaries slow-lane і phase critical-path. Scheduled live/E2E workflow щодня запускає повний release-path Docker suite. Bundled update matrix розділена за update target, щоб повторні npm update і doctor repair passes могли shard разом з іншими bundled checks. +Логіка області живе в `scripts/ci-changed-scope.mjs` і покрита модульними тестами в `src/scripts/ci-changed-scope.test.ts`. +Ручний запуск пропускає виявлення changed-scope і змушує маніфест preflight +поводитися так, ніби кожна область змінилася. +Зміни CI workflow перевіряють граф Node CI плюс лінтинг workflow, але самі по собі не примушують запускати нативні збірки Windows, Android або macOS; ці платформні лінії залишаються обмеженими змінами платформного коду. +CI-зміни лише маршрутизації, вибрані дешеві зміни core-test фікстур і вузькі зміни допоміжних засобів/маршрутизації тестів контрактів плагінів використовують швидкий Node-only шлях маніфесту: preflight, security і одне завдання `checks-fast-core`. Цей шлях уникає артефактів збірки, сумісності Node 22, контрактів каналів, повних core-шардів, шардів вбудованих плагінів і додаткових матриць запобіжників, коли змінені файли обмежені поверхнями маршрутизації або допоміжними поверхнями, які швидке завдання перевіряє напряму. +Windows Node перевірки обмежені специфічними для Windows обгортками процесів/шляхів, npm/pnpm/UI runner допоміжними засобами, конфігурацією менеджера пакетів і поверхнями CI workflow, які виконують цю лінію; непов’язані зміни джерельного коду, плагінів, install-smoke і лише тестів залишаються на Linux Node лініях, щоб вони не резервували 16-vCPU Windows worker для покриття, яке вже перевіряється звичайними тестовими шардами. +Окремий workflow `install-smoke` повторно використовує той самий scope-скрипт через власне завдання `preflight`. Він розділяє smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Pull request-и запускають швидкий шлях для поверхонь Docker/пакетів, змін пакетів/маніфестів вбудованих плагінів і поверхонь core plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke завдання. Зміни лише джерельного коду вбудованих плагінів, лише тестові редагування і лише документаційні редагування не резервують Docker worker-и. Швидкий шлях один раз збирає образ кореневого Dockerfile, перевіряє CLI, запускає smoke CLI видалення agents shared-workspace, запускає container gateway-network e2e, перевіряє build arg вбудованого розширення і запускає обмежений Docker-профіль вбудованого плагіна в межах 240-секундного сукупного таймауту команди, з окремим обмеженням Docker run для кожного сценарію. Повний шлях зберігає встановлення QR-пакета і Docker/update покриття інсталятора для нічних запланованих запусків, ручних запусків, workflow-call release checks і pull request-ів, які справді торкаються поверхонь інсталятора/пакета/Docker. Push-и в `main`, зокрема merge commit-и, не примушують повний шлях; коли логіка changed-scope запитала б повне покриття на push, workflow залишає швидкий Docker smoke і лишає повний install smoke для нічної або релізної валідації. Повільний Bun global install image-provider smoke окремо керується `run_bun_global_install_smoke`; він виконується за нічним розкладом і з release checks workflow, а ручні запуски `install-smoke` можуть увімкнути його, але pull request-и й push-и в `main` його не запускають. QR і installer Docker тести зберігають власні install-focused Dockerfile-и. Локальний `test:docker:all` попередньо збирає один спільний live-test образ, один раз пакує OpenClaw як npm tarball і збирає два спільні образи `scripts/e2e/Dockerfile`: базовий Node/Git runner для ліній installer/update/plugin-dependency і функціональний образ, який встановлює той самий tarball у `/app` для звичайних функціональних ліній. Визначення Docker-ліній живуть у `scripts/lib/docker-e2e-scenarios.mjs`, логіка планувальника живе в `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний план. Планувальник вибирає образ для кожної лінії за допомогою `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, потім запускає лінії з `OPENCLAW_SKIP_DOCKER_BUILD=1`; налаштовуйте стандартну кількість слотів main-pool 10 через `OPENCLAW_DOCKER_ALL_PARALLELISM`, а кількість слотів provider-sensitive tail-pool 10 через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Обмеження важких ліній за замовчуванням дорівнюють `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб npm install і multi-service лінії не перевантажували Docker, поки легші лінії все ще заповнюють доступні слоти. Одна лінія, важча за ефективні обмеження, усе одно може стартувати з порожнього пулу, а потім працює сама, доки не звільнить місткість. Старти ліній за замовчуванням рознесені на 2 секунди, щоб уникати локальних штормів створення в Docker daemon; перевизначайте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний агрегат попередньо перевіряє Docker, видаляє застарілі OpenClaw E2E контейнери, виводить статус активних ліній, зберігає таймінги ліній для впорядкування від найдовших і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для інспекції планувальника. За замовчуванням він припиняє планувати нові pooled-лінії після першої помилки, і кожна лінія має 120-хвилинний fallback-таймаут, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; вибрані live/tail лінії використовують суворіші per-lane обмеження. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні лінії планувальника, зокрема release-only лінії, як-от `install-e2e`, і розділені bundled update лінії, як-от `bundled-channel-update-acpx`, пропускаючи cleanup smoke, щоб агенти могли відтворити одну невдалу лінію. Багаторазовий live/E2E workflow запитує в `scripts/test-docker-all.mjs --plan-json`, яке покриття пакета, типу образу, live-образу, лінії і credentials потрібне, потім `scripts/docker-e2e.mjs` перетворює цей план на GitHub outputs і summaries. Він або пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, завантажує артефакт пакета з поточного запуску, або завантажує артефакт пакета з `package_artifact_run_id`; перевіряє інвентар tarball; збирає і пушить package-digest-tagged bare/functional GHCR Docker E2E образи через Docker layer cache Blacksmith, коли план потребує package-installed ліній; і повторно використовує надані inputs `docker_e2e_bare_image`/`docker_e2e_functional_image` або наявні package-digest образи замість перебудови. Workflow `Package Acceptance` є високорівневим пакетовим шлюзом: він визначає кандидата з npm, довіреного `package_ref`, HTTPS tarball плюс SHA-256 або артефакту попереднього workflow, а потім передає цей єдиний артефакт `package-under-test` у багаторазовий Docker E2E workflow. Він тримає `workflow_ref` окремо від `package_ref`, щоб поточна acceptance-логіка могла перевіряти старіші довірені коміти без checkout старого workflow-коду. Release checks запускають кастомну Package Acceptance delta для цільового ref: bundled-channel compat, offline plugin фікстури і Telegram package QA проти визначеного tarball. Release-path Docker suite запускає менші chunked завдання з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk завантажував лише потрібний тип образу і виконував кілька ліній через той самий зважений планувальник (`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|plugins-runtime-install-b|plugins-runtime-install-c|plugins-runtime-install-d|bundled-channels`). OpenWebUI включено в `plugins-runtime-services`, коли повне release-path покриття цього вимагає, і він зберігає окремий chunk `openwebui` лише для OpenWebUI-only запусків. Застарілі агрегатні назви chunk-ів `package-update`, `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` досі працюють для ручних повторних запусків, але release workflow використовує розділені chunk-и, щоб installer E2E і sweeps встановлення/видалення вбудованих плагінів не домінували в критичному шляху. Псевдонім лінії `install-e2e` залишається агрегатним псевдонімом ручного повторного запуску для обох provider installer ліній. Chunk `bundled-channels` запускає розділені лінії `bundled-channel-*` і `bundled-channel-update-*` замість послідовної all-in-one лінії `bundled-channel-deps`. Кожен chunk завантажує `.artifacts/docker-tests/` з логами ліній, таймінгами, `summary.json`, `failures.json`, таймінгами фаз, JSON плану планувальника, таблицями повільних ліній і командами повторного запуску для кожної лінії. Input workflow `docker_lanes` запускає вибрані лінії проти підготовлених образів замість chunk-завдань, що утримує debugging невдалої лінії в межах одного цільового Docker-завдання і готує, завантажує або повторно використовує артефакт пакета для цього запуску; якщо вибрана лінія є live Docker лінією, цільове завдання локально збирає live-test образ для цього повторного запуску. Згенеровані GitHub команди повторного запуску для кожної лінії містять `package_artifact_run_id`, `package_artifact_name` і inputs підготовлених образів, коли ці значення існують, щоб невдала лінія могла повторно використати точний пакет і образи з невдалого запуску. Використовуйте `pnpm test:docker:rerun `, щоб завантажити Docker-артефакти з GitHub запуску і вивести комбіновані/по-лінійні цільові команди повторного запуску; використовуйте `pnpm test:docker:timings ` для підсумків повільних ліній і критичного шляху фаз. Запланований live/E2E workflow щодня запускає повний release-path Docker suite. Матрицю bundled update розділено за ціллю оновлення, щоб повторні npm update і doctor repair проходи могли шардитися з іншими bundled перевірками. -Поточні release Docker chunks: `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`, `bundled-channels-core`, `bundled-channels-update-a`, `bundled-channels-update-b` і `bundled-channels-contracts`. Aggregate chunk `bundled-channels` залишається доступним для manual one-shot reruns, а `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` залишаються aggregate plugin/runtime aliases, але release workflow використовує split chunks, щоб channel smokes, update targets, plugin runtime checks і bundled plugin install/uninstall sweeps могли виконуватися паралельно. Targeted dispatches `docker_lanes` також розділяють кілька вибраних lanes на parallel jobs після одного спільного package/image preparation step, а bundled-channel update lanes повторюють спробу один раз у разі transient npm network failures. +Поточні 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`, `bundled-channels-core`, `bundled-channels-update-a`, `bundled-channels-update-b` і `bundled-channels-contracts`. Агрегатний chunk `bundled-channels` залишається доступним для ручних one-shot повторних запусків, а `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` залишаються агрегатними псевдонімами plugin/runtime, але release workflow використовує розділені chunk-и, щоб channel smokes, цілі оновлення, plugin runtime перевірки і sweeps встановлення/видалення вбудованих плагінів могли виконуватися паралельно. Цільові запуски `docker_lanes` також розділяють кілька вибраних ліній на паралельні завдання після одного спільного кроку підготовки пакета/образу, а bundled-channel update лінії повторюють спробу один раз для тимчасових npm мережевих збоїв. -Локальна логіка змінених lane зберігається в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний check gate суворіший щодо архітектурних меж, ніж широкий scope платформи CI: зміни production-коду core запускають typecheck core prod і core test плюс core lint/guards, зміни лише core test запускають тільки typecheck core test плюс core lint, зміни production-коду extension запускають typecheck extension prod і extension test плюс extension lint, а зміни лише extension test запускають typecheck extension test плюс extension lint. Зміни публічного Plugin SDK або plugin-contract розширюються до typecheck extension, бо extensions залежать від цих core-контрактів, але Vitest sweep для extensions є явною тестовою роботою. Version bump-и лише metadata release запускають цільові перевірки version/config/root-dependency. Невідомі зміни root/config fail safe до всіх check lanes. -Локальна маршрутизація змінених тестів зберігається в `scripts/test-projects.test-support.mjs` і +Логіка локального визначення змінених lanes живе в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний контрольний gate суворіший щодо архітектурних меж, ніж широка область платформи CI: зміни production-коду core запускають typecheck для core prod і core tests плюс core lint/guards, зміни лише core tests запускають тільки typecheck для core tests плюс core lint, production-зміни розширень запускають typecheck для extension prod і extension tests плюс extension lint, а зміни лише extension tests запускають typecheck для extension tests плюс extension lint. Зміни публічного Plugin SDK або plugin-contract розширюються до typecheck розширень, бо розширення залежать від цих core-контрактів, але sweeps розширень Vitest є явною тестовою роботою. Version bumps лише release metadata запускають цільові перевірки версій/config/root-dependency. Невідомі зміни root/config безпечно переходять до всіх check lanes. +Локальна маршрутизація changed-test живе в `scripts/test-projects.test-support.mjs` і навмисно дешевша за `check:changed`: прямі зміни тестів запускають самі себе, -зміни source віддають перевагу явним mapping-ам, потім sibling tests та -залежним import-graph. Shared group-room delivery config є одним із явних mapping-ів: +зміни source надають перевагу явним мапінгам, потім sibling tests та залежним +елементам import-graph. Shared group-room delivery config є одним із явних мапінгів: зміни group visible-reply config, source reply delivery mode або -message-tool system prompt проходять через core reply tests плюс регресії доставки Discord і -Slack, тож shared default change падає ще до першого push PR. -Використовуйте `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed` лише тоді, коли зміна +message-tool system prompt маршрутизуються через core reply tests плюс регресії доставлення Discord і +Slack, щоб зміна shared default падала ще до першого +push PR. Використовуйте `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed` лише тоді, коли зміна настільки harness-wide, що дешевий mapped set не є надійним proxy. -Для валідації Testbox запускайте з кореня repo й віддавайте перевагу свіжому прогрітому box для +Для валідації Testbox запускайте з кореня repo та віддавайте перевагу свіжому warmed box для широкого proof. Перед тим як витрачати повільний gate на box, який було reused, expired або -щойно повідомив про неочікувано великий sync, спершу запустіть `pnpm testbox:sanity` всередині -box. Sanity check швидко падає, коли required root files, як-от -`pnpm-lock.yaml`, зникли або коли `git status --short` показує принаймні 200 +який щойно повідомив про неочікувано великий sync, спершу запустіть `pnpm testbox:sanity` всередині +box. Sanity check швидко падає, коли обов’язкові root files, як-от +`pnpm-lock.yaml`, зникли або коли `git status --short` показує щонайменше 200 tracked deletions. Зазвичай це означає, що remote sync state не є надійною -копією PR. Зупиніть цей box і прогрійте свіжий, замість того щоб debug-ити -product test failure. Для PR з intentional large deletion задайте +копією PR. Зупиніть цей box і warm fresh one замість налагодження +product test failure. Для навмисних PR із великим видаленням встановіть `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1` для цього sanity run. -Manual CI dispatches запускають `checks-node-compat-node22` як release-candidate compatibility coverage. Звичайні pull requests і push-и в `main` пропускають цей lane та тримають matrix сфокусованою на Node 24 test/channel lanes. +Manual CI dispatches запускають `checks-node-compat-node22` і `plugin-prerelease-suite` як покриття сумісності release-candidate. Звичайні pull requests і pushes до `main` пропускають ці lanes і тримають matrix сфокусованою на Node 24 test/channel lanes. -Найповільніші Node test families розділені або збалансовані, щоб кожен job лишався малим без надмірного резервування runners: channel contracts запускаються як три weighted shards, bundled plugin tests балансуються між шістьма extension workers, small core unit lanes об’єднані в пари, auto-reply запускається як чотири balanced workers із reply subtree, розділеним на agent-runner, dispatch і commands/state-routing shards, а agentic gateway/plugin configs розподілені між наявними source-only agentic Node jobs замість очікування built artifacts. Broad browser, QA, media та miscellaneous plugin tests використовують власні dedicated Vitest configs замість shared plugin catch-all. Extension shard jobs запускають до двох plugin config groups одночасно з одним Vitest worker на group і більшим Node heap, щоб import-heavy plugin batches не створювали додаткові CI jobs. Broad agents lane використовує shared Vitest file-parallel scheduler, бо він домінований import/scheduling, а не одним повільним test file. `runtime-config` запускається з infra core-runtime shard, щоб shared runtime shard не володів tail. Include-pattern shards записують timing entries із назвою CI shard, тож `.artifacts/vitest-shard-timings.json` може відрізнити цілий config від filtered shard. `check-additional` тримає package-boundary compile/canary work разом і відокремлює runtime topology architecture від gateway watch coverage; boundary guard shard запускає свої невеликі independent guards паралельно всередині одного job. Gateway watch, channel tests і core support-boundary shard запускаються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи їхні старі check names як lightweight verifier jobs, але уникаючи двох додаткових Blacksmith workers і другої artifact-consumer queue. -Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Third-party flavor не має окремого source set або manifest; його unit-test lane все одно компілює цей flavor із SMS/call-log BuildConfig flags, уникаючи дубльованого debug APK packaging job на кожному Android-relevant push. -GitHub може позначати superseded jobs як `cancelled`, коли новіший push потрапляє в той самий PR або `main` ref. Сприймайте це як CI noise, якщо найновіший run для того самого ref також не падає. Aggregate shard checks використовують `!cancelled() && always()`, тож вони все одно повідомляють нормальні shard failures, але не стають у queue після того, як увесь workflow уже був superseded. -Automatic CI concurrency key versioned (`CI-v7-*`), щоб GitHub-side zombie у старій queue group не міг безстроково блокувати новіші main runs. Manual full-suite runs використовують `CI-manual-v1-*` і не cancel in-progress runs. +Найповільніші родини Node tests розділені або збалансовані, щоб кожна job залишалася малою без надмірного резервування runners: channel contracts запускаються як три weighted shards, bundled plugin tests балансуються між шістьма extension workers, малі core unit lanes об’єднані в пари, auto-reply запускається як чотири збалансовані workers із розділенням reply subtree на shards agent-runner, dispatch і commands/state-routing, а agentic gateway/plugin configs розподілені між наявними source-only agentic Node jobs замість очікування built artifacts. Broad browser, QA, media та miscellaneous plugin tests використовують свої dedicated Vitest configs замість спільного plugin catch-all. Extension shard jobs запускають до двох plugin config groups одночасно з одним Vitest worker на group і більшим Node heap, щоб import-heavy plugin batches не створювали додаткових CI jobs. Broad agents lane використовує спільний Vitest file-parallel scheduler, бо вона домінована import/scheduling, а не одним повільним test file. `runtime-config` запускається з infra core-runtime shard, щоб shared runtime shard не володів tail. Include-pattern shards записують timing entries з назвою CI shard, тож `.artifacts/vitest-shard-timings.json` може відрізнити цілий config від filtered shard. `check-additional` тримає package-boundary compile/canary роботу разом і відокремлює runtime topology architecture від gateway watch coverage; boundary guard shard запускає свої малі незалежні guards паралельно всередині однієї job. Gateway watch, channel tests і core support-boundary shard запускаються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` вже зібрані, зберігаючи їхні старі check names як легкі verifier jobs і водночас уникаючи двох додаткових Blacksmith workers та другої artifact-consumer queue. +Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, потім збирає Play debug APK. Third-party flavor не має окремого source set або manifest; його unit-test lane все одно компілює цей flavor із BuildConfig flags для SMS/call-log, уникаючи дубльованої job пакування debug APK на кожному Android-relevant push. +GitHub може позначати superseded jobs як `cancelled`, коли новіший push потрапляє в той самий PR або `main` ref. Вважайте це CI noise, якщо найновіший run для того самого ref також не падає. Aggregate shard checks використовують `!cancelled() && always()`, тож вони все одно повідомляють звичайні shard failures, але не стають у чергу після того, як весь workflow уже був superseded. +Автоматичний CI concurrency key версіонований (`CI-v7-*`), щоб GitHub-side zombie в старій queue group не міг нескінченно блокувати новіші main runs. Manual full-suite runs використовують `CI-manual-v1-*` і не скасовують in-progress runs. -## Ранери +## Runners -| Ранер | Jobs | +| Runner | Jobs | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`, швидкі security jobs і aggregates (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі protocol/contract/bundled checks, sharded channel contract checks, `check` shards крім lint, `check-additional` shards і aggregates, Node test aggregate verifiers, docs checks, Python skills, workflow-sanity, labeler, auto-response; install-smoke preflight також використовує GitHub-hosted Ubuntu, щоб Blacksmith matrix могла стати в queue раніше | -| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, lower-weight extension shards, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types` і `check-test-types` | +| `ubuntu-24.04` | `preflight`, швидкі security jobs та aggregates (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі protocol/contract/bundled checks, sharded channel contract checks, `check` shards, крім lint, `check-additional` shards і aggregates, Node test aggregate verifiers, docs checks, Python skills, workflow-sanity, labeler, auto-response; install-smoke preflight також використовує GitHub-hosted Ubuntu, щоб Blacksmith matrix могла стати в чергу раніше | +| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, lower-weight extension shards, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types` і `check-test-types` | | `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, Linux Node test shards, bundled plugin test shards, `android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який лишається достатньо CPU-sensitive, щоб 8 vCPU коштували більше, ніж заощадили; install-smoke Docker builds, де 32-vCPU queue time коштував більше, ніж заощадив | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який залишається достатньо CPU-sensitive, щоб 8 vCPU коштували більше, ніж заощаджували; install-smoke Docker builds, де час черги 32-vCPU коштував більше, ніж заощаджував | | `blacksmith-16vcpu-windows-2025` | `checks-windows` | -| `blacksmith-6vcpu-macos-latest` | `macos-node` на `openclaw/openclaw`; forks fallback до `macos-latest` | -| `blacksmith-12vcpu-macos-latest` | `macos-swift` на `openclaw/openclaw`; forks fallback до `macos-latest` | +| `blacksmith-6vcpu-macos-latest` | `macos-node` на `openclaw/openclaw`; forks fall back to `macos-latest` | +| `blacksmith-12vcpu-macos-latest` | `macos-swift` на `openclaw/openclaw`; forks fall back to `macos-latest` | ## Локальні еквіваленти @@ -368,4 +399,4 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac ## Пов’язане - [Огляд встановлення](/uk/install) -- [Канали релізів](/uk/install/development-channels) +- [Канали release](/uk/install/development-channels) diff --git a/docs/uk/gateway/protocol.md b/docs/uk/gateway/protocol.md index 42f605755..ba762bfc2 100644 --- a/docs/uk/gateway/protocol.md +++ b/docs/uk/gateway/protocol.md @@ -2,34 +2,35 @@ read_when: - Реалізація або оновлення WS-клієнтів Gateway - Налагодження невідповідностей протоколу або збоїв підключення - - Повторне генерування схеми/моделей протоколу -summary: 'Протокол WebSocket для Gateway: рукостискання, кадри, версіонування' + - Повторна генерація схеми/моделей протоколу +summary: 'Протокол WebSocket Gateway: рукостискання, кадри, версіонування' title: Протокол Gateway x-i18n: - generated_at: "2026-04-29T04:06:19Z" + generated_at: "2026-04-29T04:57:34Z" model: gpt-5.5 provider: openai - source_hash: c2923919857e430b2db1d9c731025dc18499e5dbe01f248c0f873bd30041cf0e + source_hash: 713a72b15f029aad00a4c6427fefeef08643aee830f23eac05e53b50f43d048c source_path: gateway/protocol.md workflow: 16 --- -Gateway WS-протокол є **єдиною площиною керування + транспортом Node** для -OpenClaw. Усі клієнти (CLI, вебінтерфейс, застосунок macOS, iOS/Android Node, headless -Node) підключаються через WebSocket і оголошують свою **роль** + **область доступу** під -час рукостискання. +Протокол Gateway WS є **єдиною площиною керування + транспортом вузлів** для +OpenClaw. Усі клієнти (CLI, вебінтерфейс, застосунок macOS, вузли iOS/Android, +безголові вузли) підключаються через WebSocket і оголошують свою **роль** + +**область дії** під час рукостискання. ## Транспорт -- WebSocket, текстові фрейми з JSON-пейлоадами. -- Перший фрейм **має** бути запитом `connect`. -- Фрейми до підключення обмежені 64 KiB. Після успішного рукостискання клієнти +- WebSocket, текстові кадри з JSON-навантаженнями. +- Перший кадр **обов’язково** має бути запитом `connect`. +- Кадри до підключення обмежені 64 KiB. Після успішного рукостискання клієнти мають дотримуватися обмежень `hello-ok.policy.maxPayload` і `hello-ok.policy.maxBufferedBytes`. Коли діагностику ввімкнено, - завеликі вхідні фрейми та повільні вихідні буфери створюють події `payload.large` - до того, як gateway закриє або відкине відповідний фрейм. Ці події зберігають - розміри, ліміти, поверхні та безпечні коди причин. Вони не зберігають тіло - повідомлення, вміст вкладень, сире тіло фрейму, токени, cookies або секретні значення. + завеликі вхідні кадри та повільні вихідні буфери створюють події `payload.large` + до того, як gateway закриє або відкине відповідний кадр. Ці події зберігають + розміри, обмеження, поверхні та безпечні коди причин. Вони не зберігають тіло + повідомлення, вміст вкладень, сире тіло кадру, токени, cookie або секретні + значення. ## Рукостискання (connect) @@ -105,11 +106,11 @@ Gateway → Клієнт: ``` `server`, `features`, `snapshot` і `policy` усі є обов’язковими за схемою -(`src/gateway/protocol/schema/frames.ts`). `auth` також є обов’язковим і повідомляє -узгоджену роль/області доступу. `canvasHostUrl` є необов’язковим. +(`src/gateway/protocol/schema/frames.ts`). `auth` також обов’язковий і повідомляє +узгоджену роль/області дії. `canvasHostUrl` необов’язковий. -Коли токен пристрою не видається, `hello-ok.auth` повідомляє узгоджені -дозволи без полів токена: +Коли токен пристрою не видано, `hello-ok.auth` повідомляє узгоджені дозволи без +полів токена: ```json { @@ -120,15 +121,16 @@ Gateway → Клієнт: } ``` -Довірені клієнти бекенда в тому самому процесі (`client.id: "gateway-client"`, -`client.mode: "backend"`) можуть опускати `device` у прямих підключеннях local loopback, коли -вони автентифікуються спільним токеном/паролем gateway. Цей шлях зарезервовано -для внутрішніх RPC площини керування й не дає застарілим базовим даним прив’язки CLI/пристрою -блокувати локальну роботу бекенда, як-от оновлення сесій субагентів. Віддалені клієнти, -клієнти з браузерним походженням, клієнти Node, а також явні клієнти з токеном пристрою/ідентичністю пристрою -далі використовують звичайні перевірки прив’язки та підвищення області доступу. +Довірені backend-клієнти в тому самому процесі (`client.id: "gateway-client"`, +`client.mode: "backend"`) можуть опускати `device` на прямих loopback-з’єднаннях, +коли вони автентифікуються спільним токеном/паролем gateway. Цей шлях +зарезервовано для внутрішніх RPC площини керування, і він не дає застарілим +базовим даним спарювання CLI/пристрою блокувати локальну backend-роботу, як-от +оновлення сеансів під агентів. Віддалені клієнти, клієнти з браузерним origin, +клієнти-вузли та явні клієнти з токеном пристрою/ідентичністю пристрою й надалі +використовують звичайні перевірки спарювання та підвищення областей дії. -Коли токен пристрою видається, `hello-ok` також містить: +Коли токен пристрою видано, `hello-ok` також містить: ```json { @@ -160,14 +162,15 @@ Gateway → Клієнт: } ``` -Для вбудованого потоку bootstrap Node/operator основний токен Node залишається -`scopes: []`, а будь-який переданий токен оператора залишається обмеженим allowlist -оператора bootstrap (`operator.approvals`, `operator.read`, -`operator.talk.secrets`, `operator.write`). Перевірки областей доступу bootstrap залишаються -префіксованими роллю: записи оператора задовольняють лише запити оператора, а ролям не-оператора -далі потрібні області доступу під власним префіксом ролі. +Для вбудованого bootstrap-потоку вузол/оператор основний токен вузла лишається +`scopes: []`, а будь-який переданий токен оператора лишається обмеженим +bootstrap-списком дозволів оператора (`operator.approvals`, `operator.read`, +`operator.talk.secrets`, `operator.write`). Bootstrap-перевірки областей дії +лишаються з префіксом ролі: записи оператора задовольняють лише запити +оператора, а неоператорським ролям усе ще потрібні області дії під власним +префіксом ролі. -### Приклад Node +### Приклад вузла ```json { @@ -202,7 +205,7 @@ Gateway → Клієнт: } ``` -## Обрамлення +## Кадрування - **Запит**: `{type:"req", id, method, params}` - **Відповідь**: `{type:"res", id, ok, payload|error}` @@ -210,16 +213,16 @@ Gateway → Клієнт: Методи з побічними ефектами потребують **ключів ідемпотентності** (див. схему). -## Ролі + області доступу +## Ролі + області дії ### Ролі - `operator` = клієнт площини керування (CLI/UI/автоматизація). - `node` = хост можливостей (camera/screen/canvas/system.run). -### Області доступу (operator) +### Області дії (оператор) -Поширені області доступу: +Поширені області дії: - `operator.read` - `operator.write` @@ -231,45 +234,46 @@ Gateway → Клієнт: `talk.config` з `includeSecrets: true` потребує `operator.talk.secrets` (або `operator.admin`). -RPC-методи gateway, зареєстровані Plugin, можуть запитувати власну область доступу оператора, але -зарезервовані префікси адміністрування ядра (`config.*`, `exec.approvals.*`, `wizard.*`, -`update.*`) завжди перетворюються на `operator.admin`. +Зареєстровані Plugin методи Gateway RPC можуть запитувати власну область дії +оператора, але зарезервовані префікси адміністрування ядра (`config.*`, +`exec.approvals.*`, `wizard.*`, `update.*`) завжди зводяться до `operator.admin`. -Область доступу методу є лише першим бар’єром. Деякі slash-команди, доступні через -`chat.send`, застосовують суворіші перевірки рівня команди поверх цього. Наприклад, постійні -записи `/config set` і `/config unset` потребують `operator.admin`. +Область дії методу є лише першою перевіркою. Деякі slash-команди, доступні через +`chat.send`, застосовують суворіші перевірки на рівні команди поверх цього. +Наприклад, постійні записи `/config set` і `/config unset` потребують +`operator.admin`. -`node.pair.approve` також має додаткову перевірку області доступу під час схвалення поверх -базової області доступу методу: +`node.pair.approve` також має додаткову перевірку області дії під час +затвердження поверх базової області дії методу: - запити без команд: `operator.pairing` -- запити з командами Node, що не належать до exec: `operator.pairing` + `operator.write` +- запити з не-exec командами вузла: `operator.pairing` + `operator.write` - запити, що містять `system.run`, `system.run.prepare` або `system.which`: `operator.pairing` + `operator.admin` -### Caps/commands/permissions (node) +### Можливості/команди/дозволи (вузол) -Node оголошують заявлені можливості під час підключення: +Вузли оголошують заявлені можливості під час підключення: - `caps`: високорівневі категорії можливостей. -- `commands`: allowlist команд для invoke. +- `commands`: список дозволених команд для invoke. - `permissions`: деталізовані перемикачі (наприклад, `screen.record`, `camera.capture`). -Gateway трактує їх як **заяви** і застосовує allowlist на серверному боці. +Gateway трактує їх як **заявки** та застосовує серверні списки дозволів. -## Presence +## Присутність - `system-presence` повертає записи з ключами за ідентичністю пристрою. -- Записи presence містять `deviceId`, `roles` і `scopes`, щоб UI міг показувати один рядок на пристрій +- Записи присутності містять `deviceId`, `roles` і `scopes`, щоб UI могли показувати один рядок на пристрій навіть коли він підключається і як **operator**, і як **node**. -- `node.list` містить необов’язкові поля `lastSeenAtMs` і `lastSeenReason`. Підключені Node повідомляють - свій поточний час підключення як `lastSeenAtMs` з причиною `connect`; прив’язані Node також можуть повідомляти - тривалу фонову presence, коли довірена подія Node оновлює їхні метадані прив’язки. +- `node.list` містить необов’язкові поля `lastSeenAtMs` і `lastSeenReason`. Підключені вузли повідомляють + час свого поточного підключення як `lastSeenAtMs` з причиною `connect`; спарені вузли також можуть повідомляти + стійку фонову присутність, коли довірена подія вузла оновлює їхні метадані спарювання. -### Фонова подія alive для Node +### Фонова подія активності вузла -Node можуть викликати `node.event` з `event: "node.presence.alive"`, щоб записати, що прив’язаний Node був -живим під час фонового пробудження, не позначаючи його підключеним. +Вузли можуть викликати `node.event` з `event: "node.presence.alive"`, щоб записати, що спарений вузол був +активний під час фонового пробудження, не позначаючи його як підключений. ```json { @@ -279,9 +283,9 @@ Node можуть викликати `node.event` з `event: "node.presence.aliv ``` `trigger` є закритим enum: `background`, `silent_push`, `bg_app_refresh`, -`significant_location`, `manual` або `connect`. Невідомі рядки trigger нормалізуються до -`background` gateway перед збереженням. Подія є довговічною лише для автентифікованих сесій пристрою -Node; сесії без пристрою або без прив’язки повертають `handled: false`. +`significant_location`, `manual` або `connect`. Невідомі рядки trigger gateway нормалізує до +`background` перед збереженням. Подія є стійкою лише для автентифікованих +сеансів пристроїв-вузлів; сеанси без пристрою або без спарювання повертають `handled: false`. Успішні gateway повертають структурований результат: @@ -294,154 +298,154 @@ Node; сесії без пристрою або без прив’язки по } ``` -Старіші gateway можуть далі повертати `{ "ok": true }` для `node.event`; клієнти мають трактувати це як -підтверджений RPC, а не як довговічне збереження presence. +Старіші gateway усе ще можуть повертати `{ "ok": true }` для `node.event`; клієнти мають трактувати це як +підтверджений RPC, а не як стійке збереження присутності. -## Обмеження області трансляції подій +## Області дії широкомовних подій -Трансляційні події WebSocket, які сервер надсилає клієнтам, обмежуються областями доступу, щоб сесії з областю прив’язки або лише Node не отримували пасивно вміст сесії. +Широкомовні події WebSocket, що надсилаються сервером, обмежуються областями дії, щоб сеанси, обмежені спарюванням або лише вузлом, не отримували пасивно вміст сеансу. -- **Фрейми чату, агента та результатів інструментів** (включно зі streamed подіями `agent` і результатами викликів інструментів) потребують щонайменше `operator.read`. Сесії без `operator.read` повністю пропускають ці фрейми. -- **Визначені Plugin трансляції `plugin.*`** обмежуються `operator.write` або `operator.admin`, залежно від того, як Plugin їх зареєстрував. -- **Події статусу й транспорту** (`heartbeat`, `presence`, `tick`, життєвий цикл connect/disconnect тощо) залишаються необмеженими, щоб справність транспорту була видимою для кожної автентифікованої сесії. -- **Невідомі сімейства трансляційних подій** за замовчуванням обмежуються областями доступу (fail-closed), якщо зареєстрований обробник явно не послаблює їх. +- **Кадри чату, агента та результатів інструментів** (зокрема потокові події `agent` і результати викликів інструментів) потребують щонайменше `operator.read`. Сеанси без `operator.read` повністю пропускають ці кадри. +- **Визначені Plugin широкомовні події `plugin.*`** обмежуються `operator.write` або `operator.admin` залежно від того, як Plugin їх зареєстрував. +- **Події статусу й транспорту** (`heartbeat`, `presence`, `tick`, життєвий цикл підключення/відключення тощо) лишаються необмеженими, щоб справність транспорту була видимою кожному автентифікованому сеансу. +- **Невідомі сімейства широкомовних подій** за замовчуванням обмежуються областями дії (fail-closed), якщо зареєстрований обробник явно не послаблює їх. -Кожне клієнтське підключення зберігає власний порядковий номер на клієнта, тому трансляції зберігають монотонне впорядкування на цьому сокеті, навіть коли різні клієнти бачать різні підмножини потоку подій, відфільтровані за областями доступу. +Кожне клієнтське підключення зберігає власний порядковий номер для клієнта, щоб широкомовлення зберігали монотонний порядок на цьому сокеті, навіть коли різні клієнти бачать різні відфільтровані за областями дії підмножини потоку подій. -## Поширені сімейства RPC-методів +## Поширені сімейства методів RPC Публічна поверхня WS ширша за наведені вище приклади рукостискання/автентифікації. Це -не згенерований дамп — `hello-ok.features.methods` є консервативним -списком для виявлення, побудованим із `src/gateway/server-methods-list.ts` плюс завантажених -експортів методів Plugin/каналів. Трактуйте його як виявлення функцій, а не повний -перелік `src/gateway/server-methods/*.ts`. +не згенерований дамп — `hello-ok.features.methods` є консервативним списком +виявлення, побудованим із `src/gateway/server-methods-list.ts` плюс експортів +методів завантажених Plugin/каналів. Сприймайте його як виявлення можливостей, +а не як повний перелік `src/gateway/server-methods/*.ts`. - + - `health` повертає кешований або щойно перевірений знімок справності gateway. - - `diagnostics.stability` повертає нещодавній обмежений реєстратор стабільності діагностики. Він зберігає операційні метадані, як-от назви подій, лічильники, розміри в байтах, показники пам’яті, стан черги/сесії, назви каналів/Plugin і ідентифікатори сесій. Він не зберігає текст чату, тіла webhook, виводи інструментів, сирі тіла запитів або відповідей, токени, cookies або секретні значення. Потрібна область доступу operator read. - - `status` повертає зведення gateway у стилі `/status`; чутливі поля включаються лише для клієнтів-операторів з областю доступу admin. - - `gateway.identity.get` повертає ідентичність пристрою gateway, яку використовують потоки relay і прив’язки. - - `system-presence` повертає поточний знімок presence для підключених пристроїв operator/node. - - `system-event` додає системну подію і може оновлювати/транслювати контекст presence. + - `diagnostics.stability` повертає нещодавній обмежений реєстратор діагностичної стабільності. Він зберігає операційні метадані, як-от назви подій, лічильники, розміри в байтах, показники пам’яті, стан черги/сеансу, назви каналів/Plugin і ідентифікатори сеансів. Він не зберігає текст чату, тіла webhook, виводи інструментів, сирі тіла запитів або відповідей, токени, cookie чи секретні значення. Потрібна область дії читання оператора. + - `status` повертає підсумок gateway у стилі `/status`; чутливі поля включаються лише для клієнтів-операторів з admin-областю дії. + - `gateway.identity.get` повертає ідентичність пристрою gateway, що використовується потоками relay і спарювання. + - `system-presence` повертає поточний знімок присутності для підключених пристроїв operator/node. + - `system-event` додає системну подію й може оновити/поширити контекст присутності. - `last-heartbeat` повертає останню збережену подію heartbeat. - - `set-heartbeats` вмикає або вимикає обробку heartbeat на gateway. + - `set-heartbeats` перемикає обробку heartbeat на gateway. - - - `models.list` повертає каталог моделей, дозволених під час виконання. Передайте `{ "view": "configured" }` для налаштованих моделей розміру picker (`agents.defaults.models` спочатку, потім `models.providers.*.models`), або `{ "view": "all" }` для повного каталогу. - - `usage.status` повертає вікна використання провайдера/зведення залишку квоти. - - `usage.cost` повертає агреговані зведення використання витрат за діапазон дат. - - `doctor.memory.status` повертає готовність vector-memory / кешованих embeddings для активного робочого простору агента за замовчуванням. Передавайте `{ "probe": true }` або `{ "deep": true }` лише коли викликач явно хоче live ping провайдера embeddings. - - `sessions.usage` повертає зведення використання за сесіями. - - `sessions.usage.timeseries` повертає timeseries використання для однієї сесії. - - `sessions.usage.logs` повертає записи журналу використання для однієї сесії. + + - `models.list` повертає дозволений середовищем виконання каталог моделей. Передайте `{ "view": "configured" }` для налаштованих моделей розміру picker (`agents.defaults.models` спершу, потім `models.providers.*.models`), або `{ "view": "all" }` для повного каталогу. + - `usage.status` повертає вікна використання провайдерів/підсумки залишку квоти. + - `usage.cost` повертає агреговані підсумки вартості використання за діапазон дат. + - `doctor.memory.status` повертає готовність vector-memory / кешованих embedding для активного робочого простору агента за замовчуванням. Передавайте `{ "probe": true }` або `{ "deep": true }` лише коли викликач явно хоче живий ping провайдера embedding. + - `sessions.usage` повертає підсумки використання за сеансами. + - `sessions.usage.timeseries` повертає часовий ряд використання для одного сеансу. + - `sessions.usage.logs` повертає записи журналу використання для одного сеансу. - - `channels.status` повертає зведення стану вбудованих і bundled каналів/plugin. + - `channels.status` повертає зведення статусів вбудованих і комплектних каналів/plugin. - `channels.logout` виконує вихід із певного каналу/облікового запису, якщо канал підтримує вихід. - - `web.login.start` запускає QR/web-потік входу для поточного web-провайдера каналу з підтримкою QR. - - `web.login.wait` очікує завершення цього QR/web-потоку входу та запускає канал у разі успіху. - - `push.test` надсилає тестовий APNs push на зареєстрований iOS-вузол. + - `web.login.start` запускає потік QR/web-входу для поточного постачальника web-каналу з підтримкою QR. + - `web.login.wait` чекає на завершення цього потоку QR/web-входу та запускає канал у разі успіху. + - `push.test` надсилає тестовий APNs push на зареєстрований iOS node. - `voicewake.get` повертає збережені тригери wake-word. - `voicewake.set` оновлює тригери wake-word і транслює зміну. - - - `send` — це прямий outbound-delivery RPC для надсилань, націлених на канал/обліковий запис/тред поза chat runner. + + - `send` — це прямий RPC вихідної доставки для надсилань, націлених на канал/обліковий запис/потік, поза chat runner. - `logs.tail` повертає налаштований хвіст файлового журналу gateway з керуванням cursor/limit і max-byte. - - `talk.config` повертає ефективний payload конфігурації Talk; `includeSecrets` потребує `operator.talk.secrets` (або `operator.admin`). - - `talk.mode` встановлює/транслює поточний стан режиму Talk для клієнтів WebChat/Control UI. - - `talk.speak` синтезує мовлення через активного провайдера мовлення Talk. - - `tts.status` повертає стан увімкнення TTS, активного провайдера, fallback-провайдерів і стан конфігурації провайдера. - - `tts.providers` повертає видимий інвентар провайдерів TTS. + - `talk.config` повертає ефективне навантаження конфігурації Talk; `includeSecrets` потребує `operator.talk.secrets` (або `operator.admin`). + - `talk.mode` задає/транслює поточний стан режиму Talk для клієнтів WebChat/Control UI. + - `talk.speak` синтезує мовлення через активного постачальника мовлення Talk. + - `tts.status` повертає стан увімкнення TTS, активного постачальника, резервних постачальників і стан конфігурації постачальника. + - `tts.providers` повертає видимий інвентар постачальників TTS. - `tts.enable` і `tts.disable` перемикають стан налаштувань TTS. - - `tts.setProvider` оновлює бажаного провайдера TTS. + - `tts.setProvider` оновлює бажаного постачальника TTS. - `tts.convert` виконує одноразове перетворення text-to-speech. - - `secrets.reload` повторно розв’язує активні SecretRefs і замінює runtime-стан секретів лише за повного успіху. - - `secrets.resolve` розв’язує призначення секретів, націлені на команду, для певного набору command/target. + - `secrets.reload` повторно вирішує активні SecretRefs і замінює стан runtime-секретів лише за повного успіху. + - `secrets.resolve` вирішує призначення секретів для цільових команд для певного набору command/target. - `config.get` повертає поточний знімок конфігурації та hash. - - `config.set` записує валідований payload конфігурації. - - `config.patch` зливає часткове оновлення конфігурації. - - `config.apply` валідує + замінює повний payload конфігурації. - - `config.schema` повертає live payload схеми конфігурації, який використовують Control UI і CLI-інструменти: schema, `uiHints`, version і metadata генерації, включно з metadata схеми plugin + channel, коли runtime може її завантажити. Схема містить metadata полів `title` / `description`, похідну від тих самих labels і help text, які використовує UI, включно з вкладеними object, wildcard, array-item і гілками композиції `anyOf` / `oneOf` / `allOf`, коли існує відповідна документація поля. - - `config.schema.lookup` повертає path-scoped lookup payload для одного шляху конфігурації: нормалізований path, shallow schema node, matched hint + `hintPath` і immediate child summaries для UI/CLI drill-down. Lookup schema nodes зберігають користувацьку документацію та common validation fields (`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, numeric/string/array/object bounds, а також flags на кшталт `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`). Child summaries відкривають `key`, нормалізований `path`, `type`, `required`, `hasChildren`, а також matched `hint` / `hintPath`. - - `update.run` запускає потік оновлення gateway і планує restart лише тоді, коли саме оновлення завершилося успішно. - - `update.status` повертає останній кешований update restart sentinel, включно з running version після restart, коли вона доступна. - - `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` надають onboarding wizard через WS RPC. + - `config.set` записує валідоване навантаження конфігурації. + - `config.patch` об’єднує часткове оновлення конфігурації. + - `config.apply` валідує та замінює повне навантаження конфігурації. + - `config.schema` повертає активне навантаження схеми конфігурації, яке використовують Control UI та інструменти CLI: schema, `uiHints`, version і метадані generation, включно з метаданими схеми plugin + channel, коли runtime може її завантажити. Схема містить метадані полів `title` / `description`, отримані з тих самих міток і довідкового тексту, які використовує UI, включно з вкладеним object, wildcard, array-item і гілками композиції `anyOf` / `oneOf` / `allOf`, коли існує відповідна документація поля. + - `config.schema.lookup` повертає навантаження пошуку, обмежене шляхом, для одного шляху конфігурації: нормалізований шлях, поверхневий вузол схеми, відповідну підказку + `hintPath` і безпосередні зведення дочірніх елементів для деталізації в UI/CLI. Вузли схеми пошуку зберігають користувацьку документацію та поширені поля валідації (`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, межі numeric/string/array/object і прапорці на кшталт `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`). Зведення дочірніх елементів відкривають `key`, нормалізований `path`, `type`, `required`, `hasChildren`, а також відповідні `hint` / `hintPath`. + - `update.run` запускає потік оновлення gateway і планує перезапуск лише тоді, коли саме оновлення завершилося успішно. + - `update.status` повертає найновіший кешований sentinel перезапуску оновлення, включно з версією, що працює після перезапуску, коли вона доступна. + - `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` відкривають майстер onboarding через WS RPC. - - - `agents.list` повертає налаштовані записи агентів, включно з effective model і runtime metadata. - - `agents.create`, `agents.update` і `agents.delete` керують записами агентів і під’єднанням workspace. - - `agents.files.list`, `agents.files.get` і `agents.files.set` керують bootstrap workspace files, доступними для агента. - - `agent.identity.get` повертає effective assistant identity для агента або сесії. - - `agent.wait` очікує завершення run і повертає terminal snapshot, коли він доступний. + + - `agents.list` повертає налаштовані записи агентів, включно з ефективною моделлю та runtime-метаданими. + - `agents.create`, `agents.update` і `agents.delete` керують записами агентів і прив’язкою робочих просторів. + - `agents.files.list`, `agents.files.get` і `agents.files.set` керують початковими файлами робочого простору, відкритими для агента. + - `agent.identity.get` повертає ефективну ідентичність assistant для агента або сесії. + - `agent.wait` чекає завершення запуску та повертає фінальний знімок, коли він доступний. - - - `sessions.list` повертає поточний session index. - - `sessions.subscribe` і `sessions.unsubscribe` перемикають підписки на session change event для поточного WS client. - - `sessions.messages.subscribe` і `sessions.messages.unsubscribe` перемикають transcript/message event subscriptions для однієї сесії. - - `sessions.preview` повертає bounded transcript previews для певних session keys. - - `sessions.resolve` розв’язує або канонікалізує session target. - - `sessions.create` створює новий session entry. + + - `sessions.list` повертає поточний індекс сесій. + - `sessions.subscribe` і `sessions.unsubscribe` перемикають підписки на події змін сесій для поточного WS-клієнта. + - `sessions.messages.subscribe` і `sessions.messages.unsubscribe` перемикають підписки на події транскрипту/повідомлень для однієї сесії. + - `sessions.preview` повертає обмежені попередні перегляди транскриптів для певних ключів сесій. + - `sessions.resolve` вирішує або канонізує ціль сесії. + - `sessions.create` створює новий запис сесії. - `sessions.send` надсилає повідомлення в наявну сесію. - - `sessions.steer` — це interrupt-and-steer variant для активної сесії. + - `sessions.steer` — це варіант переривання та скеровування для активної сесії. - `sessions.abort` перериває активну роботу для сесії. - - `sessions.patch` оновлює metadata/overrides сесії. - - `sessions.reset`, `sessions.delete` і `sessions.compact` виконують обслуговування сесії. - - `sessions.get` повертає повний збережений session row. - - Виконання чату досі використовує `chat.history`, `chat.send`, `chat.abort` і `chat.inject`. `chat.history` display-normalized для UI clients: inline directive tags видаляються з видимого тексту, plain-text tool-call XML payloads (включно з `...`, `...`, `...`, `...` і truncated tool-call blocks) та leaked ASCII/full-width model control tokens видаляються, pure silent-token assistant rows на кшталт точних `NO_REPLY` / `no_reply` опускаються, а oversized rows можуть бути замінені placeholders. + - `sessions.patch` оновлює метадані/перевизначення сесії. + - `sessions.reset`, `sessions.delete` і `sessions.compact` виконують обслуговування сесій. + - `sessions.get` повертає повний збережений рядок сесії. + - Виконання чату й далі використовує `chat.history`, `chat.send`, `chat.abort` і `chat.inject`. `chat.history` нормалізовано для відображення клієнтам UI: inline-теги директив вилучаються з видимого тексту, plain-text XML-навантаження викликів інструментів (зокрема `...`, `...`, `...`, `...` і обрізані блоки викликів інструментів) та витеклі ASCII/full-width токени керування моделі вилучаються, суто silent-token рядки assistant, як-от точні `NO_REPLY` / `no_reply`, пропускаються, а надмірно великі рядки можуть замінюватися placeholders. - - `device.pair.list` повертає pending і approved paired devices. - - `device.pair.approve`, `device.pair.reject` і `device.pair.remove` керують записами device-pairing. - - `device.token.rotate` ротує paired device token у межах його approved role і caller scope bounds. - - `device.token.revoke` відкликає paired device token у межах його approved role і caller scope bounds. + - `device.pair.list` повертає pending і approved спарені пристрої. + - `device.pair.approve`, `device.pair.reject` і `device.pair.remove` керують записами спарювання пристроїв. + - `device.token.rotate` ротує токен спареного пристрою в межах його approved role і caller scope. + - `device.token.revoke` відкликає токен спареного пристрою в межах його approved role і caller scope. - - - `node.pair.request`, `node.pair.list`, `node.pair.approve`, `node.pair.reject`, `node.pair.remove` і `node.pair.verify` охоплюють node pairing і bootstrap verification. - - `node.list` і `node.describe` повертають known/connected node state. - - `node.rename` оновлює мітку paired node. - - `node.invoke` пересилає команду до connected node. - - `node.invoke.result` повертає результат для invoke request. - - `node.event` передає node-originated events назад у gateway. - - `node.canvas.capability.refresh` оновлює scoped canvas-capability tokens. - - `node.pending.pull` і `node.pending.ack` — це connected-node queue APIs. - - `node.pending.enqueue` і `node.pending.drain` керують durable pending work для offline/disconnected nodes. + + - `node.pair.request`, `node.pair.list`, `node.pair.approve`, `node.pair.reject`, `node.pair.remove` і `node.pair.verify` охоплюють спарювання node і bootstrap verification. + - `node.list` і `node.describe` повертають стан відомих/підключених node. + - `node.rename` оновлює мітку спареного node. + - `node.invoke` пересилає команду до підключеного node. + - `node.invoke.result` повертає результат для запиту invoke. + - `node.event` переносить події, що походять із node, назад у gateway. + - `node.canvas.capability.refresh` оновлює токени scoped canvas-capability. + - `node.pending.pull` і `node.pending.ack` — це API черги connected-node. + - `node.pending.enqueue` і `node.pending.drain` керують durable pending work для offline/disconnected node. - - - `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і `exec.approval.resolve` охоплюють one-shot exec approval requests, а також pending approval lookup/replay. - - `exec.approval.waitDecision` очікує одне pending exec approval і повертає final decision (або `null` у разі timeout). - - `exec.approvals.get` і `exec.approvals.set` керують snapshots політики gateway exec approval. - - `exec.approvals.node.get` і `exec.approvals.node.set` керують node-local exec approval policy через node relay commands. - - `plugin.approval.request`, `plugin.approval.list`, `plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють plugin-defined approval flows. + + - `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і `exec.approval.resolve` охоплюють одноразові запити схвалення exec, а також пошук/відтворення pending approval. + - `exec.approval.waitDecision` чекає на одне pending exec approval і повертає остаточне рішення (або `null` у разі timeout). + - `exec.approvals.get` і `exec.approvals.set` керують знімками політики gateway exec approval. + - `exec.approvals.node.get` і `exec.approvals.node.set` керують node-local політикою exec approval через node relay commands. + - `plugin.approval.request`, `plugin.approval.list`, `plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють plugin-defined потоки схвалення. - - - Автоматизація: `wake` планує immediate або next-heartbeat wake text injection; `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`, `cron.run`, `cron.runs` керують scheduled work. + + - Автоматизація: `wake` планує негайну або next-heartbeat ін’єкцію wake text; `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`, `cron.run`, `cron.runs` керують запланованою роботою. - Skills та інструменти: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective`. @@ -449,97 +453,80 @@ Node; сесії без пристрою або без прив’язки по ### Поширені сімейства подій -- `chat`: оновлення UI chat, як-от `chat.inject` та інші transcript-only chat - events. -- `session.message` і `session.tool`: transcript/event-stream updates для - subscribed session. -- `sessions.changed`: змінено session index або metadata. -- `presence`: оновлення system presence snapshot. -- `tick`: periodic keepalive / liveness event. -- `health`: оновлення gateway health snapshot. -- `heartbeat`: оновлення Heartbeat event stream. -- `cron`: event зміни cron run/job. -- `shutdown`: сповіщення про shutdown gateway. -- `node.pair.requested` / `node.pair.resolved`: lifecycle node pairing. -- `node.invoke.request`: broadcast node invoke request. -- `device.pair.requested` / `device.pair.resolved`: paired-device lifecycle. -- `voicewake.changed`: змінено конфігурацію wake-word trigger. -- `exec.approval.requested` / `exec.approval.resolved`: lifecycle exec approval. -- `plugin.approval.requested` / `plugin.approval.resolved`: lifecycle plugin approval. +- `chat`: оновлення UI-чату, як-от `chat.inject`, та інші події чату лише для транскрипту. +- `session.message` і `session.tool`: оновлення transcript/event-stream для підписаної сесії. +- `sessions.changed`: індекс сесій або метадані змінено. +- `presence`: оновлення знімка присутності системи. +- `tick`: періодична подія keepalive / liveness. +- `health`: оновлення знімка стану gateway. +- `heartbeat`: оновлення потоку подій heartbeat. +- `cron`: подія зміни запуску/завдання cron. +- `shutdown`: сповіщення про завершення роботи gateway. +- `node.pair.requested` / `node.pair.resolved`: життєвий цикл спарювання node. +- `node.invoke.request`: трансляція запиту invoke node. +- `device.pair.requested` / `device.pair.resolved`: життєвий цикл спареного пристрою. +- `voicewake.changed`: конфігурацію тригера wake-word змінено. +- `exec.approval.requested` / `exec.approval.resolved`: життєвий цикл exec approval. +- `plugin.approval.requested` / `plugin.approval.resolved`: життєвий цикл plugin approval. -### Допоміжні методи вузлів +### Допоміжні методи node -- Вузли можуть викликати `skills.bins`, щоб отримати поточний список skill executables - для auto-allow checks. +- Node можуть викликати `skills.bins`, щоб отримати поточний список виконуваних файлів skill для перевірок auto-allow. -### Допоміжні методи операторів +### Допоміжні методи оператора -- Оператори можуть викликати `commands.list` (`operator.read`), щоб отримати runtime - command inventory для агента. - - `agentId` необов’язковий; опустіть його, щоб прочитати default agent workspace. - - `scope` керує тим, на яку surface націлюється primary `name`: - - `text` повертає primary text command token без початкового `/` - - `native` і default шлях `both` повертають provider-aware native names, - коли доступні - - `textAliases` містить exact slash aliases, як-от `/model` і `/m`. - - `nativeName` містить provider-aware native command name, коли він існує. - - `provider` необов’язковий і впливає лише на native naming, а також native plugin - command availability. - - `includeArgs=false` опускає serialized argument metadata з відповіді. -- Оператори можуть викликати `tools.catalog` (`operator.read`), щоб отримати runtime tool catalog для - агента. Відповідь містить grouped tools і provenance metadata: +- Оператори можуть викликати `commands.list` (`operator.read`), щоб отримати runtime-інвентар команд для агента. + - `agentId` є необов’язковим; пропустіть його, щоб читати робочий простір агента за замовчуванням. + - `scope` керує тим, на яку поверхню спрямовано основний `name`: + - `text` повертає основний текстовий токен команди без початкового `/` + - `native` і стандартний шлях `both` повертають provider-aware native names, коли вони доступні + - `textAliases` переносить точні slash aliases, як-от `/model` і `/m`. + - `nativeName` переносить provider-aware native command name, коли він існує. + - `provider` є необов’язковим і впливає лише на native naming, а також доступність native plugin command. + - `includeArgs=false` пропускає серіалізовані метадані аргументів у відповіді. +- Оператори можуть викликати `tools.catalog` (`operator.read`), щоб отримати runtime-каталог інструментів для агента. Відповідь містить згруповані інструменти та метадані походження: - `source`: `core` або `plugin` - `pluginId`: власник plugin, коли `source="plugin"` - - `optional`: чи є plugin tool optional -- Оператори можуть викликати `tools.effective` (`operator.read`), щоб отримати runtime-effective tool - inventory для сесії. - - `sessionKey` обов’язковий. - - Gateway виводить trusted runtime context із сесії на серверному боці замість приймання - caller-supplied auth або delivery context. - - Відповідь session-scoped і відображає те, що активна розмова може використовувати прямо зараз, - включно з core, plugin і channel tools. -- Оператори можуть викликати `skills.status` (`operator.read`), щоб отримати visible - skill inventory для агента. - - `agentId` необов’язковий; опустіть його, щоб прочитати default agent workspace. - - Відповідь містить eligibility, missing requirements, config checks і - sanitized install options без розкриття raw secret values. -- Оператори можуть викликати `skills.search` і `skills.detail` (`operator.read`) для - ClawHub discovery metadata. + - `optional`: чи є інструмент plugin необов’язковим +- Оператори можуть викликати `tools.effective` (`operator.read`), щоб отримати runtime-effective інвентар інструментів для сесії. + - `sessionKey` є обов’язковим. + - gateway виводить довірений runtime-контекст із сесії на боці сервера замість приймання caller-supplied auth або delivery context. + - Відповідь обмежена сесією та відображає те, що активна розмова може використовувати прямо зараз, включно з інструментами core, plugin і channel. +- Оператори можуть викликати `skills.status` (`operator.read`), щоб отримати видимий інвентар skill для агента. + - `agentId` є необов’язковим; пропустіть його, щоб читати робочий простір агента за замовчуванням. + - Відповідь містить eligibility, відсутні requirements, config checks і sanitized install options без розкриття raw secret values. +- Оператори можуть викликати `skills.search` і `skills.detail` (`operator.read`) для метаданих виявлення ClawHub. - Оператори можуть викликати `skills.install` (`operator.admin`) у двох режимах: - - Режим ClawHub: `{ source: "clawhub", slug, version?, force? }` встановлює - skill folder у директорію `skills/` default agent workspace. - - Режим інсталятора Gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` - запускає оголошену дію `metadata.openclaw.install` на gateway host. + - Режим ClawHub: `{ source: "clawhub", slug, version?, force? }` встановлює папку skill у каталог `skills/` робочого простору агента за замовчуванням. + - Режим installer gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` запускає оголошену дію `metadata.openclaw.install` на host gateway. - Оператори можуть викликати `skills.update` (`operator.admin`) у двох режимах: - - Режим ClawHub оновлює один tracked slug або всі tracked ClawHub installs у - default agent workspace. - - Config mode виправляє values `skills.entries.`, як-от `enabled`, - `apiKey` і `env`. + - Режим ClawHub оновлює один tracked slug або всі tracked встановлення ClawHub у робочому просторі агента за замовчуванням. + - Режим конфігурації патчить значення `skills.entries.`, як-от `enabled`, `apiKey` і `env`. ### Подання `models.list` `models.list` приймає необов’язковий параметр `view`: -- Не вказано або `"default"`: поточна поведінка runtime. Якщо налаштовано `agents.defaults.models`, відповідь є дозволеним каталогом; інакше відповідь є повним каталогом Gateway. -- `"configured"`: поведінка розміру пікера. Якщо налаштовано `agents.defaults.models`, вона все одно має пріоритет. Інакше відповідь використовує явні записи `models.providers.*.models`, повертаючись до повного каталогу лише тоді, коли налаштованих рядків моделей немає. -- `"all"`: повний каталог Gateway, оминаючи `agents.defaults.models`. Використовуйте це для діагностики та інтерфейсів виявлення, а не для звичайних пікерів моделей. +- Пропущено або `"default"`: поточна поведінка під час виконання. Якщо налаштовано `agents.defaults.models`, відповіддю буде дозволений каталог; інакше відповіддю буде повний каталог Gateway. +- `"configured"`: поведінка, розрахована на розмір засобу вибору. Якщо налаштовано `agents.defaults.models`, він усе одно має пріоритет. Інакше відповідь використовує явні записи `models.providers.*.models`, повертаючись до повного каталогу лише тоді, коли налаштованих рядків моделей немає. +- `"all"`: повний каталог Gateway в обхід `agents.defaults.models`. Використовуйте це для діагностики та інтерфейсів виявлення, а не для звичайних засобів вибору моделей. -## Схвалення exec +## Затвердження exec -- Коли запит exec потребує схвалення, Gateway транслює `exec.approval.requested`. -- Клієнти оператора виконують вирішення, викликаючи `exec.approval.resolve` (потрібна область `operator.approvals`). -- Для `host=node` `exec.approval.request` має містити `systemRunPlan` (канонічні метадані `argv`/`cwd`/`rawCommand`/сеансу). Запити без `systemRunPlan` відхиляються. -- Після схвалення переадресовані виклики `node.invoke system.run` повторно використовують цей канонічний +- Коли запит exec потребує затвердження, gateway транслює `exec.approval.requested`. +- Клієнти оператора вирішують його викликом `exec.approval.resolve` (потрібна область `operator.approvals`). +- Для `host=node` `exec.approval.request` має містити `systemRunPlan` (канонічні `argv`/`cwd`/`rawCommand`/метадані сеансу). Запити без `systemRunPlan` відхиляються. +- Після затвердження переслані виклики `node.invoke system.run` повторно використовують цей канонічний `systemRunPlan` як авторитетний контекст команди/cwd/сеансу. - Якщо викликач змінює `command`, `rawCommand`, `cwd`, `agentId` або - `sessionKey` між підготовкою та фінальним схваленим переадресуванням `system.run`, Gateway - відхиляє запуск замість того, щоб довіряти зміненому payload. + `sessionKey` між підготовкою та остаточним затвердженим пересиланням `system.run`, gateway + відхиляє запуск замість довіри зміненому корисному навантаженню. -## Резервна доставка агента +## Резервний варіант доставки агента - Запити `agent` можуть містити `deliver=true`, щоб запросити вихідну доставку. -- `bestEffortDeliver=false` зберігає сувору поведінку: невирішені або лише внутрішні цілі доставки повертають `INVALID_REQUEST`. -- `bestEffortDeliver=true` дозволяє резервний перехід до виконання лише в сеансі, коли неможливо визначити зовнішній маршрут доставки (наприклад, внутрішні/webchat-сеанси або неоднозначні багатоканальні конфігурації). +- `bestEffortDeliver=false` зберігає сувору поведінку: нерозв’язані або лише внутрішні цілі доставки повертають `INVALID_REQUEST`. +- `bestEffortDeliver=true` дозволяє резервний перехід до виконання лише в сеансі, коли неможливо визначити зовнішній маршрут доставки (наприклад, внутрішні/вебчат-сеанси або неоднозначні багатоканальні конфігурації). ## Версіонування @@ -553,29 +540,29 @@ Node; сесії без пристрою або без прив’язки по ### Константи клієнта Еталонний клієнт у `src/gateway/client.ts` використовує ці типові значення. Значення -стабільні в межах protocol v3 і є очікуваною базою для сторонніх клієнтів. +стабільні в protocol v3 і є очікуваною базою для сторонніх клієнтів. -| Константа | Типове значення | Джерело | -| ----------------------------------------- | ---------------------------------------------------- | --------------------------------------------------------- | -| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | -| Тайм-аут запиту (на RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) | -| Тайм-аут preauth / connect-challenge | `15_000` ms | `src/gateway/handshake-timeouts.ts` (clamp `250`–`15_000`) | -| Початкова затримка повторного підключення | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) | -| Максимальна затримка повторного підключення | `30_000` ms | `src/gateway/client.ts` (`scheduleReconnect`) | -| Обмеження швидкої повторної спроби після закриття device-token | `250` ms | `src/gateway/client.ts` | -| Пільговий період force-stop перед `terminate()` | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | -| Типовий тайм-аут `stopAndWait()` | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` | -| Типовий інтервал tick (до `hello-ok`) | `30_000` ms | `src/gateway/client.ts` | -| Закриття через тайм-аут tick | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` | -| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` | +| Константа | Типове значення | Джерело | +| ----------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | +| Час очікування запиту (на RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) | +| Час очікування preauth / connect-challenge | `15_000` ms | `src/gateway/handshake-timeouts.ts` (config/env можуть збільшити парний бюджет сервера/клієнта) | +| Початкова затримка повторного підключення | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) | +| Максимальна затримка повторного підключення | `30_000` ms | `src/gateway/client.ts` (`scheduleReconnect`) | +| Обмеження швидкої повторної спроби після закриття через токен пристрою | `250` ms | `src/gateway/client.ts` | +| Пільговий період force-stop перед `terminate()` | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | +| Типовий час очікування `stopAndWait()` | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` | +| Типовий інтервал такту (до `hello-ok`) | `30_000` ms | `src/gateway/client.ts` | +| Закриття через тайм-аут такту | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` | +| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` | Сервер оголошує ефективні `policy.tickIntervalMs`, `policy.maxPayload` -та `policy.maxBufferedBytes` у `hello-ok`; клієнти мають дотримуватися цих значень, +і `policy.maxBufferedBytes` у `hello-ok`; клієнти мають дотримуватися цих значень, а не типових значень до handshake. ## Автентифікація -- Автентифікація Gateway зі спільним секретом використовує `connect.params.auth.token` або +- Автентифікація gateway зі спільним секретом використовує `connect.params.auth.token` або `connect.params.auth.password`, залежно від налаштованого режиму автентифікації. - Режими з ідентичністю, як-от Tailscale Serve (`gateway.auth.allowTailscale: true`) або не-loopback @@ -583,78 +570,79 @@ Node; сесії без пристрою або без прив’язки по заголовків запиту замість `connect.params.auth.*`. - Private-ingress `gateway.auth.mode: "none"` повністю пропускає автентифікацію підключення зі спільним секретом; не відкривайте цей режим на публічному/ненадійному ingress. -- Після pairing Gateway видає **device token**, обмежений роллю підключення +- Після спарювання Gateway видає **токен пристрою**, обмежений роллю з’єднання + областями. Він повертається в `hello-ok.auth.deviceToken` і має зберігатися клієнтом для майбутніх підключень. - Клієнти мають зберігати основний `hello-ok.auth.deviceToken` після будь-якого успішного підключення. -- Повторне підключення з цим **збереженим** device token також має повторно використовувати збережений - затверджений набір областей для цього токена. Це зберігає доступ read/probe/status, +- Повторне підключення з цим **збереженим** токеном пристрою також має повторно використовувати збережений + затверджений набір областей для цього токена. Це зберігає доступ читання/перевірки/статусу, який уже було надано, і запобігає непомітному звуженню повторних підключень до вужчої неявної області лише для адміністратора. - Складання автентифікації підключення на боці клієнта (`selectConnectAuth` у `src/gateway/client.ts`): - - `auth.password` є ортогональним і завжди пересилається, коли встановлений. - - `auth.token` заповнюється в порядку пріоритету: спершу явний спільний токен, - потім явний `deviceToken`, потім збережений токен для пристрою (за ключем + - `auth.password` є ортогональним і завжди пересилається, коли заданий. + - `auth.token` заповнюється в порядку пріоритету: спочатку явний спільний токен, + потім явний `deviceToken`, потім збережений токен для пристрою (з ключем за `deviceId` + `role`). - `auth.bootstrapToken` надсилається лише тоді, коли жоден із наведених вище варіантів не визначив - `auth.token`. Спільний токен або будь-який визначений device token пригнічує його. - - Автопідвищення збереженого device token під час одноразової - повторної спроби `AUTH_TOKEN_MISMATCH` обмежене **лише довіреними endpoints** — + `auth.token`. Спільний токен або будь-який визначений токен пристрою його пригнічує. + - Автоматичне підвищення збереженого токена пристрою під час одноразової + повторної спроби `AUTH_TOKEN_MISMATCH` обмежене **лише довіреними endpoint** — loopback або `wss://` із закріпленим `tlsFingerprint`. Публічний `wss://` - без закріплення не підходить. + без закріплення не відповідає вимогам. - Додаткові записи `hello-ok.auth.deviceTokens` є токенами передачі bootstrap. Зберігайте їх лише тоді, коли підключення використовувало bootstrap-автентифікацію на довіреному транспорті, як-от `wss://` або loopback/local pairing. - Якщо клієнт надає **явний** `deviceToken` або явні `scopes`, цей - запитаний викликачем набір областей залишається авторитетним; кешовані області - повторно використовуються лише тоді, коли клієнт повторно використовує збережений токен для пристрою. -- Device tokens можна ротувати/відкликати через `device.token.rotate` та + запитаний викликачем набір областей лишається авторитетним; кешовані області лише + повторно використовуються, коли клієнт повторно використовує збережений токен для пристрою. +- Токени пристроїв можна обертати/відкликати через `device.token.rotate` і `device.token.revoke` (потрібна область `operator.pairing`). - `device.token.rotate` повертає метадані ротації. Він віддзеркалює замінний - bearer token лише для викликів із того самого пристрою, які вже автентифіковані цим - device token, щоб клієнти лише з токеном могли зберегти заміну перед - повторним підключенням. Ротації shared/admin не віддзеркалюють bearer token. -- Видача, ротація та відкликання токенів залишаються обмеженими затвердженим набором ролей, - записаним у pairing-записі цього пристрою; мутація токена не може розширити або - націлити роль пристрою, якої pairing approval ніколи не надавало. -- Для сеансів токенів paired-device керування пристроєм є self-scoped, якщо - викликач також не має `operator.admin`: викликачі без прав адміністратора можуть видаляти/відкликати/ротувати + bearer-токен лише для викликів із того самого пристрою, які вже автентифіковані цим + токеном пристрою, щоб клієнти лише з токеном могли зберегти заміну перед + повторним підключенням. Спільні/адміністративні ротації не віддзеркалюють bearer-токен. +- Випуск, ротація та відкликання токенів залишаються обмеженими затвердженим набором ролей, + записаним у записі спарювання цього пристрою; зміна токена не може розширити або + націлити роль пристрою, яку затвердження спарювання ніколи не надавало. +- Для сеансів токенів спарених пристроїв керування пристроями має самостійну область, якщо + викликач також не має `operator.admin`: викликачі без прав адміністратора можуть видаляти/відкликати/обертати лише **власний** запис пристрою. -- `device.token.rotate` і `device.token.revoke` також перевіряють цільовий набір областей operator +- `device.token.rotate` і `device.token.revoke` також перевіряють набір областей цільового operator token щодо поточних областей сеансу викликача. Викликачі без прав адміністратора - не можуть ротувати або відкликати ширший operator token, ніж уже мають. -- Збої автентифікації містять `error.details.code` плюс підказки відновлення: + не можуть обертати або відкликати ширший operator token, ніж уже мають. +- Збої автентифікації містять `error.details.code` плюс підказки для відновлення: - `error.details.canRetryWithDeviceToken` (boolean) - `error.details.recommendedNextStep` (`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`) - Поведінка клієнта для `AUTH_TOKEN_MISMATCH`: - - Довірені клієнти можуть виконати одну обмежену повторну спробу з кешованим токеном для пристрою. - - Якщо ця повторна спроба завершується невдачею, клієнти мають зупинити автоматичні цикли повторного підключення й показати оператору вказівки щодо дії. + - Довірені клієнти можуть спробувати одну обмежену повторну спробу з кешованим токеном для пристрою. + - Якщо ця повторна спроба не вдається, клієнти мають зупинити автоматичні цикли повторного підключення й показати оператору рекомендації щодо дій. -## Ідентичність пристрою + pairing +## Ідентичність пристрою + спарювання - Node мають містити стабільну ідентичність пристрою (`device.id`), отриману з - відбитка keypair. -- Gateway видають токени для пристрою + ролі. -- Pairing approvals потрібні для нових ідентифікаторів пристроїв, якщо не ввімкнено локальне автоматичне схвалення. -- Автоматичне схвалення pairing зосереджене на прямих підключеннях local loopback. -- OpenClaw також має вузький backend/container-local шлях самопідключення для - довірених допоміжних потоків зі спільним секретом. -- Підключення з того самого хоста через tailnet або LAN усе одно вважаються віддаленими для pairing і - потребують схвалення. + відбитка пари ключів. +- Gateway видають токени на пристрій + роль. +- Затвердження спарювання потрібні для нових ідентифікаторів пристроїв, якщо локальне автоматичне затвердження + не ввімкнено. +- Автоматичне затвердження спарювання зосереджене на прямих підключеннях local loopback. +- OpenClaw також має вузький шлях самопідключення всередині backend/container для + довірених helper-потоків зі спільним секретом. +- Підключення same-host tailnet або LAN усе ще розглядаються як віддалені для спарювання і + потребують затвердження. - WS-клієнти зазвичай містять ідентичність `device` під час `connect` (operator + - node). Єдині винятки operator без пристрою — явні довірені шляхи: - - `gateway.controlUi.allowInsecureAuth=true` для localhost-only insecure HTTP compatibility. - - успішна автентифікація operator Control UI `gateway.auth.mode: "trusted-proxy"`. - - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (break-glass, серйозне зниження безпеки). - - direct-loopback backend RPCs `gateway-client`, автентифіковані спільним - gateway token/password. -- Усі підключення мають підписувати наданий сервером nonce `connect.challenge`. + node). Єдині винятки для операторів без пристрою — явні довірчі шляхи: + - `gateway.controlUi.allowInsecureAuth=true` для сумісності з небезпечним HTTP лише на localhost. + - успішна автентифікація operator Control UI з `gateway.auth.mode: "trusted-proxy"`. + - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (аварійний режим, серйозне зниження безпеки). + - прямі loopback backend RPC `gateway-client`, автентифіковані спільним + токеном/паролем gateway. +- Усі з’єднання мають підписувати наданий сервером nonce `connect.challenge`. -### Діагностика міграції автентифікації пристрою +### Діагностика міграції автентифікації пристроїв -Для застарілих клієнтів, які досі використовують поведінку підписування до challenge, `connect` тепер повертає +Для застарілих клієнтів, які все ще використовують поведінку підписування до challenge, `connect` тепер повертає коди деталей `DEVICE_AUTH_*` у `error.details.code` зі стабільним `error.details.reason`. Поширені збої міграції: @@ -662,35 +650,35 @@ Node; сесії без пристрою або без прив’язки по | Повідомлення | details.code | details.reason | Значення | | --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- | | `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | Клієнт пропустив `device.nonce` (або надіслав порожнє значення). | -| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | Клієнт підписав застарілий/неправильний nonce. | -| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | Payload підпису не відповідає payload v2. | -| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Підписана мітка часу виходить за межі дозволеного skew. | +| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | Клієнт підписав застарілим/неправильним nonce. | +| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | Корисне навантаження підпису не відповідає payload v2. | +| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Підписаний timestamp виходить за межі дозволеного skew. | | `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` не відповідає відбитку публічного ключа. | -| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | Формат/канонікалізація публічного ключа не вдалася. | +| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | Формат/канонікалізація публічного ключа не вдалися. | Ціль міграції: - Завжди чекайте на `connect.challenge`. -- Підписуйте payload v2, який містить server nonce. +- Підписуйте payload v2, який містить nonce сервера. - Надсилайте той самий nonce у `connect.params.device.nonce`. -- Бажаний payload підпису — `v3`, який прив’язує `platform` і `deviceFamily` +- Бажане корисне навантаження підпису — `v3`, яке прив’язує `platform` і `deviceFamily` на додачу до полів device/client/role/scopes/token/nonce. -- Застарілі підписи `v2` залишаються прийнятими для сумісності, але закріплення метаданих paired-device - усе одно контролює політику команд під час повторного підключення. +- Застарілі підписи `v2` залишаються прийнятими для сумісності, але закріплення metadata + спареного пристрою все одно керує політикою команд під час повторного підключення. ## TLS + закріплення - TLS підтримується для WS-з’єднань. -- Клієнти можуть необов’язково закріпити відбиток сертифіката Gateway (див. конфігурацію `gateway.tls` - плюс `gateway.remote.tlsFingerprint` або CLI `--tls-fingerprint`). +- Клієнти можуть за потреби закріпити відбиток сертифіката Gateway (див. конфігурацію `gateway.tls` + разом із `gateway.remote.tlsFingerprint` або CLI `--tls-fingerprint`). -## Область +## Обсяг -Цей протокол відкриває **повний API Gateway** (status, channels, models, chat, -agent, sessions, nodes, approvals тощо). Точна поверхня визначена -схемами TypeBox у `src/gateway/protocol/schema.ts`. +Цей протокол надає **повний API Gateway** (статус, канали, моделі, чат, +агент, сесії, вузли, схвалення тощо). Точну поверхню визначено схемами +TypeBox у `src/gateway/protocol/schema.ts`. ## Пов’язане -- [Протокол мосту](/uk/gateway/bridge-protocol) -- [Операційний посібник Gateway](/uk/gateway) +- [Протокол Bridge](/uk/gateway/bridge-protocol) +- [Runbook Gateway](/uk/gateway)