chore(i18n): refresh uk translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-05-02 01:26:48 +00:00
parent 6e0c76c81d
commit 121d7c3705
2 changed files with 380 additions and 358 deletions

View File

@ -1,27 +1,27 @@
---
read_when:
- Робота над поведінкою каналу WhatsApp/веб або маршрутизацією вхідних повідомлень
- Робота з поведінкою каналу WhatsApp/вебканалу або маршрутизацією вхідних повідомлень
summary: Підтримка каналу WhatsApp, засоби керування доступом, поведінка доставки та операції
title: WhatsApp
x-i18n:
generated_at: "2026-05-01T21:50:43Z"
generated_at: "2026-05-02T01:23:54Z"
model: gpt-5.5
provider: openai
source_hash: d97215e7f3ae30457e464b35177ad0b0b3631ef6d9b242eaab490eee76bf87f9
source_hash: c25380f6a08e771b1a3f5e39f2284cffbffe76a3b05f1a885efe0a5f6a7d022c
source_path: channels/whatsapp.md
workflow: 16
---
Стан: production-ready через WhatsApp Web (Baileys). Gateway керує пов’язаними сеансами.
Стан: готовий до production через WhatsApp Web (Baileys). Gateway керує пов’язаними сесіями.
## Встановлення (за потреби)
- Онбординг (`openclaw onboard`) і `openclaw channels add --channel whatsapp`
пропонують установити WhatsApp Plugin під час першого вибору.
- `openclaw channels login --channel whatsapp` також пропонує потік установлення, коли
Plugin ще немає.
- Канал розробки + git checkout: стандартно використовує локальний шлях Plugin.
- Stable/Beta: використовує npm-пакет `@openclaw/whatsapp`, коли актуальний пакет
- Onboarding (`openclaw onboard`) і `openclaw channels add --channel whatsapp`
пропонують встановити Plugin WhatsApp, коли ви вперше його вибираєте.
- `openclaw channels login --channel whatsapp` також пропонує процес встановлення, коли
Plugin ще відсутній.
- Dev-канал + git checkout: за замовчуванням використовує локальний шлях Plugin.
- Stable/Beta: використовує npm-пакет `@openclaw/whatsapp`, коли поточний пакет
опубліковано.
Ручне встановлення залишається доступним:
@ -30,26 +30,26 @@ x-i18n:
openclaw plugins install @openclaw/whatsapp
```
Якщо npm повідомляє, що пакет, який належить OpenClaw, застарілий або відсутній, використайте
актуальну пакетовану збірку OpenClaw або локальний checkout, доки ланцюг npm-пакетів
Якщо npm повідомляє, що пакет, який належить OpenClaw, застарілий або відсутній, використовуйте
поточну пакетовану збірку OpenClaw або локальний checkout, доки черга npm-пакетів
не наздожене.
<CardGroup cols={3}>
<Card title="Pairing" icon="link" href="/uk/channels/pairing">
Стандартна політика DM — pairing для невідомих відправників.
<Card title="Спарювання" icon="link" href="/uk/channels/pairing">
Стандартна політика DM — спарювання для невідомих відправників.
</Card>
<Card title="Channel troubleshooting" icon="wrench" href="/uk/channels/troubleshooting">
Міжканальна діагностика та інструкції з відновлення.
<Card title="Усунення несправностей каналів" icon="wrench" href="/uk/channels/troubleshooting">
Діагностика між каналами та сценарії ремонту.
</Card>
<Card title="Gateway configuration" icon="settings" href="/uk/gateway/configuration">
Повні шаблони й приклади конфігурації каналу.
<Card title="Конфігурація Gateway" icon="settings" href="/uk/gateway/configuration">
Повні шаблони та приклади конфігурації каналів.
</Card>
</CardGroup>
## Швидке налаштування
<Steps>
<Step title="Configure WhatsApp access policy">
<Step title="Налаштуйте політику доступу WhatsApp">
```json5
{
@ -66,7 +66,7 @@ openclaw plugins install @openclaw/whatsapp
</Step>
<Step title="Link WhatsApp (QR)">
<Step title="Пов’яжіть WhatsApp (QR)">
```bash
openclaw channels login --channel whatsapp
@ -78,7 +78,7 @@ openclaw channels login --channel whatsapp
openclaw channels login --channel whatsapp --account work
```
Щоб під’єднати наявний/власний каталог автентифікації WhatsApp Web перед входом:
Щоб підключити наявний/власний каталог автентифікації WhatsApp Web перед входом:
```bash
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth
@ -87,7 +87,7 @@ openclaw channels login --channel whatsapp --account work
</Step>
<Step title="Start the gateway">
<Step title="Запустіть gateway">
```bash
openclaw gateway
@ -95,31 +95,31 @@ openclaw gateway
</Step>
<Step title="Approve first pairing request (if using pairing mode)">
<Step title="Схваліть перший запит на спарювання (якщо використовується режим спарювання)">
```bash
openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
```
Запити pairing спливають через 1 годину. Кількість очікуваних запитів обмежена 3 на канал.
Запити на спарювання спливають через 1 годину. Очікувані запити обмежені 3 на канал.
</Step>
</Steps>
<Note>
OpenClaw рекомендує за можливості запускати WhatsApp на окремому номері. (Метадані каналу й потік налаштування оптимізовані для такого варіанта, але налаштування з особистим номером також підтримуються.)
OpenClaw рекомендує запускати WhatsApp на окремому номері, коли це можливо. (Метадані каналу та процес налаштування оптимізовані для такого варіанта, але налаштування з особистим номером також підтримуються.)
</Note>
## Шаблони розгортання
<AccordionGroup>
<Accordion title="Dedicated number (recommended)">
<Accordion title="Виділений номер (рекомендовано)">
Це найчистіший операційний режим:
- окрема ідентичність WhatsApp для OpenClaw
- зрозуміліші allowlist для DM і межі маршрутизації
- нижча ймовірність плутанини із self-chat
- зрозуміліші allowlist DM і межі маршрутизації
- менша ймовірність плутанини із чатом із самим собою
Мінімальний шаблон політики:
@ -136,43 +136,43 @@ OpenClaw рекомендує за можливості запускати Whats
</Accordion>
<Accordion title="Personal-number fallback">
Онбординг підтримує режим особистого номера та записує базову конфігурацію, зручну для self-chat:
<Accordion title="Резервний варіант з особистим номером">
Onboarding підтримує режим особистого номера та записує базову конфігурацію, зручну для чату із самим собою:
- `dmPolicy: "allowlist"`
- `allowFrom` містить ваш особистий номер
- `selfChatMode: true`
Під час виконання захисти self-chat спираються на пов’язаний власний номер і `allowFrom`.
Під час виконання захисти чату із самим собою спираються на пов’язаний власний номер і `allowFrom`.
</Accordion>
<Accordion title="WhatsApp Web-only channel scope">
Канал платформи повідомлень у поточній архітектурі каналів OpenClaw базується на WhatsApp Web (`Baileys`).
<Accordion title="Область каналу лише WhatsApp Web">
Канал платформи повідомлень базується на WhatsApp Web (`Baileys`) у поточній архітектурі каналів OpenClaw.
У вбудованому реєстрі чат-каналів немає окремого каналу повідомлень Twilio WhatsApp.
Окремого каналу повідомлень Twilio WhatsApp у вбудованому реєстрі чат-каналів немає.
</Accordion>
</AccordionGroup>
## Модель виконання
## Runtime-модель
- Gateway керує сокетом WhatsApp і циклом повторного підключення.
- Watchdog повторного підключення використовує активність транспорту WhatsApp Web, а не лише обсяг вхідних повідомлень застосунку, тому тихий сеанс пов’язаного пристрою не перезапускається тільки через те, що нещодавно ніхто не надсилав повідомлень. Довший ліміт тиші застосунку все одно примусово виконує повторне підключення, якщо транспортні фрейми продовжують надходити, але повідомлення застосунку не обробляються протягом вікна watchdog; після тимчасового повторного підключення для нещодавно активного сеансу ця перевірка тиші застосунку використовує звичайний тайм-аут повідомлень для першого вікна відновлення.
- Таймінги сокета Baileys явно задаються в `web.whatsapp.*`: `keepAliveIntervalMs` керує ping WhatsApp Web на рівні застосунку, `connectTimeoutMs` керує тайм-аутом початкового handshake, а `defaultQueryTimeoutMs` керує тайм-аутами запитів Baileys.
- Watchdog повторного підключення використовує активність транспорту WhatsApp Web, а не лише обсяг вхідних повідомлень застосунку, тому тиха сесія пов’язаного пристрою не перезапускається тільки через те, що ніхто останнім часом не надсилав повідомлення. Довший ліміт тиші застосунку все одно примусово виконує повторне підключення, якщо транспортні кадри продовжують надходити, але повідомлення застосунку не обробляються протягом вікна watchdog; після тимчасового повторного підключення для нещодавно активної сесії ця перевірка тиші застосунку використовує звичайний таймаут повідомлень для першого вікна відновлення.
- Таймінги сокета Baileys явно задаються в `web.whatsapp.*`: `keepAliveIntervalMs` керує ping застосунку WhatsApp Web, `connectTimeoutMs` керує таймаутом початкового handshake, а `defaultQueryTimeoutMs` керує таймаутами запитів Baileys.
- Вихідні надсилання потребують активного слухача WhatsApp для цільового облікового запису.
- Чати статусів і broadcast ігноруються (`@status`, `@broadcast`).
- Watchdog повторного підключення відстежує активність транспорту WhatsApp Web, а не лише обсяг вхідних повідомлень застосунку: тихі сеанси пов’язаних пристроїв залишаються активними, доки транспортні фрейми продовжують надходити, але зупинка транспорту примушує повторне підключення значно раніше за пізніший шлях віддаленого від’єднання.
- Прямі чати використовують правила сеансу DM (`session.dmScope`; стандартне `main` зводить DM до головного сеансу агента).
- Групові сеанси ізольовані (`agent:<agentId>:whatsapp:group:<jid>`).
- Транспорт WhatsApp Web поважає стандартні змінні середовища проксі на хості Gateway (`HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY` / варіанти в нижньому регістрі). Надавайте перевагу конфігурації проксі на рівні хоста, а не специфічним для каналу налаштуванням проксі WhatsApp.
- Коли ввімкнено `messages.removeAckAfterReply`, OpenClaw очищає ack-реакцію WhatsApp після доставлення видимої відповіді.
- Чати статусів і трансляцій ігноруються (`@status`, `@broadcast`).
- Watchdog повторного підключення відстежує активність транспорту WhatsApp Web, а не лише обсяг вхідних повідомлень застосунку: тихі сесії пов’язаних пристроїв залишаються активними, поки транспортні кадри продовжують надходити, але зупинка транспорту примусово запускає повторне підключення значно раніше за пізніший шлях віддаленого відключення.
- Прямі чати використовують правила DM-сесій (`session.dmScope`; стандартне `main` згортає DM у головну сесію агента).
- Групові сесії ізольовані (`agent:<agentId>:whatsapp:group:<jid>`).
- Транспорт WhatsApp Web враховує стандартні змінні середовища proxy на хості gateway (`HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY` / варіанти в нижньому регістрі). Надавайте перевагу конфігурації proxy на рівні хоста над специфічними для каналу налаштуваннями proxy WhatsApp.
- Коли `messages.removeAckAfterReply` увімкнено, OpenClaw очищає ack-реакцію WhatsApp після доставки видимої відповіді.
## Хуки Plugin і приватність
Вхідні повідомлення WhatsApp можуть містити особистий вміст повідомлень, номери телефонів,
ідентифікатори груп, імена відправників і поля кореляції сеансу. З цієї причини
WhatsApp не транслює вхідні payload хуків `message_received` до плагінів,
ідентифікатори груп, імена відправників і поля кореляції сесій. З цієї причини
WhatsApp не транслює вхідні payload хуків `message_received` до Plugin,
якщо ви явно не ввімкнете це:
```json5
@ -187,7 +187,7 @@ WhatsApp не транслює вхідні payload хуків `message_received
}
```
Можна обмежити opt-in одним обліковим записом:
Ви можете обмежити opt-in одним обліковим записом:
```json5
{
@ -205,57 +205,57 @@ WhatsApp не транслює вхідні payload хуків `message_received
}
```
Увімкніть це лише для плагінів, яким ви довіряєте отримання вмісту та ідентифікаторів
вхідних повідомлень WhatsApp.
Увімкніть це лише для Plugin, яким ви довіряєте отримувати вхідний вміст повідомлень
WhatsApp та ідентифікатори.
## Контроль доступу й активація
## Контроль доступу та активація
<Tabs>
<Tab title="DM policy">
<Tab title="Політика DM">
`channels.whatsapp.dmPolicy` керує доступом до прямих чатів:
- `pairing` (стандартно)
- `pairing` (за замовчуванням)
- `allowlist`
- `open` (потребує, щоб `allowFrom` містив `"*"`)
- `disabled`
`allowFrom` приймає номери у стилі E.164 (нормалізуються внутрішньо).
Перевизначення для кількох облікових записів: `channels.whatsapp.accounts.<id>.dmPolicy` (і `allowFrom`) мають пріоритет над стандартами рівня каналу для цього облікового запису.
Перевизначення для кількох облікових записів: `channels.whatsapp.accounts.<id>.dmPolicy` (і `allowFrom`) мають пріоритет над стандартними значеннями рівня каналу для цього облікового запису.
Деталі поведінки під час виконання:
- pairing зберігаються в allow-store каналу та об’єднуються з налаштованим `allowFrom`
- якщо allowlist не налаштовано, пов’язаний власний номер дозволено стандартно
- OpenClaw ніколи автоматично не створює pairing для вихідних DM `fromMe` (повідомлень, які ви надсилаєте собі з пов’язаного пристрою)
- спарювання зберігаються в allow-store каналу та об’єднуються з налаштованим `allowFrom`
- якщо allowlist не налаштовано, пов’язаний власний номер дозволяється за замовчуванням
- OpenClaw ніколи автоматично не спаровує вихідні DM `fromMe` (повідомлення, які ви надсилаєте собі з пов’язаного пристрою)
</Tab>
<Tab title="Group policy + allowlists">
<Tab title="Політика груп + allowlist">
Доступ до груп має два рівні:
1. **Allowlist членства в групах** (`channels.whatsapp.groups`)
- якщо `groups` пропущено, усі групи придатні
- якщо `groups` присутній, він діє як allowlist груп (`"*"` дозволено)
2. **Політика відправників у групах** (`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
2. **Політика відправників групи** (`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
- `open`: allowlist відправників обходиться
- `allowlist`: відправник має збігатися з `groupAllowFrom` (або `*`)
- `disabled`: блокувати всі вхідні повідомлення груп
- `disabled`: блокувати всі групові вхідні повідомлення
Fallback для allowlist відправників:
Резервна логіка allowlist відправників:
- якщо `groupAllowFrom` не задано, runtime повертається до `allowFrom`, коли він доступний
- allowlist відправників оцінюються до активації згадкою/відповіддю
- allowlist відправників оцінюються перед активацією через згадку/відповідь
Примітка: якщо блок `channels.whatsapp` взагалі відсутній, fallback group-policy під час виконання`allowlist` (із попередженням у журналі), навіть якщо задано `channels.defaults.groupPolicy`.
Примітка: якщо блока `channels.whatsapp` взагалі немає, резервна runtime-політика груп`allowlist` (із попередженням у журналі), навіть якщо `channels.defaults.groupPolicy` задано.
</Tab>
<Tab title="Mentions + /activation">
Групові відповіді стандартно потребують згадки.
<Tab title="Згадки + /activation">
Групові відповіді за замовчуванням потребують згадки.
Виявлення згадки охоплює:
Виявлення згадок охоплює:
- явні згадки WhatsApp ідентичності бота
- налаштовані regex-шаблони згадок (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`)
@ -264,32 +264,32 @@ WhatsApp не транслює вхідні payload хуків `message_received
Примітка щодо безпеки:
- цитата/відповідь лише задовольняє перевірку згадки; вона **не** надає авторизацію відправнику
- з `groupPolicy: "allowlist"` відправники поза allowlist усе одно блокуються, навіть якщо відповідають на повідомлення користувача з allowlist
- цитата/відповідь лише задовольняє gating за згадкою; вона **не** надає авторизацію відправника
- з `groupPolicy: "allowlist"` відправники поза allowlist усе одно блокуються, навіть якщо вони відповідають на повідомлення користувача з allowlist
Команда активації на рівні сеансу:
Команда активації рівня сесії:
- `/activation mention`
- `/activation always`
`activation` оновлює стан сеансу (не глобальну конфігурацію). Вона обмежена власником.
`activation` оновлює стан сесії (не глобальну конфігурацію). Вона обмежена власником.
</Tab>
</Tabs>
## Поведінка особистого номера й self-chat
## Поведінка особистого номера та чату із самим собою
Коли пов’язаний власний номер також присутній у `allowFrom`, активуються захисти self-chat WhatsApp:
Коли пов’язаний власний номер також присутній у `allowFrom`, активуються захисти WhatsApp для чату із самим собою:
- пропускати read receipts для ходів self-chat
- ігнорувати поведінку mention-JID auto-trigger, яка інакше ping-увала б вас самих
- якщо `messages.responsePrefix` не задано, відповіді self-chat стандартно мають префікс `[{identity.name}]` або `[openclaw]`
- пропускати read receipts для turn чату із самим собою
- ігнорувати поведінку автозапуску mention-JID, яка інакше пінгувала б вас
- якщо `messages.responsePrefix` не задано, відповіді в чаті із самим собою за замовчуванням мають вигляд `[{identity.name}]` або `[openclaw]`
## Нормалізація повідомлень і контекст
<AccordionGroup>
<Accordion title="Inbound envelope + reply context">
Вхідні повідомлення WhatsApp обгортаються в спільний вхідний envelope.
<Accordion title="Вхідний envelope + контекст відповіді">
Вхідні повідомлення WhatsApp загортаються у спільний вхідний envelope.
Якщо існує процитована відповідь, контекст додається в такій формі:
@ -300,11 +300,15 @@ WhatsApp не транслює вхідні payload хуків `message_received
```
Поля метаданих відповіді також заповнюються, коли доступні (`ReplyToId`, `ReplyToBody`, `ReplyToSender`, JID/E.164 відправника).
Коли ціль процитованої відповіді — завантажуване медіа, OpenClaw зберігає його через
звичайне сховище вхідних медіа та надає його як `MediaPath`/`MediaType`, щоб
агент міг оглянути згадане зображення, а не лише бачити
`<media:image>`.
</Accordion>
<Accordion title="Media placeholders and location/contact extraction">
Вхідні повідомлення лише з медіа нормалізуються з placeholders, як-от:
<Accordion title="Плейсхолдери медіа та витягування локації/контактів">
Вхідні повідомлення лише з медіа нормалізуються з такими плейсхолдерами, як:
- `<media:image>`
- `<media:video>`
@ -312,24 +316,24 @@ WhatsApp не транслює вхідні payload хуків `message_received
- `<media:document>`
- `<media:sticker>`
Авторизовані групові голосові нотатки транскрибуються перед перевіркою згадки, коли
тіло містить лише `<media:audio>`, тому згадка бота, сказана в голосовій нотатці, може
запустити відповідь. Якщо транскрипт усе ще не згадує бота, його
зберігають в очікуваній історії групи замість сирого placeholder.
Авторизовані групові голосові нотатки транскрибуються перед gating за згадкою, коли
тіло містить лише `<media:audio>`, тому вимовлена згадка бота в голосовій нотатці може
запустити відповідь. Якщо транскрипт усе одно не згадує бота,
транскрипт зберігається в очікуваній історії групи замість сирого плейсхолдера.
Тіла локацій використовують стислий текст координат. Мітки/коментарі локацій і дані контактів/vCard відображаються як fenced untrusted metadata, а не як inline prompt text.
Тіла локацій використовують стислий текст координат. Мітки/коментарі локацій і деталі контактів/vCard відображаються як fenced недовірені метадані, а не як inline-текст prompt.
</Accordion>
<Accordion title="Pending group history injection">
Для груп необроблені повідомлення можуть буферизуватися й додаватися як контекст, коли бот нарешті спрацьовує.
<Accordion title="Ін’єкція очікуваної історії групи">
Для груп необроблені повідомлення можуть буферизуватися та ін’єктуватися як контекст, коли бот нарешті активується.
- стандартний ліміт: `50`
- конфігурація: `channels.whatsapp.historyLimit`
- fallback: `messages.groupChat.historyLimit`
- `0` вимикає
Маркери вставлення:
Маркери ін’єкції:
- `[Chat messages since your last reply - for context]`
- `[Current message - respond to this]`
@ -337,7 +341,7 @@ WhatsApp не транслює вхідні payload хуків `message_received
</Accordion>
<Accordion title="Read receipts">
Read receipts стандартно ввімкнені для прийнятих вхідних повідомлень WhatsApp.
Read receipts увімкнені за замовчуванням для прийнятих вхідних повідомлень WhatsApp.
Вимкнути глобально:
@ -367,56 +371,56 @@ WhatsApp не транслює вхідні payload хуків `message_received
}
```
Ходи self-chat пропускають read receipts, навіть коли їх глобально ввімкнено.
Turn чату із самим собою пропускають read receipts, навіть коли вони глобально ввімкнені.
</Accordion>
</AccordionGroup>
## Доставлення, chunking і медіа
## Доставка, chunking і медіа
<AccordionGroup>
<Accordion title="Text chunking">
- стандартний ліміт chunk: `channels.whatsapp.textChunkLimit = 4000`
<Accordion title="Поділ тексту на фрагменти">
- ліміт фрагмента за замовчуванням: `channels.whatsapp.textChunkLimit = 4000`
- `channels.whatsapp.chunkMode = "length" | "newline"`
- режим `newline` надає перевагу межам абзаців (порожнім рядкам), а потім переходить до chunking, безпечного за довжиною
- режим `newline` надає перевагу межам абзаців (порожнім рядкам), а потім повертається до безпечного за довжиною поділу на фрагменти
</Accordion>
<Accordion title="Поведінка вихідних медіа">
- підтримує зображення, відео, аудіо (голосову нотатку PTT) і документні payloads
- аудіомедіа надсилається через Baileys `audio` payload з `ptt: true`, тому клієнти WhatsApp відображають його як голосову нотатку push-to-talk
- payloads відповідей зберігають `audioAsVoice`; вивід голосової нотатки TTS для WhatsApp залишається на цьому PTT-шляху, навіть коли провайдер повертає MP3 або WebM
- підтримує корисні навантаження зображень, відео, аудіо (голосова нотатка PTT) і документів
- аудіомедіа надсилається через корисне навантаження Baileys `audio` з `ptt: true`, тому клієнти WhatsApp відображають його як голосову нотатку push-to-talk
- корисні навантаження відповідей зберігають `audioAsVoice`; вивід голосових нотаток TTS для WhatsApp залишається на цьому шляху PTT, навіть коли провайдер повертає MP3 або WebM
- нативне аудіо Ogg/Opus надсилається як `audio/ogg; codecs=opus` для сумісності з голосовими нотатками
- аудіо не у форматі Ogg, зокрема вивід Microsoft Edge TTS MP3/WebM, транскодується за допомогою `ffmpeg` у моно Ogg/Opus 48 кГц перед доставкою PTT
- `/tts latest` надсилає останню відповідь асистента як одну голосову нотатку й пригнічує повторні надсилання тієї самої відповіді; `/tts chat on|off|default` керує auto-TTS для поточного чату WhatsApp
- аудіо не у форматі Ogg, зокрема вивід Microsoft Edge TTS MP3/WebM, транскодується за допомогою `ffmpeg` у моно Ogg/Opus 48 кГц перед доставленням PTT
- `/tts latest` надсилає останню відповідь асистента як одну голосову нотатку й пригнічує повторне надсилання тієї самої відповіді; `/tts chat on|off|default` керує автоматичним TTS для поточного чату WhatsApp
- відтворення анімованих GIF підтримується через `gifPlayback: true` під час надсилання відео
- підписи застосовуються до першого медіаелемента під час надсилання payloads відповідей із кількома медіа, крім голосових нотаток PTT: вони надсилають аудіо спочатку, а видимий текст окремо, бо клієнти WhatsApp не завжди стабільно відображають підписи до голосових нотаток
- джерело медіа може бути HTTP(S), `file://` або локальними шляхами
- підписи застосовуються до першого медіаелемента під час надсилання корисних навантажень відповідей із кількома медіа, за винятком голосових нотаток PTT: аудіо надсилається першим, а видимий текст окремо, бо клієнти WhatsApp не відображають підписи до голосових нотаток послідовно
- джерелом медіа може бути HTTP(S), `file://` або локальні шляхи
</Accordion>
<Accordion title="Обмеження розміру медіа та поведінка fallback">
- обмеження збереження вхідних медіа: `channels.whatsapp.mediaMaxMb` (типово `50`)
- обмеження надсилання вихідних медіа: `channels.whatsapp.mediaMaxMb` (типово `50`)
<Accordion title="Обмеження розміру медіа та резервна поведінка">
- обмеження збереження вхідних медіа: `channels.whatsapp.mediaMaxMb` (за замовчуванням `50`)
- обмеження надсилання вихідних медіа: `channels.whatsapp.mediaMaxMb` (за замовчуванням `50`)
- перевизначення для окремого облікового запису використовують `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
- зображення автоматично оптимізуються (зміна розміру/підбір якості), щоб уміститися в обмеження
- у разі помилки надсилання медіа fallback для першого елемента надсилає текстове попередження, а не мовчки відкидає відповідь
- зображення автоматично оптимізуються (підбір розміру/якості), щоб відповідати обмеженням
- у разі помилки надсилання медіа резервний варіант для першого елемента надсилає текстове попередження замість тихого відкидання відповіді
</Accordion>
</AccordionGroup>
## Цитування відповіді
## Цитування у відповіді
WhatsApp підтримує нативне цитування відповідей, коли вихідні відповіді видимо цитують вхідне повідомлення. Керуйте цим за допомогою `channels.whatsapp.replyToMode`.
WhatsApp підтримує нативне цитування у відповіді, коли вихідні відповіді видимо цитують вхідне повідомлення. Керуйте цим за допомогою `channels.whatsapp.replyToMode`.
| Значення | Поведінка |
| ----------- | ------------------------------------------------------------------- |
| `"off"` | Ніколи не цитувати; надсилати як звичайне повідомлення |
| `"first"` | Цитувати лише перший фрагмент вихідної відповіді |
| `"all"` | Цитувати кожен фрагмент вихідної відповіді |
| ----------- | --------------------------------------------------------------------- |
| `"off"` | Ніколи не цитувати; надсилати як звичайне повідомлення |
| `"first"` | Цитувати лише перший фрагмент вихідної відповіді |
| `"all"` | Цитувати кожен фрагмент вихідної відповіді |
| `"batched"` | Цитувати поставлені в чергу пакетні відповіді, залишаючи негайні відповіді без цитування |
Типове значення — `"off"`. Перевизначення для окремого облікового запису використовують `channels.whatsapp.accounts.<id>.replyToMode`.
За замовчуванням використовується `"off"`. Перевизначення для окремого облікового запису використовують `channels.whatsapp.accounts.<id>.replyToMode`.
```json5
{
@ -430,16 +434,16 @@ WhatsApp підтримує нативне цитування відповіде
## Рівень реакцій
`channels.whatsapp.reactionLevel` керує тим, наскільки широко агент використовує emoji-реакції в WhatsApp:
`channels.whatsapp.reactionLevel` керує тим, наскільки широко агент використовує emoji-реакції у WhatsApp:
| Рівень | Реакції підтвердження | Реакції, ініційовані агентом | Опис |
| ------------ | --------------------- | ---------------------------- | ------------------------------------------------------ |
| `"off"` | Ні | Ні | Без реакцій узагалі |
| `"ack"` | Так | Ні | Лише реакції підтвердження (підтвердження отримання перед відповіддю) |
| `"minimal"` | Так | Так (консервативно) | Підтвердження + реакції агента з консервативними вказівками |
| `"extensive"` | Так | Так (заохочується) | Підтвердження + реакції агента із заохочувальними вказівками |
| Рівень | Реакції підтвердження | Реакції, ініційовані агентом | Опис |
| ------------- | ------------- | ------------------------- | ------------------------------------------------ |
| `"off"` | Ні | Ні | Без реакцій взагалі |
| `"ack"` | Так | Ні | Лише реакції підтвердження (отримання перед відповіддю) |
| `"minimal"` | Так | Так (консервативно) | Підтвердження + реакції агента з консервативними вказівками |
| `"extensive"` | Так | Так (заохочується) | Підтвердження + реакції агента із заохочувальними вказівками |
Типово: `"minimal"`.
За замовчуванням: `"minimal"`.
Перевизначення для окремого облікового запису використовують `channels.whatsapp.accounts.<id>.reactionLevel`.
@ -455,8 +459,8 @@ WhatsApp підтримує нативне цитування відповіде
## Реакції підтвердження
WhatsApp підтримує негайні реакції підтвердження на отримання вхідного повідомлення через `channels.whatsapp.ackReaction`.
Реакції підтвердження обмежуються `reactionLevel` — вони пригнічуються, коли `reactionLevel` дорівнює `"off"`.
WhatsApp підтримує негайні реакції підтвердження під час отримання вхідного повідомлення через `channels.whatsapp.ackReaction`.
Реакції підтвердження обмежуються `reactionLevel` — вони пригнічуються, коли `reactionLevel` має значення `"off"`.
```json5
{
@ -472,34 +476,34 @@ WhatsApp підтримує негайні реакції підтверджен
}
```
Нотатки щодо поведінки:
Примітки щодо поведінки:
- надсилаються негайно після прийняття вхідного повідомлення (перед відповіддю)
- помилки журналюються, але не блокують звичайну доставку відповіді
- груповий режим `mentions` реагує на ходи, запущені згадкою; групова активація `always` діє як обхід цієї перевірки
- надсилається негайно після прийняття вхідного повідомлення (перед відповіддю)
- помилки записуються в журнал, але не блокують звичайне доставлення відповіді
- груповий режим `mentions` реагує на ходи, спричинені згадкою; групова активація `always` обходить цю перевірку
- WhatsApp використовує `channels.whatsapp.ackReaction` (застарілий `messages.ackReaction` тут не використовується)
## Кілька облікових записів і облікові дані
<AccordionGroup>
<Accordion title="Вибір облікового запису та типові значення">
<Accordion title="Вибір облікового запису та значення за замовчуванням">
- ідентифікатори облікових записів беруться з `channels.whatsapp.accounts`
- типовий вибір облікового запису: `default`, якщо він є, інакше перший налаштований ідентифікатор облікового запису (відсортовано)
- вибір облікового запису за замовчуванням: `default`, якщо він є, інакше перший налаштований ідентифікатор облікового запису (у відсортованому порядку)
- ідентифікатори облікових записів внутрішньо нормалізуються для пошуку
</Accordion>
<Accordion title="Шляхи облікових даних і сумісність із застарілими версіями">
<Accordion title="Шляхи до облікових даних і сумісність із застарілими версіями">
- поточний шлях автентифікації: `~/.openclaw/credentials/whatsapp/<accountId>/creds.json`
- файл резервної копії: `creds.json.bak`
- застаріла типова автентифікація в `~/.openclaw/credentials/` усе ще розпізнається/мігрується для потоків типового облікового запису
- застаріла автентифікація за замовчуванням у `~/.openclaw/credentials/` досі розпізнається/мігрується для потоків облікового запису за замовчуванням
</Accordion>
<Accordion title="Поведінка виходу">
`openclaw channels logout --channel whatsapp [--account <id>]` очищає стан автентифікації WhatsApp для цього облікового запису.
Коли Gateway доступний, вихід спочатку зупиняє активний слухач WhatsApp для вибраного облікового запису, щоб пов’язана сесія не продовжувала отримувати повідомлення до наступного перезапуску. `openclaw channels remove --channel whatsapp` також зупиняє активний слухач перед вимкненням або видаленням конфігурації облікового запису.
Коли Gateway доступний, вихід спершу зупиняє активний прослуховувач WhatsApp для вибраного облікового запису, щоб прив'язаний сеанс не продовжував отримувати повідомлення до наступного перезапуску. `openclaw channels remove --channel whatsapp` також зупиняє активний прослуховувач перед вимкненням або видаленням конфігурації облікового запису.
У застарілих каталогах автентифікації `oauth.json` зберігається, а файли автентифікації Baileys видаляються.
@ -509,16 +513,16 @@ WhatsApp підтримує негайні реакції підтверджен
## Інструменти, дії та записи конфігурації
- Підтримка інструментів агента включає дію реакції WhatsApp (`react`).
- Обмежувачі дій:
- Обмеження дій:
- `channels.whatsapp.actions.reactions`
- `channels.whatsapp.actions.polls`
- Записи конфігурації, ініційовані каналом, увімкнені типово (вимкніть через `channels.whatsapp.configWrites=false`).
- Записи конфігурації, ініційовані каналом, увімкнені за замовчуванням (вимикаються через `channels.whatsapp.configWrites=false`).
## Усунення несправностей
<AccordionGroup>
<Accordion title="Не пов’язано (потрібен QR)">
Симптом: статус каналу повідомляє, що його не пов’язано.
<Accordion title="Не прив'язано (потрібен QR)">
Симптом: статус каналу повідомляє, що його не прив'язано.
Виправлення:
@ -529,17 +533,17 @@ WhatsApp підтримує негайні реакції підтверджен
</Accordion>
<Accordion title=ов’язано, але від’єднано / цикл повторного підключення">
Симптом: пов’язаний обліковий запис із повторними від’єднаннями або спробами повторного підключення.
<Accordion title=рив'язано, але від'єднано / цикл повторного підключення">
Симптом: прив'язаний обліковий запис із повторюваними від'єднаннями або спробами повторного підключення.
Тихі облікові записи можуть залишатися підключеними після звичайного тайм-ауту повідомлень; watchdog
перезапускається, коли активність транспорту WhatsApp Web припиняється, сокет закривається або
активність на рівні застосунку залишається тихою довше за довше безпечне вікно.
Неактивні облікові записи можуть залишатися підключеними після звичайного таймауту повідомлень; сторожовий механізм
перезапускається, коли транспортна активність WhatsApp Web зупиняється, сокет закривається або
активність на рівні застосунку мовчить довше за триваліше вікно безпеки.
Якщо журнали показують повторювані `status=408 Request Time-out Connection was lost`, налаштуйте
Якщо журнали показують повторюване `status=408 Request Time-out Connection was lost`, налаштуйте
таймінги сокета Baileys у `web.whatsapp`. Почніть зі скорочення
`keepAliveIntervalMs` нижче за тайм-аут простою вашої мережі та збільшення
`connectTimeoutMs` на повільних або нестабільних зєднаннях:
`keepAliveIntervalMs` нижче таймауту простою вашої мережі та збільшення
`connectTimeoutMs` на повільних або нестабільних з'єднаннях:
```json5
{
@ -562,85 +566,85 @@ WhatsApp підтримує негайні реакції підтверджен
Якщо `~/.openclaw/logs/whatsapp-health.log` повідомляє `Gateway inactive`, але
`openclaw gateway status` і `openclaw channels status --probe` показують, що
Gateway і WhatsApp справні, запустіть `openclaw doctor`. У Linux doctor
Gateway і WhatsApp справні, запустіть `openclaw doctor`. На Linux doctor
попереджає про застарілі записи crontab, які досі викликають
`~/.openclaw/bin/ensure-whatsapp.sh`; видаліть ці застарілі записи за допомогою
`crontab -e`, бо cron може не мати середовища користувацької шини systemd і
змушувати цей старий скрипт неправильно повідомляти про стан Gateway.
змушувати той старий скрипт неправильно повідомляти про стан Gateway.
За потреби повторно пов’яжіть за допомогою `channels login`.
За потреби повторно прив'яжіть через `channels login`.
</Accordion>
<Accordion title="Вхід за QR завершується тайм-аутом за проксі">
Симптом: `openclaw channels login --channel whatsapp` завершується помилкою до показу придатного QR-коду з `status=408 Request Time-out` або від’єднанням TLS-сокета.
<Accordion title="Вхід за QR завершується таймаутом за проксі">
Симптом: `openclaw channels login --channel whatsapp` завершується помилкою до показу придатного QR-коду з `status=408 Request Time-out` або розривом TLS-сокета.
Вхід у WhatsApp Web використовує стандартне проксі-середовище хоста Gateway (`HTTPS_PROXY`, `HTTP_PROXY`, варіанти в нижньому регістрі та `NO_PROXY`). Перевірте, що процес Gateway успадковує env проксі й що `NO_PROXY` не збігається з `mmg.whatsapp.net`.
Вхід WhatsApp Web використовує стандартне проксі-середовище хоста Gateway (`HTTPS_PROXY`, `HTTP_PROXY`, варіанти в нижньому регістрі та `NO_PROXY`). Перевірте, що процес Gateway успадковує proxy env і що `NO_PROXY` не збігається з `mmg.whatsapp.net`.
</Accordion>
<Accordion title="Немає активного слухача під час надсилання">
Вихідні надсилання швидко завершуються помилкою, коли для цільового облікового запису немає активного слухача Gateway.
<Accordion title="Немає активного прослуховувача під час надсилання">
Вихідні надсилання швидко завершуються помилкою, коли для цільового облікового запису немає активного прослуховувача Gateway.
Переконайтеся, що Gateway запущено, а обліковий запис пов’язано.
Переконайтеся, що Gateway запущено, а обліковий запис прив'язано.
</Accordion>
<Accordion title="Відповідь зявляється в транскрипті, але не в WhatsApp">
Рядки транскрипта записують те, що згенерував агент. Доставка WhatsApp перевіряється окремо: OpenClaw вважає автоматичну відповідь надісланою лише після того, як Baileys поверне ідентифікатор вихідного повідомлення принаймні для одного видимого текстового або медіанадсилання.
<Accordion title="Відповідь з'являється в транскрипті, але не в WhatsApp">
Рядки транскрипта записують те, що згенерував агент. Доставлення WhatsApp перевіряється окремо: OpenClaw вважає автовідповідь надісланою лише після того, як Baileys поверне ідентифікатор вихідного повідомлення принаймні для одного надсилання видимого тексту або медіа.
Реакції підтвердження є незалежними підтвердженнями отримання перед відповіддю. Успішна реакція не доводить, що пізнішу текстову або медіавідповідь було прийнято WhatsApp.
Реакції підтвердження є незалежними отриманнями перед відповіддю. Успішна реакція не доводить, що пізніша текстова або медіавідповідь була прийнята WhatsApp.
Перевірте журнали Gateway на `auto-reply delivery failed` або `auto-reply was not accepted by WhatsApp provider`.
</Accordion>
<Accordion title="Групові повідомлення несподівано ігноруються">
Перевірте в такому порядку:
Перевіряйте в такому порядку:
- `groupPolicy`
- `groupAllowFrom` / `allowFrom`
- записи allowlist у `groups`
- обмеження за згадкою (`requireMention` + шаблони згадок)
- дублікати ключів в `openclaw.json` (JSON5): пізніші записи перевизначають попередні, тому зберігайте один `groupPolicy` для кожної області
- записи списку дозволених `groups`
- обмеження за згадками (`requireMention` + шаблони згадок)
- дублікати ключів у `openclaw.json` (JSON5): пізніші записи перевизначають попередні, тому зберігайте один `groupPolicy` на область
</Accordion>
<Accordion title="Попередження середовища виконання Bun">
Середовище виконання WhatsApp gateway має використовувати Node. Bun позначено як несумісний зі стабільною роботою WhatsApp/Telegram gateway.
<Accordion title="Попередження про середовище виконання Bun">
Середовище виконання WhatsApp Gateway має використовувати Node. Bun позначено як несумісний для стабільної роботи WhatsApp/Telegram Gateway.
</Accordion>
</AccordionGroup>
## Системні prompts
## Системні промпти
WhatsApp підтримує системні prompts у стилі Telegram для груп і прямих чатів через мапи `groups` і `direct`.
WhatsApp підтримує системні промпти в стилі Telegram для груп і прямих чатів через мапи `groups` і `direct`.
Ієрархія розв’язання для групових повідомлень:
Ієрархія вирішення для групових повідомлень:
Ефективна мапа `groups` визначається спочатку: якщо обліковий запис визначає власні `groups`, вона повністю замінює кореневу мапу `groups` (без глибокого злиття). Потім пошук prompt виконується в отриманій єдиній мапі:
Ефективна мапа `groups` визначається першою: якщо обліковий запис визначає власну `groups`, вона повністю замінює кореневу мапу `groups` (без глибокого злиття). Потім пошук промпта виконується на отриманій єдиній мапі:
1. **Системний prompt для конкретної групи** (`groups["<groupId>"].systemPrompt`): використовується, коли конкретний запис групи існує в мапі **і** його ключ `systemPrompt` визначено. Якщо `systemPrompt` є порожнім рядком (`""`), wildcard пригнічується й системний prompt не застосовується.
2. **Wildcard системний prompt групи** (`groups["*"].systemPrompt`): використовується, коли конкретний запис групи повністю відсутній у мапі або коли він існує, але не визначає ключ `systemPrompt`.
1. **Системний промпт для конкретної групи** (`groups["<groupId>"].systemPrompt`): використовується, коли запис конкретної групи існує в мапі **і** його ключ `systemPrompt` визначено. Якщо `systemPrompt` є порожнім рядком (`""`), підстановочний шаблон пригнічується й системний промпт не застосовується.
2. **Груповий системний промпт із підстановочним шаблоном** (`groups["*"].systemPrompt`): використовується, коли запис конкретної групи повністю відсутній у мапі або коли він існує, але не визначає ключ `systemPrompt`.
Ієрархія розв’язання для прямих повідомлень:
Ієрархія вирішення для прямих повідомлень:
Ефективна мапа `direct` визначається спочатку: якщо обліковий запис визначає власні `direct`, вона повністю замінює кореневу мапу `direct` (без глибокого злиття). Потім пошук prompt виконується в отриманій єдиній мапі:
Ефективна мапа `direct` визначається першою: якщо обліковий запис визначає власну `direct`, вона повністю замінює кореневу мапу `direct` (без глибокого злиття). Потім пошук промпта виконується на отриманій єдиній мапі:
1. **Системний prompt для конкретного direct** (`direct["<peerId>"].systemPrompt`): використовується, коли конкретний запис peer існує в мапі **і** його ключ `systemPrompt` визначено. Якщо `systemPrompt` є порожнім рядком (`""`), wildcard пригнічується й системний prompt не застосовується.
2. **Wildcard системний prompt direct** (`direct["*"].systemPrompt`): використовується, коли конкретний запис peer повністю відсутній у мапі або коли він існує, але не визначає ключ `systemPrompt`.
1. **Системний промпт для конкретного прямого чату** (`direct["<peerId>"].systemPrompt`): використовується, коли запис конкретного співрозмовника існує в мапі **і** його ключ `systemPrompt` визначено. Якщо `systemPrompt` є порожнім рядком (`""`), підстановочний шаблон пригнічується й системний промпт не застосовується.
2. **Системний промпт із підстановочним шаблоном для прямих чатів** (`direct["*"].systemPrompt`): використовується, коли запис конкретного співрозмовника повністю відсутній у мапі або коли він існує, але не визначає ключ `systemPrompt`.
<Note>
`dms` залишається легким контейнером перевизначення історії для окремих DM (`dms.<id>.historyLimit`). Перевизначення prompt розміщуються в `direct`.
`dms` залишається легким контейнером перевизначення історії для кожного приватного чату (`dms.<id>.historyLimit`). Перевизначення промптів розміщуються в `direct`.
</Note>
**Відмінність від поведінки Telegram із кількома обліковими записами:** У Telegram кореневі `groups` навмисно пригнічуються для всіх облікових записів у конфігурації з кількома обліковими записами — навіть для облікових записів, які не визначають власні `groups`, — щоб запобігти отриманню ботом групових повідомлень для груп, до яких він не належить. WhatsApp не застосовує цей запобіжник: кореневі `groups` і кореневі `direct` завжди успадковуються обліковими записами, які не визначають перевизначення на рівні облікового запису, незалежно від кількості налаштованих облікових записів. У конфігурації WhatsApp із кількома обліковими записами, якщо вам потрібні prompts для груп або direct для окремого облікового запису, явно визначте повну мапу в кожному обліковому записі, а не покладайтеся на кореневі типові значення.
**Відмінність від поведінки кількох акаунтів у Telegram:** У Telegram кореневі `groups` навмисно пригнічуються для всіх акаунтів у конфігурації з кількома акаунтами — навіть для акаунтів, які не визначають власних `groups`, — щоб запобігти отриманню ботом групових повідомлень із груп, до яких він не належить. WhatsApp не застосовує цей запобіжник: кореневі `groups` і кореневі `direct` завжди успадковуються акаунтами, які не визначають перевизначення на рівні акаунта, незалежно від кількості налаштованих акаунтів. У конфігурації WhatsApp з кількома акаунтами, якщо вам потрібні окремі для кожного акаунта групові або прямі промпти, явно визначте повну мапу під кожним акаунтом, а не покладайтеся на кореневі типові значення.
Важлива поведінка:
- `channels.whatsapp.groups` є одночасно мапою конфігурації для окремих груп і списком дозволених груп на рівні чату. На кореневому рівні або в межах облікового запису `groups["*"]` означає «усі групи допущено» для цієї області.
- Додавайте wildcard-групу `systemPrompt` лише тоді, коли ви вже хочете, щоб ця область допускала всі групи. Якщо ви все ще хочете, щоб придатним був лише фіксований набір ID груп, не використовуйте `groups["*"]` для стандартного промпта. Натомість повторіть промпт у кожному явно дозволеному записі групи.
- Допуск групи та авторизація відправника є окремими перевірками. `groups["*"]` розширює набір груп, які можуть потрапити до обробки груп, але сам по собі не авторизує кожного відправника в цих групах. Доступ відправників усе ще окремо контролюється `channels.whatsapp.groupPolicy` і `channels.whatsapp.groupAllowFrom`.
- `channels.whatsapp.direct` не має такого самого побічного ефекту для особистих повідомлень. `direct["*"]` лише надає стандартну конфігурацію прямого чату після того, як особисте повідомлення вже допущено через `dmPolicy` плюс `allowFrom` або правила сховища сполучень.
- `channels.whatsapp.groups` є одночасно мапою конфігурації для кожної групи та списком дозволених груп на рівні чату. На кореневому рівні або в межах акаунта `groups["*"]` означає «усі групи допускаються» для цієї області.
- Додавайте wildcard-групу `systemPrompt` лише тоді, коли ви вже хочете, щоб ця область допускала всі групи. Якщо ви все ще хочете, щоб прийнятним був лише фіксований набір ID груп, не використовуйте `groups["*"]` як типовий промпт. Натомість повторіть промпт у кожному явно дозволеному записі групи.
- Допуск групи й авторизація відправника є окремими перевірками. `groups["*"]` розширює набір груп, які можуть потрапити до обробки груп, але сам по собі не авторизує кожного відправника в цих групах. Доступ відправника й надалі окремо контролюється `channels.whatsapp.groupPolicy` і `channels.whatsapp.groupAllowFrom`.
- `channels.whatsapp.direct` не має такого самого побічного ефекту для особистих повідомлень. `direct["*"]` лише надає типову конфігурацію прямого чату після того, як DM уже допущено через `dmPolicy` разом із `allowFrom` або правилами сховища сполучень.
Приклад:
@ -682,19 +686,19 @@ WhatsApp підтримує системні prompts у стилі Telegram дл
}
```
## Вказівники на довідку з конфігурації
## Вказівники до довідника конфігурації
Основна довідка:
Основний довідник:
- [Довідка з конфігурації - WhatsApp](/uk/gateway/config-channels#whatsapp)
- [Довідник конфігурації - WhatsApp](/uk/gateway/config-channels#whatsapp)
Найважливіші поля WhatsApp:
- доступ: `dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`, `groups`
- доставлення: `textChunkLimit`, `chunkMode`, `mediaMaxMb`, `sendReadReceipts`, `ackReaction`, `reactionLevel`
- кілька облікових записів: `accounts.<id>.enabled`, `accounts.<id>.authDir`, перевизначення на рівні облікового запису
- доставка: `textChunkLimit`, `chunkMode`, `mediaMaxMb`, `sendReadReceipts`, `ackReaction`, `reactionLevel`
- кілька акаунтів: `accounts.<id>.enabled`, `accounts.<id>.authDir`, перевизначення на рівні акаунта
- операції: `configWrites`, `debounceMs`, `web.enabled`, `web.heartbeatSeconds`, `web.reconnect.*`, `web.whatsapp.*`
- поведінка сеансу: `session.dmScope`, `historyLimit`, `dmHistoryLimit`, `dms.<id>.historyLimit`
- поведінка сесії: `session.dmScope`, `historyLimit`, `dmHistoryLimit`, `dms.<id>.historyLimit`
- промпти: `groups.<id>.systemPrompt`, `groups["*"].systemPrompt`, `direct.<id>.systemPrompt`, `direct["*"].systemPrompt`
## Пов’язане

View File

@ -1,75 +1,93 @@
---
read_when:
- Потрібно зрозуміти, чому завдання CI було або не було запущено
- Ви налагоджуєте перевірку GitHub Actions, яка не проходить
- Вам потрібно з'ясувати, чому завдання CI запустилося або не запустилося.
- Ви налагоджуєте невдалу перевірку GitHub Actions
- Ви координуєте запуск або повторний запуск валідації релізу
summary: Граф завдань CI, гейти за областю дії, парасолькові релізні перевірки та локальні еквіваленти команд
- Ви змінюєте диспетчеризацію ClawSweeper або пересилання активності GitHub
summary: Граф завдань CI, контрольні перевірки за областю, релізні набори та локальні еквіваленти команд
title: CI-конвеєр
x-i18n:
generated_at: "2026-05-01T23:38:38Z"
generated_at: "2026-05-02T01:24:16Z"
model: gpt-5.5
provider: openai
source_hash: e3aeba9260d2eb6b65f1775d457f3dd7c5470ba628e9234409e3a8483a453b48
source_hash: d7312e6367d24a5f61546fa84c3a281124d463821332ae11ac7bbbbab83cb8d4
source_path: ci.md
workflow: 16
---
OpenClaw CI запускається на кожному push до `main` і для кожного pull request. Завдання `preflight` класифікує diff і вимикає витратні lanes, коли змінилися лише непов’язані області. Ручні запуски `workflow_dispatch` навмисно обходять розумне обмеження області та розгортають повний граф для release candidates і широкої валідації. Android lanes залишаються opt-in через `include_android`. Покриття Plugin лише для релізу розміщене в окремому workflow [`Plugin передвипуск`](#plugin-prerelease) і запускається лише з [`Повна валідація релізу`](#full-release-validation) або явного ручного dispatch.
OpenClaw CI запускається під час кожного push до `main` і для кожного pull request. Завдання `preflight` класифікує diff і вимикає дорогі lanes, коли змінено лише непов’язані області. Ручні запуски `workflow_dispatch` навмисно обходять smart scoping і розгортають повний граф для release candidates і широкої валідації. Android lanes залишаються opt-in через `include_android`. Покриття Plugin лише для release міститься в окремому workflow [`Plugin Prerelease`](#plugin-prerelease) і запускається лише з [`Full Release Validation`](#full-release-validation) або явного ручного dispatch.
## Огляд pipeline
| Завдання | Призначення | Коли запускається |
| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
| `preflight` | Виявляє зміни лише в docs, змінені області, змінені extensions і будує CI manifest | Завжди для non-draft pushes і PRs |
| `preflight` | Виявляє зміни лише в docs, змінені scopes, змінені extensions і будує CI manifest | Завжди для non-draft pushes і PRs |
| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для non-draft pushes і PRs |
| `security-dependency-audit` | Production-аудит lockfile без dependencies за npm advisories | Завжди для non-draft pushes і PRs |
| `security-fast` | Обов’язковий агрегат для швидких security jobs | Завжди для non-draft pushes і PRs |
| `check-dependencies` | Production-прохід Knip лише для dependencies плюс guard allowlist невикористаних файлів | Зміни, релевантні для Node |
| `build-artifacts` | Збірка `dist/`, Control UI, перевірки built artifacts і reusable downstream artifacts | Зміни, релевантні для Node |
| `checks-fast-core` | Швидкі Linux correctness lanes, як-от bundled/plugin-contract/protocol checks | Зміни, релевантні для Node |
| `checks-fast-contracts-channels` | Sharded перевірки channel contract зі стабільним aggregate check result | Зміни, релевантні для Node |
| `checks-node-core-test` | Core Node test shards, крім channel, bundled, contract і extension lanes | Зміни, релевантні для Node |
| `check` | Sharded еквівалент основного локального 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` | Smoke tests зібраного CLI і startup-memory smoke | Зміни, релевантні для Node |
| `checks` | Verifier для built-artifact channel tests | Зміни, релевантні для Node |
| `checks-node-compat-node22` | Збірка сумісності з Node 22 і smoke lane | Ручний CI dispatch для релізів |
| `check-docs` | Форматування docs, lint і перевірки broken links | Змінено docs |
| `skills-python` | Ruff + pytest для Skills на основі Python | Зміни, релевантні для Python Skills |
| `checks-windows` | Специфічні для Windows process/path tests плюс спільні regressions runtime import specifier | Зміни, релевантні для Windows |
| `macos-node` | macOS TypeScript test lane із використанням спільних built artifacts | Зміни, релевантні для macOS |
| `macos-swift` | Swift lint, build і tests для застосунку macOS | Зміни, релевантні для macOS |
| `android` | Android unit tests для обох flavors плюс одна debug APK build | Зміни, релевантні для Android |
| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після trusted activity | Успішний main CI або ручний dispatch |
| `security-dependency-audit` | Production lockfile audit без залежностей щодо npm advisories | Завжди для non-draft pushes і PRs |
| `security-fast` | Обов’язковий aggregate для fast security jobs | Завжди для non-draft pushes і PRs |
| `check-dependencies` | Production Knip dependency-only pass плюс guard allowlist невикористаних файлів | Node-relevant changes |
| `build-artifacts` | Будує `dist/`, Control UI, built-artifact checks і reusable downstream artifacts | Node-relevant changes |
| `checks-fast-core` | Fast Linux correctness lanes, як-от bundled/plugin-contract/protocol checks | Node-relevant changes |
| `checks-fast-contracts-channels` | Sharded channel contract checks зі стабільним aggregate check result | Node-relevant changes |
| `checks-node-core-test` | Core Node test shards, крім channel, bundled, contract і extension lanes | Node-relevant changes |
| `check` | Sharded main local gate equivalent: prod types, lint, guards, test types і strict smoke | Node-relevant changes |
| `check-additional` | Architecture, boundary, extension-surface guards, package-boundary і gateway-watch shards | Node-relevant changes |
| `build-smoke` | Built-CLI smoke tests і startup-memory smoke | Node-relevant changes |
| `checks` | Verifier для built-artifact channel tests | Node-relevant changes |
| `checks-node-compat-node22` | Node 22 compatibility build і smoke lane | Manual CI dispatch for releases |
| `check-docs` | Docs formatting, lint і broken-link checks | Docs changed |
| `skills-python` | Ruff + pytest для Python-backed skills | Python-skill-relevant changes |
| `checks-windows` | Windows-specific process/path tests плюс shared runtime import specifier regressions | Windows-relevant changes |
| `macos-node` | macOS TypeScript test lane з використанням shared built artifacts | macOS-relevant changes |
| `macos-swift` | Swift lint, build і tests для macOS app | macOS-relevant changes |
| `android` | Android unit tests для обох flavors плюс одна збірка debug APK | Android-relevant changes |
| `test-performance-agent` | Щоденна оптимізація Codex slow-test після trusted activity | Main CI success або manual dispatch |
## Порядок fail-fast
1. `preflight` вирішує, які lanes взагалі існують. Логіка `docs-scope` і `changed-scope` є кроками всередині цього завдання, а не окремими jobs.
2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` швидко падають, не чекаючи важчих artifact і platform matrix jobs.
3. `build-artifacts` перекривається зі швидкими Linux lanes, щоб downstream consumers могли стартувати щойно спільна збірка буде готова.
4. Після цього розгортаються важчі platform і runtime lanes: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-core-test`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`.
1. `preflight` вирішує, які lanes взагалі існують. Логіка `docs-scope` і `changed-scope` є кроками всередині цього завдання, а не окремими завданнями.
2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` швидко завершуються з помилкою, не чекаючи на важчі artifact і platform matrix jobs.
3. `build-artifacts` перекривається з fast Linux lanes, щоб downstream consumers могли стартувати, щойно shared build буде готовий.
4. Важчі platform і runtime lanes розгортаються після цього: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-core-test`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`.
GitHub може позначати замінені jobs як `cancelled`, коли новіший push потрапляє в той самий PR або ref `main`. Вважайте це шумом CI, якщо найновіший run для того самого ref також не падає. Aggregate shard checks використовують `!cancelled() && always()`, тому вони все одно повідомляють звичайні shard failures, але не стають у чергу після того, як увесь workflow уже було замінено. Автоматичний CI concurrency key версіонований (`CI-v7-*`), щоб GitHub-side zombie у старій queue group не міг безкінечно блокувати новіші main runs. Ручні full-suite runs використовують `CI-manual-v1-*` і не скасовують runs, що вже виконуються.
GitHub може позначати замінені jobs як `cancelled`, коли новіший push потрапляє в той самий PR або ref `main`. Сприймайте це як шум CI, якщо найновіший run для того самого ref також не падає. Aggregate shard checks використовують `!cancelled() && always()`, тож вони все одно повідомляють про звичайні shard failures, але не стають у чергу після того, як увесь workflow уже був замінений. Автоматичний CI concurrency key версіонований (`CI-v7-*`), тож GitHub-side zombie у старій queue group не може безкінечно блокувати новіші main runs. Manual full-suite runs використовують `CI-manual-v1-*` і не скасовують in-progress runs.
## Область і routing
## Scope і routing
Логіка області розміщена в `scripts/ci-changed-scope.mjs` і покрита unit tests у `src/scripts/ci-changed-scope.test.ts`. Manual dispatch пропускає changed-scope detection і змушує preflight manifest поводитися так, ніби змінилася кожна scoped area.
Логіка scope міститься в `scripts/ci-changed-scope.mjs` і покрита unit tests у `src/scripts/ci-changed-scope.test.ts`. Manual dispatch пропускає changed-scope detection і змушує preflight manifest поводитися так, ніби змінилась кожна scoped area.
- **Редагування CI workflow** валідують граф Node CI плюс workflow linting, але самі по собі не примушують Windows, Android або macOS native builds; ці platform lanes залишаються прив’язаними до змін platform source.
- **Редагування лише CI routing, вибрані дешеві редагування core-test fixtures і вузькі редагування plugin contract helper/test-routing** використовують швидкий Node-only manifest path: `preflight`, security і одне завдання `checks-fast-core`. Цей path пропускає build artifacts, сумісність із Node 22, channel contracts, повні core shards, bundled-plugin shards і additional guard matrices, коли зміна обмежена routing або helper surfaces, які fast task перевіряє напряму.
- **Windows Node checks** обмежені специфічними для Windows process/path wrappers, npm/pnpm/UI runner helpers, package manager config і поверхнями CI workflow, які виконують цю lane; непов’язані source, plugin, install-smoke і test-only зміни залишаються на Linux Node lanes.
- **Зміни CI workflow** валідують Node CI graph плюс workflow linting, але самі по собі не примушують запускати Windows, Android або macOS native builds; ці platform lanes залишаються scoped до platform source changes.
- **CI routing-only edits, selected cheap core-test fixture edits і narrow plugin contract helper/test-routing edits** використовують fast Node-only manifest path: `preflight`, security і одне завдання `checks-fast-core`. Цей шлях пропускає build artifacts, Node 22 compatibility, channel contracts, full core shards, bundled-plugin shards і additional guard matrices, коли зміна обмежена routing або helper surfaces, які fast task перевіряє безпосередньо.
- **Windows Node checks** scoped до Windows-specific process/path wrappers, npm/pnpm/UI runner helpers, package manager config і CI workflow surfaces, які виконують цю lane; непов’язані source, plugin, install-smoke і test-only changes залишаються на Linux Node lanes.
Найповільніші сімейства Node tests розділені або збалансовані, щоб кожне завдання залишалося малим без надмірного резервування runners: channel contracts запускаються як три weighted shards, малі 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. Широкі browser, QA, media і miscellaneous plugin tests використовують свої dedicated Vitest configs замість спільного plugin catch-all. Include-pattern shards записують timing entries із використанням CI shard name, тому `.artifacts/vitest-shard-timings.json` може відрізнити whole config від filtered shard. `check-additional` тримає package-boundary compile/canary work разом і відокремлює runtime topology architecture від gateway watch coverage; boundary guard shard запускає свої малі незалежні guards паралельно всередині одного job. Gateway watch, channel tests і core support-boundary shard запускаються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані.
Найповільніші Node test families розділені або збалансовані, щоб кожне завдання залишалося невеликим без надмірного резервування runners: channel contracts запускаються як три weighted shards, 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. Include-pattern shards записують timing entries із використанням CI shard name, щоб `.artifacts/vitest-shard-timings.json` міг відрізнити цілий config від filtered shard. `check-additional` тримає package-boundary compile/canary work разом і відокремлює runtime topology architecture від gateway watch coverage; boundary guard shard запускає свої small independent guards паралельно в одному job. Gateway watch, channel tests і core support-boundary shard запускаються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані.
Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Third-party flavor не має окремого source set або manifest; його unit-test lane все одно компілює flavor з прапорцями SMS/call-log BuildConfig, водночас уникаючи дублювання debug APK packaging job на кожному Android-relevant push.
Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Third-party flavor не має окремого source set або manifest; його unit-test lane все одно компілює flavor з BuildConfig flags для SMS/call-log, уникаючи дублювання debug APK packaging job на кожному Android-relevant push.
Shard `check-dependencies` запускає `pnpm deadcode:dependencies` (production-прохід Knip лише для dependencies, закріплений на найновішій версії Knip, із вимкненим мінімальним віком release для pnpm під час `dlx` install) і `pnpm deadcode:unused-files`, який порівнює production unused-file findings Knip із `scripts/deadcode-unused-files.allowlist.mjs`. Guard unused-file падає, коли PR додає новий непереглянутий unused file або залишає застарілий allowlist entry, водночас зберігаючи intentional dynamic plugin, generated, build, live-test і package bridge surfaces, які Knip не може розв’язати статично.
Shard `check-dependencies` запускає `pnpm deadcode:dependencies` (production Knip dependency-only pass, pinned до найновішої версії Knip, із вимкненим pnpm minimum release age для встановлення `dlx`) і `pnpm deadcode:unused-files`, який порівнює production unused-file findings Knip із `scripts/deadcode-unused-files.allowlist.mjs`. Unused-file guard падає, коли PR додає новий неперевірений unused file або залишає stale allowlist entry, водночас зберігаючи навмисні dynamic plugin, generated, build, live-test і package bridge surfaces, які Knip не може розв’язати статично.
## Ручні dispatches
## Пересилання активності ClawSweeper
Ручні CI dispatches запускають той самий job graph, що й звичайний CI, але примусово вмикають кожну non-Android scoped lane: Linux Node shards, bundled-plugin shards, channel contracts, сумісність із Node 22, `check`, `check-additional`, build smoke, docs checks, Python skills, Windows, macOS і Control UI i18n. Окремі ручні CI dispatches запускають Android лише з `include_android=true`; повна release umbrella вмикає Android, передаючи `include_android=true`. Plugin prerelease static checks, release-only shard `agentic-plugins`, повний extension batch sweep і plugin prerelease Docker lanes виключені з CI. Docker prerelease suite запускається лише тоді, коли `Full Release Validation` dispatches окремий workflow `Plugin Prerelease` із увімкненим release-validation gate.
`.github/workflows/clawsweeper-dispatch.yml` є target-side bridge з активності репозиторію OpenClaw до ClawSweeper. Він не виконує checkout і не запускає ненадійний pull request code. Workflow створює GitHub App token з `CLAWSWEEPER_APP_PRIVATE_KEY`, а потім надсилає compact `repository_dispatch` payloads до `openclaw/clawsweeper`.
Ручні runs використовують унікальну concurrency group, щоб release-candidate full suite не було скасовано іншим push або PR run на тому самому ref. Необов’язковий input `target_ref` дає змогу trusted caller запустити цей граф для branch, tag або full commit SHA, використовуючи workflow file з вибраного dispatch ref.
Workflow має чотири lanes:
- `clawsweeper_item` для точних issue і pull request review requests;
- `clawsweeper_comment` для явних команд ClawSweeper у issue comments;
- `clawsweeper_commit_review` для commit-level review requests на `main` pushes;
- `github_activity` для загальної GitHub activity, яку ClawSweeper agent може перевіряти.
Lane `github_activity` пересилає лише normalized metadata: event type, action, actor, repository, item number, URL, title, state і short excerpts для comments або reviews, коли вони присутні. Він навмисно не пересилає повне webhook body. Receiving workflow в `openclaw/clawsweeper``.github/workflows/github-activity.yml`, який публікує normalized event до OpenClaw Gateway hook для ClawSweeper agent.
General activity — це observation, а не delivery-by-default. ClawSweeper agent отримує Discord target у своєму prompt і має публікувати в `#clawsweeper` лише коли подія є несподіваною, actionable, risky або operationally useful. Routine opens, edits, bot churn, duplicate webhook noise і normal review traffic мають завершуватися `NO_REPLY`.
Сприймайте GitHub titles, comments, bodies, review text, branch names і commit messages як ненадійні дані в усьому цьому path. Це input для summarization і triage, а не instructions для workflow або agent runtime.
## Manual dispatches
Manual CI dispatches запускають той самий job graph, що й normal CI, але примусово вмикають кожну non-Android scoped lane: Linux Node shards, bundled-plugin shards, channel contracts, Node 22 compatibility, `check`, `check-additional`, build smoke, docs checks, Python skills, Windows, macOS і Control UI i18n. Standalone manual CI dispatches запускають Android лише з `include_android=true`; full release umbrella вмикає Android, передаючи `include_android=true`. Plugin prerelease static checks, release-only shard `agentic-plugins`, full extension batch sweep і plugin prerelease Docker lanes виключені з CI. Docker prerelease suite запускається лише коли `Full Release Validation` dispatches окремий workflow `Plugin Prerelease` із увімкненим release-validation gate.
Manual runs використовують унікальну concurrency group, щоб release-candidate full suite не скасовувався іншим push або PR run на тому самому ref. Опціональний input `target_ref` дає trusted caller змогу запускати цей graph для branch, tag або full commit SHA, використовуючи workflow file з вибраного dispatch ref.
```bash
gh workflow run ci.yml --ref release/YYYY.M.D
@ -77,19 +95,19 @@ gh workflow run ci.yml --ref main -f target_ref=<branch-or-sha> -f include_andro
gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>
```
## Runners
## Ранери
| Виконавець | Завдання |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ubuntu-24.04` | `preflight`, швидкі завдання безпеки та агрегати (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі перевірки протоколу/контракту/вбудованих компонентів, сегментовані перевірки контрактів каналів, сегменти `check`, крім lint, сегменти й агрегати `check-additional`, агреговані верифікатори тестів Node, перевірки документації, Python skills, workflow-sanity, labeler, auto-response; install-smoke preflight також використовує GitHub-hosted Ubuntu, щоб матриця Blacksmith могла ставати в чергу раніше |
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, легші сегменти Plugin, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types` і `check-test-types` |
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, сегменти тестів Linux Node, сегменти тестів вбудованих plugin, `android` |
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint` (достатньо чутливий до CPU, тому 8 vCPU коштували більше, ніж заощаджували); Docker-збірки install-smoke (час очікування в черзі для 32 vCPU коштував більше, ніж заощаджував) |
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
| `blacksmith-6vcpu-macos-latest` | `macos-node` на `openclaw/openclaw`; форки повертаються до `macos-latest` |
| `blacksmith-12vcpu-macos-latest` | `macos-swift` на `openclaw/openclaw`; форки повертаються до `macos-latest` |
| Ранер | Завдання |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ubuntu-24.04` | `preflight`, швидкі завдання безпеки та агрегати (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі перевірки протоколів/контрактів/вбудованого, шардовані перевірки контрактів каналів, шарди `check`, крім lint, шарди та агрегати `check-additional`, агрегатні верифікатори тестів Node, перевірки документації, Python skills, workflow-sanity, labeler, auto-response; preflight для install-smoke також використовує Ubuntu, розміщений у GitHub, щоб матриця Blacksmith могла ставати в чергу раніше |
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, легші шарди extension, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types` і `check-test-types` |
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, шарди тестів Linux Node, шарди тестів вбудованих Plugin, `android` |
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint` (достатньо чутливий до CPU, щоб 8 vCPU коштували більше, ніж заощаджували); Docker-збірки install-smoke (час у черзі для 32-vCPU коштував більше, ніж заощаджував) |
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
| `blacksmith-6vcpu-macos-latest` | `macos-node` на `openclaw/openclaw`; форки повертаються до `macos-latest` |
| `blacksmith-12vcpu-macos-latest` | `macos-swift` на `openclaw/openclaw`; форки повертаються до `macos-latest` |
## Локальні еквіваленти
## Локальні відповідники
```bash
pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD
@ -115,35 +133,35 @@ pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-per
pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json
```
## Повна перевірка релізу
## Повна валідація релізу
`Full Release Validation` — це ручний парасольковий workflow для «запустити все перед релізом». Він приймає гілку, тег або повний SHA коміту, запускає ручний workflow `CI` з цією ціллю, запускає `Plugin Prerelease` для релізних доказів plugin/package/static/Docker і запускає `OpenClaw Release Checks` для install smoke, package acceptance, наборів Docker release-path, live/E2E, OpenWebUI, QA Lab parity, Matrix і Telegram-ліній. З `rerun_group=all` і `release_profile=full` він також запускає `NPM Telegram Beta E2E` проти артефакту `release-package-under-test` із release checks. Після публікації передайте `npm_telegram_package_spec`, щоб повторно запустити ту саму лінію пакета Telegram проти опублікованого npm-пакета.
`Full Release Validation` — це ручний парасольковий workflow для "запустити все перед релізом". Він приймає гілку, тег або повний SHA коміту, запускає ручний workflow `CI` із цією ціллю, запускає `Plugin Prerelease` для релізного підтвердження Plugin/package/static/Docker і запускає `OpenClaw Release Checks` для install smoke, package acceptance, release-path наборів Docker, live/E2E, OpenWebUI, паритету QA Lab, Matrix і каналів Telegram. З `rerun_group=all` і `release_profile=full` він також запускає `NPM Telegram Beta E2E` проти артефакта `release-package-under-test` із release checks. Після публікації передайте `npm_telegram_package_spec`, щоб повторно запустити той самий пакетний канал Telegram проти опублікованого npm-пакета.
Див. [Повна перевірка релізу](/uk/reference/full-release-validation) для
Див. [Повну валідацію релізу](/uk/reference/full-release-validation) для
матриці етапів, точних назв завдань workflow, відмінностей профілів, артефактів і
точкових ідентифікаторів повторного запуску.
цільових ідентифікаторів повторного запуску.
`release_profile` керує шириною live/provider, переданою в release checks. Ручні release workflows типово використовують `stable`; використовуйте `full` лише тоді, коли навмисно потрібна широка advisory-матриця provider/media.
`release_profile` керує шириною live/provider, що передається в release checks. Ручні release workflows за замовчуванням використовують `stable`; використовуйте `full` лише тоді, коли ви навмисно хочете широку консультативну матрицю provider/media.
- `minimum` залишає найшвидші критичні для релізу лінії OpenAI/core.
- `minimum` зберігає найшвидші критичні для релізу канали OpenAI/core.
- `stable` додає стабільний набір provider/backend.
- `full` запускає широку advisory-матрицю provider/media.
- `full` запускає широку консультативну матрицю provider/media.
Парасольковий workflow записує ідентифікатори запущених дочірніх запусків, а фінальне завдання `Verify full validation` повторно перевіряє поточні висновки дочірніх запусків і додає таблиці найповільніших завдань для кожного дочірнього запуску. Якщо дочірній workflow перезапустили й він став зеленим, перезапустіть лише батьківське завдання-верифікатор, щоб оновити результат парасолькового workflow і підсумок часу.
Парасолька записує ідентифікатори запущених дочірніх виконань, а фінальне завдання `Verify full validation` повторно перевіряє поточні висновки дочірніх виконань і додає таблиці найповільніших завдань для кожного дочірнього виконання. Якщо дочірній workflow перезапущено і він став зеленим, повторно запустіть лише батьківське завдання verifier, щоб оновити результат парасольки та підсумок таймінгів.
Для відновлення і `Full Release Validation`, і `OpenClaw Release Checks` приймають `rerun_group`. Використовуйте `all` для реліз-кандидата, `ci` лише для звичайного дочірнього full CI, `plugin-prerelease` лише для дочірнього plugin prerelease, `release-checks` для кожного release child або вужчу групу: `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live` чи `npm-telegram` у парасольковому workflow. Це утримує повторний запуск невдалого release box у межах після точкового виправлення.
Для відновлення і `Full Release Validation`, і `OpenClaw Release Checks` приймають `rerun_group`. Використовуйте `all` для кандидата релізу, `ci` лише для звичайного повного дочірнього CI, `plugin-prerelease` лише для дочірнього prerelease Plugin, `release-checks` для кожного дочірнього release або вужчу групу: `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live` або `npm-telegram` у парасольці. Це утримує повторний запуск невдалого release box у межах після цільового виправлення.
`OpenClaw Release Checks` використовує довірене посилання workflow, щоб один раз розв’язати вибране посилання в tarball `release-package-under-test`, а потім передає цей артефакт і в live/E2E release-path Docker workflow, і в сегмент package acceptance. Це зберігає байти пакета узгодженими між release boxes і уникає повторного пакування того самого кандидата в кількох дочірніх завданнях.
`OpenClaw Release Checks` використовує довірений ref workflow, щоб один раз розв’язати вибраний ref у tarball `release-package-under-test`, а потім передає цей артефакт і до live/E2E Docker workflow release-path, і до шарда package acceptance. Це зберігає байти пакета узгодженими між release boxes і уникає повторного пакування того самого кандидата в кількох дочірніх завданнях.
Дубльовані запуски `Full Release Validation` для `ref=main` і `rerun_group=all`
замінюють старіший парасольковий workflow. Батьківський монітор скасовує будь-який дочірній workflow, який
він уже запустив, коли батьківський скасовано, тому новіша перевірка main
не стоїть за застарілим двогодинним запуском release-check. Перевірка гілки/тега релізу
і точкові групи повторного запуску залишають `cancel-in-progress: false`.
Дублікати запусків `Full Release Validation` для `ref=main` і `rerun_group=all`
замінюють старішу парасольку. Батьківський монітор скасовує будь-який дочірній workflow, який
він уже запустив, коли батьківський запуск скасовано, тому новіша валідація main
не стоїть позаду застарілого двогодинного запуску release-check. Валідація release branch/tag
і цільові групи повторного запуску зберігають `cancel-in-progress: false`.
## Live та E2E-сегменти
## Live та E2E шарди
Дочірній release live/E2E зберігає широке нативне покриття `pnpm test:live`, але запускає його як іменовані сегменти через `scripts/test-live-shard.mjs` замість одного послідовного завдання:
Дочірній release live/E2E зберігає широке нативне покриття `pnpm test:live`, але запускає його як іменовані шарди через `scripts/test-live-shard.mjs` замість одного послідовного завдання:
- `native-live-src-agents`
- `native-live-src-gateway-core`
@ -155,61 +173,61 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
- `native-live-extensions-openai`
- `native-live-extensions-o-z-other`
- `native-live-extensions-xai`
- розділені сегменти media audio/video і provider-filtered music segments
- розділені медіа-шарди audio/video і provider-filtered шарди music
Це зберігає те саме файлове покриття, водночас спрощуючи повторний запуск і діагностику повільних live-збоїв provider. Агреговані назви сегментів `native-live-extensions-o-z`, `native-live-extensions-media` і `native-live-extensions-media-music` залишаються чинними для ручних одноразових повторних запусків.
Це зберігає те саме файлове покриття, водночас спрощуючи повторний запуск і діагностику повільних збоїв live provider. Агрегатні назви шардів `native-live-extensions-o-z`, `native-live-extensions-media` і `native-live-extensions-media-music` залишаються чинними для ручних одноразових повторних запусків.
Нативні live media segments працюють у `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`, зібраному workflow `Live Media Runner Image`. Цей образ попередньо встановлює `ffmpeg` і `ffprobe`; media jobs лише перевіряють бінарні файли перед налаштуванням. Тримайте Docker-backed live suites на звичайних Blacksmith runners — container jobs є неправильним місцем для запуску вкладених Docker tests.
Нативні live media шарди запускаються в `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`, зібраному workflow `Live Media Runner Image`. Цей образ попередньо встановлює `ffmpeg` і `ffprobe`; медіа-завдання лише перевіряють бінарні файли перед налаштуванням. Тримайте Docker-backed live suites на звичайних раннерах Blacksmith — container jobs є неправильним місцем для запуску вкладених Docker-тестів.
Docker-backed live model/backend shards використовують окремий спільний образ `ghcr.io/openclaw/openclaw-live-test:<sha>` для кожного вибраного коміту. Live release workflow один раз збирає та пушить цей образ, а потім сегменти Docker live model, provider-sharded gateway, CLI backend, ACP bind і Codex harness запускаються з `OPENCLAW_SKIP_DOCKER_BUILD=1`. Gateway Docker shards мають явні обмеження `timeout` на рівні скриптів нижче за timeout завдання workflow, щоб завислий контейнер або шлях очищення швидко падав, а не споживав увесь бюджет release-check. Якщо ці сегменти незалежно перебудовують повну source Docker target, release run налаштовано неправильно, і він марнуватиме час на дубльовані збірки образів.
Docker-backed шарди live model/backend використовують окремий спільний образ `ghcr.io/openclaw/openclaw-live-test:<sha>` для кожного вибраного коміту. Live release workflow збирає й пушить цей образ один раз, після чого Docker live model, provider-sharded gateway, CLI backend, ACP bind і шарди Codex harness запускаються з `OPENCLAW_SKIP_DOCKER_BUILD=1`. Gateway Docker шарди мають явні обмеження `timeout` на рівні скрипта нижче за timeout завдання workflow, щоб завислий контейнер або шлях очищення швидко падав, а не споживав увесь бюджет release-check. Якщо ці шарди незалежно перебудовують повну ціль source Docker, release run неправильно налаштований і марнуватиме wall clock на дубльовані збірки образів.
## Прийняття пакета
## Package Acceptance
Використовуйте `Package Acceptance`, коли питання звучить так: «чи працює цей встановлюваний пакет OpenClaw як продукт?» Це відрізняється від звичайного CI: звичайний CI перевіряє дерево вихідного коду, тоді як package acceptance перевіряє один tarball через той самий Docker E2E harness, який користувачі запускають після встановлення або оновлення.
Використовуйте `Package Acceptance`, коли питання таке: "чи працює цей інстальований пакет OpenClaw як продукт?" Це відрізняється від звичайного CI: звичайний CI валідує дерево джерел, тоді як package acceptance валідує один tarball через той самий Docker E2E harness, який користувачі використовують після встановлення або оновлення.
### Завдання
1. `resolve_package` виконує checkout `workflow_ref`, визначає одного кандидата пакета, записує `.artifacts/docker-e2e-package/openclaw-current.tgz`, записує `.artifacts/docker-e2e-package/package-candidate.json`, завантажує обидва як артефакт `package-under-test` і виводить джерело, ref workflow, ref пакета, версію, SHA-256 і профіль у підсумку кроку GitHub.
2. `docker_acceptance` викликає `openclaw-live-and-e2e-checks-reusable.yml` з `ref=workflow_ref` і `package_artifact_name=package-under-test`. Повторно використовуваний workflow завантажує цей артефакт, перевіряє інвентар tarball, за потреби готує Docker-образи з дайджестом пакета й запускає вибрані Docker-лінії проти цього пакета замість пакування checkout workflow. Коли профіль вибирає кілька цільових `docker_lanes`, повторно використовуваний workflow готує пакет і спільні образи один раз, а потім розгортає ці лінії як паралельні цільові Docker-завдання з унікальними артефактами.
3. `package_telegram` опціонально викликає `NPM Telegram Beta E2E`. Він запускається, коли `telegram_mode` не дорівнює `none`, і встановлює той самий артефакт `package-under-test`, коли Package Acceptance визначив його; автономний запуск Telegram все ще може встановити опубліковану npm-специфікацію.
4. `summary` завершує workflow з помилкою, якщо визначення пакета, Docker acceptance або опціональна лінія Telegram завершилися невдало.
2. `docker_acceptance` викликає `openclaw-live-and-e2e-checks-reusable.yml` з `ref=workflow_ref` і `package_artifact_name=package-under-test`. Повторно використовуваний workflow завантажує цей артефакт, перевіряє інвентар tarball, за потреби готує Docker-образи package-digest і запускає вибрані Docker-доріжки для цього пакета замість пакування checkout workflow. Коли профіль вибирає кілька цільових `docker_lanes`, повторно використовуваний workflow один раз готує пакет і спільні образи, а потім розподіляє ці доріжки як паралельні цільові Docker-завдання з унікальними артефактами.
3. `package_telegram` необов’язково викликає `NPM Telegram Beta E2E`. Він запускається, коли `telegram_mode` не дорівнює `none`, і встановлює той самий артефакт `package-under-test`, коли Package Acceptance визначив пакет; окремий dispatch Telegram усе ще може встановити опубліковану npm-специфікацію.
4. `summary` завершує workflow помилкою, якщо визначення пакета, Docker acceptance або необов’язкова доріжка Telegram завершилися невдало.
### Джерела кандидатів
- `source=npm` приймає лише `openclaw@beta`, `openclaw@latest` або точну версію релізу OpenClaw, як-от `openclaw@2026.4.27-beta.2`. Використовуйте це для acceptance опублікованих beta/stable.
- `source=ref` пакує довірену гілку `package_ref`, тег або повний commit SHA. Резолвер отримує гілки/теги OpenClaw, перевіряє, що вибраний commit досяжний з історії гілок репозиторію або release tag, встановлює залежності в від’єднаному worktree і пакує його за допомогою `scripts/package-openclaw-for-docker.mjs`.
- `source=npm` приймає лише `openclaw@beta`, `openclaw@latest` або точну версію релізу OpenClaw, наприклад `openclaw@2026.4.27-beta.2`. Використовуйте це для acceptance опублікованих beta/stable.
- `source=ref` пакує довірену гілку `package_ref`, тег або повний SHA commit. Resolver отримує гілки/теги OpenClaw, перевіряє, що вибраний commit досяжний з історії гілок репозиторію або релізного тегу, встановлює залежності у detached worktree і пакує його за допомогою `scripts/package-openclaw-for-docker.mjs`.
- `source=url` завантажує HTTPS `.tgz`; `package_sha256` є обов’язковим.
- `source=artifact` завантажує один `.tgz` з `artifact_run_id` і `artifact_name`; `package_sha256` опціональний, але його варто вказувати для артефактів, якими діляться зовні.
- `source=artifact` завантажує один `.tgz` з `artifact_run_id` і `artifact_name`; `package_sha256` необов’язковий, але його варто надати для артефактів, поширених назовні.
Тримайте `workflow_ref` і `package_ref` окремо. `workflow_ref` — це довірений код workflow/harness, який запускає тест. `package_ref` — це source commit, який пакується, коли `source=ref`. Це дає змогу поточному тестовому harness перевіряти старі довірені source commits без запуску старої логіки workflow.
Тримайте `workflow_ref` і `package_ref` окремо. `workflow_ref` — це довірений код workflow/тестового harness, який запускає тест. `package_ref` — це початковий commit, який пакується, коли `source=ref`. Це дає змогу поточному тестовому harness перевіряти старіші довірені початкові commit без запуску старої логіки workflow.
### Профілі suite
- `smoke``npm-onboard-channel-agent`, `gateway-network`, `config-reload`
- `package``npm-onboard-channel-agent`, `doctor-switch`, `update-channel-switch`, `upgrade-survivor`, `published-upgrade-survivor`, `plugins-offline`, `plugin-update`
- `product``package` плюс `mcp-channels`, `cron-mcp-cleanup`, `openai-web-search-minimal`, `openwebui`
- `full` — повні Docker-фрагменти release path з OpenWebUI
- `full` — повні фрагменти release-path Docker з OpenWebUI
- `custom` — точні `docker_lanes`; обов’язково, коли `suite_profile=custom`
Профіль `package` використовує offline-покриття Plugin, щоб перевірка опублікованого пакета не залежала від live-доступності ClawHub. Опціональна лінія Telegram повторно використовує артефакт `package-under-test` у `NPM Telegram Beta E2E`, а шлях опублікованої npm-специфікації лишається для автономних запусків.
Профіль `package` використовує offline-покриття Plugin, щоб перевірка опублікованого пакета не залежала від живої доступності ClawHub. Необов’язкова доріжка Telegram повторно використовує артефакт `package-under-test` у `NPM Telegram Beta E2E`, а шлях опублікованої npm-специфікації зберігається для окремих dispatch.
Щодо спеціальної політики тестування оновлень і Plugin, включно з локальними командами,
Docker-лініями, входами Package Acceptance, типовими параметрами релізу та triage помилок,
див. [Тестування оновлень і Plugin](/uk/help/testing-updates-plugins).
Спеціальну політику тестування оновлень і Plugin, зокрема локальні команди,
Docker-доріжки, inputs Package Acceptance, типові значення релізу та triage збоїв,
див. у [Тестування оновлень і Plugin](/uk/help/testing-updates-plugins).
Release checks викликають Package Acceptance з `source=artifact`, підготовленим артефактом release package, `suite_profile=custom`, `docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`, `published_upgrade_survivor_baselines=release-history`, `published_upgrade_survivor_scenarios=reported-issues` і `telegram_mode=mock-openai`. Це тримає перевірки міграції пакета, оновлення, очищення застарілих Plugin-залежностей, offline Plugin, plugin-update і Telegram на тому самому визначеному tarball пакета. Cross-OS release checks все ще покривають OS-специфічні onboarding, installer і поведінку платформи; product-перевірку package/update слід починати з Package Acceptance. Docker-лінія `published-upgrade-survivor` перевіряє одну опубліковану базову версію пакета за запуск. У Package Acceptance визначений tarball `package-under-test` завжди є кандидатом, а `published_upgrade_survivor_baseline` вибирає fallback опубліковану базову версію, типово `openclaw@latest`; команди повторного запуску failed lane зберігають цю базову версію. Установіть `published_upgrade_survivor_baselines=release-history`, щоб розгорнути лінію по deduped матриці історії: останні шість stable releases, `2026.4.23` і останній stable release перед `2026-03-15`. Установіть `published_upgrade_survivor_scenarios=reported-issues`, щоб розгорнути ті самі базові версії по issue-подібних fixtures для конфігурації Feishu, збережених bootstrap/persona файлів, tilde шляхів логів і застарілих legacy коренів Plugin-залежностей. Окремий workflow `Update Migration` використовує Docker-лінію `update-migration` з `all-since-2026.4.23` і `plugin-deps-cleanup`, коли питання полягає у вичерпному очищенні опублікованих оновлень, а не у звичайній ширині Full Release CI. Локальні aggregate-запуски можуть передавати точні специфікації пакетів через `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS`, залишати одну лінію з `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC`, як-от `openclaw@2026.4.15`, або встановлювати `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` для матриці сценаріїв. Опублікована лінія налаштовує базову версію за допомогою baked recipe команди `openclaw config set`, записує кроки recipe у `summary.json` і перевіряє `/healthz`, `/readyz`, а також RPC status після старту Gateway. Windows packaged і installer fresh лінії також перевіряють, що встановлений пакет може імпортувати browser-control override з raw absolute Windows path. Cross-OS agent-turn smoke для OpenAI типово використовує `OPENCLAW_CROSS_OS_OPENAI_MODEL`, якщо його задано, інакше `openai/gpt-5.5`, тому proof встановлення й Gateway лишається на бажаній тестовій моделі GPT-5.
Release checks викликають Package Acceptance з `source=artifact`, підготовленим артефактом релізного пакета, `suite_profile=custom`, `docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`, `published_upgrade_survivor_baselines=release-history`, `published_upgrade_survivor_scenarios=reported-issues` і `telegram_mode=mock-openai`. Це зберігає перевірки міграції пакета, оновлення, очищення застарілих залежностей Plugin, offline Plugin, plugin-update і Telegram на одному визначеному tarball пакета. Cross-OS release checks і надалі покривають специфічні для ОС onboarding, інсталятор і поведінку платформи; product-валидацію пакета/оновлення слід починати з Package Acceptance. Docker-доріжка `published-upgrade-survivor` перевіряє один базовий опублікований пакет за запуск. У Package Acceptance визначений tarball `package-under-test` завжди є кандидатом, а `published_upgrade_survivor_baseline` вибирає fallback опублікований baseline, типово `openclaw@latest`; команди повторного запуску невдалих доріжок зберігають цей baseline. Установіть `published_upgrade_survivor_baselines=release-history`, щоб розгорнути доріжку в deduped матрицю історії: останні шість stable-релізів, `2026.4.23` і останній stable-реліз до `2026-03-15`. Установіть `published_upgrade_survivor_scenarios=reported-issues`, щоб розгорнути ті самі baselines у fixtures, сформовані за issues, для конфігурації Feishu, збережених bootstrap/persona файлів, шляхів логів із tilde і застарілих коренів залежностей Plugin. Окремий workflow `Update Migration` використовує Docker-доріжку `update-migration` з `all-since-2026.4.23` і `plugin-deps-cleanup`, коли питання полягає у вичерпному очищенні опублікованих оновлень, а не у звичайній ширині Full Release CI. Локальні агреговані запуски можуть передавати точні специфікації пакетів через `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS`, залишати одну доріжку з `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC`, наприклад `openclaw@2026.4.15`, або задавати `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` для матриці сценаріїв. Опублікована доріжка налаштовує baseline за допомогою вбудованого рецепта команди `openclaw config set`, записує кроки рецепта в `summary.json` і перевіряє `/healthz`, `/readyz`, а також статус RPC після запуску Gateway. Windows-доріжки packaged і installer fresh також перевіряють, що встановлений пакет може імпортувати browser-control override із сирого абсолютного Windows-шляху. Cross-OS smoke агентного turn OpenAI типово використовує `OPENCLAW_CROSS_OS_OPENAI_MODEL`, коли задано, інакше `openai/gpt-5.5`, тож install і gateway proof залишаються на бажаній тестовій моделі GPT-5.
### Вікна legacy-сумісності
Package Acceptance має обмежені вікна legacy-сумісності для вже опублікованих пакетів. Пакети до `2026.4.25` включно, зокрема `2026.4.25-beta.*`, можуть використовувати шлях сумісності:
- відомі приватні QA-записи в `dist/postinstall-inventory.json` можуть вказувати на файли, пропущені в tarball;
- `doctor-switch` може пропустити підвипадок persistence `gateway install --wrapper`, коли пакет не надає цей flag;
- `update-channel-switch` може обрізати відсутні `pnpm.patchedDependencies` з tarball-derived fake git fixture і може логувати відсутній persist `update.channel`;
- plugin smokes можуть читати legacy locations install-record або приймати відсутню persistence marketplace install-record;
- `plugin-update` може дозволити міграцію config metadata, водночас все ще вимагаючи, щоб install record і поведінка no-reinstall лишалися незмінними.
- `doctor-switch` може пропустити підвипадок збереження `gateway install --wrapper`, коли пакет не надає цей прапорець;
- `update-channel-switch` може видаляти відсутні `pnpm.patchedDependencies` з підробленого git fixture, отриманого з tarball, і може логувати відсутній збережений `update.channel`;
- plugin smoke можуть читати legacy-розташування install-record або приймати відсутнє збереження marketplace install-record;
- `plugin-update` може дозволити міграцію метаданих конфігурації, водночас усе ще вимагаючи, щоб install record і поведінка без повторного встановлення залишалися незмінними.
Опублікований пакет `2026.4.26` також може попереджати про локальні stamp files build metadata, які вже були shipped. Пізніші пакети мають задовольняти сучасні contracts; ті самі умови завершуються failure, а не warn або skip.
Опублікований пакет `2026.4.26` також може попереджати про файли штампа метаданих локальної збірки, які вже були випущені. Пізніші пакети мають задовольняти сучасні контракти; ті самі умови спричиняють помилку, а не попередження чи пропуск.
### Приклади
@ -252,111 +270,111 @@ gh workflow run package-acceptance.yml \
-f docker_lanes='install-e2e plugin-update'
```
Під час налагодження невдалого запуску package acceptance починайте з підсумку `resolve_package`, щоб підтвердити джерело пакета, версію та SHA-256. Потім перевірте дочірній запуск `docker_acceptance` і його Docker-артефакти: `.artifacts/docker-tests/**/summary.json`, `failures.json`, логи ліній, phase timings і команди повторного запуску. Надавайте перевагу повторному запуску failed package profile або точних Docker-ліній замість повторного запуску повної release validation.
Під час debug невдалого запуску package acceptance починайте з підсумку `resolve_package`, щоб підтвердити джерело пакета, версію та SHA-256. Потім перегляньте дочірній запуск `docker_acceptance` і його Docker-артефакти: `.artifacts/docker-tests/**/summary.json`, `failures.json`, логи доріжок, timings фаз і команди повторного запуску. Віддавайте перевагу повторному запуску невдалого профілю пакета або точних Docker-доріжок замість повторного запуску повної release validation.
## Install smoke
Окремий workflow `Install Smoke` повторно використовує той самий scope script через власне завдання `preflight`. Він розділяє smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`.
- **Швидкий шлях** запускається для pull requests, що торкаються Docker/package surfaces, змін bundled plugin package/manifest або core plugin/channel/gateway/Plugin SDK surfaces, які виконують Docker smoke jobs. Зміни лише source у bundled plugin, test-only edits і docs-only edits не резервують Docker workers. Швидкий шлях один раз збирає образ root Dockerfile, перевіряє CLI, запускає agents delete shared-workspace CLI smoke, запускає container gateway-network e2e, перевіряє bundled extension build arg і запускає bounded bundled-plugin Docker profile у межах aggregate command timeout 240 секунд (Docker-запуск кожного сценарію обмежений окремо).
- **Повний шлях** зберігає QR package install і installer Docker/update coverage для нічних scheduled runs, manual dispatches, workflow-call release checks і pull requests, які справді торкаються installer/package/Docker surfaces. У full mode install-smoke готує або повторно використовує один target-SHA GHCR root Dockerfile smoke image, а потім запускає QR package install, root Dockerfile/gateway smokes, installer/update smokes і fast bundled-plugin Docker E2E як окремі jobs, щоб installer work не чекала за root image smokes.
- **Швидкий шлях** запускається для pull requests, що торкаються Docker/package surfaces, змін пакетів/маніфестів bundled Plugin або core plugin/channel/gateway/Plugin SDK surfaces, які перевіряють Docker smoke jobs. Зміни лише вихідного коду bundled Plugin, лише тестові правки та правки лише документації не резервують Docker workers. Швидкий шлях один раз збирає образ root Dockerfile, перевіряє CLI, запускає CLI smoke видалення agents shared-workspace, запускає container gateway-network e2e, перевіряє build arg bundled extension і запускає обмежений bundled-plugin Docker profile під сукупним timeout команди 240 секунд (Docker run кожного сценарію обмежено окремо).
- **Повний шлях** зберігає QR package install і Docker/update покриття інсталятора для нічних scheduled runs, ручних dispatch, workflow-call release checks і pull requests, які справді торкаються installer/package/Docker surfaces. У full mode install-smoke готує або повторно використовує один target-SHA GHCR root Dockerfile smoke image, а потім запускає QR package install, root Dockerfile/gateway smokes, installer/update smokes і швидкий bundled-plugin Docker E2E як окремі jobs, щоб installer work не чекав за root image smokes.
`main` pushes (зокрема merge commits) не примушують full path; коли changed-scope logic запитала б full coverage на push, workflow залишає fast Docker smoke, а full install smoke лишає нічній або release validation.
Push у `main` (зокрема merge commits) не примушують повний шлях; коли логіка changed-scope вимагала б повне покриття для push, workflow зберігає швидкий Docker smoke і залишає повний install smoke для нічної або релізної валідації.
Повільний Bun global install image-provider smoke окремо gated через `run_bun_global_install_smoke`. Він запускається за nightly schedule і з release checks workflow, а manual dispatches `Install Smoke` можуть увімкнути його, але pull requests і `main` pushes — ні. QR і installer Docker tests зберігають власні install-focused Dockerfiles.
Повільний Bun global install image-provider smoke окремо керується `run_bun_global_install_smoke`. Він запускається за нічним розкладом і з workflow release checks, а ручні dispatch `Install Smoke` можуть увімкнути його, але pull requests і push у `main` — ні. QR і installer Docker tests зберігають власні Dockerfiles, зосереджені на install.
## Локальний Docker E2E
`pnpm 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.
- bare Node/Git runner для доріжок installer/update/plugin-dependency;
- функціональний образ, який встановлює той самий tarball у `/app` для звичайних functionality lanes.
Визначення Docker-ліній розташовані в `scripts/lib/docker-e2e-scenarios.mjs`, planner logicу `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний plan. Scheduler вибирає образ для кожної лінії через `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, потім запускає лінії з `OPENCLAW_SKIP_DOCKER_BUILD=1`.
Визначення Docker-доріжок розташовані в `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`.
### Параметри налаштування
### Налаштування
| Змінна | Типово | Призначення |
| -------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | Кількість слотів основного пулу для звичайних ліній. |
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | Кількість слотів хвостового пулу, чутливого до провайдерів. |
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | Обмеження одночасних live-ліній, щоб провайдери не застосовували throttling. |
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | Обмеження одночасних ліній встановлення npm. |
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | Обмеження одночасних багатосервісних ліній. |
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | Затримка між стартами ліній, щоб уникнути сплесків створення в Docker daemon; задайте `0`, щоб вимкнути. |
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | Резервний таймаут для кожної лінії (120 хвилин); вибрані live/tail-лінії використовують жорсткіші ліміти. |
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` друкує план планувальника без запуску ліній. |
| `OPENCLAW_DOCKER_ALL_LANES` | unset | Точний список ліній через кому; пропускає cleanup smoke, щоб агенти могли відтворити одну невдалу лінію. |
| Змінна | Типове значення | Призначення |
| ------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | Кількість слотів основного пулу для звичайних lane. |
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | Кількість слотів tail-пулу, чутливого до провайдерів. |
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | Обмеження паралельних live lane, щоб провайдери не застосовували throttling. |
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | Обмеження паралельних lane встановлення npm. |
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | Обмеження паралельних multi-service lane. |
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | Затримка між стартами lane, щоб уникнути хвиль створення в daemon Docker; задайте `0`, щоб вимкнути затримку. |
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | Резервний тайм-аут на lane (120 хвилин); вибрані live/tail lane використовують жорсткіші обмеження. |
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | не задано | `1` друкує план планувальника без запуску lane. |
| `OPENCLAW_DOCKER_ALL_LANES` | не задано | Розділений комами точний список lane; пропускає cleanup smoke, щоб агенти могли відтворити одну невдалу lane. |
Лінія, важча за свій ефективний ліміт, усе ще може стартувати з порожнього пулу, а потім працює сама, доки не звільнить місткість. Локальний агрегатор попередньо перевіряє Docker, видаляє застарілі OpenClaw E2E-контейнери, виводить статус активних ліній, зберігає тривалості ліній для впорядкування від найдовших до найкоротших і типово припиняє планувати нові pooled-лінії після першої помилки.
Lane, важча за свій ефективний ліміт, усе ще може стартувати з порожнього пулу, а потім працює сама, доки не звільнить ємність. Локальний агрегат виконує попередні перевірки Docker, видаляє застарілі OpenClaw E2E контейнери, виводить статус активних lane, зберігає тривалості lane для впорядкування від найдовших до найкоротших і типово припиняє планувати нові pooled lane після першого збою.
### Багаторазовий live/E2E workflow
Багаторазовий live/E2E workflow запитує в `scripts/test-docker-all.mjs --plan-json`, яке покриття пакета, типу образу, live-образу, лінії та облікових даних потрібне. Потім `scripts/docker-e2e.mjs` перетворює цей план на GitHub outputs і підсумки. Він або пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, завантажує артефакт пакета поточного запуску, або завантажує артефакт пакета з `package_artifact_run_id`; перевіряє inventory tarball; збирає й публікує GHCR Docker E2E-образи bare/functional із тегами за digest пакета через кеш Docker-шарів Blacksmith, коли план потребує ліній із встановленим пакетом; і повторно використовує надані inputs `docker_e2e_bare_image`/`docker_e2e_functional_image` або наявні образи за digest пакета замість повторної збірки. Завантаження Docker-образів повторюються з обмеженим 180-секундним таймаутом на спробу, щоб завислий registry/cache stream швидко повторився, а не спожив більшість критичного шляху CI.
Багаторазовий live/E2E workflow запитує `scripts/test-docker-all.mjs --plan-json`, які package, image kind, live image, lane і покриття облікових даних потрібні. Потім `scripts/docker-e2e.mjs` перетворює цей план на GitHub outputs і summaries. Він або пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, завантажує package artifact поточного запуску, або завантажує package artifact з `package_artifact_run_id`; перевіряє inventory tarball; збирає й публікує package-digest-tagged bare/functional GHCR Docker E2E images через Docker layer cache Blacksmith, коли план потребує lane з установленим package; і повторно використовує надані inputs `docker_e2e_bare_image`/`docker_e2e_functional_image` або наявні package-digest images замість повторної збірки. Завантаження Docker images повторюються з обмеженим 180-секундним тайм-аутом на спробу, щоб завислий registry/cache stream швидко повторився, а не спожив більшу частину критичного шляху CI.
### Фрагменти release-path
Release Docker coverage запускає менші chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk завантажував лише потрібний йому тип образу й виконував кілька ліній через той самий зважений планувальник:
Покриття Release Docker запускає менші chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk завантажував лише потрібний йому image kind і виконував кілька lane через той самий 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..h`
Поточні 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-h`. `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` залишаються агрегованими псевдонімами plugin/runtime. Псевдонім лінії `install-e2e` залишається агрегованим ручним псевдонімом повторного запуску для обох ліній installer провайдерів.
Поточні 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-h`. `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` залишаються агрегатними псевдонімами Plugin/runtime. Псевдонім lane `install-e2e` залишається агрегатним псевдонімом ручного повторного запуску для обох lane встановлювача провайдера.
OpenWebUI включається в `plugins-runtime-services`, коли повне release-path coverage цього потребує, і зберігає окремий chunk `openwebui` лише для dispatch, що стосуються тільки OpenWebUI. Лінії оновлення bundled-channel повторюють спробу один раз для тимчасових мережевих помилок npm.
OpenWebUI входить до `plugins-runtime-services`, коли повне покриття release-path його запитує, і зберігає окремий chunk `openwebui` лише для dispatches, призначених тільки для OpenWebUI. Lane оновлення bundled-channel повторюють спробу один раз у разі тимчасових мережевих збоїв npm.
Кожен chunk завантажує `.artifacts/docker-tests/` з журналами ліній, тривалостями, `summary.json`, `failures.json`, тривалостями фаз, JSON плану планувальника, таблицями повільних ліній і командами повторного запуску для кожної лінії. Input workflow `docker_lanes` запускає вибрані лінії проти підготовлених образів замість chunk jobs, що обмежує налагодження невдалої лінії одним цільовим Docker job і готує, завантажує або повторно використовує артефакт пакета для цього запуску; якщо вибрана лінія є live Docker lane, цільовий job локально збирає live-test image для цього повторного запуску. Згенеровані GitHub-команди повторного запуску для кожної лінії включають `package_artifact_run_id`, `package_artifact_name` і inputs підготовлених образів, коли такі значення існують, щоб невдала лінія могла повторно використати точний пакет і образи з невдалого запуску.
Кожен chunk завантажує `.artifacts/docker-tests/` з журналами lane, таймінгами, `summary.json`, `failures.json`, таймінгами фаз, JSON плану планувальника, таблицями повільних lane і командами повторного запуску для кожної lane. Input workflow `docker_lanes` запускає вибрані lane проти підготовлених images замість chunk jobs, що обмежує налагодження невдалої lane одним цільовим Docker job і готує, завантажує або повторно використовує package artifact для цього запуску; якщо вибрана lane є live Docker lane, цільовий job збирає live-test image локально для цього повторного запуску. Згенеровані для кожної lane команди повторного запуску GitHub містять `package_artifact_run_id`, `package_artifact_name` і inputs підготовлених images, коли ці значення існують, тож невдала lane може повторно використати точні package і images з невдалого запуску.
```bash
pnpm test:docker:rerun <run-id> # завантажити Docker-артефакти й надрукувати combined/per-lane цільові команди повторного запуску
pnpm test:docker:timings <summary> # підсумки повільних ліній і критичного шляху фаз
pnpm test:docker:rerun <run-id> # завантажити Docker artifacts і надрукувати об’єднані/по-lane цільові команди повторного запуску
pnpm test:docker:timings <summary> # підсумки повільних lane і критичного шляху фаз
```
Запланований live/E2E workflow щодня запускає повний release-path Docker suite.
## Plugin Prerelease
`Plugin Prerelease` є дорожчим покриттям product/package, тому це окремий workflow, який запускається через `Full Release Validation` або явним оператором. Звичайні pull requests, push у `main` і окремі manual CI dispatches не запускають цей suite. Він балансує тести bundled plugin між вісьмома extension workers; ці jobs шард extension запускають до двох груп конфігурації plugin одночасно з одним Vitest worker на групу та більшим Node heap, щоб import-heavy пакети plugin не створювали додаткових CI jobs. Release-only Docker prerelease path групує цільові Docker lanes невеликими наборами, щоб не резервувати десятки runners для jobs тривалістю від однієї до трьох хвилин.
`Plugin Prerelease` є дорожчим покриттям product/package, тому це окремий workflow, який запускається `Full Release Validation` або явно оператором. Звичайні pull requests, push до `main` і окремі ручні CI dispatches не вмикають цей suite. Він балансує тести bundled Plugin між вісьмома extension workers; ці extension shard jobs запускають до двох груп конфігурації Plugin одночасно з одним Vitest worker на групу та більшим heap Node, щоб batches Plugin з важкими imports не створювали додаткових CI jobs. Release-only Docker prerelease path групує цільові Docker lane невеликими групами, щоб не резервувати десятки runners для jobs тривалістю від однієї до трьох хвилин.
## QA Lab
QA Lab має dedicated CI lanes поза основним smart-scoped workflow.
QA Lab має окремі CI lane поза основним smart-scoped workflow.
- Workflow `Parity gate` запускається на відповідних змінах PR і manual dispatch; він збирає приватний QA runtime і порівнює mock GPT-5.5 та Opus 4.6 agentic packs.
- Workflow `QA-Lab - All Lanes` запускається щоночі на `main` і через manual dispatch; він розгалужує mock parity gate, live Matrix lane, а також live Telegram і Discord lanes як паралельні jobs. Live jobs використовують середовище `qa-live-shared`, а Telegram/Discord використовують Convex leases.
- Workflow `Parity gate` запускається для відповідних змін PR і manual dispatch; він збирає приватний QA runtime і порівнює mock GPT-5.5 та Opus 4.6 agentic packs.
- Workflow `QA-Lab - All Lanes` запускається щоночі на `main` і за manual dispatch; він розгортає mock parity gate, live Matrix lane, а також live Telegram і Discord lanes як паралельні jobs. Live jobs використовують environment `qa-live-shared`, а Telegram/Discord використовують Convex leases.
Release checks запускають Matrix і Telegram live transport lanes із deterministic mock provider і mock-qualified models (`mock-openai/gpt-5.5` та `mock-openai/gpt-5.5-alt`), щоб контракт каналу був ізольований від latency live model і звичайного startup provider-plugin. Live transport gateway вимикає memory search, тому що QA parity окремо покриває поведінку пам’яті; provider connectivity покривається окремими suites live model, native provider і Docker provider.
Release checks запускають Matrix і Telegram live transport lanes з deterministic mock provider і mock-qualified models (`mock-openai/gpt-5.5` та `mock-openai/gpt-5.5-alt`), щоб контракт channel був ізольований від затримки live model і звичайного startup provider Plugin. Live transport Gateway вимикає memory search, оскільки QA parity окремо покриває поведінку memory; connectivity провайдера покривають окремі suites live model, native provider і Docker provider.
Matrix використовує `--profile fast` для scheduled і release gates, додаючи `--fail-fast` лише коли checked-out CLI це підтримує. Типове значення CLI і manual workflow input залишаються `all`; manual `matrix_profile=all` dispatch завжди шардує повне Matrix coverage на jobs `transport`, `media`, `e2ee-smoke`, `e2ee-deep` і `e2ee-cli`.
Matrix використовує `--profile fast` для scheduled і release gates, додаючи `--fail-fast` лише коли checked-out CLI це підтримує. Типове значення CLI і input manual workflow залишаються `all`; manual dispatch `matrix_profile=all` завжди розбиває повне покриття Matrix на jobs `transport`, `media`, `e2ee-smoke`, `e2ee-deep` і `e2ee-cli`.
`OpenClaw Release Checks` також запускає release-critical QA Lab lanes перед release approval; його QA parity gate запускає candidate і baseline packs як паралельні lane jobs, потім завантажує обидва артефакти в невеликий report job для фінального parity comparison.
`OpenClaw Release Checks` також запускає критичні для релізу lane QA Lab перед затвердженням релізу; його QA parity gate запускає candidate і baseline packs як паралельні lane jobs, а потім завантажує обидва artifacts у невеликий report job для фінального parity comparison.
Не ставте PR landing path за `Parity gate`, якщо зміна фактично не зачіпає QA runtime, model-pack parity або surface, яким володіє parity workflow. Для звичайних виправлень каналів, конфігурації, документації або unit-test розглядайте це як optional signal і натомість спирайтеся на scoped CI/check evidence.
Не ставте шлях landing PR за `Parity gate`, якщо зміна фактично не зачіпає QA runtime, model-pack parity або поверхню, якою володіє parity workflow. Для звичайних виправлень channel, config, docs або unit-test розглядайте це як необов’язковий сигнал і спирайтеся на scoped CI/check evidence.
## CodeQL
Workflow `CodeQL` навмисно є вузьким security scanner першого проходу, а не повним repository sweep. Daily, manual і non-draft pull request guard runs сканують код Actions workflow плюс найризикованіші JavaScript/TypeScript surfaces з high-confidence security queries, відфільтрованими до high/critical `security-severity`.
Workflow `CodeQL` навмисно є вузьким security scanner першого проходу, а не повним sweep repository. Щоденні, manual і non-draft pull request guard runs сканують код Actions workflow плюс найризикованіші поверхні JavaScript/TypeScript за допомогою high-confidence security queries, відфільтрованих до high/critical `security-severity`.
Pull request guard лишається легким: він стартує лише для змін у `.github/actions`, `.github/codeql`, `.github/workflows`, `packages` або `src`, і запускає ту саму high-confidence security matrix, що й scheduled workflow. Android і macOS CodeQL не входять у PR defaults.
Pull request guard залишається легким: він запускається лише для змін у `.github/actions`, `.github/codeql`, `.github/workflows`, `packages` або `src`, і виконує ту саму high-confidence security matrix, що й scheduled workflow. Android і macOS CodeQL не входять до типових PR defaults.
### Категорії безпеки
| Категорія | Surface |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `/codeql-security-high/core-auth-secrets` | Auth, secrets, sandbox, cron і baseline gateway |
| `/codeql-security-high/channel-runtime-boundary` | Контракти реалізації core channel плюс channel plugin runtime, gateway, Plugin SDK, secrets, audit touchpoints |
| `/codeql-security-high/network-ssrf-boundary` | Core SSRF, IP parsing, network guard, web-fetch і surfaces політики SSRF Plugin SDK |
| `/codeql-security-high/mcp-process-tool-boundary` | MCP servers, process execution helpers, outbound delivery і gates agent tool-execution |
| `/codeql-security-high/plugin-trust-boundary` | Plugin install, loader, manifest, registry, package-manager install, source-loading і trust surfaces контракту пакета Plugin SDK |
| Категорія | Поверхня |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `/codeql-security-high/core-auth-secrets` | Auth, secrets, sandbox, Cron і baseline Gateway |
| `/codeql-security-high/channel-runtime-boundary` | Контракти реалізації core channel плюс runtime channel Plugin, Gateway, Plugin SDK, secrets, audit touchpoints |
| `/codeql-security-high/network-ssrf-boundary` | Core SSRF, IP parsing, network guard, web-fetch і поверхні SSRF policy Plugin SDK |
| `/codeql-security-high/mcp-process-tool-boundary` | MCP servers, process execution helpers, outbound delivery і gates виконання tools агентом |
| `/codeql-security-high/plugin-trust-boundary` | Plugin install, loader, manifest, registry, package-manager install, source-loading і trust surfaces package contract Plugin SDK |
### Platform-specific security shards
### Платформоспецифічні security shards
- `CodeQL Android Critical Security` — scheduled Android security shard. Збирає Android app вручну для CodeQL на найменшому Blacksmith Linux runner, прийнятому workflow sanity. Завантажує під `/codeql-critical-security/android`.
- `CodeQL macOS Critical Security` — weekly/manual macOS security shard. Збирає macOS app вручну для CodeQL на Blacksmith macOS, відфільтровує dependency build results із завантаженого SARIF і завантажує під `/codeql-critical-security/macos`. Тримається поза daily defaults, тому що macOS build домінує runtime навіть у чистому стані.
- `CodeQL macOS Critical Security` — weekly/manual macOS security shard. Збирає macOS app вручну для CodeQL на Blacksmith macOS, відфільтровує результати dependency build із завантаженого SARIF і завантажує під `/codeql-critical-security/macos`. Залишається поза daily defaults, бо macOS build домінує runtime навіть коли чистий.
### Категорії Critical Quality
`CodeQL Critical Quality` є відповідним non-security shard. Він запускає лише error-severity, non-security JavaScript/TypeScript quality queries по вузьких high-value surfaces на меншому Blacksmith Linux runner. Його pull request guard навмисно менший за scheduled profile: non-draft PRs запускають лише відповідні shards `agent-runtime-boundary`, `config-boundary`, `core-auth-secrets`, `channel-runtime-boundary`, `gateway-runtime-boundary`, `memory-runtime-boundary`, `mcp-process-runtime-boundary`, `provider-runtime-boundary`, `session-diagnostics-boundary`, `plugin-boundary`, `plugin-sdk-package-contract` і `plugin-sdk-reply-runtime` для змін у коді agent command/model/tool execution і reply dispatch, config schema/migration/IO code, auth/secrets/sandbox/security code, core channel і bundled channel plugin runtime, gateway protocol/server-method, memory runtime/SDK glue, MCP/process/outbound delivery, provider runtime/model catalog, session diagnostics/delivery queues, plugin loader, Plugin SDK/package-contract або Plugin SDK reply runtime. Зміни CodeQL config і quality workflow запускають усі дванадцять PR quality shards.
`CodeQL Critical Quality` є відповідним non-security shard. Він запускає лише error-severity, non-security JavaScript/TypeScript quality queries по вузьких high-value surfaces на меншому Blacksmith Linux runner. Його pull request guard навмисно менший за scheduled profile: non-draft PRs запускають лише відповідні shards `agent-runtime-boundary`, `config-boundary`, `core-auth-secrets`, `channel-runtime-boundary`, `gateway-runtime-boundary`, `memory-runtime-boundary`, `mcp-process-runtime-boundary`, `provider-runtime-boundary`, `session-diagnostics-boundary`, `plugin-boundary`, `plugin-sdk-package-contract` і `plugin-sdk-reply-runtime` для змін у коді agent command/model/tool execution і reply dispatch, config schema/migration/IO code, auth/secrets/sandbox/security code, core channel і bundled channel Plugin runtime, Gateway protocol/server-method, memory runtime/SDK glue, MCP/process/outbound delivery, provider runtime/model catalog, session diagnostics/delivery queues, Plugin loader, Plugin SDK/package-contract або Plugin SDK reply runtime. Зміни CodeQL config і quality workflow запускають усі дванадцять PR quality shards.
Manual dispatch приймає:
@ -364,40 +382,40 @@ Manual dispatch приймає:
profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary
```
Вузькі profiles є teaching/iteration hooks для запуску одного quality shard в ізоляції.
Вузькі profiles є hooks для навчання/ітерації, щоб запускати один quality shard ізольовано.
| Категорія | Поверхня |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/codeql-critical-quality/core-auth-secrets` | Auth, секрети, sandbox, Cron і код межі безпеки Gateway |
| `/codeql-critical-quality/config-boundary` | Схема конфігурації, міграція, нормалізація та контракти IO |
| `/codeql-critical-quality/gateway-runtime-boundary` | Схеми протоколу Gateway і контракти серверних методів |
| `/codeql-critical-quality/channel-runtime-boundary` | Контракти реалізації основного каналу та вбудованого Plugin каналу |
| `/codeql-critical-quality/agent-runtime-boundary` | Виконання команд, диспетчеризація моделей/провайдерів, диспетчеризація й черги автовідповідей, а також runtime-контракти площини керування ACP |
| `/codeql-critical-quality/mcp-process-runtime-boundary` | Сервери MCP і мости інструментів, допоміжні засоби нагляду за процесами та контракти вихідної доставки |
| `/codeql-critical-quality/memory-runtime-boundary` | SDK хоста пам’яті, runtime-фасади пам’яті, псевдоніми Plugin SDK для пам’яті, зв’язувальний код активації runtime пам’яті та команди doctor для пам’яті |
| `/codeql-critical-quality/session-diagnostics-boundary` | Внутрішня логіка черги відповідей, черги доставки сесій, допоміжні засоби прив’язування/доставки вихідних сесій, поверхні діагностичних подій/пакетів журналів і контракти CLI doctor для сесій |
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | Диспетчеризація вхідних відповідей Plugin SDK, допоміжні засоби payload/фрагментації/runtime для відповідей, параметри відповідей каналу, черги доставки та допоміжні засоби прив’язування сесій/тредів |
| `/codeql-critical-quality/provider-runtime-boundary` | Нормалізація каталогу моделей, auth і виявлення провайдерів, реєстрація runtime провайдерів, стандартні налаштування/каталоги провайдерів і реєстри web/search/fetch/embedding |
| `/codeql-critical-quality/ui-control-plane` | Початкове завантаження Control UI, локальне збереження, потоки керування Gateway і runtime-контракти площини керування завданнями |
| `/codeql-critical-quality/web-media-runtime-boundary` | Контракти runtime для основних web fetch/search, медіа IO, розуміння медіа, генерації зображень і генерації медіа |
| `/codeql-critical-quality/plugin-boundary` | Контракти завантажувача, реєстру, публічної поверхні та entrypoint Plugin SDK |
| `/codeql-critical-quality/plugin-sdk-package-contract` | Опубліковане вихідне дерево Plugin SDK з боку пакета та допоміжні засоби контрактів пакетів Plugin |
| Категорія | Поверхня |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/codeql-critical-quality/core-auth-secrets` | Код межі безпеки автентифікації, секретів, пісочниці, Cron і Gateway |
| `/codeql-critical-quality/config-boundary` | Схема конфігурації, міграція, нормалізація та контракти IO |
| `/codeql-critical-quality/gateway-runtime-boundary` | Схеми протоколу Gateway і контракти серверних методів |
| `/codeql-critical-quality/channel-runtime-boundary` | Контракти реалізації основного каналу та вбудованого Plugin каналів |
| `/codeql-critical-quality/agent-runtime-boundary` | Виконання команд, диспетчеризація моделей/провайдерів, диспетчеризація та черги автовідповідей, а також runtime-контракти керівного рівня ACP |
| `/codeql-critical-quality/mcp-process-runtime-boundary` | Сервери MCP і мости інструментів, допоміжні засоби нагляду за процесами та контракти вихідної доставки |
| `/codeql-critical-quality/memory-runtime-boundary` | SDK хоста пам’яті, фасади runtime пам’яті, псевдоніми SDK пам’яті Plugin, зв’язувальний код активації runtime пам’яті та команди doctor пам’яті |
| `/codeql-critical-quality/session-diagnostics-boundary` | Внутрішня реалізація черги відповідей, черги доставки сеансів, допоміжні засоби прив’язування/доставки вихідних сеансів, поверхні діагностичних подій/пакетів журналів і контракти CLI doctor сеансів |
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | Вхідна диспетчеризація відповідей Plugin SDK, допоміжні засоби payload/розбиття на фрагменти/runtime для відповідей, параметри відповідей каналів, черги доставки та допоміжні засоби прив’язування сеансів/потоків |
| `/codeql-critical-quality/provider-runtime-boundary` | Нормалізація каталогу моделей, автентифікація та виявлення провайдерів, реєстрація runtime провайдерів, стандартні параметри/каталоги провайдерів і реєстри web/search/fetch/embedding |
| `/codeql-critical-quality/ui-control-plane` | Bootstrap керівного UI, локальне збереження, керівні потоки Gateway і runtime-контракти керівного рівня завдань |
| `/codeql-critical-quality/web-media-runtime-boundary` | Runtime-контракти основного web fetch/search, media IO, розуміння медіа, генерації зображень і генерації медіа |
| `/codeql-critical-quality/plugin-boundary` | Контракти завантажувача, реєстру, публічної поверхні та точок входу Plugin SDK |
| `/codeql-critical-quality/plugin-sdk-package-contract` | Опубліковане вихідне дерево Plugin SDK на боці пакета та допоміжні засоби контрактів пакетів plugin |
Якість залишається окремо від безпеки, щоб знахідки якості можна було планувати, вимірювати, вимикати або розширювати, не затіняючи сигнал безпеки. Розширення CodeQL для Swift, Python і вбудованих Plugin слід додавати назад як scoped або shard подальшу роботу лише після того, як вузькі профілі матимуть стабільний runtime і сигнал.
Якість залишається окремою від безпеки, щоб висновки щодо якості можна було планувати, вимірювати, вимикати або розширювати без розмивання сигналу безпеки. Розширення CodeQL для Swift, Python і вбудованих plugin слід додавати назад як обмежену або шардовану подальшу роботу лише після того, як вузькі профілі матимуть стабільний runtime і сигнал.
## Робочі процеси обслуговування
## Робочі процеси супроводу
### Docs Agent
Робочий процес `Docs Agent` — це подієва смуга обслуговування Codex для підтримання наявної документації у відповідності до нещодавно приземлених змін. Він не має чистого розкладу: успішний CI-запуск після небот-пушу в `main` може його запустити, а ручний dispatch може запустити його напряму. Виклики від workflow-run пропускаються, коли `main` уже просунувся далі або коли інший непропущений запуск Docs Agent було створено за останню годину. Коли він запускається, він переглядає діапазон комітів від попереднього непропущеного source SHA Docs Agent до поточного `main`, тому один погодинний запуск може охопити всі зміни main, накопичені з останнього проходу документації.
Робочий процес `Docs Agent` — це подієво-керована смуга супроводу Codex для підтримання наявної документації в узгодженості з нещодавно заландженими змінами. Він не має чистого розкладу: успішний CI-запуск після push не-бота в `main` може його запустити, а ручний dispatch може запустити його напряму. Виклики через workflow-run пропускаються, коли `main` уже пішов далі або коли інший непропущений запуск Docs Agent було створено протягом останньої години. Коли він запускається, він переглядає діапазон комітів від попереднього непропущеного source SHA Docs Agent до поточного `main`, тож один погодинний запуск може покрити всі зміни main, накопичені з часу останнього проходу документації.
### Test Performance Agent
Робочий процес `Test Performance Agent` — це подієва смуга обслуговування Codex для повільних тестів. Він не має чистого розкладу: успішний CI-запуск після небот-пушу в `main` може його запустити, але він пропускається, якщо інший виклик workflow-run уже виконувався або виконується цього UTC-дня. Ручний dispatch обходить цей щоденний шлюз активності. Смуга створює згрупований звіт продуктивності Vitest для повного набору тестів, дозволяє Codex робити лише невеликі виправлення продуктивності тестів зі збереженням покриття замість широких рефакторингів, потім повторно запускає звіт повного набору й відхиляє зміни, що зменшують базову кількість прохідних тестів. Якщо базова лінія має тести, що падають, Codex може виправляти лише очевидні збої, а звіт повного набору після агента має пройти перед комітом будь-чого. Коли `main` просувається до приземлення bot push, смуга робить rebase перевіреного патча, повторно запускає `pnpm check:changed` і повторює push; конфліктні застарілі патчі пропускаються. Вона використовує GitHub-hosted Ubuntu, щоб action Codex міг зберігати таку саму безпечну позицію drop-sudo, як і docs agent.
Робочий процес `Test Performance Agent` — це подієво-керована смуга супроводу Codex для повільних тестів. Він не має чистого розкладу: успішний CI-запуск після push не-бота в `main` може його запустити, але він пропускається, якщо інший виклик workflow-run уже виконувався або виконується цього UTC-дня. Ручний dispatch обходить цей добовий бар’єр активності. Смуга будує згрупований звіт продуктивності Vitest для повного набору, дозволяє Codex вносити лише невеликі виправлення продуктивності тестів зі збереженням покриття замість широких рефакторингів, потім повторно запускає звіт повного набору й відхиляє зміни, що зменшують базову кількість прохідних тестів. Якщо базова лінія має failing tests, Codex може виправляти лише очевидні failures, а звіт повного набору після агента має пройти перед будь-яким комітом. Коли `main` просувається до того, як bot push потрапляє в репозиторій, смуга rebase-ить перевірений patch, повторно запускає `pnpm check:changed` і повторює push; конфліктні застарілі patches пропускаються. Вона використовує GitHub-hosted Ubuntu, щоб дія Codex могла зберігати таку саму безпечну позицію drop-sudo, як docs agent.
### Дублікати PR після merge
Робочий процес `Duplicate PRs After Merge` — це ручний maintainer workflow для очищення дублікатів після приземлення. За замовчуванням він працює в dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перед змінами в GitHub він перевіряє, що приземлений PR змержено і що кожен дублікат має або спільне referenced issue, або перетин змінених hunks.
Робочий процес `Duplicate PRs After Merge` — це ручний maintainer workflow для очищення дублікатів після land. За замовчуванням він працює в dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перед змінами в GitHub він перевіряє, що landed PR змержено і що кожен дублікат має або спільне referenced issue, або перетин змінених hunks.
```bash
gh workflow run duplicate-after-merge.yml \
@ -408,27 +426,27 @@ gh workflow run duplicate-after-merge.yml \
## Локальні check gates і changed routing
Логіка локальних changed-lane живе в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний check gate суворіший щодо архітектурних меж, ніж широкий scope платформи CI:
Локальна логіка changed-lane міститься в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний check gate суворіший щодо архітектурних меж, ніж широкий scope CI-платформи:
- зміни core production запускають core prod і core test typecheck плюс core lint/guards;
- зміни лише core test запускають тільки core test typecheck плюс core lint;
- зміни extension production запускають extension prod і extension test typecheck плюс extension lint;
- зміни лише extension test запускають extension test typecheck плюс extension lint;
- зміни core production запускають typecheck core prod і core test, а також core lint/guards;
- зміни лише core test запускають тільки typecheck core test і core lint;
- зміни extension production запускають typecheck extension prod і extension test, а також extension lint;
- зміни лише extension test запускають typecheck extension test і extension lint;
- зміни публічного Plugin SDK або plugin-contract розширюються до extension typecheck, бо extensions залежать від цих core contracts (Vitest extension sweeps залишаються явною тестовою роботою);
- version bumps лише release metadata запускають цільові перевірки version/config/root-dependency;
- невідомі root/config changes fail safe до всіх check lanes.
- version bumps лише release metadata запускають цільові version/config/root-dependency checks;
- невідомі зміни root/config безпечно падають до всіх check lanes.
Локальний changed-test routing живе в `scripts/test-projects.test-support.mjs` і навмисно дешевший за `check:changed`: прямі редагування тестів запускають самі себе, редагування source віддають перевагу явним mappings, потім sibling tests і dependents import-graph. Конфігурація доставки shared group-room є одним із явних mappings: зміни до group visible-reply config, source reply delivery mode або message-tool system prompt проходять через core reply tests плюс регресії доставки Discord і Slack, щоб зміна shared default падала ще до першого PR push. Використовуйте `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed` лише тоді, коли зміна настільки harness-wide, що дешевий mapped set не є надійним proxy.
Локальний changed-test routing міститься в `scripts/test-projects.test-support.mjs` і навмисно дешевший за `check:changed`: прямі зміни тестів запускають самі себе, зміни source віддають перевагу явним мапінгам, потім sibling tests і import-graph dependents. Конфігурація shared group-room delivery є одним з явних мапінгів: зміни до group visible-reply config, source reply delivery mode або системного prompt message-tool маршрутизуються через core reply tests плюс регресії доставки Discord і Slack, щоб зміна shared default впала ще до першого PR push. Використовуйте `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed` лише тоді, коли зміна настільки harness-wide, що дешевий mapped set не є надійним proxy.
## Валідація Testbox
Запускайте Testbox з кореня репозиторію й віддавайте перевагу свіжому warmed box для широкого proof. Перш ніж витрачати повільний gate на box, який було повторно використано, термін дії якого минув або який щойно повідомив про несподівано великий sync, спершу запустіть `pnpm testbox:sanity` всередині box.
Запускайте Testbox із кореня репозиторію і для широкого proof віддавайте перевагу свіжій warmed box. Перед витрачанням повільного gate на box, яку було повторно використано, термін якої сплив або яка щойно повідомила про неочікувано великий sync, спершу запустіть `pnpm testbox:sanity` всередині box.
Sanity check швидко падає, коли зникають обов’язкові root files на кшталт `pnpm-lock.yaml` або коли `git status --short` показує щонайменше 200 tracked deletions. Зазвичай це означає, що стан remote sync не є надійною копією PR; зупиніть цей box і прогрійте свіжий замість налагодження product test failure. Для PR з навмисними large-deletion встановіть `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1` для цього sanity run.
Sanity check швидко падає, коли зникли обов’язкові root files на кшталт `pnpm-lock.yaml` або коли `git status --short` показує щонайменше 200 tracked deletions. Зазвичай це означає, що стан remote sync не є надійною копією PR; зупиніть цю box і прогрійте свіжу замість налагодження product test failure. Для навмисних PR із великими видаленнями встановіть `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1` для цього sanity run.
`pnpm testbox:run` також завершує локальний виклик Blacksmith CLI, який залишається у фазі sync понад п’ять хвилин без post-sync output. Установіть `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0`, щоб вимкнути цей guard, або використайте більше значення в мілісекундах для незвично великих local diffs.
`pnpm testbox:run` також завершує локальний виклик Blacksmith CLI, який залишається у фазі sync понад п’ять хвилин без post-sync output. Установіть `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0`, щоб вимкнути цей guard, або використайте більше значення в мілісекундах для незвично великих локальних diffs.
Crabbox — це другий remote-box шлях, що належить репозиторію, для Linux proof, коли Blacksmith недоступний або коли бажано використати власну cloud capacity. Прогрійте box, hydrate його через project workflow, потім запускайте команди через Crabbox CLI:
Crabbox — це другий, repo-owned шлях remote-box для Linux proof, коли Blacksmith недоступний або коли бажаніша owned cloud capacity. Прогрійте box, hydrate її через project workflow, потім запускайте команди через Crabbox CLI:
```bash
pnpm crabbox:warmup -- --idle-timeout 90m
@ -437,7 +455,7 @@ pnpm crabbox:run -- --id <cbx_id> --shell "OPENCLAW_TESTBOX=1 pnpm check:changed
pnpm crabbox:stop -- <cbx_id>
```
`.crabbox.yaml` містить стандартні налаштування provider, sync і GitHub Actions hydration. Він виключає локальний `.git`, щоб hydrated Actions checkout зберігав власні remote Git metadata замість синхронізації maintainer-local remotes і object stores, а також виключає локальні runtime/build artifacts, які ніколи не слід передавати. `.github/workflows/crabbox-hydrate.yml` відповідає за checkout, налаштування Node/pnpm, fetch `origin/main` і non-secret environment handoff, який пізніші команди `crabbox run --id <cbx_id>` використовують як source.
`.crabbox.yaml` визначає provider, sync і стандартні параметри GitHub Actions hydration. Вона виключає локальний `.git`, щоб hydrated Actions checkout зберігав власні remote Git metadata замість sync maintainer-local remotes і object stores, а також виключає локальні runtime/build artifacts, які ніколи не слід передавати. `.github/workflows/crabbox-hydrate.yml` визначає checkout, налаштування Node/pnpm, fetch `origin/main` і non-secret environment handoff, який пізніші команди `crabbox run --id <cbx_id>` підвантажують як source.
## Пов’язане